Fix for DeviceIoControl masking FILE_DEVICE_FILE_SYSTEM incorrectly.
[reactos.git] / reactos / lib / kernel32 / file / deviceio.c
1 /* $Id: deviceio.c,v 1.10 2002/10/03 19:09:04 robd Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/file/deviceio.c
6 * PURPOSE: Device I/O and Overlapped Result functions
7 * PROGRAMMER: Ariadne (ariadne@xs4all.nl)
8 * UPDATE HISTORY:
9 * Created 01/11/98
10 */
11
12 #include <ddk/ntddk.h>
13 #include <windows.h>
14
15 #define NDEBUG
16 //#define DBG
17 #include <kernel32/kernel32.h>
18 #include <kernel32/error.h>
19
20
21 WINBOOL
22 STDCALL
23 DeviceIoControl(
24 HANDLE hDevice,
25 DWORD dwIoControlCode,
26 LPVOID lpInBuffer,
27 DWORD nInBufferSize,
28 LPVOID lpOutBuffer,
29 DWORD nOutBufferSize,
30 LPDWORD lpBytesReturned,
31 LPOVERLAPPED lpOverlapped
32 )
33 {
34 NTSTATUS errCode = 0;
35 HANDLE hEvent = NULL;
36 PIO_STATUS_BLOCK IoStatusBlock;
37 IO_STATUS_BLOCK IIosb;
38
39 WINBOOL bFsIoControlCode = FALSE;
40
41 DPRINT("DeviceIoControl(hDevice %x dwIoControlCode %d lpInBuffer %x "
42 "nInBufferSize %d lpOutBuffer %x nOutBufferSize %d "
43 "lpBytesReturned %x lpOverlapped %x)\n",
44 hDevice,dwIoControlCode,lpInBuffer,nInBufferSize,lpOutBuffer,
45 nOutBufferSize,lpBytesReturned,lpOverlapped);
46
47 if (lpBytesReturned == NULL)
48 {
49 DPRINT("DeviceIoControl() - returning STATUS_INVALID_PARAMETER\n");
50 SetLastErrorByStatus (STATUS_INVALID_PARAMETER);
51 return FALSE;
52 }
53 //
54 // TODO: Review and approve this change by RobD. IoCtrls for Serial.sys were
55 // going to NtFsControlFile instead of NtDeviceIoControlFile.
56 // Don't know at this point if anything else is affected by this change.
57 //
58 // if (((dwIoControlCode >> 16) & FILE_DEVICE_FILE_SYSTEM) == FILE_DEVICE_FILE_SYSTEM) {
59 //
60
61 if ((dwIoControlCode >> 16) == FILE_DEVICE_FILE_SYSTEM) {
62
63 bFsIoControlCode = TRUE;
64 DPRINT("DeviceIoControl() - FILE_DEVICE_FILE_SYSTEM == TRUE %x %x\n", dwIoControlCode, dwIoControlCode >> 16);
65 } else {
66 bFsIoControlCode = FALSE;
67 DPRINT("DeviceIoControl() - FILE_DEVICE_FILE_SYSTEM == FALSE %x %x\n", dwIoControlCode, dwIoControlCode >> 16);
68 }
69
70 if(lpOverlapped != NULL)
71 {
72 hEvent = lpOverlapped->hEvent;
73 lpOverlapped->Internal = STATUS_PENDING;
74 IoStatusBlock = (PIO_STATUS_BLOCK)lpOverlapped;
75 }
76 else
77 {
78 IoStatusBlock = &IIosb;
79 }
80
81 if (bFsIoControlCode == TRUE)
82 {
83 errCode = NtFsControlFile (hDevice,
84 hEvent,
85 NULL,
86 NULL,
87 IoStatusBlock,
88 dwIoControlCode,
89 lpInBuffer,
90 nInBufferSize,
91 lpOutBuffer,
92 nOutBufferSize);
93 }
94 else
95 {
96 errCode = NtDeviceIoControlFile (hDevice,
97 hEvent,
98 NULL,
99 NULL,
100 IoStatusBlock,
101 dwIoControlCode,
102 lpInBuffer,
103 nInBufferSize,
104 lpOutBuffer,
105 nOutBufferSize);
106 }
107
108 if (errCode == STATUS_PENDING)
109 {
110 DPRINT("DeviceIoControl() - STATUS_PENDING\n");
111 if (NtWaitForSingleObject(hDevice,FALSE,NULL) < 0)
112 {
113 *lpBytesReturned = IoStatusBlock->Information;
114 SetLastErrorByStatus (errCode);
115 DPRINT("DeviceIoControl() - STATUS_PENDING wait failed.\n");
116 return FALSE;
117 }
118 }
119 else if (!NT_SUCCESS(errCode))
120 {
121 SetLastErrorByStatus (errCode);
122 DPRINT("DeviceIoControl() - ERROR: %x\n", errCode);
123 return FALSE;
124 }
125
126 if (lpOverlapped)
127 *lpBytesReturned = lpOverlapped->InternalHigh;
128 else
129 *lpBytesReturned = IoStatusBlock->Information;
130
131 return TRUE;
132 }
133
134
135 WINBOOL
136 STDCALL
137 GetOverlappedResult (
138 HANDLE hFile,
139 LPOVERLAPPED lpOverlapped,
140 LPDWORD lpNumberOfBytesTransferred,
141 WINBOOL bWait
142 )
143 {
144 DWORD WaitStatus;
145
146 if (lpOverlapped == NULL)
147 {
148 SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
149 return FALSE;
150 }
151
152 if (lpOverlapped ->Internal == STATUS_PENDING)
153 {
154 if (lpNumberOfBytesTransferred == 0)
155 {
156 SetLastErrorByStatus (STATUS_PENDING);
157 return FALSE;
158 }
159 else if (bWait == TRUE)
160 {
161 if (lpOverlapped->hEvent != NULL)
162 {
163 WaitStatus = WaitForSingleObject (lpOverlapped->hEvent,
164 -1);
165 if (WaitStatus == STATUS_TIMEOUT)
166 {
167 SetLastError (ERROR_IO_INCOMPLETE);
168 return FALSE;
169 }
170 else
171 return GetOverlappedResult (hFile,
172 lpOverlapped,
173 lpNumberOfBytesTransferred,
174 FALSE);
175 }
176 }
177 }
178
179 *lpNumberOfBytesTransferred = lpOverlapped->InternalHigh;
180
181 if (lpOverlapped->Internal < 0)
182 {
183 SetLastErrorByStatus (lpOverlapped->Internal);
184 return FALSE;
185 }
186
187 return TRUE;
188 }
189
190 /* EOF */
191
192