Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / modules / rostests / apitests / kernel32 / DeviceIoControl.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for DeviceIoControl
5 * PROGRAMMER: Pierre Schweitzer <pierre@reactos.org>
6 */
7
8 #include <apitest.h>
9 #include <strsafe.h>
10 #include <winioctl.h>
11 #include <mountmgr.h>
12
13 WCHAR Letter;
14 HANDLE Device;
15
16 static
17 VOID
18 GetDiskGeometry(VOID)
19 {
20 UINT Ret;
21 DISK_GEOMETRY DG;
22 DWORD Size, Error;
23 DISK_GEOMETRY_EX DGE;
24
25 Size = 0;
26 Ret = DeviceIoControl(Device, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &DG, sizeof(DG) - 1, &Size, NULL);
27 ok(Ret == 0, "DeviceIoControl succeed\n");
28 Error = GetLastError();
29 ok(Error == ERROR_INSUFFICIENT_BUFFER, "Expecting ERROR_INSUFFICIENT_BUFFER, got %ld\n", Error);
30 ok(Size == 0, "Invalid output size: %ld\n", Size);
31
32 Size = 0;
33 Ret = DeviceIoControl(Device, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &DG, sizeof(DG), &Size, NULL);
34 ok(Ret != 0, "DeviceIoControl failed: %ld\n", GetLastError());
35 ok(Size == sizeof(DG), "Invalid output size: %ld\n", Size);
36
37 Size = 0;
38 Ret = DeviceIoControl(Device, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &DGE, FIELD_OFFSET(DISK_GEOMETRY_EX, Data) - 1, &Size, NULL);
39 ok(Ret == 0, "DeviceIoControl succeed\n");
40 Error = GetLastError();
41 ok(Error == ERROR_INSUFFICIENT_BUFFER, "Expecting ERROR_INSUFFICIENT_BUFFER, got %ld\n", Error);
42 ok(Size == 0, "Invalid output size: %ld\n", Size);
43
44 Size = 0;
45 Ret = DeviceIoControl(Device, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &DGE, FIELD_OFFSET(DISK_GEOMETRY_EX, Data), &Size, NULL);
46 ok(Ret != 0, "DeviceIoControl failed: %ld\n", GetLastError());
47 ok(Size == FIELD_OFFSET(DISK_GEOMETRY_EX, Data), "Invalid output size: %ld\n", Size);
48
49 Size = 0;
50 Ret = DeviceIoControl(Device, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &DGE, sizeof(DGE), &Size, NULL);
51 ok(Ret != 0, "DeviceIoControl failed: %ld\n", GetLastError());
52 ok(Size == sizeof(DGE), "Invalid output size: %ld\n", Size);
53 }
54
55 static
56 VOID
57 QueryDeviceName(VOID)
58 {
59 UINT Ret;
60 BOOL IsValid;
61 DWORD Size, Error;
62 MOUNTDEV_NAME MDN, *AllocatedMDN;
63
64 Ret = DeviceIoControl(Device, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, &MDN, sizeof(MDN) - 1, &Size, NULL);
65 ok(Ret == 0, "DeviceIoControl succeed\n");
66 Error = GetLastError();
67 ok(Error == ERROR_INVALID_PARAMETER, "Expecting ERROR_INVALID_PARAMETER, got %ld\n", Error);
68 ok(Size == 40 /* ?! */, "Invalid output size: %ld\n", Size);
69
70 Ret = DeviceIoControl(Device, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, &MDN, sizeof(MDN), &Size, NULL);
71 ok(Ret == 0, "DeviceIoControl succeed\n");
72 Error = GetLastError();
73 ok(Error == ERROR_MORE_DATA, "Expecting ERROR_MORE_DATA, got %ld\n", Error);
74 ok(Size == sizeof(MOUNTDEV_NAME), "Invalid output size: %ld\n", Size);
75
76 AllocatedMDN = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MOUNTDEV_NAME, Name) + MDN.NameLength + sizeof(UNICODE_NULL));
77 if (AllocatedMDN == NULL)
78 {
79 skip("Memory allocation failure\n");
80 return;
81 }
82
83 Size = 0;
84 Ret = DeviceIoControl(Device, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, AllocatedMDN, FIELD_OFFSET(MOUNTDEV_NAME, Name) + MDN.NameLength, &Size, NULL);
85 ok(Ret != 0, "DeviceIoControl failed: %ld\n", GetLastError());
86 ok(Size == FIELD_OFFSET(MOUNTDEV_NAME, Name) + MDN.NameLength, "Invalid output size: %ld\n", Size);
87 ok(AllocatedMDN->NameLength == MDN.NameLength, "Mismatching sizes: %d %d\n", AllocatedMDN->NameLength, MDN.NameLength);
88
89 if (Ret != 0)
90 {
91 IsValid = FALSE;
92 AllocatedMDN->Name[AllocatedMDN->NameLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
93
94 if (wcsstr(AllocatedMDN->Name, L"\\Device\\HarddiskVolume") != NULL)
95 {
96 IsValid = TRUE;
97 }
98 else if (wcsstr(AllocatedMDN->Name, L"\\DosDevices\\") != NULL)
99 {
100 IsValid = (AllocatedMDN->Name[12] == Letter && AllocatedMDN->Name[13] == L':');
101 }
102
103 ok(IsValid, "Invalid name: %.*S", AllocatedMDN->NameLength, AllocatedMDN->Name);
104 }
105 else
106 {
107 skip("Failed to query device name\n");
108 }
109
110 HeapFree(GetProcessHeap(), 0, AllocatedMDN);
111 }
112
113 START_TEST(DeviceIoControl)
114 {
115 UINT Ret;
116 WCHAR Path[MAX_PATH];
117
118 Path[0] = 'C';
119 Path[1] = ':';
120 Path[2] = '\\';
121 Ret = GetSystemDirectoryW(Path, MAX_PATH);
122 ok(Ret > 0, "GetSystemDirectory failed\n");
123
124 Letter = towupper(Path[0]);
125 ok(Path[1] == ':', "Not a drive letter: %c\n", Path[1]);
126 ok(Path[2] == '\\', "Not a drive letter: %c\n", Path[2]);
127
128 Ret = StringCchPrintfW(Path, MAX_PATH, L"\\\\?\\%c:", Letter);
129 ok(Ret == S_OK, "StringCchPrintfW failed: %d\n", Ret);
130
131 Device = CreateFileW(Path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
132 if (Device == INVALID_HANDLE_VALUE)
133 {
134 skip("CreateFileW for %S failed: %ld\n", Path, GetLastError());
135 return;
136 }
137
138 GetDiskGeometry();
139 QueryDeviceName();
140
141 CloseHandle(Device);
142 }