Fixed bug in DeviceIoContol().
[reactos.git] / reactos / lib / kernel32 / file / deviceio.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/kernel32/file/deviceio.c
5 * PURPOSE: Device I/O and Overlapped Result functions
6 * PROGRAMMER: Ariadne (ariadne@xs4all.nl)
7 * UPDATE HISTORY:
8 * Created 01/11/98
9 */
10
11 #include <windows.h>
12 #include <ddk/ntddk.h>
13
14 #define NDEBUG
15 #include <kernel32/kernel32.h>
16
17
18 WINBOOL
19 STDCALL
20 DeviceIoControl(
21 HANDLE hDevice,
22 DWORD dwIoControlCode,
23 LPVOID lpInBuffer,
24 DWORD nInBufferSize,
25 LPVOID lpOutBuffer,
26 DWORD nOutBufferSize,
27 LPDWORD lpBytesReturned,
28 LPOVERLAPPED lpOverlapped
29 )
30 {
31 NTSTATUS errCode = 0;
32 HANDLE hEvent = NULL;
33 PIO_STATUS_BLOCK IoStatusBlock;
34 IO_STATUS_BLOCK IIosb;
35
36 WINBOOL bFsIoControlCode = FALSE;
37
38 if ( lpBytesReturned == NULL ) {
39 SetLastError(RtlNtStatusToDosError(STATUS_INVALID_PARAMETER));
40 return FALSE;;
41 }
42
43 if( ( ( dwIoControlCode >> 16 ) & FILE_DEVICE_FILE_SYSTEM ) == FILE_DEVICE_FILE_SYSTEM )
44 bFsIoControlCode = TRUE;
45 else
46 bFsIoControlCode = FALSE;
47 CHECKPOINT
48 if(lpOverlapped != NULL) {
49 hEvent = lpOverlapped->hEvent;
50 lpOverlapped->Internal = STATUS_PENDING;
51 IoStatusBlock = (PIO_STATUS_BLOCK)lpOverlapped;
52 }
53 else {
54 IoStatusBlock = &IIosb;
55 }
56
57 CHECKPOINT
58 if(bFsIoControlCode == TRUE) {
59 errCode = NtFsControlFile(hDevice,hEvent,NULL,NULL,IoStatusBlock,dwIoControlCode,lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize );
60 } else {
61 errCode = NtDeviceIoControlFile(hDevice,hEvent,NULL,NULL,IoStatusBlock,dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize);
62 }
63 CHECKPOINT
64 if(errCode == STATUS_PENDING ) {
65
66 if(NtWaitForSingleObject(hDevice,FALSE,NULL) < 0) {
67 *lpBytesReturned = IoStatusBlock->Information;
68 SetLastError(RtlNtStatusToDosError(errCode));
69 return FALSE;;
70 }
71
72 } else if ( !NT_SUCCESS(errCode) ) {
73 SetLastError(RtlNtStatusToDosError(errCode));
74 return FALSE;
75 }
76 CHECKPOINT
77 if (lpOverlapped)
78 *lpBytesReturned = lpOverlapped->InternalHigh;
79 else
80 *lpBytesReturned = IoStatusBlock->Information;
81 CHECKPOINT
82 return TRUE;
83 }
84
85
86
87 WINBOOL
88 STDCALL
89 GetOverlappedResult(
90 HANDLE hFile,
91 LPOVERLAPPED lpOverlapped,
92 LPDWORD lpNumberOfBytesTransferred,
93 WINBOOL bWait
94 )
95 {
96 DWORD WaitStatus;
97
98 if ( lpOverlapped == NULL ) {
99 SetLastError(RtlNtStatusToDosError(STATUS_INVALID_PARAMETER));
100 return FALSE;
101 }
102 if ( lpOverlapped ->Internal == STATUS_PENDING) {
103 if ( lpNumberOfBytesTransferred == 0 ) {
104 SetLastError(RtlNtStatusToDosError(STATUS_PENDING));
105 return FALSE;
106 }
107 else if ( bWait == TRUE ) {
108 if ( lpOverlapped->hEvent != NULL ) {
109 WaitStatus = WaitForSingleObject(lpOverlapped->hEvent,-1);
110 if ( WaitStatus == STATUS_TIMEOUT ) {
111 SetLastError(ERROR_IO_INCOMPLETE);
112 return FALSE;
113 }
114 else
115 return GetOverlappedResult(hFile,lpOverlapped,lpNumberOfBytesTransferred,FALSE);
116
117 }
118 }
119 }
120 *lpNumberOfBytesTransferred = lpOverlapped->InternalHigh;
121 if ( lpOverlapped->Internal < 0 ) {
122 SetLastError(RtlNtStatusToDosError(lpOverlapped->Internal));
123 return FALSE;
124 }
125 return TRUE;
126
127
128
129 }
130
131
132