VirtualBox

Changeset 2849 in kBuild


Ignore:
Timestamp:
Aug 30, 2016 2:28:46 PM (9 years ago)
Author:
bird
Message:

split nt_fullpath_cached out into its own file.

Location:
trunk/src
Files:
1 added
3 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/w32/pathstuff.c

    r2848 r2849  
    2121#include <stdlib.h>
    2222#include "pathstuff.h"
     23#if 1 /* bird */
     24# include "nt_fullpath.h"
     25#endif
    2326
    2427/*
     
    9295    return Path;
    9396}
    94 
    95 #if 1 /* bird */
    96 extern void nt_fullpath_cached(const char *pszPath, char *pszFull, size_t cchFull);
    97 #endif
    9897
    9998/*
  • trunk/src/lib/Makefile.kmk

    r2844 r2849  
    4343kUtil_SOURCES.win = \
    4444        nt_fullpath.c \
     45        nt_fullpath_cached.c \
    4546        quote_argv.c \
    4647        quoted_spawn.c \
  • trunk/src/lib/nt_fullpath.c

    r2848 r2849  
    3333#include <ctype.h>
    3434#include <direct.h>
    35 #include <assert.h>
    36 
    37 
    38 /*********************************************************************************************************************************
    39 *   Structures and Typedefs                                                                                                      *
    40 *********************************************************************************************************************************/
    41 typedef struct NTFULLPATHENTRY
    42 {
    43     /** Pointer to the next entry with the same hash table index. */
    44     struct NTFULLPATHENTRY *pNext;
    45     /** The input hash. */
    46     unsigned                uHash;
    47     /** The input length. */
    48     unsigned                cchInput;
    49     /** Length of the result. */
    50     unsigned                cchResult;
    51     /** The result string (stored immediately after this structure). */
    52     const char             *pszResult;
    53     /** The input string (variable length). */
    54     char                    szInput[1];
    55 } NTFULLPATHENTRY;
    56 typedef NTFULLPATHENTRY *PNTFULLPATHENTRY;
    57 
    58 
    59 /*********************************************************************************************************************************
    60 *   Global Variables                                                                                                             *
    61 *********************************************************************************************************************************/
    62 /** Number of result in the nt_fullpath cache.  */
    63 size_t              g_cNtFullPathHashEntries = 0;
    64 /** Number of bytes used for nt_fullpath cache result entries. */
    65 size_t              g_cbNtFullPathHashEntries = 0;
    66 /** Number of hash table collsioins in the nt_fullpath cache.  */
    67 size_t              g_cNtFullPathHashCollisions = 0;
    68 /** Hash table. */
    69 PNTFULLPATHENTRY    g_apNtFullPathHashTab[16381];
     35
     36#include "nt_fullpath.h"
    7037
    7138
     
    602569}
    603570
    604 
    605 
    606 /**
    607  * A nt_fullpath frontend which caches the result of previous calls.
    608  */
    609 void
    610 nt_fullpath_cached(const char *pszPath, char *pszFull, size_t cchFull)
    611 {
    612     PNTFULLPATHENTRY        pEntry;
    613     unsigned                cchInput;
    614     unsigned                idx;
    615     unsigned                cchResult;
    616 
    617     /* We use the sdbm hash algorithm here (see kDep.c for full details). */
    618     unsigned const char    *puch = (unsigned const char *)pszPath;
    619     unsigned                uHash = 0;
    620     unsigned                uChar;
    621     while ((uChar = *puch++) != 0)
    622         uHash = uChar + (uHash << 6) + (uHash << 16) - uHash;
    623 
    624     cchInput = (unsigned)((uintptr_t)&puch[-1] - (uintptr_t)pszPath);
    625 
    626     /* Do the cache lookup. */
    627     idx = uHash % (sizeof(g_apNtFullPathHashTab) / sizeof(g_apNtFullPathHashTab[0]));
    628     for (pEntry = g_apNtFullPathHashTab[idx]; pEntry != NULL; pEntry = pEntry->pNext)
    629         if (   pEntry->uHash == uHash
    630             && pEntry->cchInput == cchInput
    631             && memcmp(pEntry->szInput, pszPath, cchInput) == 0)
    632         {
    633             if (cchFull > pEntry->cchResult)
    634                 memcpy(pszFull, pEntry->pszResult, pEntry->cchResult + 1);
    635             else
    636             {
    637                 assert(0);
    638                 memcpy(pszFull, pEntry->pszResult, cchFull);
    639                 pszFull[cchFull - 1] = '\0';
    640             }
    641             return;
    642         }
    643 
    644     /* Make the call... */
    645     nt_fullpath(pszPath, pszFull, cchFull);
    646 
    647     /* ... and cache the result. */
    648     cchResult = (unsigned)strlen(pszFull);
    649     pEntry = malloc(sizeof(*pEntry) + cchInput + cchResult + 1);
    650     if (pEntry)
    651     {
    652         g_cbNtFullPathHashEntries += sizeof(*pEntry) + cchInput + cchResult + 1;
    653         pEntry->cchInput  = cchInput;
    654         pEntry->cchResult = cchResult;
    655         pEntry->pszResult = &pEntry->szInput[cchInput + 1];
    656         pEntry->uHash     = uHash;
    657         memcpy(pEntry->szInput, pszPath, cchInput + 1);
    658         memcpy((char *)pEntry->pszResult, pszFull, cchResult + 1);
    659 
    660         pEntry->pNext = g_apNtFullPathHashTab[idx];
    661         if (pEntry->pNext)
    662             g_cNtFullPathHashCollisions++;
    663         g_apNtFullPathHashTab[idx] = pEntry;
    664 
    665         g_cNtFullPathHashEntries++;
    666     }
    667 }
    668 
  • trunk/src/lib/nt_fullpath_cached.c

    r2848 r2849  
    3535#include <assert.h>
    3636
     37#include "nt_fullpath.h"
     38
    3739
    3840/*********************************************************************************************************************************
     
    6870/** Hash table. */
    6971PNTFULLPATHENTRY    g_apNtFullPathHashTab[16381];
    70 
    71 
    72 /*
    73  * Corrects the case of a path.
    74  * Expects a fullpath!
    75  * Added by bird for the $(abspath ) function and w32ify
    76  */
    77 static void w32_fixcase(char *pszPath)
    78 {
    79     static char     s_szLast[260];
    80     size_t          cchLast;
    81 
    82 #ifndef NDEBUG
    83 # define my_assert(expr) \
    84     do { \
    85         if (!(expr)) { \
    86             printf("my_assert: %s, file %s, line %d\npszPath=%s\npsz=%s\n", \
    87                    #expr, __FILE__, __LINE__, pszPath, psz); \
    88             __debugbreak(); \
    89             exit(1); \
    90         } \
    91     } while (0)
    92 #else
    93 # define my_assert(expr) do {} while (0)
    94 #endif
    95 
    96     char *psz = pszPath;
    97     if (*psz == '/' || *psz == '\\')
    98     {
    99         if (psz[1] == '/' || psz[1] == '\\')
    100         {
    101             /* UNC */
    102             my_assert(psz[1] == '/' || psz[1] == '\\');
    103             my_assert(psz[2] != '/' && psz[2] != '\\');
    104 
    105             /* skip server name */
    106             psz += 2;
    107             while (*psz != '\\' && *psz != '/')
    108             {
    109                 if (!*psz)
    110                     return;
    111                 *psz++ = toupper(*psz);
    112             }
    113 
    114             /* skip the share name */
    115             psz++;
    116             my_assert(*psz != '/' && *psz != '\\');
    117             while (*psz != '\\' && *psz != '/')
    118             {
    119                 if (!*psz)
    120                     return;
    121                 *psz++ = toupper(*psz);
    122             }
    123             my_assert(*psz == '/' || *psz == '\\');
    124             psz++;
    125         }
    126         else
    127         {
    128             /* Unix spec */
    129             psz++;
    130         }
    131     }
    132     else
    133     {
    134         /* Drive letter */
    135         my_assert(psz[1] == ':');
    136         *psz = toupper(*psz);
    137         my_assert(psz[0] >= 'A' && psz[0] <= 'Z');
    138         my_assert(psz[2] == '/' || psz[2] == '\\');
    139         psz += 3;
    140     }
    141 
    142     /*
    143      * Try make use of the result from the previous call.
    144      * This is ignorant to slashes and similar, but may help even so.
    145      */
    146     if (    s_szLast[0] == pszPath[0]
    147         &&  (psz - pszPath == 1 || s_szLast[1] == pszPath[1])
    148         &&  (psz - pszPath <= 2 || s_szLast[2] == pszPath[2])
    149        )
    150     {
    151         char *pszLast = &s_szLast[psz - pszPath];
    152         char *pszCur = psz;
    153         char *pszSrc0 = pszLast;
    154         char *pszDst0 = pszCur;
    155         for (;;)
    156         {
    157             const char ch1 = *pszCur;
    158             const char ch2 = *pszLast;
    159             if (    ch1 != ch2
    160                 &&  (ch1 != '\\' || ch2 != '/')
    161                 &&  (ch1 != '/'  || ch2 != '\\')
    162                 &&  tolower(ch1) != tolower(ch2)
    163                 &&  toupper(ch1) != toupper(ch2))
    164                 break;
    165             if (ch1 == '/' || ch1 == '\\')
    166             {
    167                                 psz = pszCur + 1;
    168                 *pszLast = ch1; /* preserve the slashes */
    169             }
    170             else if (ch1 == '\0')
    171             {
    172                 psz = pszCur;
    173                 break;
    174             }
    175             pszCur++;
    176             pszLast++;
    177         }
    178         if (psz != pszDst0)
    179             memcpy(pszDst0, pszSrc0, psz - pszDst0);
    180     }
    181 
    182     /*
    183      * Pointing to the first char after the unc or drive specifier,
    184      * or in case of a cache hit, the first non-matching char (following a slash of course).
    185      */
    186     while (*psz)
    187     {
    188         WIN32_FIND_DATA FindFileData;
    189         HANDLE hDir;
    190         char chSaved0;
    191         char chSaved1;
    192         char *pszEnd;
    193         int iLongNameDiff;
    194         size_t cch;
    195 
    196 
    197         /* find the end of the component. */
    198         pszEnd = psz;
    199         while (*pszEnd && *pszEnd != '/' && *pszEnd != '\\')
    200             pszEnd++;
    201         cch = pszEnd - psz;
    202 
    203         /* replace the end with "?\0" */
    204         chSaved0 = pszEnd[0];
    205         chSaved1 = pszEnd[1];
    206         pszEnd[0] = '?';
    207         pszEnd[1] = '\0';
    208 
    209         /* find the right filename. */
    210         hDir = FindFirstFile(pszPath, &FindFileData);
    211         pszEnd[1] = chSaved1;
    212         if (!hDir)
    213         {
    214             cchLast = psz - pszPath;
    215             memcpy(s_szLast, pszPath, cchLast + 1);
    216             s_szLast[cchLast + 1] = '\0';
    217             pszEnd[0] = chSaved0;
    218             return;
    219         }
    220         pszEnd[0] = '\0';
    221         while (   (iLongNameDiff = stricmp(FindFileData.cFileName, psz))
    222                && stricmp(FindFileData.cAlternateFileName, psz))
    223         {
    224             if (!FindNextFile(hDir, &FindFileData))
    225             {
    226                 cchLast = psz - pszPath;
    227                 memcpy(s_szLast, pszPath, cchLast + 1);
    228                 s_szLast[cchLast + 1] = '\0';
    229                 pszEnd[0] = chSaved0;
    230                 return;
    231             }
    232         }
    233         pszEnd[0] = chSaved0;
    234         if (    iLongNameDiff                           /* matched the short name */
    235             ||  !FindFileData.cAlternateFileName[0]     /* no short name */
    236             || !memchr(psz, ' ', cch))                  /* no spaces in the matching name */
    237             memcpy(psz, !iLongNameDiff ? FindFileData.cFileName : FindFileData.cAlternateFileName, cch);
    238         else
    239         {
    240             /* replace spacy name with the short name. */
    241             const size_t cchAlt = strlen(FindFileData.cAlternateFileName);
    242             const size_t cchDelta = cch - cchAlt;
    243             my_assert(cchAlt > 0);
    244             if (!cchDelta)
    245                 memcpy(psz, FindFileData.cAlternateFileName, cch);
    246             else
    247             {
    248                 size_t cbLeft = strlen(pszEnd) + 1;
    249                 if ((psz - pszPath) + cbLeft + cchAlt <= _MAX_PATH)
    250                 {
    251                     memmove(psz + cchAlt, pszEnd, cbLeft);
    252                     pszEnd -= cchDelta;
    253                     memcpy(psz, FindFileData.cAlternateFileName, cchAlt);
    254                 }
    255                 else
    256                     fprintf(stderr, "kBuild: case & space fixed filename is growing too long (%d bytes)! '%s'\n",
    257                             (psz - pszPath) + cbLeft + cchAlt, pszPath);
    258             }
    259         }
    260         my_assert(pszEnd[0] == chSaved0);
    261         FindClose(hDir);
    262 
    263         /* advance to the next component */
    264         if (!chSaved0)
    265         {
    266             psz = pszEnd;
    267             break;
    268         }
    269         psz = pszEnd + 1;
    270         my_assert(*psz != '/' && *psz != '\\');
    271     }
    272 
    273     /* *psz == '\0', the end. */
    274     cchLast = psz - pszPath;
    275     memcpy(s_szLast, pszPath, cchLast + 1);
    276 #undef my_assert
    277 }
    278 
    279 #define MY_FileNameInformation 9
    280 typedef struct _MY_FILE_NAME_INFORMATION
    281 {
    282     ULONG FileNameLength;
    283     WCHAR FileName[1];
    284 } MY_FILE_NAME_INFORMATION, *PMY_FILE_NAME_INFORMATION;
    285 
    286 #define MY_FileInternalInformation 6
    287 typedef struct _MY_FILE_INTERNAL_INFORMATION {
    288     LARGE_INTEGER IndexNumber;
    289 } MY_FILE_INTERNAL_INFORMATION, *PMY_FILE_INTERNAL_INFORMATION;
    290 
    291 #define MY_FileFsVolumeInformation 1
    292 typedef struct _MY_FILE_FS_VOLUME_INFORMATION
    293 {
    294     LARGE_INTEGER VolumeCreationTime;
    295     ULONG VolumeSerialNumber;
    296     ULONG VolumeLabelLength;
    297     BOOLEAN SupportsObjects;
    298     WCHAR VolumeLabel[/*1*/128];
    299 } MY_FILE_FS_VOLUME_INFORMATION, *PMY_FILE_FS_VOLUME_INFORMATION;
    300 
    301 #define MY_FileFsAttributeInformation 5
    302 typedef struct _MY_FILE_FS_ATTRIBUTE_INFORMATION
    303 {
    304     ULONG FileSystemAttributes;
    305     LONG MaximumComponentNameLength;
    306     ULONG FileSystemNameLength;
    307     WCHAR FileSystemName[/*1*/64];
    308 } MY_FILE_FS_ATTRIBUTE_INFORMATION, *PMY_FILE_FS_ATTRIBUTE_INFORMATION;
    309 
    310 #define MY_FileFsDeviceInformation 4
    311 typedef struct MY_FILE_FS_DEVICE_INFORMATION
    312 {
    313     ULONG DeviceType;
    314     ULONG Characteristics;
    315 } MY_FILE_FS_DEVICE_INFORMATION, *PMY_FILE_FS_DEVICE_INFORMATION;
    316 #define MY_FILE_DEVICE_DISK              7
    317 #define MY_FILE_DEVICE_DISK_FILE_SYSTEM  8
    318 #define MY_FILE_DEVICE_FILE_SYSTEM       9
    319 #define MY_FILE_DEVICE_VIRTUAL_DISK     36
    320 
    321 
    322 typedef struct
    323 {
    324     union
    325     {
    326         LONG    Status;
    327         PVOID   Pointer;
    328     };
    329     ULONG_PTR   Information;
    330 } MY_IO_STATUS_BLOCK, *PMY_IO_STATUS_BLOCK;
    331 
    332 static BOOL                             g_fInitialized = FALSE;
    333 static int                              g_afNtfsDrives['Z' - 'A' + 1];
    334 static MY_FILE_FS_VOLUME_INFORMATION    g_aVolumeInfo['Z' - 'A' + 1];
    335 
    336 static LONG (NTAPI *g_pfnNtQueryInformationFile)(HANDLE FileHandle,
    337     PMY_IO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation,
    338     ULONG Length, ULONG FileInformationClass);
    339 static LONG (NTAPI *g_pfnNtQueryVolumeInformationFile)(HANDLE FileHandle,
    340     PMY_IO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation,
    341     ULONG Length, ULONG FsInformationClass);
    342 
    343 
    344 int
    345 nt_get_filename_info(const char *pszPath, char *pszFull, size_t cchFull)
    346 {
    347     static char                     abBuf[8192];
    348     PMY_FILE_NAME_INFORMATION       pFileNameInfo = (PMY_FILE_NAME_INFORMATION)abBuf;
    349     PMY_FILE_FS_VOLUME_INFORMATION  pFsVolInfo = (PMY_FILE_FS_VOLUME_INFORMATION)abBuf;
    350     MY_IO_STATUS_BLOCK              Ios;
    351     LONG                            rcNt;
    352     HANDLE                      hFile;
    353     int                             cchOut;
    354     char                           *psz;
    355     int                             iDrv;
    356     int                             rc;
    357 
    358     /*
    359      * Check for NtQueryInformationFile the first time around.
    360      */
    361     if (!g_fInitialized)
    362     {
    363         g_fInitialized = TRUE;
    364         if (!getenv("KMK_DONT_USE_NT_QUERY_INFORMATION_FILE"))
    365         {
    366             *(FARPROC *)&g_pfnNtQueryInformationFile =
    367                 GetProcAddress(LoadLibrary("ntdll.dll"), "NtQueryInformationFile");
    368             *(FARPROC *)&g_pfnNtQueryVolumeInformationFile =
    369                 GetProcAddress(LoadLibrary("ntdll.dll"), "NtQueryVolumeInformationFile");
    370         }
    371         if (    g_pfnNtQueryInformationFile
    372             &&  g_pfnNtQueryVolumeInformationFile)
    373         {
    374             unsigned i;
    375             for (i = 0; i < sizeof(g_afNtfsDrives) / sizeof(g_afNtfsDrives[0]); i++ )
    376                 g_afNtfsDrives[i] = -1;
    377         }
    378         else
    379         {
    380             g_pfnNtQueryVolumeInformationFile = NULL;
    381             g_pfnNtQueryInformationFile = NULL;
    382         }
    383     }
    384     if (!g_pfnNtQueryInformationFile)
    385         return -1;
    386 
    387     /*
    388      * The FileNameInformation we get is relative to where the volume is mounted,
    389      * so we have to extract the driveletter prefix ourselves.
    390      *
    391      * FIXME: This will probably not work for volumes mounted in NTFS sub-directories.
    392      */
    393     psz = pszFull;
    394     if (pszPath[0] == '\\' || pszPath[0] == '/')
    395     {
    396         /* unc or root of volume */
    397         if (    (pszPath[1] == '\\' || pszPath[1] == '/')
    398             &&  (pszPath[2] != '\\' || pszPath[2] == '/'))
    399         {
    400 #if 0 /* don't bother with unc yet. */
    401             /* unc - we get the server + name back */
    402             *psz++ = '\\';
    403 #endif
    404             return -1;
    405         }
    406         /* root slash */
    407         *psz++ = _getdrive() + 'A' - 1;
    408         *psz++ = ':';
    409     }
    410     else if (pszPath[1] == ':' && isalpha(pszPath[0]))
    411     {
    412         /* drive letter */
    413         *psz++ = toupper(pszPath[0]);
    414         *psz++ = ':';
    415     }
    416     else
    417     {
    418         /* relative */
    419         *psz++ = _getdrive() + 'A' - 1;
    420         *psz++ = ':';
    421     }
    422     iDrv = *pszFull - 'A';
    423 
    424     /*
    425      * Fat32 doesn't return filenames with the correct case, so restrict it
    426      * to NTFS volumes for now.
    427      */
    428     if (g_afNtfsDrives[iDrv] == -1)
    429     {
    430         /* FSCTL_GET_REPARSE_POINT? Enumerate mount points? */
    431         g_afNtfsDrives[iDrv] = 0;
    432         psz[0] = '\\';
    433         psz[1] = '\0';
    434 #if 1
    435         hFile = CreateFile(pszFull,
    436                            GENERIC_READ,
    437                            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    438                            NULL,
    439                            OPEN_EXISTING,
    440                            FILE_FLAG_BACKUP_SEMANTICS,
    441                            NULL);
    442         if (hFile != INVALID_HANDLE_VALUE)
    443         {
    444             PMY_FILE_FS_ATTRIBUTE_INFORMATION pFsAttrInfo = (PMY_FILE_FS_ATTRIBUTE_INFORMATION)abBuf;
    445 
    446             memset(&Ios, 0, sizeof(Ios));
    447             rcNt = g_pfnNtQueryVolumeInformationFile(hFile, &Ios, abBuf, sizeof(abBuf),
    448                                                      MY_FileFsAttributeInformation);
    449             if (    rcNt >= 0
    450                 //&&  pFsAttrInfo->FileSystemNameLength == 4
    451                 &&  pFsAttrInfo->FileSystemName[0] == 'N'
    452                 &&  pFsAttrInfo->FileSystemName[1] == 'T'
    453                 &&  pFsAttrInfo->FileSystemName[2] == 'F'
    454                 &&  pFsAttrInfo->FileSystemName[3] == 'S'
    455                 &&  pFsAttrInfo->FileSystemName[4] == '\0')
    456             {
    457                 memset(&Ios, 0, sizeof(Ios));
    458                 rcNt = g_pfnNtQueryVolumeInformationFile(hFile, &Ios, &g_aVolumeInfo[iDrv],
    459                                                          sizeof(MY_FILE_FS_VOLUME_INFORMATION),
    460                                                          MY_FileFsVolumeInformation);
    461                 if (rcNt >= 0)
    462                 {
    463                     DWORD dwDriveType = GetDriveType(pszFull);
    464                     if (    dwDriveType == DRIVE_FIXED
    465                         ||  dwDriveType == DRIVE_RAMDISK)
    466                         g_afNtfsDrives[iDrv] = 1;
    467                 }
    468             }
    469             CloseHandle(hFile);
    470         }
    471 #else
    472         {
    473             char szFSName[32];
    474             if (    GetVolumeInformation(pszFull,
    475                                          NULL, 0,   /* volume name */
    476                                          NULL,      /* serial number */
    477                                          NULL,      /* max component */
    478                                          NULL,      /* volume attribs */
    479                                          szFSName,
    480                                          sizeof(szFSName))
    481                 &&  !strcmp(szFSName, "NTFS"))
    482             {
    483                 g_afNtfsDrives[iDrv] = 1;
    484             }
    485         }
    486 #endif
    487     }
    488     if (!g_afNtfsDrives[iDrv])
    489         return -1;
    490 
    491     /*
    492      * Try open the path and query its file name information.
    493      */
    494     hFile = CreateFile(pszPath,
    495                        GENERIC_READ,
    496                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    497                        NULL,
    498                        OPEN_EXISTING,
    499                        FILE_FLAG_BACKUP_SEMANTICS,
    500                        NULL);
    501     if (hFile != INVALID_HANDLE_VALUE)
    502     {
    503         /* check that the driver letter is correct first (reparse / symlink issues). */
    504         memset(&Ios, 0, sizeof(Ios));
    505         rcNt = g_pfnNtQueryVolumeInformationFile(hFile, &Ios, pFsVolInfo, sizeof(*pFsVolInfo), MY_FileFsVolumeInformation);
    506         if (rcNt >= 0)
    507         {
    508             /** @todo do a quick search and try correct the drive letter? */
    509             if (    pFsVolInfo->VolumeCreationTime.QuadPart == g_aVolumeInfo[iDrv].VolumeCreationTime.QuadPart
    510                 &&  pFsVolInfo->VolumeSerialNumber == g_aVolumeInfo[iDrv].VolumeSerialNumber)
    511             {
    512                 memset(&Ios, 0, sizeof(Ios));
    513                 rcNt = g_pfnNtQueryInformationFile(hFile, &Ios, abBuf, sizeof(abBuf), MY_FileNameInformation);
    514                 if (rcNt >= 0)
    515                 {
    516                     cchOut = WideCharToMultiByte(CP_ACP, 0,
    517                                                  pFileNameInfo->FileName, pFileNameInfo->FileNameLength / sizeof(WCHAR),
    518                                                  psz, (int)(cchFull - (psz - pszFull) - 2), NULL, NULL);
    519                     if (cchOut > 0)
    520                     {
    521                         const char *pszEnd;
    522 #if 0
    523                         /* upper case the server and share */
    524                         if (fUnc)
    525                         {
    526                             for (psz++; *psz != '/' && *psz != '\\'; psz++)
    527                                 *psz = toupper(*psz);
    528                             for (psz++; *psz != '/' && *psz != '\\'; psz++)
    529                                 *psz = toupper(*psz);
    530                         }
    531 #endif
    532                         /* add trailing slash on directories if input has it. */
    533                         pszEnd = strchr(pszPath, '\0');
    534                         if (    (pszEnd[-1] == '/' || pszEnd[-1] == '\\')
    535                             &&  psz[cchOut - 1] != '\\'
    536                             &&  psz[cchOut - 1] != '//')
    537                             psz[cchOut++] = '\\';
    538 
    539                         /* make sure it's terminated */
    540                         psz[cchOut] = '\0';
    541                         rc = 0;
    542                     }
    543                     else
    544                         rc = -3;
    545                 }
    546                 else
    547                     rc = -4;
    548             }
    549             else
    550                 rc = -5;
    551         }
    552         else
    553             rc = -6;
    554         CloseHandle(hFile);
    555     }
    556     else
    557         rc = -7;
    558     return rc;
    559 }
    560 
    561 /**
    562  * Somewhat similar to fullpath, except that it will fix
    563  * the case of existing path components.
    564  */
    565 void
    566 nt_fullpath(const char *pszPath, char *pszFull, size_t cchFull)
    567 {
    568 #if 0
    569     static int s_cHits = 0;
    570     static int s_cFallbacks = 0;
    571 #endif
    572 
    573     /*
    574      * The simple case, the file / dir / whatever exists and can be
    575      * queried without problems and spaces.
    576      */
    577     if (nt_get_filename_info(pszPath, pszFull, cchFull) == 0)
    578     {
    579         /** @todo make nt_get_filename_info return spaceless path. */
    580         if (strchr(pszFull, ' '))
    581             w32_fixcase(pszFull);
    582 #if 0
    583         fprintf(stdout, "nt #%d - %s\n", ++s_cHits, pszFull);
    584         fprintf(stdout, "   #%d - %s\n", s_cHits, pszPath);
    585 #endif
    586         return;
    587     }
    588     if (g_pfnNtQueryInformationFile)
    589     {
    590         /* do _fullpath and drop off path elements until we get a hit... - later */
    591     }
    592 
    593     /*
    594      * For now, simply fall back on the old method.
    595      */
    596     _fullpath(pszFull, pszPath, cchFull);
    597     w32_fixcase(pszFull);
    598 #if 0
    599     fprintf(stderr, "fb #%d - %s\n", ++s_cFallbacks, pszFull);
    600     fprintf(stderr, "   #%d - %s\n", s_cFallbacks, pszPath);
    601 #endif
    602 }
    603 
    60472
    60573
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