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)
15 #include "../include/debug.h"
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
)
35 FsIoCtl
= ((dwIoControlCode
>> 16) == FILE_DEVICE_FILE_SYSTEM
);
37 if (lpBytesReturned
!= NULL
)
42 if (lpOverlapped
!= NULL
)
46 lpOverlapped
->Internal
= STATUS_PENDING
;
47 ApcContext
= (((ULONG_PTR
)lpOverlapped
->hEvent
& 0x1) ? NULL
: lpOverlapped
);
51 Status
= NtFsControlFile(hDevice
,
55 (PIO_STATUS_BLOCK
)lpOverlapped
,
64 Status
= NtDeviceIoControlFile(hDevice
,
68 (PIO_STATUS_BLOCK
)lpOverlapped
,
76 /* return FALSE in case of failure and pending operations! */
77 if (!NT_SUCCESS(Status
) || Status
== STATUS_PENDING
)
79 SetLastErrorByStatus(Status
);
83 if (lpBytesReturned
!= NULL
)
85 *lpBytesReturned
= lpOverlapped
->InternalHigh
;
94 Status
= NtFsControlFile(hDevice
,
107 Status
= NtDeviceIoControlFile(hDevice
,
119 /* wait in case operation is pending */
120 if (Status
== STATUS_PENDING
)
122 Status
= NtWaitForSingleObject(hDevice
,
125 if (NT_SUCCESS(Status
))
127 Status
= Iosb
.Status
;
131 if (NT_SUCCESS(Status
))
133 /* lpBytesReturned must not be NULL here, in fact Win doesn't
134 check that case either and crashes (only after the operation
136 *lpBytesReturned
= Iosb
.Information
;
140 SetLastErrorByStatus(Status
);
154 GetOverlappedResult (
156 IN LPOVERLAPPED lpOverlapped
,
157 OUT LPDWORD lpNumberOfBytesTransferred
,
164 if (lpOverlapped
->Internal
== STATUS_PENDING
)
168 /* can't use SetLastErrorByStatus(STATUS_PENDING) here,
169 since STATUS_PENDING translates to ERROR_IO_PENDING */
170 SetLastError(ERROR_IO_INCOMPLETE
);
174 hObject
= lpOverlapped
->hEvent
? lpOverlapped
->hEvent
: hFile
;
176 /* Wine delivers pending APC's while waiting, but Windows does
178 WaitStatus
= WaitForSingleObject(hObject
, INFINITE
);
180 if (WaitStatus
== WAIT_FAILED
)
182 DPRINT("Wait failed!\n");
183 /* WaitForSingleObjectEx sets the last error */
188 *lpNumberOfBytesTransferred
= lpOverlapped
->InternalHigh
;
190 if (!NT_SUCCESS(lpOverlapped
->Internal
))
192 SetLastErrorByStatus(lpOverlapped
->Internal
);