VirtualBox

Changeset 1165 in kBuild for trunk/src/kmk/w32


Ignore:
Timestamp:
Sep 30, 2007 7:36:23 AM (18 years ago)
Author:
bird
Message:

Optimized kDebIDB a bit for Windows; use nt_fullpath and map the IDB file into memory.

Location:
trunk/src/kmk/w32
Files:
2 edited

Legend:

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

    r1127 r1165  
    8383
    8484#if 1 /* bird */
    85 /*
    86  * Corrects the case of a path.
    87  * Expects a fullpath!
    88  * Added by bird for the $(abspath ) function and w32ify
    89  */
    90 void
    91 w32_fixcase(char *pszPath)
    92 {
    93     static char     s_szLast[260];
    94     unsigned        cchLast;
    95 
    96 #ifndef NDEBUG
    97 # define my_assert(expr) \
    98     do { \
    99         if (!(expr)) { \
    100             printf("my_assert: %s, file %s, line %d\npszPath=%s\npsz=%s\n", \
    101                    #expr, __FILE__, __LINE__, pszPath, psz); \
    102             __debugbreak(); \
    103             exit(1); \
    104         } \
    105     } while (0)
    106 #else
    107 # define my_assert(expr) do {} while (0)
    108 #endif
    109 
    110     char *psz = pszPath;
    111     if (*psz == '/' || *psz == '\\')
    112     {
    113         if (psz[1] == '/' || psz[1] == '\\')
    114         {
    115             /* UNC */
    116             my_assert(psz[1] == '/' || psz[1] == '\\');
    117             my_assert(psz[2] != '/' && psz[2] != '\\');
    118 
    119             /* skip server name */
    120             psz += 2;
    121             while (*psz != '\\' && *psz != '/')
    122             {
    123                 if (!*psz)
    124                     return;
    125                 *psz++ = toupper(*psz);
    126             }
    127 
    128             /* skip the share name */
    129             psz++;
    130             my_assert(*psz != '/' && *psz != '\\');
    131             while (*psz != '\\' && *psz != '/')
    132             {
    133                 if (!*psz)
    134                     return;
    135                 *psz++ = toupper(*psz);
    136             }
    137             my_assert(*psz == '/' || *psz == '\\');
    138             psz++;
    139         }
    140         else
    141         {
    142             /* Unix spec */
    143             psz++;
    144         }
    145     }
    146     else
    147     {
    148         /* Drive letter */
    149         my_assert(psz[1] == ':');
    150         *psz = toupper(*psz);
    151         my_assert(psz[0] >= 'A' && psz[0] <= 'Z');
    152         my_assert(psz[2] == '/' || psz[2] == '\\');
    153         psz += 3;
    154     }
    155 
    156     /*
    157      * Try make use of the result from the previous call.
    158      * This is ignorant to slashes and similar, but may help even so.
    159      */
    160     if (    s_szLast[0] == pszPath[0]
    161         &&  (psz - pszPath == 1 || s_szLast[1] == pszPath[1])
    162         &&  (psz - pszPath <= 2 || s_szLast[2] == pszPath[2])
    163        )
    164     {
    165         char *pszLast = &s_szLast[psz - pszPath];
    166         char *pszCur = psz;
    167         for (;;)
    168         {
    169             const char ch1 = *pszCur;
    170             const char ch2 = *pszLast;
    171             if (    ch1 != ch2
    172                 &&  (ch1 != '\\' || ch2 != '/')
    173                 &&  (ch1 != '/'  || ch2 != '\\'))
    174             {
    175                 if (    tolower(ch1) != tolower(ch2)
    176                     &&  toupper(ch1) != toupper(ch2))
    177                     break;
    178                 /* optimistic, component mismatch will be corrected in the next loop. */
    179                 *pszCur = ch2;
    180             }
    181             if (ch1 == '/' || ch1 == '\\')
    182                 psz = pszCur + 1;
    183             else if (ch1 == '\0')
    184             {
    185                 psz = pszCur;
    186                 break;
    187             }
    188             pszCur++;
    189             pszLast++;
    190         }
    191     }
    192 
    193     /*
    194      * Pointing to the first char after the unc or drive specifier,
    195      * or in case of a cache hit, the first non-matching char (following a slash of course).
    196      */
    197     while (*psz)
    198     {
    199         WIN32_FIND_DATA FindFileData;
    200         HANDLE hDir;
    201         char chSaved0;
    202         char chSaved1;
    203         char *pszEnd;
    204         int iLongNameDiff;
    205 
    206 
    207         /* find the end of the component. */
    208         pszEnd = psz;
    209         while (*pszEnd && *pszEnd != '/' && *pszEnd != '\\')
    210             pszEnd++;
    211 
    212         /* replace the end with "?\0" */
    213         chSaved0 = pszEnd[0];
    214         chSaved1 = pszEnd[1];
    215         pszEnd[0] = '?';
    216         pszEnd[1] = '\0';
    217 
    218         /* find the right filename. */
    219         hDir = FindFirstFile(pszPath, &FindFileData);
    220         pszEnd[1] = chSaved1;
    221         if (!hDir)
    222         {
    223             cchLast = psz - pszPath;
    224             memcpy(s_szLast, pszPath, cchLast + 1);
    225             pszEnd[0] = chSaved0;
    226             return;
    227         }
    228         pszEnd[0] = '\0';
    229         while (   (iLongNameDiff = stricmp(FindFileData.cFileName, psz))
    230                && stricmp(FindFileData.cAlternateFileName, psz))
    231         {
    232             if (!FindNextFile(hDir, &FindFileData))
    233             {
    234                 cchLast = psz - pszPath;
    235                 memcpy(s_szLast, pszPath, cchLast + 1);
    236                 pszEnd[0] = chSaved0;
    237                 return;
    238             }
    239         }
    240         strcpy(psz, !iLongNameDiff ? FindFileData.cFileName : FindFileData.cAlternateFileName);
    241         pszEnd[0] = chSaved0;
    242         FindClose(hDir);
    243 
    244         /* advance to the next component */
    245         if (!chSaved0)
    246         {
    247             psz = pszEnd;
    248             break;
    249         }
    250         psz = pszEnd + 1;
    251         my_assert(*psz != '/' && *psz != '\\');
    252     }
    253 
    254     /* *psz == '\0', the end. */
    255     cchLast = psz - pszPath;
    256     memcpy(s_szLast, pszPath, cchLast + 1);
    257 #undef my_assert
    258 }
    259 
    260 #define MY_FileNameInformation 9
    261 
    262 typedef struct _MY_FILE_NAME_INFORMATION
    263 {
    264     ULONG FileNameLength;
    265     WCHAR FileName[1];
    266 } MY_FILE_NAME_INFORMATION, *PMY_FILE_NAME_INFORMATION;
    267 
    268 typedef struct _IO_STATUS_BLOCK
    269 {
    270     union
    271     {
    272         LONG Status;
    273         PVOID Pointer;
    274     };
    275     ULONG_PTR Information;
    276 } MY_IO_STATUS_BLOCK, *PMY_IO_STATUS_BLOCK;
    277 
    278 static BOOL g_fInitialized = FALSE;
    279 static LONG (NTAPI *g_pfnNtQueryInformationFile)(HANDLE FileHandle,
    280     PMY_IO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, 
    281     ULONG Length, ULONG FileInformationClass);
    282 
    283 
    284 int
    285 nt_get_filename_info(const char *pszPath, char *pszFull, size_t cchFull)
    286 {
    287     static char                 abBuf[8192];
    288     PMY_FILE_NAME_INFORMATION   pFileNameInfo = (PMY_FILE_NAME_INFORMATION)abBuf;
    289     MY_IO_STATUS_BLOCK          Ios;
    290     LONG                        rcNt;
    291     HANDLE                      hFile;
    292 
    293     /*
    294      * Check for NtQueryInformationFile the first time around.
    295      */
    296     if (!g_fInitialized)
    297     {
    298         g_fInitialized = TRUE;
    299         if (!getenv("KMK_DONT_USE_NT_QUERY_INFORMATION_FILE"))
    300             *(FARPROC *)&g_pfnNtQueryInformationFile =
    301                 GetProcAddress(LoadLibrary("ntdll.dll"), "NtQueryInformationFile");
    302     }
    303     if (!g_pfnNtQueryInformationFile)
    304         return -1;
    305 
    306     /*
    307      * Try open the path and query its file name information.
    308      */
    309     hFile = CreateFile(pszPath,
    310                        GENERIC_READ,
    311                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    312                        NULL,
    313                        OPEN_EXISTING,
    314                        FILE_FLAG_BACKUP_SEMANTICS,
    315                        NULL);
    316     if (hFile)
    317     {
    318         memset(&Ios, 0, sizeof(Ios));
    319         rcNt = g_pfnNtQueryInformationFile(hFile, &Ios, abBuf, sizeof(abBuf), MY_FileNameInformation);
    320         CloseHandle(hFile);
    321         if (rcNt >= 0)
    322         {
    323             /*
    324              * The FileNameInformation we get is relative to where the volume is mounted,
    325              * so we have to extract the driveletter prefix ourselves.
    326              *
    327              * FIXME: This will probably not work for volumes mounted in NTFS sub-directories.
    328              */
    329             int cchOut;
    330             int fUnc = 0;
    331             char *psz = pszFull;
    332             if (pszPath[0] == '\\' || pszPath[0] == '/')
    333             {
    334                 /* unc or root of volume */
    335                 if (    (pszPath[1] == '\\' || pszPath[1] == '/')
    336                     &&  (pszPath[2] != '\\' || pszPath[2] == '/'))
    337                 {
    338                     /* unc - we get the server + name back */
    339                     *psz++ = '\\';
    340                     fUnc = 1;
    341                 }
    342                 else
    343                 {
    344                     /* root slash */
    345                     *psz++ = _getdrive() + 'A' - 1;
    346                     *psz++ = ':';
    347                 }
    348             }
    349             else if (pszPath[1] == ':' && isalpha(pszPath[0]))
    350             {
    351                 /* drive letter */
    352                 *psz++ = toupper(pszPath[0]);
    353                 *psz++ = ':';
    354             }
    355             else
    356             {
    357                 /* relative */
    358                 *psz++ = _getdrive() + 'A' - 1;
    359                 *psz++ = ':';
    360             }
    361 
    362             cchOut = WideCharToMultiByte(CP_ACP, 0,
    363                                          pFileNameInfo->FileName, pFileNameInfo->FileNameLength / sizeof(WCHAR),
    364                                          psz, cchFull - (psz - pszFull) - 2, NULL, NULL);
    365             if (cchOut > 0)
    366             {
    367                 const char *pszEnd;
    368 
    369                 /* upper case the server and share */
    370                 if (fUnc)
    371                 {
    372                     for (psz++; *psz != '/' && *psz != '\\'; psz++)
    373                         *psz = toupper(*psz);
    374                     for (psz++; *psz != '/' && *psz != '\\'; psz++)
    375                         *psz = toupper(*psz);
    376                 }
    377 
    378                 /* add trailing slash on directories if input has it. */
    379                 pszEnd = strchr(pszPath, '\0');
    380                 if (    (pszEnd[-1] == '/' || pszEnd[-1] == '\\')
    381                     &&  psz[cchOut - 1] != '\\'
    382                     &&  psz[cchOut - 1] != '//')
    383                     psz[cchOut++] = '\\';
    384 
    385                 /* make sure it's terminated */
    386                 psz[cchOut] = '\0';
    387                 return 0;
    388             }
    389             return -3;
    390         }
    391     }
    392     return -2;
    393 }
    394 
    395 void
    396 nt_fullpath(const char *pszPath, char *pszFull, size_t cchFull)
    397 {
    398 #if 0
    399     static int s_cHits = 0;
    400     static int s_cFallbacks = 0;
    401 #endif
    402 
    403     /*
    404      * The simple case, the file / dir / whatever exists and can be
    405      * queried without problems.
    406      */
    407     if (nt_get_filename_info(pszPath, pszFull, cchFull) == 0)
    408     {
    409 #if 0
    410         fprintf(stderr, "nt #%d - %s\n", ++s_cHits, pszFull);
    411 #endif
    412         return;
    413     }
    414     if (g_pfnNtQueryInformationFile)
    415     {
    416         /* do _fullpath and drop off path elements until we get a hit... - later */
    417     }
    418    
    419     /*
    420      * For now, simply fall back on the old method.
    421      */
    422     _fullpath(pszFull, pszPath, cchFull);
    423     w32_fixcase(pszFull);
    424 #if 0
    425     fprintf(stderr, "fb #%d - %s\n", ++s_cFallbacks, pszFull);
    426 #endif
    427 }
    428 
    429 #endif /* bird */
    430 
     85extern void nt_fullpath(const char *pszPath, char *pszFull, size_t cchFull);
     86#endif
    43187
    43288/*
     
    44197    if (resolve) {
    44298#if 1 /* bird */
    443 # if 1
    44499        nt_fullpath(filename, w32_path, sizeof(w32_path));
    445 # else
    446         _fullpath(w32_path, filename, sizeof(w32_path));
    447         w32_fixcase(w32_path);
    448 # endif
    449100#else   /* !bird */
    450101        _fullpath(w32_path, filename, sizeof (w32_path));
  • trunk/src/kmk/w32/subproc/sub_proc.c

    r540 r1165  
    737737
    738738        while (!stdin_eof || !stdout_eof || !stderr_eof || !child_dead) {
     739long tick;
    739740                wait_count = 0;
    740741                if (!stdin_eof) {
     
    751752                }
    752753
     754tick = GetTickCount();
    753755                wait_return = WaitForMultipleObjects(wait_count, wait_list,
    754756                         FALSE, /* don't wait for all: one ready will do */
    755757                         child_dead? 1000 :INFINITE); /* after the child dies, subthreads have
    756758                                one second to collect all remaining output */
     759printf("waitformultipleobjects: %d ms rc=%d\n", GetTickCount() - tick, wait_return);
    757760
    758761                if (wait_return == WAIT_FAILED) {
     
    10751078#ifdef KMK /* for the space before the final " in case we need it. */
    10761079        bytes_required++;
    1077 #endif 
     1080#endif
    10781081
    10791082        command_line = (char*) malloc(bytes_required);
     
    11251128                                         */
    11261129                                        backslash_count++;
    1127        
     1130
    11281131                                        while(backslash_count) {
    11291132                                                *(command_line_i++) = '\\';
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