1 /* 2 * PROJECT: ReactOS kernel-mode tests 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: Kernel-Mode Test Suite Volume Device test 5 * COPYRIGHT: Copyright 2019 Thomas Faber (thomas.faber@reactos.org) 6 */ 7 8 #include <kmt_test.h> 9 10 static 11 NTSTATUS 12 GetNextVolumeDevice( 13 _Inout_ PUNICODE_STRING VolumeDeviceName, 14 _Inout_ PULONG VolumeNumber, 15 _In_ NTSTATUS PreviousStatus) 16 { 17 NTSTATUS Status; 18 19 #ifndef __REACTOS__ 20 *VolumeNumber++; 21 Status = RtlStringCbPrintfW(VolumeDeviceName->Buffer, 22 VolumeDeviceName->MaximumLength, 23 L"\\Device\\HarddiskVolume%lu", 24 *VolumeNumber); 25 #else 26 /* ROS's storage stack is old an broken, we don't have HarddiskVolumeN */ 27 ULONG DiskNumber, PartitionNumber; 28 DiskNumber = *VolumeNumber >> 16; 29 PartitionNumber = *VolumeNumber & 0xffff; 30 if (!NT_SUCCESS(PreviousStatus)) 31 { 32 if (PartitionNumber == 1) 33 { 34 /* Looks like this disk doesn't exist (or has no partitions), 35 * so we're done */ 36 return STATUS_NO_MORE_ENTRIES; 37 } 38 DiskNumber++; 39 PartitionNumber = 0; 40 } 41 PartitionNumber++; 42 Status = RtlStringCbPrintfW(VolumeDeviceName->Buffer, 43 VolumeDeviceName->MaximumLength, 44 L"\\Device\\Harddisk%lu\\Partition%lu", 45 DiskNumber, 46 PartitionNumber); 47 *VolumeNumber = DiskNumber << 16 | PartitionNumber; 48 #endif 49 return Status; 50 } 51 52 static 53 void 54 TestIoVolumeDeviceToDosName(void) 55 { 56 NTSTATUS Status; 57 ULONG VolumeNumber; 58 WCHAR VolumeDeviceNameBuffer[32]; 59 UNICODE_STRING VolumeDeviceName; 60 PFILE_OBJECT FileObject; 61 PDEVICE_OBJECT DeviceObject; 62 UNICODE_STRING DosName; 63 UNICODE_STRING DosVolumePrefix = RTL_CONSTANT_STRING(L"\\\\?\\Volume"); 64 65 RtlInitEmptyUnicodeString(&VolumeDeviceName, 66 VolumeDeviceNameBuffer, 67 sizeof(VolumeDeviceNameBuffer)); 68 VolumeNumber = 0; 69 Status = STATUS_SUCCESS; 70 while (1) 71 { 72 Status = GetNextVolumeDevice(&VolumeDeviceName, 73 &VolumeNumber, 74 Status); 75 if (!NT_SUCCESS(Status)) 76 { 77 trace("GetNextVolumeDevice(0x%lx) failed with %lx\n", 78 VolumeNumber, Status); 79 break; 80 } 81 82 RtlInitUnicodeString(&VolumeDeviceName, VolumeDeviceNameBuffer); 83 Status = IoGetDeviceObjectPointer(&VolumeDeviceName, 84 READ_CONTROL, 85 &FileObject, 86 &DeviceObject); 87 if (!NT_SUCCESS(Status)) 88 { 89 trace("IoGetDeviceObjectPointer(%wZ) failed with %lx\n", 90 &VolumeDeviceName, Status); 91 continue; 92 } 93 94 Status = IoVolumeDeviceToDosName(DeviceObject, &DosName); 95 ok_eq_hex(Status, STATUS_SUCCESS); 96 if (!skip(NT_SUCCESS(Status), "No DOS name\n")) 97 { 98 trace("DOS name for %wZ is %wZ\n", &VolumeDeviceName, &DosName); 99 if (DosName.Length == 2 * sizeof(WCHAR)) 100 { 101 ok(DosName.Buffer[0] >= L'A' && 102 DosName.Buffer[0] <= L'Z' && 103 DosName.Buffer[1] == L':', 104 "Unexpected drive letter: %wZ\n", &DosName); 105 } 106 else 107 { 108 ok(RtlPrefixUnicodeString(&DosVolumePrefix, &DosName, FALSE), 109 "Unexpected volume path: %wZ\n", &DosName); 110 } 111 RtlFreeUnicodeString(&DosName); 112 } 113 ObDereferenceObject(FileObject); 114 Status = STATUS_SUCCESS; 115 } 116 ok(VolumeNumber > 1, "No volumes found\n"); 117 } 118 119 START_TEST(IoVolume) 120 { 121 TestIoVolumeDeviceToDosName(); 122 } 123