update for HEAD-2003021201
[reactos.git] / 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 //#define DBG
16 #include <kernel32/kernel32.h>
17
18
19 WINBOOL
20 STDCALL
21 DeviceIoControl(
22                 HANDLE hDevice,
23                 DWORD dwIoControlCode,
24                 LPVOID lpInBuffer,
25                 DWORD nInBufferSize,
26                 LPVOID lpOutBuffer,
27                 DWORD nOutBufferSize,
28                 LPDWORD lpBytesReturned,
29                 LPOVERLAPPED lpOverlapped
30                 )
31 {
32         NTSTATUS errCode = 0;
33         HANDLE hEvent = NULL;
34         PIO_STATUS_BLOCK IoStatusBlock;
35         IO_STATUS_BLOCK IIosb;
36
37         WINBOOL bFsIoControlCode = FALSE;
38
39     DPRINT("DeviceIoControl(hDevice %x dwIoControlCode %d lpInBuffer %x "
40           "nInBufferSize %d lpOutBuffer %x nOutBufferSize %d "
41           "lpBytesReturned %x lpOverlapped %x)\n",
42           hDevice,dwIoControlCode,lpInBuffer,nInBufferSize,lpOutBuffer,
43           nOutBufferSize,lpBytesReturned,lpOverlapped);
44
45         if (lpBytesReturned == NULL)
46         {
47         DPRINT("DeviceIoControl() - returning STATUS_INVALID_PARAMETER\n");
48                 SetLastErrorByStatus (STATUS_INVALID_PARAMETER);
49                 return FALSE;
50         }
51         //
52         // TODO: Review and approve this change by RobD. IoCtrls for Serial.sys were 
53         //       going to NtFsControlFile instead of NtDeviceIoControlFile.
54         //               Don't know at this point if anything else is affected by this change.
55         //
56         // if (((dwIoControlCode >> 16) & FILE_DEVICE_FILE_SYSTEM) == FILE_DEVICE_FILE_SYSTEM) {
57         //
58
59         if ((dwIoControlCode >> 16) == FILE_DEVICE_FILE_SYSTEM) {
60
61                 bFsIoControlCode = TRUE;
62         DPRINT("DeviceIoControl() - FILE_DEVICE_FILE_SYSTEM == TRUE %x %x\n", dwIoControlCode, dwIoControlCode >> 16);
63         } else {
64                 bFsIoControlCode = FALSE;
65         DPRINT("DeviceIoControl() - FILE_DEVICE_FILE_SYSTEM == FALSE %x %x\n", dwIoControlCode, dwIoControlCode >> 16);
66         }
67
68         if(lpOverlapped  != NULL)
69         {
70                 hEvent = lpOverlapped->hEvent;
71                 lpOverlapped->Internal = STATUS_PENDING;
72                 IoStatusBlock = (PIO_STATUS_BLOCK)lpOverlapped;
73         }
74         else
75         {
76                 IoStatusBlock = &IIosb;
77         }
78
79         if (bFsIoControlCode == TRUE)
80         {
81                 errCode = NtFsControlFile (hDevice,
82                                            hEvent,
83                                            NULL,
84                                            NULL,
85                                            IoStatusBlock,
86                                            dwIoControlCode,
87                                            lpInBuffer,
88                                            nInBufferSize,
89                                            lpOutBuffer,
90                                            nOutBufferSize);
91         }
92         else
93         {
94                 errCode = NtDeviceIoControlFile (hDevice,
95                                                  hEvent,
96                                                  NULL,
97                                                  NULL,
98                                                  IoStatusBlock,
99                                                  dwIoControlCode,
100                                                  lpInBuffer,
101                                                  nInBufferSize,
102                                                  lpOutBuffer,
103                                                  nOutBufferSize);
104         }
105
106         if (errCode == STATUS_PENDING)
107         {
108         DPRINT("DeviceIoControl() - STATUS_PENDING\n");
109                 if (NtWaitForSingleObject(hDevice,FALSE,NULL) < 0)
110                 {
111                         *lpBytesReturned = IoStatusBlock->Information;
112                         SetLastErrorByStatus (errCode);
113             DPRINT("DeviceIoControl() - STATUS_PENDING wait failed.\n");
114                         return FALSE;
115                 }
116         }
117         else if (!NT_SUCCESS(errCode))
118         {
119                 SetLastErrorByStatus (errCode);
120         DPRINT("DeviceIoControl() - ERROR: %x\n", errCode);
121                 return FALSE;
122         }
123
124         if (lpOverlapped)
125                 *lpBytesReturned = lpOverlapped->InternalHigh;
126         else
127                 *lpBytesReturned = IoStatusBlock->Information;
128
129         return TRUE;
130 }
131
132
133 WINBOOL
134 STDCALL
135 GetOverlappedResult (
136         HANDLE          hFile,
137         LPOVERLAPPED    lpOverlapped,
138         LPDWORD         lpNumberOfBytesTransferred,
139         WINBOOL         bWait
140         )
141 {
142         DWORD WaitStatus;
143
144         if (lpOverlapped == NULL)
145         {
146                 SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
147                 return FALSE;
148         }
149
150         if (lpOverlapped ->Internal == STATUS_PENDING)
151         {
152                 if (lpNumberOfBytesTransferred == 0)
153                 {
154                         SetLastErrorByStatus (STATUS_PENDING);
155                         return FALSE;
156                 }
157                 else if (bWait == TRUE)
158                 {
159                         if (lpOverlapped->hEvent != NULL)
160                         {
161                                 WaitStatus = WaitForSingleObject (lpOverlapped->hEvent,
162                                                                   -1);
163                                 if (WaitStatus ==  STATUS_TIMEOUT)
164                                 {
165                                         SetLastError (ERROR_IO_INCOMPLETE);
166                                         return FALSE;
167                                 }
168                                 else
169                                         return GetOverlappedResult (hFile,
170                                                                     lpOverlapped,
171                                                                     lpNumberOfBytesTransferred,
172                                                                     FALSE);
173                         }
174                 }
175         }
176
177         *lpNumberOfBytesTransferred = lpOverlapped->InternalHigh;
178
179         if (lpOverlapped->Internal < 0)
180         {
181                 SetLastErrorByStatus (lpOverlapped->Internal);
182                 return FALSE;
183         }
184
185         return TRUE;
186 }
187
188 /* EOF */
189
190