VirtualBox

Changeset 2985 in kBuild for trunk/src/lib/nt/nthlpfs.c


Ignore:
Timestamp:
Nov 1, 2016 6: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/nthlpfs.c

    r2713 r2985  
    3434*******************************************************************************/
    3535#include "nthlp.h"
     36#include <stddef.h>
     37#include <string.h>
     38#include <wchar.h>
     39#include <errno.h>
    3640
    3741
     
    6165
    6266
     67static int birdHasTrailingSlashW(const wchar_t *pwszPath)
     68{
     69    wchar_t wc, wc2;
     70
     71    /* Skip leading slashes. */
     72    while ((wc = *pwszPath) == '/' || wc == '\\')
     73        pwszPath++;
     74    if (wc == '\0')
     75        return 0;
     76
     77    /* Find the last char. */
     78    while ((wc2 = *++pwszPath) != '\0')
     79        wc = wc2;
     80
     81    return wc == '/' || wc == '\\' || wc == ':';
     82}
     83
     84
    6385static int birdIsPathDirSpec(const char *pszPath)
    6486{
     
    7597
    7698    return ch == '/' || ch == '\\' || ch == ':';
     99}
     100
     101
     102static int birdIsPathDirSpecW(const wchar_t *pwszPath)
     103{
     104    wchar_t wc, wc2;
     105
     106    /* Check for empty string. */
     107    wc = *pwszPath;
     108    if (wc == '\0')
     109        return 0;
     110
     111    /* Find the last char. */
     112    while ((wc2 = *++pwszPath) != '\0')
     113        wc = wc2;
     114
     115    return wc == '/' || wc == '\\' || wc == ':';
    77116}
    78117
     
    119158
    120159
     160int birdDosToNtPathW(const wchar_t *pwszPath, MY_UNICODE_STRING *pNtPath)
     161{
     162    birdResolveImports();
     163
     164    pNtPath->Length = pNtPath->MaximumLength = 0;
     165    pNtPath->Buffer = NULL;
     166
     167    /*
     168     * Convert the wide DOS path to an NT path.
     169     */
     170    if (g_pfnRtlDosPathNameToNtPathName_U(pwszPath, pNtPath, NULL, FALSE))
     171        return 0;
     172    return birdSetErrnoFromNt(STATUS_NO_MEMORY);
     173}
     174
     175
     176/**
     177 * Converts UNIX slashes to DOS ones and trims trailing ones.
     178 *
     179 * @returns 0
     180 * @param   pNtPath     The relative NT path to fix up.
     181 */
     182static int birdFixRelativeNtPathSlashesAndReturn0(MY_UNICODE_STRING *pNtPath)
     183{
     184    size_t   cwcLeft  = pNtPath->Length / sizeof(wchar_t);
     185    wchar_t *pwcStart = pNtPath->Buffer;
     186    wchar_t *pwcHit;
     187
     188    /* Convert slashes. */
     189    while ((pwcHit = wmemchr(pwcStart,  '/', cwcLeft)) != NULL)
     190    {
     191        *pwcHit = '\\';
     192        cwcLeft -= pwcHit - pwcStart;
     193        pwcHit = pwcStart;
     194    }
     195
     196    /* Strip trailing slashes (NT doesn't like them). */
     197    while (   pNtPath->Length >= sizeof(wchar_t)
     198           && pNtPath->Buffer[(pNtPath->Length - sizeof(wchar_t)) / sizeof(wchar_t)] == '\\')
     199    {
     200        pNtPath->Length -= sizeof(wchar_t);
     201        pNtPath->Buffer[pNtPath->Length / sizeof(wchar_t)] = '\0';
     202    }
     203
     204    /* If it was all trailing slashes we convert it to a dot path. */
     205    if (   pNtPath->Length == 0
     206        && pNtPath->MaximumLength >= sizeof(wchar_t) * 2)
     207    {
     208        pNtPath->Length = sizeof(wchar_t);
     209        pNtPath->Buffer[0] = '.';
     210        pNtPath->Buffer[1] = '\0';
     211    }
     212
     213    return 0;
     214}
     215
     216
     217/**
     218 * Similar to birdDosToNtPath, but it does call RtlDosPathNameToNtPathName_U.
     219 *
     220 * @returns 0 on success, -1 + errno on failure.
     221 * @param   pszPath     The relative path.
     222 * @param   pNtPath     Where to return the NT path.  Call birdFreeNtPath when done.
     223 */
     224int birdDosToRelativeNtPath(const char *pszPath, MY_UNICODE_STRING *pNtPath)
     225{
     226    MY_NTSTATUS         rcNt;
     227    MY_ANSI_STRING      Src;
     228
     229    birdResolveImports();
     230
     231    /*
     232     * Just convert to wide char.
     233     */
     234    pNtPath->Length   = pNtPath->MaximumLength = 0;
     235    pNtPath->Buffer   = NULL;
     236
     237    Src.Buffer        = (PCHAR)pszPath;
     238    Src.MaximumLength = Src.Length = (USHORT)strlen(pszPath);
     239
     240    rcNt = g_pfnRtlAnsiStringToUnicodeString(pNtPath, &Src, TRUE /* Allocate */);
     241    if (MY_NT_SUCCESS(rcNt))
     242        return birdFixRelativeNtPathSlashesAndReturn0(pNtPath);
     243    return birdSetErrnoFromNt(rcNt);
     244}
     245
     246
     247/**
     248 * Similar to birdDosToNtPathW, but it does call RtlDosPathNameToNtPathName_U.
     249 *
     250 * @returns 0 on success, -1 + errno on failure.
     251 * @param   pwszPath    The relative path.
     252 * @param   pNtPath     Where to return the NT path.  Call birdFreeNtPath when done.
     253 */
     254int birdDosToRelativeNtPathW(const wchar_t *pwszPath, MY_UNICODE_STRING *pNtPath)
     255{
     256    size_t cwcPath = wcslen(pwszPath);
     257    if (cwcPath < 0xfffe)
     258    {
     259        pNtPath->Length = (USHORT)(cwcPath * sizeof(wchar_t));
     260        pNtPath->MaximumLength = pNtPath->Length + sizeof(wchar_t);
     261        pNtPath->Buffer = HeapAlloc(GetProcessHeap(), 0, pNtPath->MaximumLength);
     262        if (pNtPath->Buffer)
     263        {
     264            memcpy(pNtPath->Buffer, pwszPath, pNtPath->MaximumLength);
     265            return birdFixRelativeNtPathSlashesAndReturn0(pNtPath);
     266        }
     267        errno = ENOMEM;
     268    }
     269    else
     270        errno = ENAMETOOLONG;
     271    return -1;
     272}
     273
     274
     275/**
     276 * Frees a string returned by birdDosToNtPath, birdDosToNtPathW or
     277 * birdDosToRelativeNtPath.
     278 *
     279 * @param   pNtPath             The the NT path to free.
     280 */
    121281void birdFreeNtPath(MY_UNICODE_STRING *pNtPath)
    122282{
     
    128288
    129289
    130 MY_NTSTATUS birdOpenFileUniStr(MY_UNICODE_STRING *pNtPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
     290MY_NTSTATUS birdOpenFileUniStr(HANDLE hRoot, MY_UNICODE_STRING *pNtPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
    131291                               ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
    132292                               HANDLE *phFile)
     
    144304    Ios.Information = -1;
    145305    Ios.u.Status = 0;
    146     MyInitializeObjectAttributes(&ObjAttr, pNtPath, fObjAttribs, NULL /*hRoot*/, NULL /*pSecAttr*/);
     306    MyInitializeObjectAttributes(&ObjAttr, pNtPath, fObjAttribs, hRoot, NULL /*pSecAttr*/);
    147307
    148308    rcNt = g_pfnNtCreateFile(phFile,
     
    185345
    186346
    187 HANDLE birdOpenFile(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess,
    188                     ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
     347HANDLE birdOpenFile(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
     348                    ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
    189349{
    190350    MY_UNICODE_STRING   NtPath;
     
    198358
    199359    /*
    200      * Call the NT API directly.
     360     * Convert the path and call birdOpenFileUniStr to do the real work.
    201361     */
    202362    if (birdDosToNtPath(pszPath, &NtPath) == 0)
    203363    {
    204364        HANDLE hFile;
    205         rcNt = birdOpenFileUniStr(&NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
     365        rcNt = birdOpenFileUniStr(NULL /*hRoot*/, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
    206366                                  fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
     367        birdFreeNtPath(&NtPath);
     368        if (MY_NT_SUCCESS(rcNt))
     369            return hFile;
     370        birdSetErrnoFromNt(rcNt);
     371    }
     372
     373    return INVALID_HANDLE_VALUE;
     374}
     375
     376
     377HANDLE birdOpenFileW(const wchar_t *pwszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
     378                     ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
     379{
     380    MY_UNICODE_STRING   NtPath;
     381    MY_NTSTATUS         rcNt;
     382
     383    /*
     384     * Adjust inputs.
     385     */
     386    if (birdIsPathDirSpecW(pwszPath))
     387        fCreateOptions |= FILE_DIRECTORY_FILE;
     388
     389    /*
     390     * Convert the path and call birdOpenFileUniStr to do the real work.
     391     */
     392    if (birdDosToNtPathW(pwszPath, &NtPath) == 0)
     393    {
     394        HANDLE hFile;
     395        rcNt = birdOpenFileUniStr(NULL /*hRoot*/, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
     396                                  fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
     397        birdFreeNtPath(&NtPath);
     398        if (MY_NT_SUCCESS(rcNt))
     399            return hFile;
     400        birdSetErrnoFromNt(rcNt);
     401    }
     402
     403    return INVALID_HANDLE_VALUE;
     404}
     405
     406
     407HANDLE birdOpenFileEx(HANDLE hRoot, const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
     408                      ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
     409{
     410    MY_UNICODE_STRING   NtPath;
     411    MY_NTSTATUS         rcNt;
     412
     413    /*
     414     * Adjust inputs.
     415     */
     416    if (birdIsPathDirSpec(pszPath))
     417        fCreateOptions |= FILE_DIRECTORY_FILE;
     418
     419    /*
     420     * Convert the path and call birdOpenFileUniStr to do the real work.
     421     */
     422    if (hRoot == INVALID_HANDLE_VALUE)
     423        hRoot = NULL;
     424    if ((hRoot != NULL ? birdDosToRelativeNtPath(pszPath, &NtPath) : birdDosToNtPath(pszPath, &NtPath)) == 0)
     425    {
     426        HANDLE hFile;
     427        rcNt = birdOpenFileUniStr(hRoot, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
     428                                  fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
     429        birdFreeNtPath(&NtPath);
     430        if (MY_NT_SUCCESS(rcNt))
     431            return hFile;
     432        birdSetErrnoFromNt(rcNt);
     433    }
     434
     435    return INVALID_HANDLE_VALUE;
     436}
     437
     438
     439HANDLE birdOpenFileExW(HANDLE hRoot, const wchar_t *pwszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
     440                       ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
     441{
     442    MY_UNICODE_STRING   NtPath;
     443    MY_NTSTATUS         rcNt;
     444
     445    /*
     446     * Adjust inputs.
     447     */
     448    if (birdIsPathDirSpecW(pwszPath))
     449        fCreateOptions |= FILE_DIRECTORY_FILE;
     450
     451    /*
     452     * Convert the path (could save ourselves this if pwszPath is perfect) and
     453     * call birdOpenFileUniStr to do the real work.
     454     */
     455    if (hRoot == INVALID_HANDLE_VALUE)
     456        hRoot = NULL;
     457    if ((hRoot != NULL ? birdDosToRelativeNtPathW(pwszPath, &NtPath) : birdDosToNtPathW(pwszPath, &NtPath)) == 0)
     458    {
     459        HANDLE hFile;
     460        rcNt = birdOpenFileUniStr(hRoot, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
     461                                  fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
     462        birdFreeNtPath(&NtPath);
     463        if (MY_NT_SUCCESS(rcNt))
     464            return hFile;
     465        birdSetErrnoFromNt(rcNt);
     466    }
     467
     468    return INVALID_HANDLE_VALUE;
     469}
     470
     471
     472static HANDLE birdOpenParentDirCommon(HANDLE hRoot, MY_UNICODE_STRING *pNtPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
     473                                      ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
     474                                      MY_UNICODE_STRING *pNameUniStr)
     475{
     476    MY_NTSTATUS rcNt;
     477
     478    /*
     479     * Strip the path down to the directory.
     480     */
     481    USHORT offName = pNtPath->Length / sizeof(WCHAR);
     482    USHORT cwcName = offName;
     483    WCHAR  wc = 0;
     484    while (   offName > 0
     485           && (wc = pNtPath->Buffer[offName - 1]) != '\\'
     486           && wc != '/'
     487           && wc != ':')
     488        offName--;
     489    if (   offName > 0
     490        || (hRoot != NULL && cwcName > 0))
     491    {
     492        cwcName -= offName;
     493
     494        /* Make a copy of the file name, if requested. */
     495        rcNt = STATUS_SUCCESS;
     496        if (pNameUniStr)
     497        {
     498            pNameUniStr->Length        = cwcName * sizeof(WCHAR);
     499            pNameUniStr->MaximumLength = pNameUniStr->Length + sizeof(WCHAR);
     500            pNameUniStr->Buffer        = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, pNameUniStr->MaximumLength);
     501            if (pNameUniStr->Buffer)
     502            {
     503                memcpy(pNameUniStr->Buffer, &pNtPath->Buffer[offName], pNameUniStr->Length);
     504                pNameUniStr->Buffer[cwcName] = '\0';
     505            }
     506            else
     507                rcNt = STATUS_NO_MEMORY;
     508        }
     509
     510        /* Chop, chop. */
     511        // Bad idea, breaks \\?\c:\pagefile.sys. //while (   offName > 0
     512        // Bad idea, breaks \\?\c:\pagefile.sys. //       && (   (wc = pNtPath->Buffer[offName - 1]) == '\\'
     513        // Bad idea, breaks \\?\c:\pagefile.sys. //           || wc == '/'))
     514        // Bad idea, breaks \\?\c:\pagefile.sys. //    offName--;
     515        if (offName == 0)
     516            pNtPath->Buffer[offName++] = '.'; /* Hack for dir handle + dir entry name. */
     517        pNtPath->Length = offName * sizeof(WCHAR);
     518        pNtPath->Buffer[offName] = '\0';
    207519        if (MY_NT_SUCCESS(rcNt))
    208520        {
    209             birdFreeNtPath(&NtPath);
    210             return hFile;
    211         }
    212 
    213         birdFreeNtPath(&NtPath);
    214         birdSetErrnoFromNt(rcNt);
    215     }
    216 
    217     return INVALID_HANDLE_VALUE;
    218 }
    219 
    220 
    221 HANDLE birdOpenParentDir(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess,
    222                          ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
    223                          MY_UNICODE_STRING *pNameUniStr)
    224 {
    225     MY_UNICODE_STRING   NtPath;
    226     MY_NTSTATUS         rcNt;
    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';
     521            /*
     522             * Finally, try open the directory.
     523             */
     524            HANDLE hFile;
     525            fCreateOptions |= FILE_DIRECTORY_FILE;
     526            rcNt = birdOpenFileUniStr(hRoot, pNtPath, fDesiredAccess, fFileAttribs, fShareAccess,
     527                                      fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
    274528            if (MY_NT_SUCCESS(rcNt))
    275529            {
    276                 /*
    277                  * Finally, try open the directory.
    278                  */
    279                 HANDLE hFile;
    280                 rcNt = birdOpenFileUniStr(&NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
    281                                           fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
    282                 if (MY_NT_SUCCESS(rcNt))
    283                 {
    284                     birdFreeNtPath(&NtPath);
    285                     return hFile;
    286                 }
     530                birdFreeNtPath(pNtPath);
     531                return hFile;
    287532            }
    288 
    289             if (pNameUniStr)
    290                 birdFreeNtPath(pNameUniStr);
    291533        }
    292534
    293         birdFreeNtPath(&NtPath);
    294         birdSetErrnoFromNt(rcNt);
    295     }
    296 
     535        if (pNameUniStr)
     536            birdFreeNtPath(pNameUniStr);
     537    }
     538    else
     539        rcNt = STATUS_INVALID_PARAMETER;
     540
     541    birdFreeNtPath(pNtPath);
     542    birdSetErrnoFromNt(rcNt);
    297543    return INVALID_HANDLE_VALUE;
     544}
     545
     546
     547HANDLE birdOpenParentDir(HANDLE hRoot, const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
     548                         ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
     549                         MY_UNICODE_STRING *pNameUniStr)
     550{
     551    /*
     552     * Convert the path and join up with the UTF-16 version (it'll free NtPath).
     553     */
     554    MY_UNICODE_STRING NtPath;
     555    if (hRoot == INVALID_HANDLE_VALUE)
     556        hRoot = NULL;
     557    if (  hRoot == NULL
     558        ? birdDosToNtPath(pszPath, &NtPath) == 0
     559        : birdDosToRelativeNtPath(pszPath, &NtPath) == 0)
     560        return birdOpenParentDirCommon(hRoot, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
     561                                       fCreateDisposition, fCreateOptions, fObjAttribs, pNameUniStr);
     562    return INVALID_HANDLE_VALUE;
     563}
     564
     565
     566HANDLE birdOpenParentDirW(HANDLE hRoot, const wchar_t *pwszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
     567                          ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
     568                          MY_UNICODE_STRING *pNameUniStr)
     569{
     570    /*
     571     * Convert the path and join up with the ansi version (it'll free NtPath).
     572     */
     573    MY_UNICODE_STRING NtPath;
     574    if (hRoot == INVALID_HANDLE_VALUE)
     575        hRoot = NULL;
     576    if (  hRoot == NULL
     577        ? birdDosToNtPathW(pwszPath, &NtPath) == 0
     578        : birdDosToRelativeNtPathW(pwszPath, &NtPath) == 0)
     579        return birdOpenParentDirCommon(hRoot, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
     580                                       fCreateDisposition, fCreateOptions, fObjAttribs, pNameUniStr);
     581    return INVALID_HANDLE_VALUE;
     582}
     583
     584
     585/**
     586 * Returns a handle to the current working directory of the process.
     587 *
     588 * @returns CWD handle with FILE_TRAVERSE and SYNCHRONIZE access.  May return
     589 *          INVALID_HANDLE_VALUE w/ errno for invalid CWD.
     590 */
     591HANDLE birdOpenCurrentDirectory(void)
     592{
     593    PMY_RTL_USER_PROCESS_PARAMETERS pProcParams;
     594    MY_NTSTATUS rcNt;
     595    HANDLE hRet = INVALID_HANDLE_VALUE;
     596
     597    birdResolveImports();
     598
     599    /*
     600     * We'll try get this from the PEB.
     601     */
     602    g_pfnRtlAcquirePebLock();
     603    pProcParams = (PMY_RTL_USER_PROCESS_PARAMETERS)MY_NT_CURRENT_PEB()->ProcessParameters;
     604    if (pProcParams != NULL)
     605        rcNt = g_pfnNtDuplicateObject(MY_NT_CURRENT_PROCESS, pProcParams->CurrentDirectory.Handle,
     606                                      MY_NT_CURRENT_PROCESS, &hRet,
     607                                      FILE_TRAVERSE | SYNCHRONIZE,
     608                                      0 /*fAttribs*/,
     609                                      0 /*fOptions*/);
     610    else
     611        rcNt = STATUS_INVALID_PARAMETER;
     612    g_pfnRtlReleasePebLock();
     613    if (MY_NT_SUCCESS(rcNt))
     614        return hRet;
     615
     616    /*
     617     * Fallback goes thru birdOpenFileW.
     618     */
     619    return birdOpenFileW(L".",
     620                         FILE_TRAVERSE | SYNCHRONIZE,
     621                         FILE_ATTRIBUTE_NORMAL,
     622                         FILE_SHARE_READ | FILE_SHARE_WRITE,
     623                         FILE_OPEN,
     624                         FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
     625                         OBJ_CASE_INSENSITIVE);
    298626}
    299627
Note: See TracChangeset for help on using the changeset viewer.

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