fix Beep() to make it work with xp's beep.sys
Modified: trunk/reactos/lib/kernel32/misc/error.c

Modified: trunk/reactos/lib/kernel32/misc/error.c
--- trunk/reactos/lib/kernel32/misc/error.c	2005-10-27 19:42:06 UTC (rev 18797)
+++ trunk/reactos/lib/kernel32/misc/error.c	2005-10-27 20:00:27 UTC (rev 18798)
@@ -42,34 +42,74 @@
 Beep (DWORD dwFreq, DWORD dwDuration)
 {
     HANDLE hBeep;
+    UNICODE_STRING BeepDevice;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    IO_STATUS_BLOCK IoStatusBlock;
     BEEP_SET_PARAMETERS BeepSetParameters;
-    DWORD dwReturned;
+    NTSTATUS Status;
 
-    hBeep = CreateFileW(L"\\\\.\\Beep",
-                       FILE_GENERIC_READ | FILE_GENERIC_WRITE,
-                       0,
-                       NULL,
-                       OPEN_EXISTING,
-                       0,
-                       NULL);
-    if (hBeep == INVALID_HANDLE_VALUE)
-        return FALSE;
+    /* check the parameters */
+    if ((dwFreq >= 0x25 && dwFreq <= 0x7FFF) ||
+        (dwFreq == 0x0 && dwDuration == 0x0))
+    {
+        /* open the device */
+        RtlInitUnicodeString(&BeepDevice,
+                             L"\\Device\\Beep");
 
-    /* Set beep data */
-    BeepSetParameters.Frequency = dwFreq;
-    BeepSetParameters.Duration  = dwDuration;
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &BeepDevice,
+                                   0,
+                                   NULL,
+                                   NULL);
 
-    DeviceIoControl(hBeep,
-                    IOCTL_BEEP_SET,
-                    &BeepSetParameters,
-                    sizeof(BEEP_SET_PARAMETERS),
-                    NULL,
-                    0,
-                    &dwReturned,
-                    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;
 
-    CloseHandle (hBeep);
+            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 != (DWORD)-1)
+            {
+                SleepEx(dwDuration,
+                        TRUE);
+            }
+
+            NtClose(hBeep);
+        }
+    }
+    else
+        Status = STATUS_INVALID_PARAMETER;
+
+    if (!NT_SUCCESS(Status))
+    {
+        SetLastErrorByStatus (Status);
+        return FALSE;
+    }
+
     return TRUE;
 }