2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: kernel32/file/deviceio.c
5 * PURPOSE: Device I/O Base Client Functionality
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES *******************************************************************/
15 /* FUNCTIONS ******************************************************************/
19 NotifySoundSentry(VOID
)
21 CSR_API_MESSAGE ApiMessage
;
23 /* Get the video mode */
24 if (!GetConsoleDisplayMode(&ApiMessage
.Data
.SoundSentryRequest
.VideoMode
))
26 ApiMessage
.Data
.SoundSentryRequest
.VideoMode
= 0;
29 /* Make sure it's not fullscreen, and send the message if not */
30 if (ApiMessage
.Data
.SoundSentryRequest
.VideoMode
== 0)
32 CsrClientCallServer(&ApiMessage
,
34 CSR_CREATE_API_NUMBER(CSR_NATIVE
, SOUND_SENTRY
),
35 sizeof(CSR_API_MESSAGE
));
48 UNICODE_STRING BeepDevice
;
49 OBJECT_ATTRIBUTES ObjectAttributes
;
50 IO_STATUS_BLOCK IoStatusBlock
;
51 BEEP_SET_PARAMETERS BeepSetParameters
;
55 // On TS systems, we need to Load Winsta.dll and call WinstationBeepOpen
56 // after doing a GetProcAddress for it
60 RtlInitUnicodeString(&BeepDevice
, L
"\\Device\\Beep");
61 InitializeObjectAttributes(&ObjectAttributes
, &BeepDevice
, 0, NULL
, NULL
);
62 Status
= NtCreateFile(&hBeep
,
63 FILE_READ_DATA
| FILE_WRITE_DATA
,
68 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
73 if (!NT_SUCCESS(Status
))
75 BaseSetLastNTError(Status
);
79 /* check the parameters */
80 if ((dwFreq
>= 0x25 && dwFreq
<= 0x7FFF) ||
81 (dwFreq
== 0x0 && dwDuration
== 0x0))
84 BeepSetParameters
.Frequency
= dwFreq
;
85 BeepSetParameters
.Duration
= dwDuration
;
88 Status
= NtDeviceIoControlFile(hBeep
,
95 sizeof(BeepSetParameters
),
101 /* We'll fail the call, but still notify the sound sentry */
102 Status
= STATUS_INVALID_PARAMETER
;
105 /* Notify the sound sentry */
108 /* Bail out if the hardware beep failed */
109 if (!NT_SUCCESS(Status
))
112 BaseSetLastNTError(Status
);
116 /* If an actual beep was emitted, wait for it */
117 if (((dwFreq
!= 0x0) || (dwDuration
!= 0x0)) && (dwDuration
!= MAXDWORD
))
119 SleepEx(dwDuration
, TRUE
);
122 /* Close the handle and return success */
132 DeviceIoControl(IN HANDLE hDevice
,
133 IN DWORD dwIoControlCode
,
134 IN LPVOID lpInBuffer OPTIONAL
,
135 IN DWORD nInBufferSize OPTIONAL
,
136 OUT LPVOID lpOutBuffer OPTIONAL
,
137 IN DWORD nOutBufferSize OPTIONAL
,
138 OUT LPDWORD lpBytesReturned OPTIONAL
,
139 IN LPOVERLAPPED lpOverlapped OPTIONAL
)
144 IO_STATUS_BLOCK Iosb
;
147 // Note: on a TS Machine, we should call IsTSAppCompatEnabled and unless the
148 // IOCTLs are IOCTL_STORAGE_EJECT_MEDIA, IOCTL_DISK_EJECT_MEDIA, FSCTL_DISMOUNT_VOLUME
149 // we should call IsCallerAdminOrSystem and return STATUS_ACCESS_DENIED for
153 /* Check what kind of IOCTL to send */
154 FsIoCtl
= ((dwIoControlCode
>> 16) == FILE_DEVICE_FILE_SYSTEM
);
156 /* CHeck for async */
157 if (lpOverlapped
!= NULL
)
159 /* Set pending status */
160 lpOverlapped
->Internal
= STATUS_PENDING
;
162 /* Check if there's an APC context */
163 ApcContext
= (((ULONG_PTR
)lpOverlapped
->hEvent
& 0x1) ? NULL
: lpOverlapped
);
165 /* Send file system control? */
169 Status
= NtFsControlFile(hDevice
,
170 lpOverlapped
->hEvent
,
173 (PIO_STATUS_BLOCK
)lpOverlapped
,
182 /* Otherwise send a device control */
183 Status
= NtDeviceIoControlFile(hDevice
,
184 lpOverlapped
->hEvent
,
187 (PIO_STATUS_BLOCK
)lpOverlapped
,
195 /* Check for or information instead of failure */
196 if (!(NT_ERROR(Status
)) && (lpBytesReturned
))
198 /* Protect with SEH */
201 /* Return the bytes */
202 *lpBytesReturned
= lpOverlapped
->InternalHigh
;
204 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
206 /* Return zero bytes */
207 *lpBytesReturned
= 0;
212 /* Now check for any kind of failure except pending*/
213 if (!(NT_SUCCESS(Status
)) || (Status
== STATUS_PENDING
))
216 BaseSetLastNTError(Status
);
222 /* Sync case -- send file system code? */
226 Status
= NtFsControlFile(hDevice
,
239 /* Send device code instead */
240 Status
= NtDeviceIoControlFile(hDevice
,
252 /* Now check if the operation isn't done yet */
253 if (Status
== STATUS_PENDING
)
255 /* Wait for it and get the final status */
256 Status
= NtWaitForSingleObject(hDevice
, FALSE
, NULL
);
257 if (NT_SUCCESS(Status
)) Status
= Iosb
.Status
;
260 /* Check for success */
261 if (NT_SUCCESS(Status
))
263 /* Return the byte count */
264 *lpBytesReturned
= Iosb
.Information
;
268 /* Check for informational or warning failure */
269 if (!NT_ERROR(Status
)) *lpBytesReturned
= Iosb
.Information
;
271 /* Return a failure */
272 BaseSetLastNTError(Status
);
286 CancelIo(IN HANDLE hFile
)
288 IO_STATUS_BLOCK IoStatusBlock
;
291 Status
= NtCancelIoFile(hFile
, &IoStatusBlock
);
292 if (!NT_SUCCESS(Status
))
294 BaseSetLastNTError(Status
);