Ignore:
Timestamp:
Nov 1, 2016, 7:26:35 PM (9 years ago)
Author:
bird
Message:

lib/nt: Got fts-nt halfways working, quite a few NT interface changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/nt/ntstat.c

    r2880 r2985  
    9393
    9494
    95 static int birdIsFileExecutableW(WCHAR const *pwcName, ULONG cwcName)
     95/**
     96 * @a pwcName could be the full path.
     97 */
     98static int birdIsFileExecutableW(WCHAR const *pwcName, size_t cwcName)
    9699{
    97100    char            szExt[8];
     
    128131
    129132static unsigned short birdFileInfoToMode(HANDLE hFile, ULONG fAttribs, const char *pszName,
    130                                          MY_FILE_NAME_INFORMATION *pNameInfo, __int16 *pfIsDirSymlink)
     133                                         const wchar_t *pwszName, size_t cbNameW, __int16 *pfIsDirSymlink)
    131134{
    132135    unsigned short fMode;
     
    169172        || (pszName
    170173            ? birdIsFileExecutable(pszName)
    171             : birdIsFileExecutableW(pNameInfo->FileName, pNameInfo->FileNameLength)) )
     174            : birdIsFileExecutableW(pwszName, cbNameW)) )
    172175        fMode |= S_IXOTH | S_IXGRP | S_IXUSR;
    173176
     
    186189void birdStatFillFromFileIdFullDirInfo(BirdStat_T *pStat, MY_FILE_ID_FULL_DIR_INFORMATION const *pBuf, const char *pszPath)
    187190{
    188     pStat->st_mode          = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes, pszPath,
    189                                                  NULL, &pStat->st_dirsymlink);
     191    pStat->st_mode          = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes,
     192                                                 pszPath, pBuf->FileName, pBuf->FileNameLength, &pStat->st_dirsymlink);
    190193    pStat->st_padding0[0]   = 0;
    191194    pStat->st_padding0[1]   = 0;
     
    218221void birdStatFillFromFileIdBothDirInfo(BirdStat_T *pStat, MY_FILE_ID_BOTH_DIR_INFORMATION const *pBuf, const char *pszPath)
    219222{
    220     pStat->st_mode          = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes, pszPath,
    221                                                  NULL, &pStat->st_dirsymlink);
     223    pStat->st_mode          = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes,
     224                                                 pszPath, pBuf->FileName, pBuf->FileNameLength, &pStat->st_dirsymlink);
    222225    pStat->st_padding0[0]   = 0;
    223226    pStat->st_padding0[1]   = 0;
     
    250253void birdStatFillFromFileBothDirInfo(BirdStat_T *pStat, MY_FILE_BOTH_DIR_INFORMATION const *pBuf, const char *pszPath)
    251254{
    252     pStat->st_mode          = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes, pszPath,
    253                                                  NULL, &pStat->st_dirsymlink);
     255    pStat->st_mode          = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes,
     256                                                 pszPath, pBuf->FileName, pBuf->FileNameLength, &pStat->st_dirsymlink);
    254257    pStat->st_padding0[0]   = 0;
    255258    pStat->st_padding0[1]   = 0;
     
    272275
    273276
    274 int birdStatHandle(HANDLE hFile, BirdStat_T *pStat, const char *pszPath)
     277int birdStatHandle2(HANDLE hFile, BirdStat_T *pStat, const char *pszPath, const wchar_t *pwszPath)
    275278{
    276279    int                      rc;
     
    290293        {
    291294            pStat->st_mode          = birdFileInfoToMode(hFile, pAll->BasicInformation.FileAttributes, pszPath,
    292                                                          &pAll->NameInformation, &pStat->st_dirsymlink);
     295                                                         pAll->NameInformation.FileNamepAll->NameInformation.FileNameLength,
     296                                                         &pStat->st_dirsymlink);
    293297            pStat->st_padding0[0]   = 0;
    294298            pStat->st_padding0[1]   = 0;
     
    352356    if (MY_NT_SUCCESS(rcNt))
    353357        rcNt = Ios.u.Status;
    354     if (MY_NT_SUCCESS(rcNt) && !pszPath)
     358    if (MY_NT_SUCCESS(rcNt) && !pszPath && !pwszPath)
    355359    {
    356360        cbNameInfo = 0x10020;
     
    364368    {
    365369        pStat->st_mode          = birdFileInfoToMode(hFile, BasicInfo.FileAttributes, pszPath,
    366                                                      pNameInfo, &pStat->st_dirsymlink);
     370                                                     pNameInfo ? pNameInfo->FileName : pwszPath,
     371                                                     pNameInfo ? pNameInfo->FileNameLength
     372                                                     : pwszPath ? wcslen(pwszPath) * sizeof(wchar_t) : 0,
     373                                                     &pStat->st_dirsymlink);
    367374        pStat->st_padding0[0]   = 0;
    368375        pStat->st_padding0[1]   = 0;
     
    413420
    414421
     422int birdStatHandle(HANDLE hFile, BirdStat_T *pStat, const char *pszPath)
     423{
     424    return birdStatHandle2(hFile, pStat, pszPath, NULL);
     425}
     426
     427
    415428/**
    416429 * Generates a device number from the volume information.
     
    460473
    461474
    462 static int birdStatInternal(const char *pszPath, BirdStat_T *pStat, int fFollow)
     475static int birdStatInternal(HANDLE hRoot, const char *pszPath, BirdStat_T *pStat, int fFollow)
    463476{
    464477    int rc;
    465     HANDLE hFile = birdOpenFile(pszPath,
    466                                 FILE_READ_ATTRIBUTES,
    467                                 FILE_ATTRIBUTE_NORMAL,
    468                                 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    469                                 FILE_OPEN,
    470                                 FILE_OPEN_FOR_BACKUP_INTENT | (fFollow ? 0 : FILE_OPEN_REPARSE_POINT),
    471                                 OBJ_CASE_INSENSITIVE);
     478    HANDLE hFile = birdOpenFileEx(hRoot, pszPath,
     479                                  FILE_READ_ATTRIBUTES,
     480                                  FILE_ATTRIBUTE_NORMAL,
     481                                  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
     482                                  FILE_OPEN,
     483                                  FILE_OPEN_FOR_BACKUP_INTENT | (fFollow ? 0 : FILE_OPEN_REPARSE_POINT),
     484                                  OBJ_CASE_INSENSITIVE);
    472485    if (hFile != INVALID_HANDLE_VALUE)
    473486    {
    474         rc = birdStatHandle(hFile, pStat, pszPath);
     487        rc = birdStatHandle2(hFile, pStat, pszPath, NULL);
    475488        birdCloseFile(hFile);
    476489
     
    500513        {
    501514            MY_UNICODE_STRING NameUniStr;
    502             hFile = birdOpenParentDir(pszPath,
     515            hFile = birdOpenParentDir(hRoot, pszPath,
    503516                                      FILE_READ_DATA | SYNCHRONIZE,
    504517                                      FILE_ATTRIBUTE_NORMAL,
     
    552565
    553566
     567static int birdStatInternalW(HANDLE hRoot, const wchar_t *pwszPath, BirdStat_T *pStat, int fFollow)
     568{
     569    int rc;
     570    HANDLE hFile = birdOpenFileExW(hRoot, pwszPath,
     571                                   FILE_READ_ATTRIBUTES,
     572                                   FILE_ATTRIBUTE_NORMAL,
     573                                   FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
     574                                   FILE_OPEN,
     575                                   FILE_OPEN_FOR_BACKUP_INTENT | (fFollow ? 0 : FILE_OPEN_REPARSE_POINT),
     576                                   OBJ_CASE_INSENSITIVE);
     577    if (hFile != INVALID_HANDLE_VALUE)
     578    {
     579        rc = birdStatHandle2(hFile, pStat, NULL, pwszPath);
     580        birdCloseFile(hFile);
     581    }
     582    else
     583    {
     584        /*
     585         * On things like pagefile.sys we may get sharing violation.  We fall
     586         * back on directory enumeration for dealing with that.
     587         */
     588        if (   errno == ETXTBSY
     589            && wcschr(pwszPath, '*') == NULL /* Serious paranoia... */
     590            && wcschr(pwszPath, '?') == NULL)
     591        {
     592            MY_UNICODE_STRING NameUniStr;
     593            hFile = birdOpenParentDirW(hRoot, pwszPath,
     594                                       FILE_READ_DATA | SYNCHRONIZE,
     595                                       FILE_ATTRIBUTE_NORMAL,
     596                                       FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
     597                                       FILE_OPEN,
     598                                       FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
     599                                       OBJ_CASE_INSENSITIVE,
     600                                       &NameUniStr);
     601            if (hFile != INVALID_HANDLE_VALUE)
     602            {
     603                MY_FILE_ID_FULL_DIR_INFORMATION *pBuf;
     604                ULONG               cbBuf = sizeof(*pBuf) + NameUniStr.MaximumLength + 1024;
     605                MY_IO_STATUS_BLOCK  Ios;
     606                MY_NTSTATUS         rcNt;
     607
     608                pBuf = (MY_FILE_ID_FULL_DIR_INFORMATION *)alloca(cbBuf);
     609                Ios.u.Status    = -1;
     610                Ios.Information = -1;
     611                rcNt = g_pfnNtQueryDirectoryFile(hFile, NULL, NULL, NULL, &Ios, pBuf, cbBuf,
     612                                                 MyFileIdFullDirectoryInformation, FALSE, &NameUniStr, TRUE);
     613                if (MY_NT_SUCCESS(rcNt))
     614                    rcNt = Ios.u.Status;
     615                if (MY_NT_SUCCESS(rcNt))
     616                {
     617                    /*
     618                     * Convert the data.
     619                     */
     620                    birdStatFillFromFileIdFullDirInfo(pStat, pBuf, NULL);
     621
     622                    /* Get the serial number, reusing the buffer from above. */
     623                    rcNt = birdQueryVolumeDeviceNumber(hFile, (MY_FILE_FS_VOLUME_INFORMATION *)pBuf, cbBuf, &pStat->st_dev);
     624                    if (MY_NT_SUCCESS(rcNt))
     625                        rc = 0;
     626                    else
     627                        rc = birdSetErrnoFromNt(rcNt);
     628                }
     629
     630                birdFreeNtPath(&NameUniStr);
     631                birdCloseFile(hFile);
     632
     633                if (MY_NT_SUCCESS(rcNt))
     634                    return 0;
     635                birdSetErrnoFromNt(rcNt);
     636            }
     637        }
     638        rc = -1;
     639    }
     640
     641    return rc;
     642}
     643
     644
    554645/**
    555646 * Implements UNIX fstat().
     
    570661        {
    571662            case FILE_TYPE_DISK:
    572                 rc = birdStatHandle(hFile, pStat, NULL);
     663                rc = birdStatHandle2(hFile, pStat, NULL, NULL);
    573664                break;
    574665
     
    657748int birdStatFollowLink(const char *pszPath, BirdStat_T *pStat)
    658749{
    659     return birdStatInternal(pszPath, pStat, 1 /*fFollow*/);
     750    return birdStatInternal(NULL, pszPath, pStat, 1 /*fFollow*/);
     751}
     752
     753
     754/**
     755 * Implements UNIX stat().
     756 */
     757int birdStatFollowLinkW(const wchar_t *pwszPath, BirdStat_T *pStat)
     758{
     759    return birdStatInternalW(NULL, pwszPath, pStat, 1 /*fFollow*/);
    660760}
    661761
     
    666766int birdStatOnLink(const char *pszPath, BirdStat_T *pStat)
    667767{
    668     return birdStatInternal(pszPath, pStat, 0 /*fFollow*/);
     768    return birdStatInternal(NULL, pszPath, pStat, 0 /*fFollow*/);
     769}
     770
     771
     772/**
     773 * Implements UNIX lstat().
     774 */
     775int birdStatOnLinkW(const wchar_t *pwszPath, BirdStat_T *pStat)
     776{
     777    return birdStatInternalW(NULL, pwszPath, pStat, 0 /*fFollow*/);
     778}
     779
     780
     781/**
     782 * Implements an API like UNIX fstatat().
     783 *
     784 * @returns 0 on success, -1 and errno on failure.
     785 * @param   hRoot               NT handle pwszPath is relative to.
     786 * @param   pszPath             The path.
     787 * @param   pStat               Where to return stats.
     788 * @param   fFollowLink         Whether to follow links.
     789 */
     790int birdStatAt(HANDLE hRoot, const char *pszPath, BirdStat_T *pStat, int fFollowLink)
     791{
     792    return birdStatInternal(hRoot, pszPath, pStat, fFollowLink != 0);
     793}
     794
     795
     796/**
     797 * Implements an API like UNIX fstatat().
     798 *
     799 * @returns 0 on success, -1 and errno on failure.
     800 * @param   hRoot               NT handle pwszPath is relative to.
     801 * @param   pwszPath            The path.
     802 * @param   pStat               Where to return stats.
     803 * @param   fFollowLink         Whether to follow links.
     804 */
     805int birdStatAtW(HANDLE hRoot, const wchar_t *pwszPath, BirdStat_T *pStat, int fFollowLink)
     806{
     807    return birdStatInternalW(hRoot, pwszPath, pStat, fFollowLink != 0);
    669808}
    670809
Note: See TracChangeset for help on using the changeset viewer.