Пример #1
0
/*++

Function :

    PAL_GetPALDirectoryW
    
    Returns the fully qualified path name
    where the PALL DLL was loaded from.
    
    On failure it returns FALSE and sets the 
    proper LastError code.

--*/
BOOL 
PAL_GetPALDirectoryW(PathWCharString& lpDirectoryName) 
{
    LPCWSTR lpFullPathAndName = NULL;
    LPCWSTR lpEndPoint = NULL;
    BOOL bRet = FALSE;

    PERF_ENTRY(PAL_GetPALDirectoryW);

    MODSTRUCT *module = LOADGetPalLibrary();
    if (!module)
    {
        SetLastError(ERROR_INTERNAL_ERROR);
        goto EXIT;
    }
    lpFullPathAndName = module->lib_name;
    if (lpFullPathAndName == NULL)
    {
        SetLastError(ERROR_INTERNAL_ERROR);
        goto EXIT;
    }
    lpEndPoint = PAL_wcsrchr( lpFullPathAndName, '/' );
    if ( lpEndPoint )
    {
        /* The path that we return is required to have
           the trailing slash on the end.*/
        lpEndPoint++;
    
        
        if(!lpDirectoryName.Set(lpFullPathAndName,lpEndPoint - lpFullPathAndName))
        {
            ASSERT( "The buffer was not large enough.\n" );
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            goto EXIT;
        }

        bRet = TRUE;
    }
    else
    {
        ASSERT( "Unable to determine the path.\n" );
        /* Error path, should not be executed. */
        SetLastError( ERROR_INTERNAL_ERROR );
    }
    
EXIT:    
    PERF_EXIT(PAL_GetPALDirectoryW);
    return bRet;
}
Пример #2
0
/*++
Function:
  _wsplitpath

See MSDN doc.

Notes :
    This implementation ignores drive letters as they should not be
    present. If the drive argument is non-NULL, it always returns an empty
    string.
    File names in which the only period is at the beginning (like .bashrc, but
    not .bashrc.bak), the file is treated as having no extension
    (fname is ".bashrc", ext is "")

--*/
void
__cdecl
_wsplitpath(
            const wchar_16 *dospath,
            wchar_16 *drive,
            wchar_16 *dir,
            wchar_16 *fname,
            wchar_16 *ext)
{
    WCHAR path[_MAX_PATH+1];
    LPCWSTR slash_ptr = NULL;
    LPCWSTR period_ptr = NULL;
    INT size = 0;

    PERF_ENTRY(_wsplitpath);
    ENTRY("_wsplitpath (path=%p (%S), drive=%p, dir=%p, fname=%p, ext=%p)\n",
          path?path:W16_NULLSTRING,
          path?path:W16_NULLSTRING, drive, dir, fname, ext);

    /* Do performance intensive error checking only in debug builds.
    
    NOTE: This function must fail predictably across all platforms.
    Under Windows this function throw an access violation if NULL
    was passed in as the value for path.

    */
#if _DEBUG
    if ( !dospath )
    {
        ERROR( "path cannot be NULL!\n" );
    }
#endif
    
    if( lstrlenW( dospath ) >= _MAX_PATH )
    {
        ERROR("Path length is > _MAX_PATH (%d)!\n", _MAX_PATH);
	ON_ERROR;
    }


    PAL_wcscpy(path, dospath);
    FILEDosToUnixPathW(path);

    /* no drive letters in the PAL */
    if( drive != NULL )
    {
        drive[0] = 0;
    }

    /* find last path separator char */
    slash_ptr = PAL_wcsrchr(path, '/');

    if( slash_ptr == NULL )
    {
        TRACE("No path separator in path\n");
        slash_ptr = path - 1;
    }
    /* find extension separator, if any */
    period_ptr = PAL_wcsrchr(path, '.');

    /* make sure we only consider periods after the last path separator */
    if( period_ptr < slash_ptr )
    {
        period_ptr = NULL;
    }

    /* if the only period in the file is a leading period (denoting a hidden
       file), don't treat what follows as an extension */
    if( period_ptr == slash_ptr+1 )
    {
        period_ptr = NULL;
    }

    if( period_ptr == NULL )
    {
        TRACE("No extension in path\n");
        period_ptr = path + lstrlenW(path);
    }

    size = slash_ptr - path + 1;
    if( dir != NULL )
    {
        INT i;

        if( (size + 1 ) > _MAX_DIR )
        {
            ERROR("Directory component needs %d characters, _MAX_DIR is %d\n",
                  size+1, _MAX_DIR);
            ON_ERROR;
        }
        
        memcpy(dir, path, size*sizeof(WCHAR));
        dir[size] = 0;

        /* only allow / separators in returned path */
        i = 0;
        while( dir[ i ] )
        {
            if( dir[ i ] == '\\' )
            {
                dir[i]='/';
            }
            i++;
        }
    }

    size = period_ptr-slash_ptr-1;
    if( fname != NULL )
    {
        if( (size+1) > _MAX_FNAME )
        {
            ERROR("Filename component needs %d characters, _MAX_FNAME is %d\n",
                 size+1, _MAX_FNAME);
            ON_ERROR;
        }
        memcpy(fname, slash_ptr+1, size*sizeof(WCHAR));
        fname[size] = 0;
    }

    size = 1 + lstrlenW( period_ptr );
    if( ext != NULL )
    {
        if( size > _MAX_EXT )
        {
            ERROR("Extension component needs %d characters, _MAX_EXT is %d\n",
                 size, _MAX_EXT);
            ON_ERROR;
        }
        memcpy(ext, period_ptr, size*sizeof(WCHAR));
        ext[size-1] = 0;
    }
    
    TRACE("Path components are '%S' '%S' '%S'\n", dir, fname, ext);

done:
    
    LOGEXIT("_wsplitpath returns.\n");
    PERF_EXIT(_wsplitpath);
}
Пример #3
0
/*++
Function:
  SearchPathW

See MSDN doc.

PAL-specific notes :
-lpPath must be non-NULL; path delimiters are platform-dependent (':' for Unix)
-lpFileName must be non-NULL, may be an absolute path
-lpExtension must be NULL
-lpFilePart (if non-NULL) doesn't need to be used (but we do)
--*/
DWORD
PALAPI
SearchPathW(
    IN LPCWSTR lpPath,
    IN LPCWSTR lpFileName,
    IN LPCWSTR lpExtension,
    IN DWORD nBufferLength,
    OUT LPWSTR lpBuffer,
    OUT LPWSTR *lpFilePart
    )
{
    DWORD nRet = 0;
    WCHAR FullPath[MAX_PATH];
    LPCWSTR pPathStart;
    LPCWSTR pPathEnd;
    size_t PathLength;
    size_t FileNameLength;
    DWORD dw;
    char AnsiPath[MAX_PATH];
    WCHAR CanonicalPath[MAX_PATH];

    PERF_ENTRY(SearchPathW);
    ENTRY("SearchPathW(lpPath=%p (%S), lpFileName=%p (%S), lpExtension=%p, "
          "nBufferLength=%u, lpBuffer=%p, lpFilePart=%p)\n",
	  lpPath,
	  lpPath, lpFileName, lpFileName, lpExtension, nBufferLength, lpBuffer, 
          lpFilePart);

    /* validate parameters */
    
    if(NULL == lpPath)
    {
        ASSERT("lpPath may not be NULL\n");
        SetLastError(ERROR_INVALID_PARAMETER);
        goto done;
    }
    if(NULL == lpFileName)
    {
        ASSERT("lpFileName may not be NULL\n");
        SetLastError(ERROR_INVALID_PARAMETER);
        goto done;
    }
    if(NULL != lpExtension)
    {
        ASSERT("lpExtension must be NULL, is %p instead\n", lpExtension);
        SetLastError(ERROR_INVALID_PARAMETER);
        goto done;
    }          

    /* special case : if file name contains absolute path, don't search the 
       provided path */
    if('\\' == lpFileName[0] || '/' == lpFileName[0])
    {
        /* Canonicalize the path to deal with back-to-back '/', etc. */
        dw = GetFullPathNameW(lpFileName, MAX_PATH, CanonicalPath, NULL);
        if (dw == 0 || dw >= MAX_PATH) 
        {
            WARN("couldn't canonicalize path <%S>, error is %#x. failing.\n",
                 lpPath, GetLastError());
            SetLastError(ERROR_INVALID_PARAMETER);
            goto done;
        }

        /* see if the file exists */
	WideCharToMultiByte(CP_ACP, 0, CanonicalPath, -1,
			    AnsiPath, MAX_PATH, NULL, NULL);
        if(0 == access(AnsiPath, F_OK))
        {
            /* found it */
            nRet = dw;
        }
    }
    else
    {
        LPCWSTR pNextPath;

        pNextPath = lpPath;
    
        FileNameLength = PAL_wcslen(lpFileName);

        while (*pNextPath) 
        {
            pPathStart = pNextPath;
    
            /* get a pointer to the end of the first path in pPathStart */
            pPathEnd = PAL_wcschr(pPathStart, ':');
            if (!pPathEnd)
            {
                pPathEnd = pPathStart + PAL_wcslen(pPathStart);
                /* we want to break out of the loop after this pass, so let
                   *pNextPath be '\0' */
                pNextPath = pPathEnd;
            }
            else
            {
                /* point to the next component in the path string */
                pNextPath = pPathEnd+1;
            }
    
            PathLength = pPathEnd-pPathStart;
    
            if (PathLength+FileNameLength+1 >= MAX_PATH) 
            {
                /* The path+'/'+file length is too long.  Skip it. */
                WARN("path component %.*S is too long, skipping it\n", 
                     (int)PathLength, pPathStart);
                continue;
            }
            else if(0 == PathLength)
            {
                /* empty component : there were 2 consecutive ':' */
                continue;
            }
    
            /* Construct a pathname by concatenating one path from lpPath, '/' 
               and lpFileName */
            memcpy(FullPath, pPathStart, PathLength*sizeof(WCHAR));
            FullPath[PathLength] = '/';
            PAL_wcscpy(&FullPath[PathLength+1], lpFileName);
    
            /* Canonicalize the path to deal with back-to-back '/', etc. */
            dw = GetFullPathNameW(FullPath, MAX_PATH,
                                  CanonicalPath, NULL);
            if (dw == 0 || dw >= MAX_PATH) 
            {
                /* Call failed - possibly low memory.  Skip the path */
                WARN("couldn't canonicalize path <%S>, error is %#x. "
                     "skipping it\n", FullPath, GetLastError());
                continue;
            }
    
            /* see if the file exists */
            WideCharToMultiByte(CP_ACP, 0, CanonicalPath, -1,
                                AnsiPath, MAX_PATH, NULL, NULL);
            if(0 == access(AnsiPath, F_OK))
            {
                /* found it */
                nRet = dw;
                break;
            }
        }
    }

    if (nRet == 0) 
    {
       /* file not found anywhere; say so. in Windows, this always seems to say
          FILE_NOT_FOUND, even if path doesn't exist */
       SetLastError(ERROR_FILE_NOT_FOUND);
    }
    else
    {
        /* find out the required buffer size, copy path to buffer if it's 
           large enough */
        nRet = PAL_wcslen(CanonicalPath)+1;
        if(nRet <= nBufferLength)
        {
            if(NULL == lpBuffer)
            {
                /* Windows merily crashes here, but let's not */
                ERROR("caller told us buffer size was %d, but buffer is NULL\n",
                      nBufferLength);
                SetLastError(ERROR_INVALID_PARAMETER);
                nRet = 0;
                goto done;
            }
            PAL_wcscpy(lpBuffer, CanonicalPath);

            /* don't include the null-terminator in the count if buffer was 
               large enough */
            nRet--;
            
            if(NULL != lpFilePart)
            {
                *lpFilePart = PAL_wcsrchr(lpBuffer, '/');
                if(NULL == *lpFilePart)
                {
                    ASSERT("no '/' in full path!\n");
                }
                else
                {
                    /* point to character after last '/' */
                    (*lpFilePart)++;
                }
            }
        }
    }
done:
    LOGEXIT("SearchPathW returns DWORD %u\n", nRet);
    PERF_EXIT(SearchPathW);
    return nRet;
}
Пример #4
0
/*++

Function :

    PAL_GetPALDirectoryW
    
    Returns the fully qualified path name
    where the PALL DLL was loaded from.
    
    On failure it returns FALSE and sets the 
    proper LastError code.
    
See rotor_pal.doc for more details.

--*/
BOOL 
PALAPI
PAL_GetPALDirectoryW( OUT LPWSTR lpDirectoryName, IN UINT cchDirectoryName ) 
{
    LPWSTR lpFullPathAndName = NULL;
    LPWSTR lpEndPoint = NULL;
    BOOL bRet = FALSE;

    PERF_ENTRY(PAL_GetPALDirectoryW);
    ENTRY( "PAL_GetPALDirectoryW( %p, %d )\n", lpDirectoryName, cchDirectoryName );

    MODSTRUCT *module = LOADGetPalLibrary();
    if (!module)
    {
        SetLastError(ERROR_INTERNAL_ERROR);
        goto EXIT;
    }
    lpFullPathAndName = module->lib_name;
    if (lpFullPathAndName == NULL)
    {
        SetLastError(ERROR_INTERNAL_ERROR);
        goto EXIT;
    }
    lpEndPoint = PAL_wcsrchr( lpFullPathAndName, '/' );
    if ( lpEndPoint )
    {
        /* The path that we return is required to have
           the trailing slash on the end.*/
        lpEndPoint++;
    }
    if ( lpFullPathAndName && lpEndPoint && *lpEndPoint != '\0' )
    {
        while ( cchDirectoryName - 1 && lpFullPathAndName != lpEndPoint )
        {
            *lpDirectoryName = *lpFullPathAndName;
            lpFullPathAndName++;
            lpDirectoryName++;
            cchDirectoryName--;
        }
            
        if ( lpFullPathAndName == lpEndPoint )
        {
            *lpDirectoryName = '\0';
            bRet = TRUE;
            goto EXIT;
        }
        else
        {
            ASSERT( "The buffer was not large enough.\n" );
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            goto EXIT;
        }
    }
    else
    {
        ASSERT( "Unable to determine the path.\n" );
    }
    
    /* Error path, should not be executed. */
    SetLastError( ERROR_INTERNAL_ERROR );
EXIT:    
    LOGEXIT( "PAL_GetPALDirectoryW returns BOOL %d.\n", bRet);
    PERF_EXIT(PAL_GetPALDirectoryW);
    return bRet;
}