8ff7173777b01742a4559de379c08642532438d6
[reactos.git] / reactos / lib / kernel32 / file / deviceio.c
1 /* $Id: deviceio.c,v 1.9 2002/09/08 10:22:41 chorns 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 #include <kernel32/kernel32.h>
17 #include <kernel32/error.h>
18
19
20 WINBOOL
21 STDCALL
22 DeviceIoControl(
23 HANDLE hDevice,
24 DWORD dwIoControlCode,
25 LPVOID lpInBuffer,
26 DWORD nInBufferSize,
27 LPVOID lpOutBuffer,
28 DWORD nOutBufferSize,
29 LPDWORD lpBytesReturned,
30 LPOVERLAPPED lpOverlapped
31 )
32 {
33 NTSTATUS errCode = 0;
34 HANDLE hEvent = NULL;
35 PIO_STATUS_BLOCK IoStatusBlock;
36 IO_STATUS_BLOCK IIosb;
37
38 WINBOOL bFsIoControlCode = FALSE;
39
40 if (lpBytesReturned == NULL)
41 {
42 SetLastErrorByStatus (STATUS_INVALID_PARAMETER);
43 return FALSE;
44 }
45
46 if (((dwIoControlCode >> 16) & FILE_DEVICE_FILE_SYSTEM) == FILE_DEVICE_FILE_SYSTEM)
47 bFsIoControlCode = TRUE;
48 else
49 bFsIoControlCode = FALSE;
50
51 if(lpOverlapped != NULL)
52 {
53 hEvent = lpOverlapped->hEvent;
54 lpOverlapped->Internal = STATUS_PENDING;
55 IoStatusBlock = (PIO_STATUS_BLOCK)lpOverlapped;
56 }
57 else
58 {
59 IoStatusBlock = &IIosb;
60 }
61
62 if (bFsIoControlCode == TRUE)
63 {
64 errCode = NtFsControlFile (hDevice,
65 hEvent,
66 NULL,
67 NULL,
68 IoStatusBlock,
69 dwIoControlCode,
70 lpInBuffer,
71 nInBufferSize,
72 lpOutBuffer,
73 nOutBufferSize);
74 }
75 else
76 {
77 errCode = NtDeviceIoControlFile (hDevice,
78 hEvent,
79 NULL,
80 NULL,
81 IoStatusBlock,
82 dwIoControlCode,
83 lpInBuffer,
84 nInBufferSize,
85 lpOutBuffer,
86 nOutBufferSize);
87 }
88
89 if (errCode == STATUS_PENDING)
90 {
91 if (NtWaitForSingleObject(hDevice,FALSE,NULL) < 0)
92 {
93 *lpBytesReturned = IoStatusBlock->Information;
94 SetLastErrorByStatus (errCode);
95 return FALSE;
96 }
97 }
98 else if (!NT_SUCCESS(errCode))
99 {
100 SetLastErrorByStatus (errCode);
101 return FALSE;
102 }
103
104 if (lpOverlapped)
105 *lpBytesReturned = lpOverlapped->InternalHigh;
106 else
107 *lpBytesReturned = IoStatusBlock->Information;
108
109 return TRUE;
110 }
111
112
113 WINBOOL
114 STDCALL
115 GetOverlappedResult (
116 HANDLE hFile,
117 LPOVERLAPPED lpOverlapped,
118 LPDWORD lpNumberOfBytesTransferred,
119 WINBOOL bWait
120 )
121 {
122 DWORD WaitStatus;
123
124 if (lpOverlapped == NULL)
125 {
126 SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
127 return FALSE;
128 }
129
130 if (lpOverlapped ->Internal == STATUS_PENDING)
131 {
132 if (lpNumberOfBytesTransferred == 0)
133 {
134 SetLastErrorByStatus (STATUS_PENDING);
135 return FALSE;
136 }
137 else if (bWait == TRUE)
138 {
139 if (lpOverlapped->hEvent != NULL)
140 {
141 WaitStatus = WaitForSingleObject (lpOverlapped->hEvent,
142 -1);
143 if (WaitStatus == STATUS_TIMEOUT)
144 {
145 SetLastError (ERROR_IO_INCOMPLETE);
146 return FALSE;
147 }
148 else
149 return GetOverlappedResult (hFile,
150 lpOverlapped,
151 lpNumberOfBytesTransferred,
152 FALSE);
153 }
154 }
155 }
156
157 *lpNumberOfBytesTransferred = lpOverlapped->InternalHigh;
158
159 if (lpOverlapped->Internal < 0)
160 {
161 SetLastErrorByStatus (lpOverlapped->Internal);
162 return FALSE;
163 }
164
165 return TRUE;
166 }
167
168 /* EOF */
169
170