Changeset 78535 in vbox for trunk/src/VBox/ValidationKit/utils/fs
- Timestamp:
- May 15, 2019 11:48:14 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 130580
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/fs/FsPerf.cpp
r78486 r78535 2199 2199 }; 2200 2200 2201 void fsPerfNtQueryInfoFileWorker(HANDLE hNtFile1 )2201 void fsPerfNtQueryInfoFileWorker(HANDLE hNtFile1, uint32_t fType) 2202 2202 { 2203 2203 /** @todo may run out of buffer for really long paths? */ … … 2345 2345 ) 2346 2346 RTTestIFailed("%s/%#x: %#x, expected STATUS_BUFFER_OVERFLOW", pszClass, cbBuf, rcNt); 2347 /** @todo check name and length fields */ 2347 2348 } 2348 2349 else … … 2384 2385 || enmClass == FileCaseSensitiveInformation 2385 2386 || enmClass == FileStorageReserveIdInformation 2386 || enmClass == FileCaseSensitiveInformationForceAccessCheck)) 2387 || enmClass == FileCaseSensitiveInformationForceAccessCheck) 2388 || ( fType == RTFS_TYPE_DIRECTORY 2389 && (enmClass == FileSfioReserveInformation || enmClass == FileStatLxInformation))) 2387 2390 ) 2388 2391 RTTestIFailed("%s/%#x: %#x", pszClass, cbBuf, rcNt); 2389 if (Ios.Status != VirginIos.Status || Ios.Information != VirginIos.Information) 2392 if ( (Ios.Status != VirginIos.Status || Ios.Information != VirginIos.Information) 2393 && !( fType == RTFS_TYPE_DIRECTORY /* NTFS/W10-17763 */ 2394 && Ios.Status == rcNt && Ios.Information == 0) ) 2390 2395 RTTestIFailed("%s/%#x: I/O status block was modified: %#x %#zx", pszClass, cbBuf, Ios.Status, Ios.Information); 2391 2396 if (!ASMMemIsAllU8(&uBuf, sizeof(uBuf), 0xff)) … … 2395 2400 } 2396 2401 2397 2398 2402 void fsPerfNtQueryInfoFile(void) 2399 2403 { … … 2403 2407 RTFILE hFile1; 2404 2408 RTTESTI_CHECK_RC_RETV(RTFileOpen(&hFile1, InDir(RT_STR_TUPLE("file2qif")), 2405 RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE | RTFILE_O_ WRITE), VINF_SUCCESS);2406 fsPerfNtQueryInfoFileWorker((HANDLE)RTFileToNative(hFile1) );2409 RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE | RTFILE_O_READWRITE), VINF_SUCCESS); 2410 fsPerfNtQueryInfoFileWorker((HANDLE)RTFileToNative(hFile1), RTFS_TYPE_FILE); 2407 2411 RTTESTI_CHECK_RC(RTFileClose(hFile1), VINF_SUCCESS); 2408 2412 2409 2413 /* On a directory: */ 2410 2414 HANDLE hDir1 = INVALID_HANDLE_VALUE; 2411 RTTESTI_CHECK_RC(RTNtPathOpenDir(InDir(RT_STR_TUPLE("")), GENERIC_READ, 2412 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 2413 FILE_OPEN, 0, &hDir1, NULL), VINF_SUCCESS); 2414 } 2415 2415 RTTESTI_CHECK_RC_RETV(RTNtPathOpenDir(InDir(RT_STR_TUPLE("")), GENERIC_READ | SYNCHRONIZE | FILE_SYNCHRONOUS_IO_NONALERT, 2416 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 2417 FILE_OPEN, 0, &hDir1, NULL), VINF_SUCCESS); 2418 fsPerfNtQueryInfoFileWorker(hDir1, RTFS_TYPE_DIRECTORY); 2419 RTTESTI_CHECK(CloseHandle(hDir1) == TRUE); 2420 } 2421 2422 2423 /** 2424 * Nt(Query|Set)VolumeInformationFile) information class info. 2425 */ 2426 static const struct 2427 { 2428 const char *pszName; 2429 int enmValue; 2430 bool fQuery; 2431 bool fSet; 2432 uint8_t cbMin; 2433 } g_aNtQueryVolInfoFileClasses[] = 2434 { 2435 #define E(a_enmValue, a_fQuery, a_fSet, a_cbMin) \ 2436 { #a_enmValue, a_enmValue, a_fQuery, a_fSet, a_cbMin } 2437 { "invalid0", 0, false, false, 0 }, 2438 E(FileFsVolumeInformation, 1, 0, sizeof(FILE_FS_VOLUME_INFORMATION)), 2439 E(FileFsLabelInformation, 0, 1, sizeof(FILE_FS_LABEL_INFORMATION)), 2440 E(FileFsSizeInformation, 1, 0, sizeof(FILE_FS_SIZE_INFORMATION)), 2441 E(FileFsDeviceInformation, 1, 0, sizeof(FILE_FS_DEVICE_INFORMATION)), 2442 E(FileFsAttributeInformation, 1, 0, sizeof(FILE_FS_ATTRIBUTE_INFORMATION)), 2443 E(FileFsControlInformation, 1, 1, sizeof(FILE_FS_CONTROL_INFORMATION)), 2444 E(FileFsFullSizeInformation, 1, 0, sizeof(FILE_FS_FULL_SIZE_INFORMATION)), 2445 E(FileFsObjectIdInformation, 1, 1, sizeof(FILE_FS_OBJECTID_INFORMATION)), 2446 E(FileFsDriverPathInformation, 1, 0, sizeof(FILE_FS_DRIVER_PATH_INFORMATION)), 2447 E(FileFsVolumeFlagsInformation, 1, 1, sizeof(FILE_FS_VOLUME_FLAGS_INFORMATION)), 2448 E(FileFsSectorSizeInformation, 1, 0, sizeof(FILE_FS_SECTOR_SIZE_INFORMATION)), 2449 E(FileFsDataCopyInformation, 1, 0, sizeof(FILE_FS_DATA_COPY_INFORMATION)), 2450 E(FileFsMetadataSizeInformation, 1, 0, sizeof(FILE_FS_METADATA_SIZE_INFORMATION)), 2451 E(FileFsFullSizeInformationEx, 1, 0, sizeof(FILE_FS_FULL_SIZE_INFORMATION_EX)), 2452 #undef E 2453 }; 2454 2455 void fsPerfNtQueryVolInfoFileWorker(HANDLE hNtFile1, uint32_t fType) 2456 { 2457 char const chType = fType == RTFS_TYPE_DIRECTORY ? 'd' : 'r'; 2458 union 2459 { 2460 uint8_t ab[4096]; 2461 FILE_FS_VOLUME_INFORMATION Vol; 2462 FILE_FS_LABEL_INFORMATION Label; 2463 FILE_FS_SIZE_INFORMATION Size; 2464 FILE_FS_DEVICE_INFORMATION Dev; 2465 FILE_FS_ATTRIBUTE_INFORMATION Attrib; 2466 FILE_FS_CONTROL_INFORMATION Ctrl; 2467 FILE_FS_FULL_SIZE_INFORMATION FullSize; 2468 FILE_FS_OBJECTID_INFORMATION ObjId; 2469 FILE_FS_DRIVER_PATH_INFORMATION DrvPath; 2470 FILE_FS_VOLUME_FLAGS_INFORMATION VolFlags; 2471 FILE_FS_SECTOR_SIZE_INFORMATION SectorSize; 2472 FILE_FS_DATA_COPY_INFORMATION DataCopy; 2473 FILE_FS_METADATA_SIZE_INFORMATION Metadata; 2474 FILE_FS_FULL_SIZE_INFORMATION_EX FullSizeEx; 2475 } uBuf; 2476 2477 IO_STATUS_BLOCK const VirginIos = RTNT_IO_STATUS_BLOCK_INITIALIZER; 2478 for (unsigned i = 0; i < RT_ELEMENTS(g_aNtQueryVolInfoFileClasses); i++) 2479 { 2480 FS_INFORMATION_CLASS const enmClass = (FS_INFORMATION_CLASS)g_aNtQueryVolInfoFileClasses[i].enmValue; 2481 const char * const pszClass = g_aNtQueryVolInfoFileClasses[i].pszName; 2482 2483 memset(&uBuf, 0xff, sizeof(uBuf)); 2484 IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER; 2485 ULONG cbBuf = sizeof(uBuf); 2486 NTSTATUS rcNt = NtQueryVolumeInformationFile(hNtFile1, &Ios, &uBuf, cbBuf, enmClass); 2487 if (g_uVerbosity > 3) 2488 RTTestIPrintf(RTTESTLVL_ALWAYS, "%+34s/%#04x/%c: rcNt=%#x Ios.Status=%#x Info=%#zx\n", 2489 pszClass, cbBuf, chType, rcNt, Ios.Status, Ios.Information); 2490 if (NT_SUCCESS(rcNt)) 2491 { 2492 if (Ios.Status == VirginIos.Status || Ios.Information == VirginIos.Information) 2493 RTTestIFailed("%s/%#x/%c: I/O status block was not modified: %#x %#zx", 2494 pszClass, cbBuf, chType, Ios.Status, Ios.Information); 2495 else if (!g_aNtQueryVolInfoFileClasses[i].fQuery) 2496 RTTestIFailed("%s/%#x/%c: This isn't supposed to be queriable! (rcNt=%#x)", pszClass, cbBuf, chType, rcNt); 2497 else 2498 { 2499 ULONG const cbActualMin = Ios.Information; 2500 ULONG *pcbName = NULL; 2501 ULONG offName = 0; 2502 2503 switch (enmClass) 2504 { 2505 case FileFsVolumeInformation: 2506 pcbName = &uBuf.Vol.VolumeLabelLength; 2507 offName = RT_UOFFSETOF(FILE_FS_VOLUME_INFORMATION, VolumeLabel); 2508 if (RT_UOFFSETOF_DYN(FILE_FS_VOLUME_INFORMATION, 2509 VolumeLabel[uBuf.Vol.VolumeLabelLength / sizeof(WCHAR)]) != cbActualMin) 2510 RTTestIFailed("%s/%#x/%c: Wrong VolumeLabelLength=%#x vs cbActual=%#x", 2511 pszClass, cbActualMin, chType, uBuf.Vol.VolumeLabelLength, cbActualMin); 2512 if (uBuf.Vol.VolumeLabel[uBuf.Vol.VolumeLabelLength / sizeof(WCHAR) - 1] == '\0') 2513 RTTestIFailed("%s/%#x/%c: Zero terminated name!", pszClass, cbActualMin, chType); 2514 if (g_uVerbosity > 1) 2515 RTTestIPrintf(RTTESTLVL_ALWAYS, "%+34s/%#04x/%c: VolumeLabelLength=%#x VolumeLabel='%.*ls'\n", 2516 pszClass, cbActualMin, chType, uBuf.Vol.VolumeLabelLength, 2517 uBuf.Vol.VolumeLabelLength / sizeof(WCHAR), uBuf.Vol.VolumeLabel); 2518 break; 2519 2520 case FileFsAttributeInformation: 2521 pcbName = &uBuf.Attrib.FileSystemNameLength; 2522 offName = RT_UOFFSETOF(FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName); 2523 if (RT_UOFFSETOF_DYN(FILE_FS_ATTRIBUTE_INFORMATION, 2524 FileSystemName[uBuf.Attrib.FileSystemNameLength / sizeof(WCHAR)]) != cbActualMin) 2525 RTTestIFailed("%s/%#x/%c: Wrong FileSystemNameLength=%#x vs cbActual=%#x", 2526 pszClass, cbActualMin, chType, uBuf.Attrib.FileSystemNameLength, cbActualMin); 2527 if (uBuf.Attrib.FileSystemName[uBuf.Attrib.FileSystemNameLength / sizeof(WCHAR) - 1] == '\0') 2528 RTTestIFailed("%s/%#x/%c: Zero terminated name!", pszClass, cbActualMin, chType); 2529 if (g_uVerbosity > 1) 2530 RTTestIPrintf(RTTESTLVL_ALWAYS, "%+34s/%#04x/%c: FileSystemNameLength=%#x FileSystemName='%.*ls' Attribs=%#x MaxCompName=%#x\n", 2531 pszClass, cbActualMin, chType, uBuf.Attrib.FileSystemNameLength, 2532 uBuf.Attrib.FileSystemNameLength / sizeof(WCHAR), uBuf.Attrib.FileSystemName, 2533 uBuf.Attrib.FileSystemAttributes, uBuf.Attrib.MaximumComponentNameLength); 2534 break; 2535 2536 case FileFsDriverPathInformation: 2537 pcbName = &uBuf.DrvPath.DriverNameLength; 2538 offName = RT_UOFFSETOF(FILE_FS_DRIVER_PATH_INFORMATION, DriverName); 2539 if (RT_UOFFSETOF_DYN(FILE_FS_DRIVER_PATH_INFORMATION, 2540 DriverName[uBuf.DrvPath.DriverNameLength / sizeof(WCHAR)]) != cbActualMin) 2541 RTTestIFailed("%s/%#x/%c: Wrong DriverNameLength=%#x vs cbActual=%#x", 2542 pszClass, cbActualMin, chType, uBuf.DrvPath.DriverNameLength, cbActualMin); 2543 if (uBuf.DrvPath.DriverName[uBuf.DrvPath.DriverNameLength / sizeof(WCHAR) - 1] == '\0') 2544 RTTestIFailed("%s/%#x/%c: Zero terminated name!", pszClass, cbActualMin, chType); 2545 if (g_uVerbosity > 1) 2546 RTTestIPrintf(RTTESTLVL_ALWAYS, "%+34s/%#04x/%c: DriverNameLength=%#x DriverName='%.*ls'\n", 2547 pszClass, cbActualMin, chType, uBuf.DrvPath.DriverNameLength, 2548 uBuf.DrvPath.DriverNameLength / sizeof(WCHAR), uBuf.DrvPath.DriverName); 2549 break; 2550 2551 case FileFsSectorSizeInformation: 2552 if (g_uVerbosity > 1) 2553 RTTestIPrintf(RTTESTLVL_ALWAYS, "%+34s/%#04x/%c: Flags=%#x log=%#x atomic=%#x perf=%#x eff=%#x offSec=%#x offPart=%#x\n", 2554 pszClass, cbActualMin, chType, uBuf.SectorSize.Flags, 2555 uBuf.SectorSize.LogicalBytesPerSector, 2556 uBuf.SectorSize.PhysicalBytesPerSectorForAtomicity, 2557 uBuf.SectorSize.PhysicalBytesPerSectorForPerformance, 2558 uBuf.SectorSize.FileSystemEffectivePhysicalBytesPerSectorForAtomicity, 2559 uBuf.SectorSize.ByteOffsetForSectorAlignment, 2560 uBuf.SectorSize.ByteOffsetForPartitionAlignment); 2561 break; 2562 2563 default: 2564 if (g_uVerbosity > 2) 2565 RTTestIPrintf(RTTESTLVL_ALWAYS, "%+34s/%#04x/%c:\n", pszClass, cbActualMin, chType); 2566 break; 2567 } 2568 ULONG const cbName = pcbName ? *pcbName : 0; 2569 uint8_t abNameCopy[4096]; 2570 RT_ZERO(abNameCopy); 2571 if (pcbName) 2572 memcpy(abNameCopy, &uBuf.ab[offName], cbName); 2573 2574 ULONG const cbMin = g_aNtQueryVolInfoFileClasses[i].cbMin; 2575 ULONG const cbMax = RT_MIN(cbActualMin + 64, sizeof(uBuf)); 2576 for (cbBuf = 0; cbBuf < cbMax; cbBuf++) 2577 { 2578 memset(&uBuf, 0xfe, sizeof(uBuf)); 2579 RTNT_IO_STATUS_BLOCK_REINIT(&Ios); 2580 rcNt = NtQueryVolumeInformationFile(hNtFile1, &Ios, &uBuf, cbBuf, enmClass); 2581 if (!ASMMemIsAllU8(&uBuf.ab[cbBuf], sizeof(uBuf) - cbBuf, 0xfe)) 2582 RTTestIFailed("%s/%#x/%c: Touched memory beyond end of buffer (rcNt=%#x)", pszClass, cbBuf, chType, rcNt); 2583 if (cbBuf < cbMin) 2584 { 2585 if (rcNt != STATUS_INFO_LENGTH_MISMATCH) 2586 RTTestIFailed("%s/%#x/%c: %#x, expected STATUS_INFO_LENGTH_MISMATCH", pszClass, cbBuf, chType, rcNt); 2587 if (Ios.Status != VirginIos.Status || Ios.Information != VirginIos.Information) 2588 RTTestIFailed("%s/%#x/%c: I/O status block was modified (STATUS_INFO_LENGTH_MISMATCH): %#x %#zx", 2589 pszClass, cbBuf, chType, Ios.Status, Ios.Information); 2590 } 2591 else if (cbBuf < cbActualMin) 2592 { 2593 if (rcNt != STATUS_BUFFER_OVERFLOW) 2594 RTTestIFailed("%s/%#x/%c: %#x, expected STATUS_BUFFER_OVERFLOW", pszClass, cbBuf, chType, rcNt); 2595 if (pcbName) 2596 { 2597 size_t const cbNameAlt = offName < cbBuf ? cbBuf - offName : 0; 2598 if ( *pcbName != cbName 2599 && !( *pcbName == cbNameAlt 2600 && (enmClass == FileFsAttributeInformation /*NTFS,FAT*/))) 2601 RTTestIFailed("%s/%#x/%c: Wrong name length: %#x, expected %#x (or %#x)", 2602 pszClass, cbBuf, chType, *pcbName, cbName, cbNameAlt); 2603 if (memcmp(abNameCopy, &uBuf.ab[offName], cbNameAlt) != 0) 2604 RTTestIFailed("%s/%#x/%c: Wrong partial name: %.*Rhxs", 2605 pszClass, cbBuf, chType, cbNameAlt, &uBuf.ab[offName]); 2606 } 2607 if (Ios.Information != cbBuf) 2608 RTTestIFailed("%s/%#x/%c: Ios.Information = %#x, expected %#x", 2609 pszClass, cbBuf, chType, Ios.Information, cbBuf); 2610 } 2611 else 2612 { 2613 if ( !ASMMemIsAllU8(&uBuf.ab[cbActualMin], sizeof(uBuf) - cbActualMin, 0xfe) 2614 && enmClass != FileStorageReserveIdInformation /* NTFS bug? */ ) 2615 RTTestIFailed("%s/%#x/%c: Touched memory beyond returned length (cbActualMin=%#x, rcNt=%#x)", 2616 pszClass, cbBuf, chType, cbActualMin, rcNt); 2617 if (pcbName && *pcbName != cbName) 2618 RTTestIFailed("%s/%#x/%c: Wrong name length: %#x, expected %#x", 2619 pszClass, cbBuf, chType, *pcbName, cbName); 2620 if (pcbName && memcmp(abNameCopy, &uBuf.ab[offName], cbName) != 0) 2621 RTTestIFailed("%s/%#x/%c: Wrong name: %.*Rhxs", 2622 pszClass, cbBuf, chType, cbName, &uBuf.ab[offName]); 2623 } 2624 } 2625 } 2626 } 2627 else 2628 { 2629 if (!g_aNtQueryVolInfoFileClasses[i].fQuery) 2630 { 2631 if (rcNt != STATUS_INVALID_INFO_CLASS) 2632 RTTestIFailed("%s/%#x/%c: %#x, expected STATUS_INVALID_INFO_CLASS", pszClass, cbBuf, chType, rcNt); 2633 } 2634 else if ( rcNt != STATUS_INVALID_INFO_CLASS 2635 && rcNt != STATUS_INVALID_PARAMETER 2636 && !(rcNt == STATUS_ACCESS_DENIED && enmClass == FileFsControlInformation /* RDR2/W10 */) 2637 && !(rcNt == STATUS_OBJECT_NAME_NOT_FOUND && enmClass == FileFsObjectIdInformation /* RDR2/W10 */) 2638 ) 2639 RTTestIFailed("%s/%#x/%c: %#x", pszClass, cbBuf, chType, rcNt); 2640 if ( (Ios.Status != VirginIos.Status || Ios.Information != VirginIos.Information) 2641 && !( Ios.Status == 0 && Ios.Information == 0 2642 && fType == RTFS_TYPE_DIRECTORY 2643 && ( enmClass == FileFsObjectIdInformation /* RDR2+NTFS on W10 */ 2644 || enmClass == FileFsControlInformation /* RDR2 on W10 */ 2645 || enmClass == FileFsVolumeFlagsInformation /* RDR2+NTFS on W10 */ 2646 || enmClass == FileFsDataCopyInformation /* RDR2 on W10 */ 2647 || enmClass == FileFsMetadataSizeInformation /* RDR2+NTFS on W10 */ 2648 || enmClass == FileFsFullSizeInformationEx /* RDR2 on W10 */ 2649 ) ) 2650 ) 2651 RTTestIFailed("%s/%#x/%c: I/O status block was modified: %#x %#zx (rcNt=%#x)", 2652 pszClass, cbBuf, chType, Ios.Status, Ios.Information, rcNt); 2653 if (!ASMMemIsAllU8(&uBuf, sizeof(uBuf), 0xff)) 2654 RTTestIFailed("%s/%#x/%c: Buffer was touched in failure case!", pszClass, cbBuf, chType); 2655 } 2656 } 2657 RT_NOREF(fType); 2658 } 2416 2659 2417 2660 void fsPerfNtQueryVolInfoFile(void) 2418 2661 { 2419 /** @todo */ 2662 RTTestISub("NtQueryVolumeInformationFile"); 2663 2664 /* On a regular file: */ 2665 RTFILE hFile1; 2666 RTTESTI_CHECK_RC_RETV(RTFileOpen(&hFile1, InDir(RT_STR_TUPLE("file2qvif")), 2667 RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE | RTFILE_O_READWRITE), VINF_SUCCESS); 2668 fsPerfNtQueryVolInfoFileWorker((HANDLE)RTFileToNative(hFile1), RTFS_TYPE_FILE); 2669 RTTESTI_CHECK_RC(RTFileClose(hFile1), VINF_SUCCESS); 2670 2671 /* On a directory: */ 2672 HANDLE hDir1 = INVALID_HANDLE_VALUE; 2673 RTTESTI_CHECK_RC_RETV(RTNtPathOpenDir(InDir(RT_STR_TUPLE("")), GENERIC_READ | SYNCHRONIZE | FILE_SYNCHRONOUS_IO_NONALERT, 2674 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 2675 FILE_OPEN, 0, &hDir1, NULL), VINF_SUCCESS); 2676 fsPerfNtQueryVolInfoFileWorker(hDir1, RTFS_TYPE_DIRECTORY); 2677 RTTESTI_CHECK(CloseHandle(hDir1) == TRUE); 2678 2679 /* On a regular file opened for reading: */ 2680 RTTESTI_CHECK_RC_RETV(RTFileOpen(&hFile1, InDir(RT_STR_TUPLE("file2qvif")), 2681 RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_READ), VINF_SUCCESS); 2682 fsPerfNtQueryVolInfoFileWorker((HANDLE)RTFileToNative(hFile1), RTFS_TYPE_FILE); 2683 RTTESTI_CHECK_RC(RTFileClose(hFile1), VINF_SUCCESS); 2420 2684 } 2421 2685
Note:
See TracChangeset
for help on using the changeset viewer.