1 /*
2 * PROJECT: ReactOS API Tests
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Test for IOCTL_MOUNTMGR_QUERY_POINTS
5 * COPYRIGHT: Copyright 2019 Pierre Schweitzer <pierre@reactos.org>
6 */
7
8 #include "precomp.h"
9
10 VOID
TraceMountPoint(_In_ const MOUNTMGR_MOUNT_POINTS * MountPoints,_In_ const MOUNTMGR_MOUNT_POINT * MountPoint)11 TraceMountPoint(
12 _In_ const MOUNTMGR_MOUNT_POINTS* MountPoints,
13 _In_ const MOUNTMGR_MOUNT_POINT* MountPoint)
14 {
15 trace("MountPoint: %p\n", MountPoint);
16 trace("\tSymbolicOffset: %ld\n", MountPoint->SymbolicLinkNameOffset);
17 trace("\tSymbolicLinkName: %.*S\n",
18 MountPoint->SymbolicLinkNameLength / sizeof(WCHAR),
19 (PWCHAR)((ULONG_PTR)MountPoints + MountPoint->SymbolicLinkNameOffset));
20 trace("\tDeviceOffset: %ld\n", MountPoint->DeviceNameOffset);
21 trace("\tDeviceName: %.*S\n",
22 MountPoint->DeviceNameLength / sizeof(WCHAR),
23 (PWCHAR)((ULONG_PTR)MountPoints + MountPoint->DeviceNameOffset));
24 }
25
START_TEST(QueryPoints)26 START_TEST(QueryPoints)
27 {
28 BOOL Ret;
29 HANDLE MountMgrHandle;
30 DWORD LastError, BytesReturned, Drives, i;
31 struct
32 {
33 MOUNTMGR_MOUNT_POINT;
34 WCHAR Buffer[sizeof("\\DosDevice\\A:")];
35 } SinglePoint;
36 MOUNTMGR_MOUNT_POINTS MountPoints;
37 PMOUNTMGR_MOUNT_POINTS AllocatedPoints;
38
39 MountMgrHandle = GetMountMgrHandle(FILE_READ_ATTRIBUTES);
40 if (!MountMgrHandle)
41 {
42 win_skip("MountMgr unavailable: %lu\n", GetLastError());
43 return;
44 }
45
46 ZeroMemory(&SinglePoint, sizeof(SinglePoint));
47
48 /* Retrieve the size needed to enumerate all the existing mount points */
49 Ret = DeviceIoControl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS,
50 &SinglePoint, sizeof(MOUNTMGR_MOUNT_POINT), // Size without the string.
51 &MountPoints, sizeof(MountPoints),
52 &BytesReturned, NULL);
53 LastError = GetLastError();
54 ok(Ret == FALSE, "IOCTL unexpectedly succeeded\n");
55 ok(LastError == ERROR_MORE_DATA, "Unexpected failure: %lu\n", LastError);
56
57 /* Allocate a suitably-sized buffer for the mount points */
58 AllocatedPoints = RtlAllocateHeap(RtlGetProcessHeap(), 0, MountPoints.Size);
59 if (AllocatedPoints == NULL)
60 {
61 skip("Insufficient memory\n");
62 }
63 else
64 {
65 AllocatedPoints->NumberOfMountPoints = 0;
66
67 /* Retrieve the list of all the existing mount points */
68 Ret = DeviceIoControl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS,
69 &SinglePoint, sizeof(MOUNTMGR_MOUNT_POINT), // Size without the string.
70 AllocatedPoints, MountPoints.Size,
71 &BytesReturned, NULL);
72 ok(Ret == TRUE, "IOCTL unexpectedly failed: %lu\n", GetLastError());
73
74 for (i = 0; i < AllocatedPoints->NumberOfMountPoints; ++i)
75 {
76 TraceMountPoint(AllocatedPoints, &AllocatedPoints->MountPoints[i]);
77 }
78
79 RtlFreeHeap(RtlGetProcessHeap(), 0, AllocatedPoints);
80 }
81
82 /* Now, find the first unused drive letter */
83 Drives = GetLogicalDrives();
84 if (Drives == 0)
85 {
86 skip("Drives map unavailable: %lu\n", GetLastError());
87 goto Done;
88 }
89 for (i = 0; i <= 'Z'-'A'; ++i)
90 {
91 if (!(Drives & (1 << i)))
92 break;
93 }
94 if (i > 'Z'-'A')
95 {
96 skip("All the drive letters are in use, skipping\n");
97 goto Done;
98 }
99
100 /* Check that this drive letter is not an existing mount point */
101 SinglePoint.SymbolicLinkNameOffset = ((ULONG_PTR)&SinglePoint.Buffer - (ULONG_PTR)&SinglePoint);
102 SinglePoint.SymbolicLinkNameLength = sizeof(SinglePoint.Buffer) - sizeof(UNICODE_NULL);
103 StringCbPrintfW(SinglePoint.Buffer, sizeof(SinglePoint.Buffer),
104 L"\\DosDevice\\%C:", L'A' + i);
105
106 Ret = DeviceIoControl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS,
107 &SinglePoint, sizeof(SinglePoint),
108 &MountPoints, sizeof(MountPoints),
109 &BytesReturned, NULL);
110 LastError = GetLastError();
111 ok(Ret == FALSE, "IOCTL unexpectedly succeeded\n");
112 ok(LastError == ERROR_FILE_NOT_FOUND, "Unexpected failure: %lu\n", LastError);
113
114 Done:
115 CloseHandle(MountMgrHandle);
116 }
117