Author: ion
Date: Sat Nov 12 08:18:18 2011
New Revision: 54358
URL:
http://svn.reactos.org/svn/reactos?rev=54358&view=rev
Log:
[KERNEL32]: Refactor Beep such that opening the device happens first -- this makes sure
the error codes are generated in the same order/conditions as on Windows.
[KERNEL32]: Add notes on how DeviceIoControl and Beep should support TS scenarios in the
future (nod to Ged).
[KERNEL32]: Make Beep call NotifySoundSentry, and implement the latter, which sends a
message to CSRSS w.r.t the previous commit. Obviously we are not anywhere close real sound
sentry support, but at least part of the path is there now.
Modified:
trunk/reactos/dll/win32/kernel32/client/file/deviceio.c
Modified: trunk/reactos/dll/win32/kernel32/client/file/deviceio.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/file/deviceio.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/file/deviceio.c [iso-8859-1] Sat Nov 12
08:18:18 2011
@@ -14,12 +14,35 @@
/* FUNCTIONS ******************************************************************/
+VOID
+WINAPI
+NotifySoundSentry(VOID)
+{
+ CSR_API_MESSAGE ApiMessage;
+
+ /* Get the video mode */
+ if (!GetConsoleDisplayMode(&ApiMessage.Data.SoundSentryRequest.VideoMode))
+ {
+ ApiMessage.Data.SoundSentryRequest.VideoMode = 0;
+ }
+
+ /* Make sure it's not fullscreen, and send the message if not */
+ if (ApiMessage.Data.SoundSentryRequest.VideoMode == 0)
+ {
+ CsrClientCallServer(&ApiMessage,
+ NULL,
+ MAKE_CSR_API(SOUND_SENTRY, CSR_NATIVE),
+ sizeof(CSR_API_MESSAGE));
+ }
+}
+
/*
* @implemented
*/
BOOL
WINAPI
-Beep (DWORD dwFreq, DWORD dwDuration)
+Beep(IN DWORD dwFreq,
+ IN DWORD dwDuration)
{
HANDLE hBeep;
UNICODE_STRING BeepDevice;
@@ -27,69 +50,77 @@
IO_STATUS_BLOCK IoStatusBlock;
BEEP_SET_PARAMETERS BeepSetParameters;
NTSTATUS Status;
+
+ //
+ // On TS systems, we need to Load Winsta.dll and call WinstationBeepOpen
+ // after doing a GetProcAddress for it
+ //
+
+ /* Open the device */
+ RtlInitUnicodeString(&BeepDevice, L"\\Device\\Beep");
+ InitializeObjectAttributes(&ObjectAttributes, &BeepDevice, 0, NULL, NULL);
+ Status = NtCreateFile(&hBeep,
+ FILE_READ_DATA | FILE_WRITE_DATA,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_OPEN_IF,
+ 0,
+ NULL,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ BaseSetLastNTError(Status);
+ return FALSE;
+ }
/* check the parameters */
if ((dwFreq >= 0x25 && dwFreq <= 0x7FFF) ||
(dwFreq == 0x0 && dwDuration == 0x0))
{
- /* open the device */
- RtlInitUnicodeString(&BeepDevice,
- L"\\Device\\Beep");
-
- InitializeObjectAttributes(&ObjectAttributes,
- &BeepDevice,
- 0,
- NULL,
- NULL);
-
- Status = NtCreateFile(&hBeep,
- FILE_READ_DATA | FILE_WRITE_DATA,
- &ObjectAttributes,
- &IoStatusBlock,
- NULL,
- 0,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- FILE_OPEN_IF,
- 0,
- NULL,
- 0);
- if (NT_SUCCESS(Status))
- {
- /* Set beep data */
- BeepSetParameters.Frequency = dwFreq;
- BeepSetParameters.Duration = dwDuration;
-
- Status = NtDeviceIoControlFile(hBeep,
- NULL,
- NULL,
- NULL,
- &IoStatusBlock,
- IOCTL_BEEP_SET,
- &BeepSetParameters,
- sizeof(BEEP_SET_PARAMETERS),
- NULL,
- 0);
-
- /* do an alertable wait if necessary */
- if (NT_SUCCESS(Status) &&
- (dwFreq != 0x0 || dwDuration != 0x0) && dwDuration != MAXDWORD)
- {
- SleepEx(dwDuration,
- TRUE);
- }
-
- NtClose(hBeep);
- }
+ /* Set beep data */
+ BeepSetParameters.Frequency = dwFreq;
+ BeepSetParameters.Duration = dwDuration;
+
+ /* Send the beep */
+ Status = NtDeviceIoControlFile(hBeep,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ IOCTL_BEEP_SET,
+ &BeepSetParameters,
+ sizeof(BeepSetParameters),
+ NULL,
+ 0);
}
else
+ {
+ /* We'll fail the call, but still notify the sound sentry */
Status = STATUS_INVALID_PARAMETER;
-
+ }
+
+ /* Notify the sound sentry */
+ NotifySoundSentry();
+
+ /* Bail out if the hardware beep failed */
if (!NT_SUCCESS(Status))
{
- BaseSetLastNTError (Status);
+ NtClose(hBeep);
+ BaseSetLastNTError(Status);
return FALSE;
}
+ /* If an actual beep was emitted, wait for it */
+ if (((dwFreq != 0x0) || (dwDuration != 0x0)) && (dwDuration != MAXDWORD))
+ {
+ SleepEx(dwDuration, TRUE);
+ }
+
+ /* Close the handle and return success */
+ NtClose(hBeep);
return TRUE;
}
@@ -112,6 +143,13 @@
PVOID ApcContext;
IO_STATUS_BLOCK Iosb;
+ //
+ // Note: on a TS Machine, we should call IsTSAppCompatEnabled and unless the
+ // IOCTLs are IOCTL_STORAGE_EJECT_MEDIA, IOCTL_DISK_EJECT_MEDIA,
FSCTL_DISMOUNT_VOLUME
+ // we should call IsCallerAdminOrSystem and return STATUS_ACCESS_DENIED for
+ // any other IOCTLs.
+ //
+
/* Check what kind of IOCTL to send */
FsIoCtl = ((dwIoControlCode >> 16) == FILE_DEVICE_FILE_SYSTEM);
@@ -121,11 +159,9 @@
/* Set pending status */
lpOverlapped->Internal = STATUS_PENDING;
-
/* Check if there's an APC context */
ApcContext = (((ULONG_PTR)lpOverlapped->hEvent & 0x1) ? NULL :
lpOverlapped);
-
/* Send file system control? */
if (FsIoCtl)
{