ReactOS 0.4.15-dev-7961-gdcf9eb0
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
20static
21BOOL
23{
24 UINT Ret;
28
29 Size = 0;
31 ok_type(Ret == 0, "DeviceIoControl succeed\n");
33 ok_type(Error == ERROR_INSUFFICIENT_BUFFER, "Expecting ERROR_INSUFFICIENT_BUFFER, got %ld\n", Error);
34 ok_type(Size == 0, "Invalid output size: %ld\n", Size);
35
36 Size = 0;
38 /* Specific for CDROM, no disk present */
39 if (Ret == 0 && GetLastError() == ERROR_NOT_READY)
40 {
41 skip_type("No CDROM present\n");
42 return FALSE;
43 }
44 ok_type(Ret != 0, "DeviceIoControl failed: %ld\n", GetLastError());
45 ok_type(Size == sizeof(DG), "Invalid output size: %ld\n", Size);
46
47 Size = 0;
49 ok_type(Ret == 0, "DeviceIoControl succeed\n");
51 ok_type(Error == ERROR_INSUFFICIENT_BUFFER, "Expecting ERROR_INSUFFICIENT_BUFFER, got %ld\n", Error);
52 ok_type(Size == 0, "Invalid output size: %ld\n", Size);
53
54 Size = 0;
56 ok_type(Ret != 0, "DeviceIoControl failed: %ld\n", GetLastError());
57 ok_type(Size == FIELD_OFFSET(DISK_GEOMETRY_EX, Data), "Invalid output size: %ld\n", Size);
58
59 Size = 0;
60 Ret = DeviceIoControl(Device, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &DGE, sizeof(DGE), &Size, NULL);
61 ok_type(Ret != 0, "DeviceIoControl failed: %ld\n", GetLastError());
63 {
64 ok_type(Size == sizeof(DGE), "Invalid output size: %ld\n", Size);
65 }
66 else
67 {
68 ok_type(Size == FIELD_OFFSET(DISK_GEOMETRY_EX, Data), "Invalid output size: %ld\n", Size);
69 }
70
71 return TRUE;
72}
73
74static
75VOID
77{
78 UINT Ret;
79 BOOL IsValid;
81 MOUNTDEV_NAME MDN, *AllocatedMDN;
82
83 Size = 0;
84 Ret = DeviceIoControl(Device, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, &MDN, sizeof(MDN) - 1, &Size, NULL);
85 ok_type(Ret == 0, "DeviceIoControl succeed\n");
88 {
89 ok_type(Error == ERROR_INVALID_PARAMETER, "Expecting ERROR_INVALID_PARAMETER, got %ld\n", Error);
90 }
91 else
92 {
93 ok_type(Error == ERROR_INSUFFICIENT_BUFFER, "Expecting ERROR_INSUFFICIENT_BUFFER, got %ld\n", Error);
94 }
95 ok_type(Size == 0, "Invalid output size: %ld\n", Size);
96
97 Ret = DeviceIoControl(Device, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, &MDN, sizeof(MDN), &Size, NULL);
98 ok_type(Ret == 0, "DeviceIoControl succeed\n");
100 ok_type(Error == ERROR_MORE_DATA, "Expecting ERROR_MORE_DATA, got %ld\n", Error);
101 ok_type(Size == sizeof(MOUNTDEV_NAME), "Invalid output size: %ld\n", Size);
102
103 AllocatedMDN = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MOUNTDEV_NAME, Name) + MDN.NameLength + sizeof(UNICODE_NULL));
104 if (AllocatedMDN == NULL)
105 {
106 skip_type("Memory allocation failure\n");
107 return;
108 }
109
110 Size = 0;
112 ok_type(Ret != 0, "DeviceIoControl failed: %ld\n", GetLastError());
113 ok_type(Size == FIELD_OFFSET(MOUNTDEV_NAME, Name) + MDN.NameLength, "Invalid output size: %ld\n", Size);
114 ok_type(AllocatedMDN->NameLength == MDN.NameLength, "Mismatching sizes: %d %d\n", AllocatedMDN->NameLength, MDN.NameLength);
115
116 if (Ret != 0)
117 {
118 IsValid = FALSE;
119 AllocatedMDN->Name[AllocatedMDN->NameLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
120
121 if ((DriveType == DRIVE_FIXED && wcsstr(AllocatedMDN->Name, L"\\Device\\HarddiskVolume") != NULL) ||
122 (DriveType == DRIVE_CDROM && wcsstr(AllocatedMDN->Name, L"\\Device\\CdRom") != NULL))
123 {
124 IsValid = TRUE;
125 }
126 else if (wcsstr(AllocatedMDN->Name, L"\\DosDevices\\") != NULL)
127 {
128 IsValid = (AllocatedMDN->Name[12] == Letter && AllocatedMDN->Name[13] == L':');
129 }
130
131 ok_type(IsValid, "Invalid name: %.*S\n", AllocatedMDN->NameLength, AllocatedMDN->Name);
132 }
133 else
134 {
135 skip_type("Failed to query device name\n");
136 }
137
138 HeapFree(GetProcessHeap(), 0, AllocatedMDN);
139}
140
141static
142VOID
144{
145 UINT Ret;
147 MOUNTDEV_UNIQUE_ID MUI, *AllocatedMUI;
148
149 Size = 0;
150 Ret = DeviceIoControl(Device, IOCTL_MOUNTDEV_QUERY_UNIQUE_ID, NULL, 0, &MUI, sizeof(MUI) - 1, &Size, NULL);
151 ok_type(Ret == 0, "DeviceIoControl succeed\n");
153 if (DriveType == DRIVE_FIXED)
154 {
155 ok_type(Error == ERROR_INVALID_PARAMETER, "Expecting ERROR_INVALID_PARAMETER, got %ld\n", Error);
156 }
157 else
158 {
159 ok_type(Error == ERROR_INSUFFICIENT_BUFFER, "Expecting ERROR_INSUFFICIENT_BUFFER, got %ld\n", Error);
160 }
161 ok_type(Size == 0, "Invalid output size: %ld\n", Size);
162
163 Ret = DeviceIoControl(Device, IOCTL_MOUNTDEV_QUERY_UNIQUE_ID, NULL, 0, &MUI, sizeof(MUI), &Size, NULL);
164 ok_type(Ret == 0, "DeviceIoControl succeed\n");
166 ok_type(Error == ERROR_MORE_DATA, "Expecting ERROR_MORE_DATA, got %ld\n", Error);
167 ok_type(Size == sizeof(MOUNTDEV_UNIQUE_ID), "Invalid output size: %ld\n", Size);
168
169 AllocatedMUI = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + MUI.UniqueIdLength + sizeof(UNICODE_NULL));
170 if (AllocatedMUI == NULL)
171 {
172 skip_type("Memory allocation failure\n");
173 return;
174 }
175
176 Size = 0;
178 ok_type(Ret != 0, "DeviceIoControl failed: %ld\n", GetLastError());
179 ok_type(Size == FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + MUI.UniqueIdLength, "Invalid output size: %ld\n", Size);
180 ok_type(AllocatedMUI->UniqueIdLength == MUI.UniqueIdLength, "Mismatching sizes: %d %d\n", AllocatedMUI->UniqueIdLength, MUI.UniqueIdLength);
181
182 HeapFree(GetProcessHeap(), 0, AllocatedMUI);
183}
184
185static
186VOID
188{
189 UINT Ret;
192
193 Size = 0;
194 Ret = DeviceIoControl(Device, IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME, NULL, 0, &MSLN, sizeof(MSLN) - 1, &Size, NULL);
195 ok_type(Ret == 0, "DeviceIoControl succeed\n");
197 if (DriveType == DRIVE_FIXED)
198 {
199 ok_type(Error == ERROR_INVALID_PARAMETER, "Expecting ERROR_INVALID_PARAMETER, got %ld\n", Error);
200 }
201 else
202 {
203 ok_type(Error == ERROR_INSUFFICIENT_BUFFER, "Expecting ERROR_INSUFFICIENT_BUFFER, got %ld\n", Error);
204 }
205 ok_type(Size == 0, "Invalid output size: %ld\n", Size);
206
208 ok_type(Ret == 0, "DeviceIoControl succeed\n");
210 if (DriveType == DRIVE_FIXED)
211 {
212 ok_type(Error == ERROR_NOT_FOUND, "Expecting ERROR_NOT_FOUND, got %ld\n", Error);
213 }
214 else
215 {
216 ok_type(Error == ERROR_FILE_NOT_FOUND, "Expecting ERROR_FILE_NOT_FOUND, got %ld\n", Error);
217 }
218 ok_type(Size == 0, "Invalid output size: %ld\n", Size);
219}
220
222{
223 UINT Ret;
225 DWORD DriveMap, Current;
226 BOOL DiskDone, CdRomDone;
227
228 DiskDone = FALSE;
229 CdRomDone = FALSE;
230 DriveMap = GetLogicalDrives();
231 for (Current = 0; Current < 26; ++Current)
232 {
233 if (DriveMap & (1 << Current))
234 {
235 Ret = StringCchPrintfW(Path, MAX_PATH, L"%c:\\", Current + L'A');
236 ok(Ret == S_OK, "StringCchPrintfW failed: %d\n", Ret);
237
239 if ((DriveType == DRIVE_FIXED && !DiskDone) ||
240 (DriveType == DRIVE_CDROM && !CdRomDone))
241 {
242 Ret = StringCchPrintfW(Path, MAX_PATH, L"\\\\?\\%c:", Current + L'A');
243 ok(Ret == S_OK, "StringCchPrintfW failed: %d\n", Ret);
244
247 {
248 skip_type("CreateFileW for %S failed: %ld\n", Path, GetLastError());
249 continue;
250 }
251
252 DiskDone = (DiskDone || (DriveType == DRIVE_FIXED));
253 CdRomDone = (CdRomDone || (DriveType == DRIVE_CDROM));
254
255 if (GetDiskGeometry())
256 {
260 }
261
263 }
264
265 if (CdRomDone && DiskDone)
266 {
267 break;
268 }
269 }
270 }
271
272 if (!DiskDone)
273 {
274 skip("No disk drive found\n");
275 }
276
277 if (!CdRomDone)
278 {
279 skip("No CDROM drive found\n");
280 }
281}
#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)
UINT DriveType
HANDLE Device
PRTL_UNICODE_STRING_BUFFER Path
#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
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
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 INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#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
#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
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#define S_OK
Definition: intsafe.h:52
#define DRIVE_CDROM
Definition: machpc98.h:119
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
#define IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
Definition: imports.h:99
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
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
#define L(x)
Definition: ntvdm.h:50
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
USHORT NameLength
Definition: imports.h:143
WCHAR Name[1]
Definition: imports.h:144
USHORT UniqueIdLength
Definition: imports.h:138
TW_UINT32 DG
Definition: twain.h:1827
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_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:4533
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetLogicalDrives(void)
Definition: disk.c:110
#define DRIVE_FIXED
Definition: winbase.h:252
#define ERROR_NOT_READY
Definition: winerror.h:124
#define ERROR_NOT_FOUND
Definition: winerror.h:690
__wchar_t WCHAR
Definition: xmlstorage.h:180