ReactOS 0.4.17-dev-218-g5635d24
DeviceIoControl.c
Go to the documentation of this file.
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 "precomp.h"
9
10#include <winioctl.h>
11#include <mountdev.h>
12
16
17#define ok_type(condition, format, ...) ok(condition, "(%d): " format, DriveType, ##__VA_ARGS__)
18#define skip_type(format, ...) skip("(%d): " format, DriveType, ##__VA_ARGS__)
19
20#define IOCTL_KSEC_RANDOM_FILL_BUFFER \
21 CTL_CODE(FILE_DEVICE_KSEC, 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS)
22
24{
25 static const PWSTR KsecDevicePath = L"\\\\.\\Global\\GLOBALROOT\\Device\\KsecDD";
26 UCHAR Buffer[16];
27 HANDLE hDevice;
28 BOOL ret;
29
30 /* Open ksecdd device */
31 hDevice = CreateFileW(KsecDevicePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
32 if (hDevice == INVALID_HANDLE_VALUE)
33 {
34 skip("CreateFile failed: %lu\n", GetLastError());
35 return;
36 }
37
38 /* Test NULL lpBytesReturned (used by wine's wbemprox) */
39 SetLastError(0xDEADBEEF);
40 StartSeh()
41 ret = DeviceIoControl(hDevice,
43 NULL,
44 0,
45 Buffer,
46 sizeof(Buffer),
47 NULL, /* lpBytesReturned */
48 NULL);
50 ok_eq_ulong(GetLastError(), 0xDEADBEEF);
52
53 CloseHandle(hDevice);
54}
55
56static
57BOOL
59{
60 UINT Ret;
64
65 Size = 0;
67 ok_type(Ret == 0, "DeviceIoControl succeed\n");
69 ok_type(Error == ERROR_INSUFFICIENT_BUFFER, "Expecting ERROR_INSUFFICIENT_BUFFER, got %ld\n", Error);
70 ok_type(Size == 0, "Invalid output size: %ld\n", Size);
71
72 Size = 0;
74 /* Specific for CDROM, no disk present */
75 if (Ret == 0 && GetLastError() == ERROR_NOT_READY)
76 {
77 skip_type("No CDROM present\n");
78 return FALSE;
79 }
80 ok_type(Ret != 0, "DeviceIoControl failed: %ld\n", GetLastError());
81 ok_type(Size == sizeof(DG), "Invalid output size: %ld\n", Size);
82
83 Size = 0;
85 ok_type(Ret == 0, "DeviceIoControl succeed\n");
87 ok_type(Error == ERROR_INSUFFICIENT_BUFFER, "Expecting ERROR_INSUFFICIENT_BUFFER, got %ld\n", Error);
88 ok_type(Size == 0, "Invalid output size: %ld\n", Size);
89
90 Size = 0;
92 ok_type(Ret != 0, "DeviceIoControl failed: %ld\n", GetLastError());
93 ok_type(Size == FIELD_OFFSET(DISK_GEOMETRY_EX, Data), "Invalid output size: %ld\n", Size);
94
95 Size = 0;
96 Ret = DeviceIoControl(Device, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &DGE, sizeof(DGE), &Size, NULL);
97 ok_type(Ret != 0, "DeviceIoControl failed: %ld\n", GetLastError());
99 {
100 ok_type(Size == sizeof(DGE), "Invalid output size: %ld\n", Size);
101 }
102 else
103 {
104 ok_type(Size == FIELD_OFFSET(DISK_GEOMETRY_EX, Data), "Invalid output size: %ld\n", Size);
105 }
106
107 return TRUE;
108}
109
110static
111VOID
113{
114 UINT Ret;
115 BOOL IsValid;
117 MOUNTDEV_NAME MDN, *AllocatedMDN;
118
119 Size = 0;
120 Ret = DeviceIoControl(Device, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, &MDN, sizeof(MDN) - 1, &Size, NULL);
121 ok_type(Ret == 0, "DeviceIoControl succeed\n");
123 if (DriveType == DRIVE_FIXED)
124 {
125 ok_type(Error == ERROR_INVALID_PARAMETER, "Expecting ERROR_INVALID_PARAMETER, got %ld\n", Error);
126 }
127 else
128 {
129 ok_type(Error == ERROR_INSUFFICIENT_BUFFER, "Expecting ERROR_INSUFFICIENT_BUFFER, got %ld\n", Error);
130 }
131 ok_type(Size == 0, "Invalid output size: %ld\n", Size);
132
133 Ret = DeviceIoControl(Device, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, &MDN, sizeof(MDN), &Size, NULL);
134 ok_type(Ret == 0, "DeviceIoControl succeed\n");
136 ok_type(Error == ERROR_MORE_DATA, "Expecting ERROR_MORE_DATA, got %ld\n", Error);
137 ok_type(Size == sizeof(MOUNTDEV_NAME), "Invalid output size: %ld\n", Size);
138
139 AllocatedMDN = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MOUNTDEV_NAME, Name) + MDN.NameLength + sizeof(UNICODE_NULL));
140 if (AllocatedMDN == NULL)
141 {
142 skip_type("Memory allocation failure\n");
143 return;
144 }
145
146 Size = 0;
148 ok_type(Ret != 0, "DeviceIoControl failed: %ld\n", GetLastError());
149 ok_type(Size == FIELD_OFFSET(MOUNTDEV_NAME, Name) + MDN.NameLength, "Invalid output size: %ld\n", Size);
150 ok_type(AllocatedMDN->NameLength == MDN.NameLength, "Mismatching sizes: %d %d\n", AllocatedMDN->NameLength, MDN.NameLength);
151
152 if (Ret != 0)
153 {
154 IsValid = FALSE;
155 AllocatedMDN->Name[AllocatedMDN->NameLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
156
157 if ((DriveType == DRIVE_FIXED && wcsstr(AllocatedMDN->Name, L"\\Device\\HarddiskVolume") != NULL) ||
158 (DriveType == DRIVE_CDROM && wcsstr(AllocatedMDN->Name, L"\\Device\\CdRom") != NULL))
159 {
160 IsValid = TRUE;
161 }
162 else if (wcsstr(AllocatedMDN->Name, L"\\DosDevices\\") != NULL)
163 {
164 IsValid = (AllocatedMDN->Name[12] == Letter && AllocatedMDN->Name[13] == L':');
165 }
166
167 ok_type(IsValid, "Invalid name: %.*S\n", AllocatedMDN->NameLength, AllocatedMDN->Name);
168 }
169 else
170 {
171 skip_type("Failed to query device name\n");
172 }
173
174 HeapFree(GetProcessHeap(), 0, AllocatedMDN);
175}
176
177static
178VOID
180{
181 UINT Ret;
183 MOUNTDEV_UNIQUE_ID MUI, *AllocatedMUI;
184
185 Size = 0;
186 Ret = DeviceIoControl(Device, IOCTL_MOUNTDEV_QUERY_UNIQUE_ID, NULL, 0, &MUI, sizeof(MUI) - 1, &Size, NULL);
187 ok_type(Ret == 0, "DeviceIoControl succeed\n");
189 if (DriveType == DRIVE_FIXED)
190 {
191 ok_type(Error == ERROR_INVALID_PARAMETER, "Expecting ERROR_INVALID_PARAMETER, got %ld\n", Error);
192 }
193 else
194 {
195 ok_type(Error == ERROR_INSUFFICIENT_BUFFER, "Expecting ERROR_INSUFFICIENT_BUFFER, got %ld\n", Error);
196 }
197 ok_type(Size == 0, "Invalid output size: %ld\n", Size);
198
199 Ret = DeviceIoControl(Device, IOCTL_MOUNTDEV_QUERY_UNIQUE_ID, NULL, 0, &MUI, sizeof(MUI), &Size, NULL);
200 ok_type(Ret == 0, "DeviceIoControl succeed\n");
202 ok_type(Error == ERROR_MORE_DATA, "Expecting ERROR_MORE_DATA, got %ld\n", Error);
203 ok_type(Size == sizeof(MOUNTDEV_UNIQUE_ID), "Invalid output size: %ld\n", Size);
204
205 AllocatedMUI = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + MUI.UniqueIdLength + sizeof(UNICODE_NULL));
206 if (AllocatedMUI == NULL)
207 {
208 skip_type("Memory allocation failure\n");
209 return;
210 }
211
212 Size = 0;
214 ok_type(Ret != 0, "DeviceIoControl failed: %ld\n", GetLastError());
215 ok_type(Size == FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + MUI.UniqueIdLength, "Invalid output size: %ld\n", Size);
216 ok_type(AllocatedMUI->UniqueIdLength == MUI.UniqueIdLength, "Mismatching sizes: %d %d\n", AllocatedMUI->UniqueIdLength, MUI.UniqueIdLength);
217
218 HeapFree(GetProcessHeap(), 0, AllocatedMUI);
219}
220
221static
222VOID
224{
225 UINT Ret;
228
229 Size = 0;
230 Ret = DeviceIoControl(Device, IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME, NULL, 0, &MSLN, sizeof(MSLN) - 1, &Size, NULL);
231 ok_type(Ret == 0, "DeviceIoControl succeed\n");
233 if (DriveType == DRIVE_FIXED)
234 {
235 ok_type(Error == ERROR_INVALID_PARAMETER, "Expecting ERROR_INVALID_PARAMETER, got %ld\n", Error);
236 }
237 else
238 {
239 ok_type(Error == ERROR_INSUFFICIENT_BUFFER, "Expecting ERROR_INSUFFICIENT_BUFFER, got %ld\n", Error);
240 }
241 ok_type(Size == 0, "Invalid output size: %ld\n", Size);
242
244 ok_type(Ret == 0, "DeviceIoControl succeed\n");
246 if (DriveType == DRIVE_FIXED)
247 {
248 ok_type(Error == ERROR_NOT_FOUND, "Expecting ERROR_NOT_FOUND, got %ld\n", Error);
249 }
250 else
251 {
252 ok_type(Error == ERROR_FILE_NOT_FOUND, "Expecting ERROR_FILE_NOT_FOUND, got %ld\n", Error);
253 }
254 ok_type(Size == 0, "Invalid output size: %ld\n", Size);
255}
256
258{
259 UINT Ret;
261 DWORD DriveMap, Current;
262 BOOL DiskDone, CdRomDone;
263
265
266 DiskDone = FALSE;
267 CdRomDone = FALSE;
268 DriveMap = GetLogicalDrives();
269 for (Current = 0; Current < 26; ++Current)
270 {
271 if (DriveMap & (1 << Current))
272 {
273 Ret = StringCchPrintfW(Path, MAX_PATH, L"%c:\\", Current + L'A');
274 ok(Ret == S_OK, "StringCchPrintfW failed: %d\n", Ret);
275
277 if ((DriveType == DRIVE_FIXED && !DiskDone) ||
278 (DriveType == DRIVE_CDROM && !CdRomDone))
279 {
280 Ret = StringCchPrintfW(Path, MAX_PATH, L"\\\\?\\%c:", Current + L'A');
281 ok(Ret == S_OK, "StringCchPrintfW failed: %d\n", Ret);
282
285 {
286 skip_type("CreateFileW for %S failed: %ld\n", Path, GetLastError());
287 continue;
288 }
289
290 DiskDone = (DiskDone || (DriveType == DRIVE_FIXED));
291 CdRomDone = (CdRomDone || (DriveType == DRIVE_CDROM));
292
293 if (GetDiskGeometry())
294 {
298 }
299
301 }
302
303 if (CdRomDone && DiskDone)
304 {
305 break;
306 }
307 }
308 }
309
310 if (!DiskDone)
311 {
312 skip("No disk drive found\n");
313 }
314
315 if (!CdRomDone)
316 {
317 skip("No CDROM drive found\n");
318 }
319}
#define ok_type(condition, format,...)
WCHAR Letter
static VOID QueryUniqueId(VOID)
static BOOL GetDiskGeometry(VOID)
static VOID QuerySuggestedLinkName(VOID)
#define skip_type(format,...)
static VOID QueryDeviceName(VOID)
#define IOCTL_KSEC_RANDOM_FILL_BUFFER
UINT DriveType
static void Test_DeviceIoControl_Parameters(void)
HANDLE Device
PRTL_UNICODE_STRING_BUFFER Path
#define ok_eq_ulong(value, expected)
Definition: apitest.h:120
#define GetNTVersion()
Definition: apitest.h:17
#define StartSeh()
Definition: apitest.h:93
#define ok_eq_bool(value, expected)
Definition: apitest.h:137
#define EndSeh(ExpectedStatus)
Definition: apitest.h:99
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
BOOL Error
Definition: chkdsk.c:66
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
Definition: bufpool.h:45
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
LPWSTR Name
Definition: desk.c:124
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
UINT WINAPI GetDriveTypeW(IN LPCWSTR lpRootPathName)
Definition: disk.c:497
DWORD WINAPI DECLSPEC_HOTPATCH GetLogicalDrives(void)
Definition: volume.c:513
_ACRTIMP wchar_t *__cdecl wcsstr(const wchar_t *, const wchar_t *)
Definition: wcs.c:2993
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
Definition: ntddk_ex.h:208
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define S_OK
Definition: intsafe.h:52
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:91
#define IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
Definition: imports.h:97
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:78
unsigned int UINT
Definition: ndis.h:50
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define UNICODE_NULL
short WCHAR
Definition: pedump.c:58
#define _WIN32_WINNT_WIN8
Definition: sdkddkver.h:29
#define STATUS_SUCCESS
Definition: shellext.h:65
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
USHORT NameLength
Definition: imports.h:141
WCHAR Name[1]
Definition: imports.h:142
USHORT UniqueIdLength
Definition: imports.h:136
TW_UINT32 DG
Definition: twain.h:1827
uint16_t * PWSTR
Definition: typedefs.h:56
unsigned char UCHAR
Definition: typedefs.h:53
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define DRIVE_CDROM
Definition: winbase.h:278
#define DRIVE_FIXED
Definition: winbase.h:276
#define ERROR_NOT_READY
Definition: winerror.h:246
#define ERROR_NOT_FOUND
Definition: winerror.h:1014