mirror of
https://github.com/reactos/reactos.git
synced 2024-08-08 12:18:13 +00:00
[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. svn path=/trunk/; revision=54358
This commit is contained in:
parent
c461e96188
commit
e84bdd4857
|
@ -14,12 +14,35 @@
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* 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
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
WINAPI
|
WINAPI
|
||||||
Beep (DWORD dwFreq, DWORD dwDuration)
|
Beep(IN DWORD dwFreq,
|
||||||
|
IN DWORD dwDuration)
|
||||||
{
|
{
|
||||||
HANDLE hBeep;
|
HANDLE hBeep;
|
||||||
UNICODE_STRING BeepDevice;
|
UNICODE_STRING BeepDevice;
|
||||||
|
@ -28,20 +51,14 @@ Beep (DWORD dwFreq, DWORD dwDuration)
|
||||||
BEEP_SET_PARAMETERS BeepSetParameters;
|
BEEP_SET_PARAMETERS BeepSetParameters;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* check the parameters */
|
//
|
||||||
if ((dwFreq >= 0x25 && dwFreq <= 0x7FFF) ||
|
// On TS systems, we need to Load Winsta.dll and call WinstationBeepOpen
|
||||||
(dwFreq == 0x0 && dwDuration == 0x0))
|
// after doing a GetProcAddress for it
|
||||||
{
|
//
|
||||||
/* open the device */
|
|
||||||
RtlInitUnicodeString(&BeepDevice,
|
|
||||||
L"\\Device\\Beep");
|
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
&BeepDevice,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
|
/* Open the device */
|
||||||
|
RtlInitUnicodeString(&BeepDevice, L"\\Device\\Beep");
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &BeepDevice, 0, NULL, NULL);
|
||||||
Status = NtCreateFile(&hBeep,
|
Status = NtCreateFile(&hBeep,
|
||||||
FILE_READ_DATA | FILE_WRITE_DATA,
|
FILE_READ_DATA | FILE_WRITE_DATA,
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
|
@ -53,12 +70,21 @@ Beep (DWORD dwFreq, DWORD dwDuration)
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
0);
|
0);
|
||||||
if (NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
BaseSetLastNTError(Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check the parameters */
|
||||||
|
if ((dwFreq >= 0x25 && dwFreq <= 0x7FFF) ||
|
||||||
|
(dwFreq == 0x0 && dwDuration == 0x0))
|
||||||
{
|
{
|
||||||
/* Set beep data */
|
/* Set beep data */
|
||||||
BeepSetParameters.Frequency = dwFreq;
|
BeepSetParameters.Frequency = dwFreq;
|
||||||
BeepSetParameters.Duration = dwDuration;
|
BeepSetParameters.Duration = dwDuration;
|
||||||
|
|
||||||
|
/* Send the beep */
|
||||||
Status = NtDeviceIoControlFile(hBeep,
|
Status = NtDeviceIoControlFile(hBeep,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -66,30 +92,35 @@ Beep (DWORD dwFreq, DWORD dwDuration)
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
IOCTL_BEEP_SET,
|
IOCTL_BEEP_SET,
|
||||||
&BeepSetParameters,
|
&BeepSetParameters,
|
||||||
sizeof(BEEP_SET_PARAMETERS),
|
sizeof(BeepSetParameters),
|
||||||
NULL,
|
NULL,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
/* do an alertable wait if necessary */
|
|
||||||
if (NT_SUCCESS(Status) &&
|
|
||||||
(dwFreq != 0x0 || dwDuration != 0x0) && dwDuration != MAXDWORD)
|
|
||||||
{
|
|
||||||
SleepEx(dwDuration,
|
|
||||||
TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
NtClose(hBeep);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
/* We'll fail the call, but still notify the sound sentry */
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Notify the sound sentry */
|
||||||
|
NotifySoundSentry();
|
||||||
|
|
||||||
|
/* Bail out if the hardware beep failed */
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
BaseSetLastNTError (Status);
|
NtClose(hBeep);
|
||||||
|
BaseSetLastNTError(Status);
|
||||||
return FALSE;
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +143,13 @@ DeviceIoControl(IN HANDLE hDevice,
|
||||||
PVOID ApcContext;
|
PVOID ApcContext;
|
||||||
IO_STATUS_BLOCK Iosb;
|
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 */
|
/* Check what kind of IOCTL to send */
|
||||||
FsIoCtl = ((dwIoControlCode >> 16) == FILE_DEVICE_FILE_SYSTEM);
|
FsIoCtl = ((dwIoControlCode >> 16) == FILE_DEVICE_FILE_SYSTEM);
|
||||||
|
|
||||||
|
@ -121,11 +159,9 @@ DeviceIoControl(IN HANDLE hDevice,
|
||||||
/* Set pending status */
|
/* Set pending status */
|
||||||
lpOverlapped->Internal = STATUS_PENDING;
|
lpOverlapped->Internal = STATUS_PENDING;
|
||||||
|
|
||||||
|
|
||||||
/* Check if there's an APC context */
|
/* Check if there's an APC context */
|
||||||
ApcContext = (((ULONG_PTR)lpOverlapped->hEvent & 0x1) ? NULL : lpOverlapped);
|
ApcContext = (((ULONG_PTR)lpOverlapped->hEvent & 0x1) ? NULL : lpOverlapped);
|
||||||
|
|
||||||
|
|
||||||
/* Send file system control? */
|
/* Send file system control? */
|
||||||
if (FsIoCtl)
|
if (FsIoCtl)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue