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 #include <mountmgr.h>
10
11 static
12 void
TestIoVolumeDeviceToDosName(void)13 TestIoVolumeDeviceToDosName(void)
14 {
15 NTSTATUS Status;
16 ULONG VolumeNumber;
17 WCHAR VolumeDeviceNameBuffer[32];
18 UNICODE_STRING VolumeDeviceName;
19 PFILE_OBJECT FileObject;
20 PDEVICE_OBJECT DeviceObject;
21 UNICODE_STRING DosName;
22 UNICODE_STRING DosVolumePrefix = RTL_CONSTANT_STRING(L"\\\\?\\Volume");
23
24 RtlInitEmptyUnicodeString(&VolumeDeviceName,
25 VolumeDeviceNameBuffer,
26 sizeof(VolumeDeviceNameBuffer));
27 // TODO: Query the partition/volume manager for the list of volumes.
28 for (VolumeNumber = 0; VolumeNumber < 32; ++VolumeNumber)
29 {
30 Status = RtlStringCbPrintfW(VolumeDeviceName.Buffer,
31 VolumeDeviceName.MaximumLength,
32 L"\\Device\\HarddiskVolume%lu",
33 VolumeNumber);
34 if (!NT_SUCCESS(Status))
35 {
36 trace("RtlStringCbPrintfW(%lu) failed with 0x%lx\n",
37 VolumeNumber, Status);
38 break;
39 }
40
41 RtlInitUnicodeString(&VolumeDeviceName, VolumeDeviceNameBuffer);
42 Status = IoGetDeviceObjectPointer(&VolumeDeviceName,
43 READ_CONTROL,
44 &FileObject,
45 &DeviceObject);
46 if (!NT_SUCCESS(Status))
47 {
48 trace("IoGetDeviceObjectPointer(%wZ) failed with 0x%lx\n",
49 &VolumeDeviceName, Status);
50 continue;
51 }
52
53 Status = IoVolumeDeviceToDosName(DeviceObject, &DosName);
54 ok_eq_hex(Status, STATUS_SUCCESS);
55 if (!skip(NT_SUCCESS(Status), "No DOS name\n"))
56 {
57 trace("DOS name for %wZ is %wZ\n", &VolumeDeviceName, &DosName);
58
59 /* The DosName should contain one NUL-terminated string (always there?),
60 * plus one final NUL-terminator */
61 ok(DosName.MaximumLength == DosName.Length + sizeof(UNICODE_NULL),
62 "Unexpected DOS name maximum length %hu, expected %hu\n",
63 DosName.MaximumLength, DosName.Length + sizeof(UNICODE_NULL));
64 ok(DosName.Length >= sizeof(UNICODE_NULL),
65 "DOS name too short (length: %lu)\n",
66 DosName.Length / sizeof(WCHAR));
67 ok(DosName.Buffer[DosName.Length / sizeof(WCHAR)] == UNICODE_NULL,
68 "Missing NUL-terminator (1)\n");
69 ok(DosName.Buffer[DosName.MaximumLength / sizeof(WCHAR) - 1] == UNICODE_NULL,
70 "Missing NUL-terminator (2)\n");
71
72 /* The DOS name is either a drive letter, or a
73 * volume GUID name (if the volume is not mounted) */
74 if (DosName.Length == 2 * sizeof(WCHAR))
75 {
76 ok(DosName.Buffer[0] >= L'A' &&
77 DosName.Buffer[0] <= L'Z' &&
78 DosName.Buffer[1] == L':',
79 "Unexpected drive letter: %wZ\n", &DosName);
80 }
81 else
82 {
83 ok(RtlPrefixUnicodeString(&DosVolumePrefix, &DosName, FALSE),
84 "Unexpected volume path: %wZ\n", &DosName);
85 ok(MOUNTMGR_IS_DOS_VOLUME_NAME(&DosName),
86 "Invalid DOS volume path returned: %wZ\n", &DosName);
87 }
88 RtlFreeUnicodeString(&DosName);
89 }
90 ObDereferenceObject(FileObject);
91 }
92 ok(VolumeNumber > 1, "No volumes found\n");
93 }
94
START_TEST(IoVolume)95 START_TEST(IoVolume)
96 {
97 TestIoVolumeDeviceToDosName();
98 }
99