- Optimize CallNamedPipeA too and remove accidental define.
[reactos.git] / reactos / lib / kernel32 / file / deviceio.c
1 /* $Id$
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 <k32.h>
13
14 #define NDEBUG
15 #include "../include/debug.h"
16
17
18 /*
19 * @implemented
20 */
21 BOOL
22 STDCALL
23 DeviceIoControl(IN HANDLE hDevice,
24 IN DWORD dwIoControlCode,
25 IN LPVOID lpInBuffer OPTIONAL,
26 IN DWORD nInBufferSize OPTIONAL,
27 OUT LPVOID lpOutBuffer OPTIONAL,
28 IN DWORD nOutBufferSize OPTIONAL,
29 OUT LPDWORD lpBytesReturned OPTIONAL,
30 IN LPOVERLAPPED lpOverlapped OPTIONAL)
31 {
32 BOOL FsIoCtl;
33 NTSTATUS Status;
34
35 FsIoCtl = ((dwIoControlCode >> 16) == FILE_DEVICE_FILE_SYSTEM);
36
37 if (lpBytesReturned != NULL)
38 {
39 *lpBytesReturned = 0;
40 }
41
42 if (lpOverlapped != NULL)
43 {
44 PVOID ApcContext;
45
46 lpOverlapped->Internal = STATUS_PENDING;
47 ApcContext = (((ULONG_PTR)lpOverlapped->hEvent & 0x1) ? NULL : lpOverlapped);
48
49 if (FsIoCtl)
50 {
51 Status = NtFsControlFile(hDevice,
52 lpOverlapped->hEvent,
53 NULL,
54 ApcContext,
55 (PIO_STATUS_BLOCK)lpOverlapped,
56 dwIoControlCode,
57 lpInBuffer,
58 nInBufferSize,
59 lpOutBuffer,
60 nOutBufferSize);
61 }
62 else
63 {
64 Status = NtDeviceIoControlFile(hDevice,
65 lpOverlapped->hEvent,
66 NULL,
67 ApcContext,
68 (PIO_STATUS_BLOCK)lpOverlapped,
69 dwIoControlCode,
70 lpInBuffer,
71 nInBufferSize,
72 lpOutBuffer,
73 nOutBufferSize);
74 }
75
76 /* return FALSE in case of failure and pending operations! */
77 if (!NT_SUCCESS(Status) || Status == STATUS_PENDING)
78 {
79 SetLastErrorByStatus(Status);
80 return FALSE;
81 }
82
83 if (lpBytesReturned != NULL)
84 {
85 *lpBytesReturned = lpOverlapped->InternalHigh;
86 }
87 }
88 else
89 {
90 IO_STATUS_BLOCK Iosb;
91
92 if (FsIoCtl)
93 {
94 Status = NtFsControlFile(hDevice,
95 NULL,
96 NULL,
97 NULL,
98 &Iosb,
99 dwIoControlCode,
100 lpInBuffer,
101 nInBufferSize,
102 lpOutBuffer,
103 nOutBufferSize);
104 }
105 else
106 {
107 Status = NtDeviceIoControlFile(hDevice,
108 NULL,
109 NULL,
110 NULL,
111 &Iosb,
112 dwIoControlCode,
113 lpInBuffer,
114 nInBufferSize,
115 lpOutBuffer,
116 nOutBufferSize);
117 }
118
119 /* wait in case operation is pending */
120 if (Status == STATUS_PENDING)
121 {
122 Status = NtWaitForSingleObject(hDevice,
123 FALSE,
124 NULL);
125 if (NT_SUCCESS(Status))
126 {
127 Status = Iosb.Status;
128 }
129 }
130
131 if (NT_SUCCESS(Status))
132 {
133 /* lpBytesReturned must not be NULL here, in fact Win doesn't
134 check that case either and crashes (only after the operation
135 completed) */
136 *lpBytesReturned = Iosb.Information;
137 }
138 else
139 {
140 SetLastErrorByStatus(Status);
141 return FALSE;
142 }
143 }
144
145 return TRUE;
146 }
147
148
149 /*
150 * @implemented
151 */
152 BOOL
153 STDCALL
154 GetOverlappedResult (
155 IN HANDLE hFile,
156 IN LPOVERLAPPED lpOverlapped,
157 OUT LPDWORD lpNumberOfBytesTransferred,
158 IN BOOL bWait
159 )
160 {
161 DWORD WaitStatus;
162 HANDLE hObject;
163
164 if (lpOverlapped->Internal == STATUS_PENDING)
165 {
166 if (!bWait)
167 {
168 /* can't use SetLastErrorByStatus(STATUS_PENDING) here,
169 since STATUS_PENDING translates to ERROR_IO_PENDING */
170 SetLastError(ERROR_IO_INCOMPLETE);
171 return FALSE;
172 }
173
174 hObject = lpOverlapped->hEvent ? lpOverlapped->hEvent : hFile;
175
176 /* Wine delivers pending APC's while waiting, but Windows does
177 not, nor do we... */
178 WaitStatus = WaitForSingleObject(hObject, INFINITE);
179
180 if (WaitStatus == WAIT_FAILED)
181 {
182 DPRINT("Wait failed!\n");
183 /* WaitForSingleObjectEx sets the last error */
184 return FALSE;
185 }
186 }
187
188 *lpNumberOfBytesTransferred = lpOverlapped->InternalHigh;
189
190 if (!NT_SUCCESS(lpOverlapped->Internal))
191 {
192 SetLastErrorByStatus(lpOverlapped->Internal);
193 return FALSE;
194 }
195
196 return TRUE;
197 }
198
199 /* EOF */
200
201