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)
         {