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

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.