Changeset 1127 in kBuild
- Timestamp:
- Sep 26, 2007 10:16:47 PM (17 years ago)
- Location:
- trunk/src/kmk/w32
- Files:
-
- 2 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/w32/pathstuff.c
r911 r1127 82 82 } 83 83 84 #if 1 /* bird */ 84 85 /* 85 86 * Corrects the case of a path. … … 257 258 } 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 431 259 432 /* 260 433 * Convert to forward slashes. Resolve to full pathname optionally … … 267 440 268 441 if (resolve) { 442 #if 1 /* bird */ 443 # if 1 444 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 449 #else /* !bird */ 269 450 _fullpath(w32_path, filename, sizeof (w32_path)); 270 w32_fixcase(w32_path); /*bird */451 #endif /* !bird */ 271 452 } else 272 453 strncpy(w32_path, filename, sizeof (w32_path));
Note:
See TracChangeset
for help on using the changeset viewer.