ReactOS  0.4.12-dev-916-gffc4e30
DeviceIoControl.c File Reference
#include "precomp.h"
#include <winioctl.h>
#include <mountdev.h>
Include dependency graph for DeviceIoControl.c:

Go to the source code of this file.

Macros

#define ok_type(condition, format, ...)   ok(condition, "(%d): " format, DriveType, ##__VA_ARGS__)
 
#define skip_type(format, ...)   skip("(%d): " format, DriveType, ##__VA_ARGS__)
 

Functions

static BOOL GetDiskGeometry (VOID)
 
static VOID QueryDeviceName (VOID)
 
static VOID QueryUniqueId (VOID)
 
static VOID QuerySuggestedLinkName (VOID)
 
 START_TEST (DeviceIoControl)
 

Variables

WCHAR Letter
 
HANDLE Device
 
UINT DriveType
 

Macro Definition Documentation

◆ ok_type

#define ok_type (   condition,
  format,
  ... 
)    ok(condition, "(%d): " format, DriveType, ##__VA_ARGS__)

Definition at line 17 of file DeviceIoControl.c.

◆ skip_type

#define skip_type (   format,
  ... 
)    skip("(%d): " format, DriveType, ##__VA_ARGS__)

Definition at line 18 of file DeviceIoControl.c.

Function Documentation

◆ GetDiskGeometry()

static BOOL GetDiskGeometry ( VOID  )
static

Definition at line 22 of file DeviceIoControl.c.

23 {
24  UINT Ret;
26  DWORD Size, Error;
27  DISK_GEOMETRY_EX DGE;
28 
29  Size = 0;
30  Ret = DeviceIoControl(Device, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &DG, sizeof(DG) - 1, &Size, NULL);
31  ok_type(Ret == 0, "DeviceIoControl succeed\n");
32  Error = GetLastError();
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");
50  Error = GetLastError();
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());
62  if (DriveType == DRIVE_FIXED)
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 }
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
Definition: ntddk_ex.h:208
#define TRUE
Definition: types.h:120
#define ok_type(condition, format,...)
#define skip_type(format,...)
UINT DriveType
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
HANDLE Device
smooth NULL
Definition: ftsmooth.c:416
#define ERROR_NOT_READY
Definition: winerror.h:124
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL Error
Definition: chkdsk.c:66
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
TW_UINT32 DG
Definition: twain.h:1827
#define DRIVE_FIXED
Definition: winbase.h:249
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 FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int UINT
Definition: ndis.h:50
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10

Referenced by START_TEST().

◆ QueryDeviceName()

static VOID QueryDeviceName ( VOID  )
static

Definition at line 76 of file DeviceIoControl.c.

77 {
78  UINT Ret;
79  BOOL IsValid;
80  DWORD Size, Error;
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");
86  Error = GetLastError();
87  if (DriveType == DRIVE_FIXED)
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");
99  Error = GetLastError();
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 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define TRUE
Definition: types.h:120
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#define ok_type(condition, format,...)
#define skip_type(format,...)
UINT DriveType
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
HANDLE Device
#define UNICODE_NULL
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR Name[1]
Definition: imports.h:144
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL Error
Definition: chkdsk.c:66
static const WCHAR L[]
Definition: oid.c:1250
WCHAR Letter
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define DRIVE_FIXED
Definition: winbase.h:249
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 FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define DRIVE_CDROM
Definition: winbase.h:251
unsigned int UINT
Definition: ndis.h:50
USHORT NameLength
Definition: imports.h:143
#define HeapFree(x, y, z)
Definition: compat.h:394
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10

Referenced by START_TEST().

◆ QuerySuggestedLinkName()

static VOID QuerySuggestedLinkName ( VOID  )
static

Definition at line 187 of file DeviceIoControl.c.

188 {
189  UINT Ret;
190  DWORD Size, Error;
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");
196  Error = GetLastError();
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 
207  Ret = DeviceIoControl(Device, IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME, NULL, 0, &MSLN, sizeof(MSLN), &Size, NULL);
208  ok_type(Ret == 0, "DeviceIoControl succeed\n");
209  Error = GetLastError();
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 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define ok_type(condition, format,...)
UINT DriveType
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
HANDLE Device
smooth NULL
Definition: ftsmooth.c:416
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL Error
Definition: chkdsk.c:66
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define DRIVE_FIXED
Definition: winbase.h:249
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 IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
Definition: imports.h:99
unsigned int UINT
Definition: ndis.h:50
#define ERROR_NOT_FOUND
Definition: winerror.h:690
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10

Referenced by START_TEST().

◆ QueryUniqueId()

static VOID QueryUniqueId ( VOID  )
static

Definition at line 143 of file DeviceIoControl.c.

144 {
145  UINT Ret;
146  DWORD Size, Error;
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");
152  Error = GetLastError();
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");
165  Error = GetLastError();
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 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define ok_type(condition, format,...)
USHORT UniqueIdLength
Definition: imports.h:138
#define skip_type(format,...)
UINT DriveType
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
HANDLE Device
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL Error
Definition: chkdsk.c:66
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define DRIVE_FIXED
Definition: winbase.h:249
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 FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int UINT
Definition: ndis.h:50
#define HeapFree(x, y, z)
Definition: compat.h:394
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10

Referenced by START_TEST().

◆ START_TEST()

START_TEST ( DeviceIoControl  )

Definition at line 221 of file DeviceIoControl.c.

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  {
257  QueryDeviceName();
258  QueryUniqueId();
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 CloseHandle
Definition: compat.h:398
static VOID QuerySuggestedLinkName(VOID)
#define skip_type(format,...)
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
UINT DriveType
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_SHARE_READ
Definition: compat.h:125
HANDLE Device
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
#define OPEN_EXISTING
Definition: compat.h:426
#define ok(value,...)
Definition: CComObject.cpp:34
__wchar_t WCHAR
Definition: xmlstorage.h:180
static VOID QueryDeviceName(VOID)
#define MAX_PATH
Definition: compat.h:26
unsigned long DWORD
Definition: ntddk_ex.h:95
static VOID QueryUniqueId(VOID)
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static const WCHAR L[]
Definition: oid.c:1250
UINT WINAPI GetDriveTypeW(IN LPCWSTR lpRootPathName)
Definition: disk.c:497
#define DRIVE_FIXED
Definition: winbase.h:249
DWORD WINAPI GetLogicalDrives(VOID)
Definition: disk.c:110
#define S_OK
Definition: intsafe.h:59
PRTL_UNICODE_STRING_BUFFER Path
static BOOL GetDiskGeometry(VOID)
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
#define skip(...)
Definition: CString.cpp:57
#define DRIVE_CDROM
Definition: winbase.h:251
unsigned int UINT
Definition: ndis.h:50
#define CreateFileW
Definition: compat.h:400

Variable Documentation

◆ Device

◆ DriveType

◆ Letter