VirtualBox

Changeset 2704 in kBuild for trunk/src


Ignore:
Timestamp:
Nov 21, 2013 1:26:52 AM (11 years ago)
Author:
bird
Message:

Drop the w32 createfile option, implemented sharing-violation fallback for stat() and lstat().

Location:
trunk/src/lib/nt
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/nt/nthlp.h

    r2702 r2704  
    5656HANDLE      birdOpenFile(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess,
    5757                         ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs);
     58HANDLE      birdOpenParentDir(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess,
     59                              ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
     60                              MY_UNICODE_STRING *pNameUniStr);
    5861void        birdCloseFile(HANDLE hFile);
     62void        birdFreeNtPath(MY_UNICODE_STRING *pNtPath);
    5963
    6064
  • trunk/src/lib/nt/nthlpfs.c

    r2703 r2704  
    3636
    3737
     38/*******************************************************************************
     39*   Global Variables                                                           *
     40*******************************************************************************/
     41static int g_fHaveOpenReparsePoint = -1;
     42
     43
    3844
    3945static int birdHasTrailingSlash(const char *pszPath)
     
    7177}
    7278
    73 #ifndef BIRD_USE_WIN32
    7479
    7580static int birdDosToNtPath(const char *pszPath, MY_UNICODE_STRING *pNtPath)
     
    112117
    113118
    114 static void birdFreeNtPath(MY_UNICODE_STRING *pNtPath)
     119void birdFreeNtPath(MY_UNICODE_STRING *pNtPath)
    115120{
    116121    HeapFree(GetProcessHeap(), 0, pNtPath->Buffer);
    117122    pNtPath->Buffer = NULL;
    118 }
    119 
    120 #endif /* !BIRD_USE_WIN32 */
    121 
    122 
    123 HANDLE birdOpenFile(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess,
    124                     ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
    125 {
    126     static int          s_fHaveOpenReparsePoint = -1;
    127     HANDLE              hFile;
    128 #ifdef BIRD_USE_WIN32
    129     SECURITY_ATTRIBUTES SecAttr;
    130     DWORD               dwErr;
    131     DWORD               fW32Disp;
    132     DWORD               fW32Flags;
    133 #else
    134     MY_UNICODE_STRING   NtPath;
    135     MY_NTSTATUS         rcNt;
    136 #endif
    137 
    138     birdResolveImports();
    139 
    140     if (birdIsPathDirSpec(pszPath))
    141         fCreateOptions |= FILE_DIRECTORY_FILE;
     123    pNtPath->Length = 0;
     124    pNtPath->MaximumLength = 0;
     125}
     126
     127
     128static MY_NTSTATUS birdOpenFileInternal(MY_UNICODE_STRING *pNtPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
     129                                        ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
     130                                        HANDLE *phFile)
     131{
     132    MY_IO_STATUS_BLOCK      Ios;
     133    MY_OBJECT_ATTRIBUTES    ObjAttr;
     134    MY_NTSTATUS             rcNt;
     135
    142136    if (  (fCreateOptions & FILE_OPEN_REPARSE_POINT)
    143         && s_fHaveOpenReparsePoint == 0)
     137        && g_fHaveOpenReparsePoint == 0)
    144138        fCreateOptions &= ~FILE_OPEN_REPARSE_POINT;
    145139
    146 #ifdef BIRD_USE_WIN32
    147     /* NT -> W32 */
    148 
    149     SecAttr.nLength              = sizeof(SecAttr);
    150     SecAttr.lpSecurityDescriptor = NULL;
    151     SecAttr.bInheritHandle       = fObjAttribs & OBJ_INHERIT ? TRUE : FALSE;
    152 
    153     fW32Flags = 0;
    154     if (!(fObjAttribs & OBJ_CASE_INSENSITIVE))
    155         fW32Flags |= FILE_FLAG_POSIX_SEMANTICS;
    156     if (fCreateOptions & FILE_OPEN_FOR_BACKUP_INTENT)
    157         fW32Flags |= FILE_FLAG_BACKUP_SEMANTICS;
    158     if (fCreateOptions & FILE_OPEN_REPARSE_POINT)
    159         fW32Flags |= FILE_FLAG_OPEN_REPARSE_POINT;
    160     //?? if (fCreateOptions & FILE_DIRECTORY_FILE)
    161     //??    fW32Flags |= ;
    162 
    163     switch (fCreateDisposition)
    164     {
    165         case FILE_OPEN:             fW32Disp = OPEN_EXISTING; break;
    166         case FILE_CREATE:           fW32Disp = CREATE_NEW; break;
    167         case FILE_OPEN_IF:          fW32Disp = OPEN_ALWAYS; break;
    168         case FILE_OVERWRITE_IF:     fW32Disp = CREATE_ALWAYS; break;
    169         default:
    170 # ifndef NDEBUG
    171             __debugbreak();
    172 # endif
    173             return INVALID_HANDLE_VALUE;
    174     }
    175 
    176     hFile = CreateFileA(pszPath, fDesiredAccess, fShareAccess, &SecAttr, fW32Disp, fW32Flags, NULL /*hTemplateFile*/);
    177     if (hFile != INVALID_HANDLE_VALUE)
    178         return hFile;
    179 
    180     dwErr = GetLastError();
    181 
    182     /* Deal with FILE_FLAG_OPEN_REPARSE_POINT the first times around. */
    183     if (   dwErr == ERROR_INVALID_PARAMETER
    184         && s_fHaveOpenReparsePoint < 0
    185         && (fCreateOptions & FILE_OPEN_REPARSE_POINT) )
     140    Ios.Information = -1;
     141    Ios.u.Status = 0;
     142    MyInitializeObjectAttributes(&ObjAttr, pNtPath, fObjAttribs, NULL /*hRoot*/, NULL /*pSecAttr*/);
     143
     144    rcNt = g_pfnNtCreateFile(phFile,
     145                             fDesiredAccess,
     146                             &ObjAttr,
     147                             &Ios,
     148                             NULL,   /* cbFileInitialAlloc */
     149                             fFileAttribs,
     150                             fShareAccess,
     151                             fCreateDisposition,
     152                             fCreateOptions,
     153                             NULL,   /* pEaBuffer */
     154                             0);     /* cbEaBuffer*/
     155    if (   rcNt == STATUS_INVALID_PARAMETER
     156        && g_fHaveOpenReparsePoint < 0
     157        && (fCreateOptions & FILE_OPEN_REPARSE_POINT))
    186158    {
    187159        fCreateOptions &= ~FILE_OPEN_REPARSE_POINT;
    188         fW32Flags      &= ~FILE_FLAG_OPEN_REPARSE_POINT;
    189         hFile = CreateFileA(pszPath, fDesiredAccess, fFileAttribs, &SecAttr, fW32Disp, fW32Flags, NULL /*hTemplateFile*/);
    190         if (hFile != INVALID_HANDLE_VALUE)
    191         {
    192             s_fHaveOpenReparsePoint = 0;
    193             return hFile;
    194         }
    195     }
    196 
    197     birdSetErrnoFromWin32(dwErr);
    198 
    199 #else  /* !BIRD_USE_WIN32 */
    200 
    201     /*
    202      * Call the NT API directly.
    203      */
    204     if (birdDosToNtPath(pszPath, &NtPath) == 0)
    205     {
    206         MY_IO_STATUS_BLOCK      Ios;
    207         MY_OBJECT_ATTRIBUTES    ObjAttr;
    208160
    209161        Ios.Information = -1;
    210162        Ios.u.Status = 0;
    211 
    212         MyInitializeObjectAttributes(&ObjAttr, &NtPath, fObjAttribs, NULL /*hRoot*/, NULL /*pSecAttr*/);
    213 
    214         rcNt = g_pfnNtCreateFile(&hFile,
     163        MyInitializeObjectAttributes(&ObjAttr, pNtPath, fObjAttribs, NULL /*hRoot*/, NULL /*pSecAttr*/);
     164
     165        rcNt = g_pfnNtCreateFile(phFile,
    215166                                 fDesiredAccess,
    216167                                 &ObjAttr,
     
    223174                                 NULL,   /* pEaBuffer */
    224175                                 0);     /* cbEaBuffer*/
     176        if (rcNt != STATUS_INVALID_PARAMETER)
     177            g_fHaveOpenReparsePoint = 0;
     178    }
     179    return rcNt;
     180}
     181
     182
     183HANDLE birdOpenFile(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess,
     184                    ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
     185{
     186    MY_UNICODE_STRING   NtPath;
     187    MY_NTSTATUS         rcNt;
     188
     189    birdResolveImports();
     190
     191    /*
     192     * Adjust inputs.
     193     */
     194    if (birdIsPathDirSpec(pszPath))
     195        fCreateOptions |= FILE_DIRECTORY_FILE;
     196
     197    /*
     198     * Call the NT API directly.
     199     */
     200    if (birdDosToNtPath(pszPath, &NtPath) == 0)
     201    {
     202        HANDLE hFile;
     203        rcNt = birdOpenFileInternal(&NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
     204                                    fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
    225205        if (MY_NT_SUCCESS(rcNt))
    226206        {
     
    233213    }
    234214
    235 #endif /* !BIRD_USE_WIN32 */
    236215    return INVALID_HANDLE_VALUE;
    237216}
    238217
    239218
     219HANDLE birdOpenParentDir(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess,
     220                         ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
     221                         MY_UNICODE_STRING *pNameUniStr)
     222{
     223    MY_UNICODE_STRING   NtPath;
     224    MY_NTSTATUS         rcNt;
     225
     226    birdResolveImports();
     227
     228    /*
     229     * Adjust inputs.
     230     */
     231    fCreateOptions |= FILE_DIRECTORY_FILE;
     232
     233    /*
     234     * Convert the path and split off the filename.
     235     */
     236    if (birdDosToNtPath(pszPath, &NtPath) == 0)
     237    {
     238        USHORT offName = NtPath.Length / sizeof(WCHAR);
     239        USHORT cwcName = offName;
     240        WCHAR  wc = 0;
     241
     242        while (   offName > 0
     243               && (wc = NtPath.Buffer[offName - 1]) != '\\'
     244               && wc != '/'
     245               && wc != ':')
     246            offName--;
     247        if (offName > 0)
     248        {
     249            cwcName -= offName;
     250
     251            /* Make a copy of the file name, if requested. */
     252            rcNt = STATUS_SUCCESS;
     253            if (pNameUniStr)
     254            {
     255                pNameUniStr->Length        = cwcName * sizeof(WCHAR);
     256                pNameUniStr->MaximumLength = pNameUniStr->Length + sizeof(WCHAR);
     257                pNameUniStr->Buffer        = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, pNameUniStr->MaximumLength);
     258                if (pNameUniStr->Buffer)
     259                {
     260                    memcpy(pNameUniStr->Buffer, &NtPath.Buffer[offName],pNameUniStr->Length);
     261                    pNameUniStr->Buffer[cwcName] = '\0';
     262                }
     263                else
     264                    rcNt = STATUS_NO_MEMORY;
     265            }
     266
     267            /* Chop, chop. */
     268            // Bad idea, breaks \\?\c:\pagefile.sys. //while (   offName > 0
     269            // Bad idea, breaks \\?\c:\pagefile.sys. //       && (   (wc = NtPath.Buffer[offName - 1]) == '\\'
     270            // Bad idea, breaks \\?\c:\pagefile.sys. //           || wc == '/'))
     271            // Bad idea, breaks \\?\c:\pagefile.sys. //    offName--;
     272            NtPath.Length = offName * sizeof(WCHAR);
     273            NtPath.Buffer[offName] = '\0';
     274            if (MY_NT_SUCCESS(rcNt))
     275            {
     276                /*
     277                 * Finally, try open the directory.
     278                 */
     279                HANDLE hFile;
     280                rcNt = birdOpenFileInternal(&NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
     281                                            fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
     282                if (MY_NT_SUCCESS(rcNt))
     283                {
     284                    birdFreeNtPath(&NtPath);
     285                    return hFile;
     286                }
     287            }
     288
     289            if (pNameUniStr)
     290                birdFreeNtPath(pNameUniStr);
     291        }
     292
     293        birdFreeNtPath(&NtPath);
     294        birdSetErrnoFromNt(rcNt);
     295    }
     296
     297    return INVALID_HANDLE_VALUE;
     298}
     299
     300
    240301void birdCloseFile(HANDLE hFile)
    241302{
    242 #ifdef BIRD_USE_WIN32
    243     CloseHandle(hFile);
    244 #else
    245303    birdResolveImports();
    246304    g_pfnNtClose(hFile);
    247 #endif
    248 }
    249 
     305}
     306
  • trunk/src/lib/nt/ntstat.c

    r2703 r2704  
    133133
    134134    /* File type. */
    135     if (fAttribs & FILE_ATTRIBUTE_REPARSE_POINT)
     135    if (  (fAttribs & FILE_ATTRIBUTE_REPARSE_POINT)
     136        && hFile != INVALID_HANDLE_VALUE)
    136137    {
    137138        MY_FILE_ATTRIBUTE_TAG_INFORMATION   TagInfo;
     
    357358        //fprintf(stderr, "stat: %s -> %u\n", pszPath, GetLastError());
    358359
    359         /* On things like pagefile.sys we may get sharing violation. */
    360         if (errno == ETXTBSY)
    361         {
    362             /** @todo Fall back on the parent directory enum if we run into a sharing
    363              *        violation. */
     360        /*
     361         * On things like pagefile.sys we may get sharing violation.  We fall
     362         * back on directory enumeration for dealing with that.
     363         */
     364        if (   errno == ETXTBSY
     365            && strchr(pszPath, '*') == NULL /* Serious paranoia... */
     366            && strchr(pszPath, '?') == NULL)
     367        {
     368            MY_UNICODE_STRING NameUniStr;
     369            hFile = birdOpenParentDir(pszPath,
     370                                      FILE_READ_DATA | SYNCHRONIZE,
     371                                      FILE_ATTRIBUTE_NORMAL,
     372                                      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
     373                                      FILE_OPEN,
     374                                      FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
     375                                      OBJ_CASE_INSENSITIVE,
     376                                      &NameUniStr);
     377            if (hFile != INVALID_HANDLE_VALUE)
     378            {
     379                MY_FILE_ID_FULL_DIR_INFORMATION *pBuf;
     380                ULONG               cbBuf = sizeof(*pBuf) + NameUniStr.MaximumLength + 1024;
     381                MY_IO_STATUS_BLOCK  Ios;
     382                MY_NTSTATUS         rcNt;
     383
     384                pBuf = (MY_FILE_ID_FULL_DIR_INFORMATION *)alloca(cbBuf);
     385                Ios.u.Status    = -1;
     386                Ios.Information = -1;
     387                rcNt = g_pfnNtQueryDirectoryFile(hFile, NULL, NULL, NULL, &Ios, pBuf, cbBuf,
     388                                                 MyFileIdFullDirectoryInformation, FALSE, &NameUniStr, TRUE);
     389                if (MY_NT_SUCCESS(rcNt))
     390                    rcNt = Ios.u.Status;
     391                if (MY_NT_SUCCESS(rcNt))
     392                {
     393                    /*
     394                     * Convert the data.
     395                     */
     396                    pStat->st_mode          = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes, pszPath,
     397                                                                 NULL, &pStat->st_dirsymlink);
     398                    pStat->st_padding0[0]   = 0;
     399                    pStat->st_padding0[1]   = 0;
     400                    pStat->st_size          = pBuf->EndOfFile.QuadPart;
     401                    birdNtTimeToTimeSpec(pBuf->CreationTime.QuadPart,   &pStat->st_birthtim);
     402                    birdNtTimeToTimeSpec(pBuf->ChangeTime.QuadPart,     &pStat->st_ctim);
     403                    birdNtTimeToTimeSpec(pBuf->LastWriteTime.QuadPart,  &pStat->st_mtim);
     404                    birdNtTimeToTimeSpec(pBuf->LastAccessTime.QuadPart, &pStat->st_atim);
     405                    pStat->st_ino           = pBuf->FileId.QuadPart;
     406                    pStat->st_nlink         = 1;
     407                    pStat->st_rdev          = 0;
     408                    pStat->st_uid           = 0;
     409                    pStat->st_gid           = 0;
     410                    pStat->st_padding1[0]   = 0;
     411                    pStat->st_padding1[1]   = 0;
     412                    pStat->st_padding1[2]   = 0;
     413                    pStat->st_blksize       = 65536;
     414                    pStat->st_blocks        = (pBuf->AllocationSize.QuadPart + BIRD_STAT_BLOCK_SIZE - 1)
     415                                            / BIRD_STAT_BLOCK_SIZE;
     416
     417                    /* Get the serial number, reusing the buffer from above. */
     418                    rcNt = g_pfnNtQueryVolumeInformationFile(hFile, &Ios, pBuf, cbBuf, MyFileFsVolumeInformation);
     419                    if (MY_NT_SUCCESS(rcNt))
     420                        rcNt = Ios.u.Status;
     421                    if (MY_NT_SUCCESS(rcNt))
     422                    {
     423                        MY_FILE_FS_VOLUME_INFORMATION const *pVolInfo = (MY_FILE_FS_VOLUME_INFORMATION const *)pBuf;
     424                        pStat->st_dev       = pVolInfo->VolumeSerialNumber
     425                                            | (pVolInfo->VolumeCreationTime.QuadPart << 32);
     426                        rc = 0;
     427                    }
     428                    else
     429                    {
     430                        pStat->st_dev       = 0;
     431                        rc = birdSetErrnoFromNt(rcNt);
     432                    }
     433                }
     434
     435                birdFreeNtPath(&NameUniStr);
     436                birdCloseFile(hFile);
     437
     438                if (MY_NT_SUCCESS(rcNt))
     439                    return 0;
     440                birdSetErrnoFromNt(rcNt);
     441            }
    364442        }
    365443        rc = -1;
  • trunk/src/lib/nt/ntstuff.h

    r2702 r2704  
    179179/** The sizeof(MY_FILE_NAMES_INFORMATION) without the FileName. */
    180180#define MIN_SIZEOF_MY_FILE_NAMES_INFORMATION  (4 + 4 + 4)
     181
     182
     183typedef struct MY_FILE_ID_FULL_DIR_INFORMATION
     184{
     185    ULONG           NextEntryOffset;
     186    ULONG           FileIndex;
     187    LARGE_INTEGER   CreationTime;
     188    LARGE_INTEGER   LastAccessTime;
     189    LARGE_INTEGER   LastWriteTime;
     190    LARGE_INTEGER   ChangeTime;
     191    LARGE_INTEGER   EndOfFile;
     192    LARGE_INTEGER   AllocationSize;
     193    ULONG           FileAttributes;
     194    ULONG           FileNameLength;
     195    ULONG           EaSize;
     196    LARGE_INTEGER   FileId;
     197    WCHAR           FileName[1];
     198} MY_FILE_ID_FULL_DIR_INFORMATION;
    181199
    182200
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette