[ros-diffs] [silverblade] 34595: Beginning of MME audio support rewrite. Made the message entrypoints thread-safe. Refactored parts of the code, in particular the device I/O handling. Uniformly implemented the GETNUMDEVS message for all device types (wave/midi/mixer/aux). Pops up message boxes for each device found. Tested on NT4. Removed lots of redundant debug code.

silverblade at svn.reactos.org silverblade at svn.reactos.org
Sun Jul 20 00:17:18 CEST 2008


Author: silverblade
Date: Sat Jul 19 17:17:17 2008
New Revision: 34595

URL: http://svn.reactos.org/svn/reactos?rev=34595&view=rev
Log:
Beginning of MME audio support rewrite. Made the message entrypoints
thread-safe. Refactored parts of the code, in particular the device I/O
handling. Uniformly implemented the GETNUMDEVS message for all device
types (wave/midi/mixer/aux). Pops up message boxes for each device found.
Tested on NT4. Removed lots of redundant debug code.


Added:
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/auxiliary/
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c   (with props)
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/deviceinstance.c   (with props)
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/devicelist.c   (with props)
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/kernel.c   (with props)
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/midi/
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/midi/midMessage.c   (with props)
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/midi/modMessage.c   (with props)
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/mixer/
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c   (with props)
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/mmebuddy.rbuild   (with props)
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/mmebuddy.rbuild~
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/nt4.c   (with props)
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/reentrancy.c   (with props)
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/utility.c   (with props)
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/widMessage.c   (with props)
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wodMessage.c   (with props)
Modified:
    branches/silverblade-audio/dll/win32/sndblst/sndblst.c
    branches/silverblade-audio/dll/win32/sndblst/sndblst.def
    branches/silverblade-audio/dll/win32/sndblst/sndblst.rbuild
    branches/silverblade-audio/dll/win32/win32.rbuild
    branches/silverblade-audio/include/ddk/ntddsnd.h
    branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h

Modified: branches/silverblade-audio/dll/win32/sndblst/sndblst.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/dll/win32/sndblst/sndblst.c?rev=34595&r1=34594&r2=34595&view=diff
==============================================================================
--- branches/silverblade-audio/dll/win32/sndblst/sndblst.c [iso-8859-1] (original)
+++ branches/silverblade-audio/dll/win32/sndblst/sndblst.c [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -18,11 +18,99 @@
 #include <mmebuddy.h>
 //#include <debug.h>
 
-PWSTR SBWaveOutDeviceName = L"Sound Blaster Playback (silverblade)";
-PWSTR SBWaveInDeviceName  = L"Sound Blaster Recording (silverblade)";
+PWSTR SBWaveOutDeviceName = L"ROS Sound Blaster Playback";
+PWSTR SBWaveInDeviceName  = L"ROS Sound Blaster Recording";
 /* TODO: Mixer etc */
 
-
+BOOLEAN FoundDevice(
+    UCHAR DeviceType,
+    PWSTR DevicePath)
+{
+    MMRESULT Result;
+    PSOUND_DEVICE SoundDevice = NULL;
+
+    POPUP(DevicePath);
+
+/*
+    MMFUNCTION_TABLE FuncTable;
+
+    ZeroMemory(&FuncTable, sizeof(MMFUNCTION_TABLE));
+
+    FuncTable.GetCapabilities = GetSoundBlasterDeviceCapabilities;
+*/
+
+    Result = ListSoundDevice(DeviceType, DevicePath, &SoundDevice);
+
+    if ( Result != MMSYSERR_NOERROR )
+    {
+        return FALSE;
+    }
+
+    /* TODO: Set up function table */
+
+    return TRUE;
+}
+
+APIENTRY LONG
+DriverProc(
+    DWORD DriverId,
+    HANDLE DriverHandle,
+    UINT Message,
+    LONG Parameter1,
+    LONG Parameter2)
+{
+    MMRESULT Result;
+
+    switch ( Message )
+    {
+        case DRV_LOAD :
+        {
+            POPUP(L"DRV_LOAD");
+
+            Result = InitEntrypointMutexes();
+
+            if ( Result != MMSYSERR_NOERROR )
+                return 0L;
+
+            Result = EnumerateNt4ServiceSoundDevices(L"sndblst",
+                                                     0,
+                                                     FoundDevice);
+
+            if ( Result != MMSYSERR_NOERROR )
+            {
+                CleanupEntrypointMutexes();
+
+                Result = UnlistAllSoundDevices();
+                SND_ASSERT( Result == MMSYSERR_NOERROR );
+
+                return 0L;
+            }
+
+            return 1L;
+        }
+
+        case DRV_FREE :
+        {
+            POPUP(L"DRV_FREE");
+
+            CleanupEntrypointMutexes();
+
+            POPUP(L"Unfreed memory blocks: %d", GetMemoryAllocationCount());
+
+            return 1L;
+        }
+
+        case DRV_QUERYCONFIGURE :
+            return 0L;
+        case DRV_CONFIGURE :
+            return DRVCNF_OK;
+
+        default :
+            return 1L;
+    }
+}
+
+#if 0
 MMRESULT
 GetSoundBlasterDeviceCapabilities(
     IN  PSOUND_DEVICE Device,
@@ -61,12 +149,12 @@
     return MMSYSERR_NOERROR;
 }
 
-
 BOOLEAN FoundDevice(
     UCHAR DeviceType,
     PWSTR DevicePath,
     HANDLE Handle)
 {
+    PSOUND_DEVICE SoundDevice;
     MMFUNCTION_TABLE FuncTable;
 
     ZeroMemory(&FuncTable, sizeof(MMFUNCTION_TABLE));
@@ -74,9 +162,9 @@
     FuncTable.GetCapabilities = GetSoundBlasterDeviceCapabilities;
 
     /* Nothing particularly special required... */
-    return ( AddSoundDevice(DeviceType, DevicePath, &FuncTable) == MMSYSERR_NOERROR );
-}
-
+    return ( ListSoundDevice(DeviceType, DevicePath, &SoundDevice)
+             == MMSYSERR_NOERROR );
+}
 
 APIENTRY LONG
 DriverProc(
@@ -266,6 +354,7 @@
     return 0;
 }
 #endif
+#endif
 
 BOOL WINAPI DllMain(
     HINSTANCE hinstDLL,

Modified: branches/silverblade-audio/dll/win32/sndblst/sndblst.def
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/dll/win32/sndblst/sndblst.def?rev=34595&r1=34594&r2=34595&view=diff
==============================================================================
--- branches/silverblade-audio/dll/win32/sndblst/sndblst.def [iso-8859-1] (original)
+++ branches/silverblade-audio/dll/win32/sndblst/sndblst.def [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -7,9 +7,9 @@
 LIBRARY sndblst.dll
 EXPORTS
 DriverProc at 20
-;widMessage at 20
+widMessage at 20
 wodMessage at 20
-;midMessage at 20
-;modMessage at 20
-;mxdMessage at 20
-;auxMessage at 20
+midMessage at 20
+modMessage at 20
+mxdMessage at 20
+auxMessage at 20

Modified: branches/silverblade-audio/dll/win32/sndblst/sndblst.rbuild
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/dll/win32/sndblst/sndblst.rbuild?rev=34595&r1=34594&r2=34595&view=diff
==============================================================================
--- branches/silverblade-audio/dll/win32/sndblst/sndblst.rbuild [iso-8859-1] (original)
+++ branches/silverblade-audio/dll/win32/sndblst/sndblst.rbuild [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -4,7 +4,7 @@
 	<importlibrary definition="sndblst.def" />
     <include base="ReactOS">include/reactos/libs/sound</include>
 	<include base="sndblst">.</include>
-	<!--define name="NDEBUG" /-->
+	<define name="DEBUG_NT4" />
     <library>mmebuddy</library>
 	<library>ntdll</library>
 	<library>kernel32</library>

Modified: branches/silverblade-audio/dll/win32/win32.rbuild
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/dll/win32/win32.rbuild?rev=34595&r1=34594&r2=34595&view=diff
==============================================================================
--- branches/silverblade-audio/dll/win32/win32.rbuild [iso-8859-1] (original)
+++ branches/silverblade-audio/dll/win32/win32.rbuild [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -133,9 +133,9 @@
 <directory name="mlang">
 	<xi:include href="mlang/mlang.rbuild" />
 </directory>
-<directory name="mmdrv">
+<!--directory name="mmdrv">
 	<xi:include href="mmdrv/mmdrv.rbuild" />
-</directory>
+</directory-->
 <directory name="mpr">
 	<xi:include href="mpr/mpr.rbuild" />
 </directory>

Modified: branches/silverblade-audio/include/ddk/ntddsnd.h
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/include/ddk/ntddsnd.h?rev=34595&r1=34594&r2=34595&view=diff
==============================================================================
--- branches/silverblade-audio/include/ddk/ntddsnd.h [iso-8859-1] (original)
+++ branches/silverblade-audio/include/ddk/ntddsnd.h [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -47,7 +47,7 @@
 #define MAX_SOUND_DEVICE_TYPE   MIXER_DEVICE_TYPE
 #define SOUND_DEVICE_TYPES      6
 
-#define VALID_SOUND_DEVICE_TYPE(x) \
+#define IS_VALID_SOUND_DEVICE_TYPE(x) \
     ( ( x >= MIN_SOUND_DEVICE_TYPE ) && ( x <= MAX_SOUND_DEVICE_TYPE ) )
 
 #define IS_WAVE_DEVICE_TYPE(x) \

Modified: branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h?rev=34595&r1=34594&r2=34595&view=diff
==============================================================================
--- branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h [iso-8859-1] (original)
+++ branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -22,90 +22,50 @@
     Hacky debug macro
 */
 
-#define POPUP(msg) \
-    MessageBoxA(0, msg, __FUNCTION__, MB_OK | MB_TASKMODAL)
-
-
-//#define NDEBUG
-#define NTRACE
-
-#ifdef ASSERT
-    #undef ASSERT
+#define POPUP(...) \
+    { \
+        WCHAR dbg_popup_msg[1024], dbg_popup_title[256]; \
+        wsprintf(dbg_popup_title, L"%hS(%d)", __FILE__, __LINE__); \
+        wsprintf(dbg_popup_msg, __VA_ARGS__); \
+        MessageBox(0, dbg_popup_msg, dbg_popup_title, MB_OK | MB_TASKMODAL); \
+    }
+
+#ifdef DEBUG_NT4
+    #define SND_ERR(...) \
+        { \
+            WCHAR dbg_popup_msg[1024]; \
+            wsprintf(dbg_popup_msg, __VA_ARGS__); \
+            OutputDebugString(dbg_popup_msg); \
+        }
+    #define SND_WARN(...) \
+        { \
+            WCHAR dbg_popup_msg[1024]; \
+            wsprintf(dbg_popup_msg, __VA_ARGS__); \
+            OutputDebugString(dbg_popup_msg); \
+        }
+    #define SND_TRACE(...) \
+        { \
+            WCHAR dbg_popup_msg[1024]; \
+            wsprintf(dbg_popup_msg, __VA_ARGS__); \
+            OutputDebugString(dbg_popup_msg); \
+        }
+
+    #define SND_ASSERT(condition) \
+        { \
+            if ( ! ( condition ) ) \
+            { \
+                SND_ERR(L"ASSERT FAILED: %wS\n", #condition); \
+            } \
+        }
+#else
+    /* TODO */
 #endif
 
-#ifndef NDEBUG
-
-/* HACK for testing */
-#include <stdio.h>
-
-#define TRACE_(...) \
-    { \
-        printf("  %s: ", __FUNCTION__); \
-        printf(__VA_ARGS__); \
-    }
-
-#define WARN_(...) \
-    { \
-        printf("o %s: ", __FUNCTION__); \
-        printf(__VA_ARGS__); \
-    }
-
-#define ERR_(...) \
-    { \
-        printf("X %s: ", __FUNCTION__); \
-        printf(__VA_ARGS__); \
-    }
-
-#define ASSERT(x) \
-    { \
-        if ( ! (x) ) \
-        { \
-            ERR_("ASSERT failed! %s\n", #x); \
-            exit(1); \
-        } \
-    }
-
-#ifndef NTRACE
-
-#define TRACE_ENTRY() \
-    TRACE_("entered function\n")
-
-#define TRACE_EXIT(retval) \
-    TRACE_("returning %d (0x%x)\n", (int)retval, (int)retval)
-
-#endif
-
-#else
-
-#define TRACE_(...) do { } while ( 0 )
-#define WARN_(...) do { } while ( 0 )
-#define ERR_(...) do { } while ( 0 )
-#define ASSERT(x) do { } while ( 0 )
-
-#define NTRACE
-
-#endif
-
-#ifdef NTRACE
-    #define TRACE_ENTRY() do { } while ( 0 )
-    #define TRACE_EXIT(retval) do { } while ( 0 )
-#endif
-
-
 /*
     Some memory allocation helper macros
 */
 
-#define AllocateMemory(amount) \
-    AllocateTaggedMemory(0x00000000, amount)
-
-#define FreeMemory(ptr) \
-    FreeTaggedMemory(0x00000000, ptr)
-
-#define AllocateTaggedMemoryFor(tag, thing) \
-    (thing*) AllocateTaggedMemory(tag, sizeof(thing))
-
-#define AllocateMemoryFor(thing) \
+#define AllocateStruct(thing) \
     (thing*) AllocateMemory(sizeof(thing))
 
 #define StringLengthToBytes(chartype, string_length) \
@@ -133,19 +93,219 @@
 
 
 /*
+    Convert a device type into a zero-based array index
+*/
+
+#define SOUND_DEVICE_TYPE_TO_INDEX(x) \
+    ( x - MIN_SOUND_DEVICE_TYPE )
+
+#define INDEX_TO_SOUND_DEVICE_TYPE(x) \
+    ( x + MIN_SOUND_DEVICE_TYPE )
+
+
+/*
     Validation
 */
+
+#define IsValidSoundDeviceType IS_VALID_SOUND_DEVICE_TYPE
 
 #define VALIDATE_MMSYS_PARAMETER(parameter_condition) \
     { \
         if ( ! (parameter_condition) ) \
         { \
-            ERR_("Parameter check: %s\n", #parameter_condition); \
-            TRACE_EXIT(MMSYSERR_INVALPARAM); \
+            SND_ERR(L"Parameter check: %s\n", #parameter_condition); \
             return MMSYSERR_INVALPARAM; \
         } \
     }
 
+
+/*
+    Types and Structures
+*/
+
+typedef UCHAR MMDEVICE_TYPE, *PMMDEVICE_TYPE;
+
+typedef struct _SOUND_DEVICE
+{
+} SOUND_DEVICE, *PSOUND_DEVICE;
+
+typedef struct _SOUND_DEVICE_INSTANCE
+{
+    HANDLE KernelDeviceHandle;
+} SOUND_DEVICE_INSTANCE, *PSOUND_DEVICE_INSTANCE;
+
+
+/*
+    reentrancy.c
+*/
+
+MMRESULT
+InitEntrypointMutexes();
+
+VOID
+CleanupEntrypointMutexes();
+
+VOID
+AcquireEntrypointMutex(
+    IN  MMDEVICE_TYPE DeviceType);
+
+VOID
+ReleaseEntrypointMutex(
+    IN  MMDEVICE_TYPE DeviceType);
+
+
+/*
+    devicelist.c
+*/
+
+ULONG
+GetSoundDeviceCount(
+    IN  MMDEVICE_TYPE DeviceType);
+
+BOOLEAN
+IsValidSoundDevice(
+    IN  PSOUND_DEVICE SoundDevice);
+
+MMRESULT
+ListSoundDevice(
+    IN  MMDEVICE_TYPE DeviceType,
+    IN  LPWSTR DevicePath,
+    OUT PSOUND_DEVICE* SoundDevice OPTIONAL);
+
+MMRESULT
+UnlistSoundDevice(
+    IN  MMDEVICE_TYPE DeviceType,
+    IN  PSOUND_DEVICE SoundDevice);
+
+MMRESULT
+UnlistSoundDevices(
+    IN  MMDEVICE_TYPE DeviceType);
+
+MMRESULT
+UnlistAllSoundDevices();
+
+MMRESULT
+GetSoundDevice(
+    IN  MMDEVICE_TYPE DeviceType,
+    IN  DWORD DeviceIndex,
+    OUT PSOUND_DEVICE* Device);
+
+
+/*
+    deviceinstance.c
+*/
+
+BOOLEAN
+IsValidSoundDeviceInstance(
+    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance);
+
+
+/*
+    nt4.c
+*/
+
+typedef BOOLEAN (*SOUND_DEVICE_DETECTED_PROC)(
+    UCHAR DeviceType,
+    PWSTR DevicePath);
+
+MMRESULT
+OpenSoundDriverParametersRegKey(
+    IN  LPWSTR ServiceName,
+    OUT PHKEY KeyHandle);
+
+MMRESULT
+OpenSoundDeviceRegKey(
+    IN  LPWSTR ServiceName,
+    IN  DWORD DeviceIndex,
+    OUT PHKEY KeyHandle);
+
+MMRESULT
+EnumerateNt4ServiceSoundDevices(
+    IN  LPWSTR ServiceName,
+    IN  MMDEVICE_TYPE DeviceType,
+    IN  SOUND_DEVICE_DETECTED_PROC SoundDeviceDetectedProc);
+
+MMRESULT
+DetectNt4SoundDevices(
+    IN  MMDEVICE_TYPE DeviceType,
+    IN  PWSTR BaseDeviceName,
+    IN  SOUND_DEVICE_DETECTED_PROC SoundDeviceDetectedProc);
+
+
+/*
+    utility.c
+*/
+
+PVOID
+AllocateMemory(
+    IN  UINT Size);
+
+VOID
+FreeMemory(
+    IN  PVOID Pointer);
+
+UINT
+GetMemoryAllocationCount();
+
+UINT
+GetDigitCount(
+    IN  UINT Number);
+
+MMRESULT
+Win32ErrorToMmResult(
+    IN  UINT ErrorCode);
+
+MMRESULT
+TranslateInternalMmResult(
+    IN  MMRESULT Result);
+
+
+/*
+    kernel.c
+*/
+
+#define QueryDevice(h, ctl, o, o_size, xfer, ovl) \
+    Win32ErrorToMmResult( \
+        DeviceIoControl(h, ctl, NULL, 0, o, o_size, xfer, ovl) != 0 \
+        ? ERROR_SUCCESS : GetLastError() \
+    )
+
+#define ControlDevice(h, ctl, i, i_size, xfer, ovl) \
+    Win32ErrorToMmResult( \
+        DeviceIoControl(h, ctl, i, i_size, NULL, 0, xfer, ovl) != 0 \
+        ? ERROR_SUCCESS : GetLastError() \
+    )
+
+#define QuerySoundDevice(sd, ctl, o, o_size, xfer) \
+    SoundDeviceIoControl(sd, ctl, NULL, 0, o, o_size, xfer)
+
+#define ControlSoundDevice(sd, ctl, i, i_size, xfer) \
+    SoundDeviceIoControl(sd, ctl, i, i_size, NULL, 0, xfer)
+
+MMRESULT
+OpenKernelSoundDeviceByName(
+    IN  PWSTR DeviceName,
+    IN  BOOLEAN ReadOnly,
+    OUT PHANDLE Handle);
+
+MMRESULT
+CloseKernelSoundDevice(
+    IN  HANDLE Handle);
+
+MMRESULT
+SoundDeviceIoControl(
+    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
+    IN  DWORD IoControlCode,
+    IN  LPVOID InBuffer,
+    IN  DWORD InBufferSize,
+    OUT LPVOID OutBuffer,
+    IN  DWORD OutBufferSize,
+    OUT LPDWORD BytesTransferred OPTIONAL);
+
+
+#if 0
+
+typedef UCHAR MMDEVICE_TYPE, *PMMDEVICE_TYPE;
 
 struct _SOUND_DEVICE;
 struct _SOUND_DEVICE_INSTANCE;
@@ -553,16 +713,19 @@
 TranslateInternalMmResult(MMRESULT Result);
 
 MMRESULT
-InitEntrypointMutex();
-
-VOID
-CleanupEntrypointMutex();
-
-VOID
-AcquireEntrypointMutex();
-
-VOID
-ReleaseEntrypointMutex();
+InitEntrypointMutexes();
+
+VOID
+CleanupEntrypointMutexes();
+
+VOID
+AcquireEntrypointMutex(
+    IN  MMDEVICE_TYPE DeviceType);
+
+VOID
+ReleaseEntrypointMutex(
+    IN  MMDEVICE_TYPE DeviceType);
+
 
 BOOLEAN
 InitMmeBuddyLib();
@@ -750,6 +913,6 @@
     PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
     DWORD Message,
     DWORD Parameter);
-
-
 #endif
+
+#endif

Added: branches/silverblade-audio/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c?rev=34595&view=auto
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c (added)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -1,0 +1,44 @@
+/*
+ * PROJECT:     ReactOS Sound System "MME Buddy" Library
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        lib/sound/mmebuddy/auxiliary/auxMessage.c
+ *
+ * PURPOSE:     Provides the auxMessage exported function, as required by
+ *              the MME API, for auxiliary device support.
+ *
+ * PROGRAMMERS: Andrew Greenwood (silverblade at reactos.org)
+*/
+
+#include <windows.h>
+#include <mmsystem.h>
+#include <mmddk.h>
+
+#include <ntddsnd.h>
+
+#include <mmebuddy.h>
+
+APIENTRY DWORD
+auxMessage(
+    DWORD DeviceId,
+    DWORD Message,
+    DWORD PrivateHandle,
+    DWORD Parameter1,
+    DWORD Parameter2)
+{
+    MMRESULT Result = MMSYSERR_NOERROR;
+
+    AcquireEntrypointMutex(AUX_DEVICE_TYPE);
+
+    switch ( Message )
+    {
+        case AUXDM_GETNUMDEVS :
+        {
+            Result = GetSoundDeviceCount(AUX_DEVICE_TYPE);
+            break;
+        }
+    }
+
+    ReleaseEntrypointMutex(AUX_DEVICE_TYPE);
+
+    return Result;
+}

Propchange: branches/silverblade-audio/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/silverblade-audio/lib/drivers/sound/mmebuddy/deviceinstance.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/deviceinstance.c?rev=34595&view=auto
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/deviceinstance.c (added)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/deviceinstance.c [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -1,0 +1,20 @@
+/*
+ * PROJECT:     ReactOS Sound System "MME Buddy" Library
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        lib/sound/mmebuddy/deviceinstance.c
+ *
+ * PURPOSE:     Manages instances of sound devices.
+ *
+ * PROGRAMMERS: Andrew Greenwood (silverblade at reactos.org)
+*/
+
+#include <windows.h>
+#include <mmebuddy.h>
+
+BOOLEAN
+IsValidSoundDeviceInstance(
+    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
+{
+    /* TODO */
+    return TRUE;
+}

Propchange: branches/silverblade-audio/lib/drivers/sound/mmebuddy/deviceinstance.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/silverblade-audio/lib/drivers/sound/mmebuddy/devicelist.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/devicelist.c?rev=34595&view=auto
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/devicelist.c (added)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/devicelist.c [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -1,0 +1,76 @@
+/*
+ * PROJECT:     ReactOS Sound System "MME Buddy" Library
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        lib/sound/mmebuddy/devicelist.c
+ *
+ * PURPOSE:     Manages lists of sound devices.
+ *
+ * PROGRAMMERS: Andrew Greenwood (silverblade at reactos.org)
+*/
+
+#include <windows.h>
+#include <ntddsnd.h>
+#include <mmebuddy.h>
+
+ULONG           SoundDeviceCounts[SOUND_DEVICE_TYPES];
+PSOUND_DEVICE   SoundDeviceLists[SOUND_DEVICE_TYPES];
+
+ULONG
+GetSoundDeviceCount(
+    IN  MMDEVICE_TYPE DeviceType)
+{
+    ULONG Index = SOUND_DEVICE_TYPE_TO_INDEX(DeviceType);
+
+    if ( ! IsValidSoundDeviceType(DeviceType) )
+    {
+        return 0;
+    }
+
+    return SoundDeviceCounts[Index];
+}
+
+BOOLEAN
+IsValidSoundDevice(
+    IN  PSOUND_DEVICE SoundDevice)
+{
+    return TRUE;
+}
+
+MMRESULT
+ListSoundDevice(
+    IN  MMDEVICE_TYPE DeviceType,
+    IN  LPWSTR DevicePath,
+    OUT PSOUND_DEVICE* SoundDevice)
+{
+    return MMSYSERR_NOTSUPPORTED;
+}
+
+MMRESULT
+UnlistSoundDevice(
+    IN  MMDEVICE_TYPE DeviceType,
+    IN  PSOUND_DEVICE SoundDevice)
+{
+    return MMSYSERR_NOTSUPPORTED;
+}
+
+MMRESULT
+UnlistSoundDevices(
+    IN  MMDEVICE_TYPE DeviceType)
+{
+    return MMSYSERR_NOTSUPPORTED;
+}
+
+MMRESULT
+UnlistAllSoundDevices()
+{
+    return MMSYSERR_NOTSUPPORTED;
+}
+
+MMRESULT
+GetSoundDevice(
+    IN  MMDEVICE_TYPE DeviceType,
+    IN  DWORD DeviceIndex,
+    OUT PSOUND_DEVICE* Device OPTIONAL)
+{
+    return MMSYSERR_NOTSUPPORTED;
+}

Propchange: branches/silverblade-audio/lib/drivers/sound/mmebuddy/devicelist.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/silverblade-audio/lib/drivers/sound/mmebuddy/kernel.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/kernel.c?rev=34595&view=auto
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/kernel.c (added)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/kernel.c [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -1,0 +1,116 @@
+/*
+ * PROJECT:     ReactOS Sound System "MME Buddy" Library
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        lib/sound/mmebuddy/kernel.c
+ *
+ * PURPOSE:     Routines assisting with device I/O between user-mode and
+ *              kernel-mode.
+ *
+ * PROGRAMMERS: Andrew Greenwood (silverblade at reactos.org)
+*/
+
+#include <windows.h>
+#include <mmsystem.h>
+#include <ntddsnd.h>
+#include <mmebuddy.h>
+
+MMRESULT
+OpenKernelSoundDeviceByName(
+    IN  PWSTR DeviceName,
+    IN  BOOLEAN ReadOnly,
+    OUT PHANDLE Handle)
+{
+    DWORD AccessRights;
+
+    VALIDATE_MMSYS_PARAMETER( DeviceName );
+    VALIDATE_MMSYS_PARAMETER( Handle );
+
+    AccessRights = ReadOnly ? GENERIC_READ : GENERIC_WRITE;
+
+    *Handle = CreateFile(DeviceName,
+                         AccessRights,
+                         FILE_SHARE_WRITE,  /* FIXME? Should be read also? */
+                         NULL,
+                         OPEN_EXISTING,
+                         ReadOnly ? 0 : FILE_FLAG_OVERLAPPED,
+                         NULL);
+
+    if ( *Handle == INVALID_HANDLE_VALUE )
+    {
+        return Win32ErrorToMmResult(GetLastError());
+    }
+
+    return MMSYSERR_NOERROR;
+}
+
+MMRESULT
+CloseKernelSoundDevice(
+    IN  HANDLE Handle)
+{
+    VALIDATE_MMSYS_PARAMETER( Handle );
+
+    CloseHandle(Handle);
+
+    return MMSYSERR_NOERROR;
+}
+
+MMRESULT
+SoundDeviceIoControl(
+    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
+    IN  DWORD IoControlCode,
+    IN  LPVOID InBuffer,
+    IN  DWORD InBufferSize,
+    OUT LPVOID OutBuffer,
+    IN  DWORD OutBufferSize,
+    OUT LPDWORD BytesTransferred OPTIONAL)
+{
+    OVERLAPPED Overlapped;
+    BOOLEAN IoResult;
+    DWORD Transferred;
+
+    VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
+
+    /* Overlapped I/O is done here - this is used for waiting for completion */
+    ZeroMemory(&Overlapped, sizeof(OVERLAPPED));
+    Overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+    if ( ! Overlapped.hEvent )
+        return Win32ErrorToMmResult(GetLastError());
+
+    /* Talk to the device */
+    IoResult = DeviceIoControl(SoundDeviceInstance->KernelDeviceHandle,
+                               IoControlCode,
+                               InBuffer,
+                               InBufferSize,
+                               OutBuffer,
+                               OutBufferSize,
+                               NULL,
+                               &Overlapped);
+
+    /* If failure occurs, make sure it's not just due to the overlapped I/O */
+    if ( ! IoResult )
+    {
+        if ( GetLastError() != ERROR_IO_PENDING )
+        {
+            CloseHandle(Overlapped.hEvent);
+            return Win32ErrorToMmResult(GetLastError());
+        }
+    }
+
+    /* Wait for the I/O to complete */
+    IoResult = GetOverlappedResult(SoundDeviceInstance->KernelDeviceHandle,
+                                   &Overlapped,
+                                   &Transferred,
+                                   TRUE);
+
+    /* Don't need this any more */
+    CloseHandle(Overlapped.hEvent);
+
+    if ( ! IoResult )
+        return Win32ErrorToMmResult(GetLastError());
+
+    if ( BytesTransferred )
+        *BytesTransferred = Transferred;
+
+    return MMSYSERR_NOERROR;
+}

Propchange: branches/silverblade-audio/lib/drivers/sound/mmebuddy/kernel.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/silverblade-audio/lib/drivers/sound/mmebuddy/midi/midMessage.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/midi/midMessage.c?rev=34595&view=auto
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/midi/midMessage.c (added)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/midi/midMessage.c [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -1,0 +1,44 @@
+/*
+ * PROJECT:     ReactOS Sound System "MME Buddy" Library
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        lib/sound/mmebuddy/midi/midMessage.c
+ *
+ * PURPOSE:     Provides the midMessage exported function, as required by
+ *              the MME API, for MIDI input device support.
+ *
+ * PROGRAMMERS: Andrew Greenwood (silverblade at reactos.org)
+*/
+
+#include <windows.h>
+#include <mmsystem.h>
+#include <mmddk.h>
+
+#include <ntddsnd.h>
+
+#include <mmebuddy.h>
+
+APIENTRY DWORD
+midMessage(
+    DWORD DeviceId,
+    DWORD Message,
+    DWORD PrivateHandle,
+    DWORD Parameter1,
+    DWORD Parameter2)
+{
+    MMRESULT Result = MMSYSERR_NOERROR;
+
+    AcquireEntrypointMutex(MIDI_IN_DEVICE_TYPE);
+
+    switch ( Message )
+    {
+        case MIDM_GETNUMDEVS :
+        {
+            Result = GetSoundDeviceCount(MIDI_IN_DEVICE_TYPE);
+            break;
+        }
+    }
+
+    ReleaseEntrypointMutex(MIDI_IN_DEVICE_TYPE);
+
+    return Result;
+}

Propchange: branches/silverblade-audio/lib/drivers/sound/mmebuddy/midi/midMessage.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/silverblade-audio/lib/drivers/sound/mmebuddy/midi/modMessage.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/midi/modMessage.c?rev=34595&view=auto
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/midi/modMessage.c (added)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/midi/modMessage.c [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -1,0 +1,44 @@
+/*
+ * PROJECT:     ReactOS Sound System "MME Buddy" Library
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        lib/sound/mmebuddy/midi/modMessage.c
+ *
+ * PURPOSE:     Provides the modMessage exported function, as required by
+ *              the MME API, for MIDI output device support.
+ *
+ * PROGRAMMERS: Andrew Greenwood (silverblade at reactos.org)
+*/
+
+#include <windows.h>
+#include <mmsystem.h>
+#include <mmddk.h>
+
+#include <ntddsnd.h>
+
+#include <mmebuddy.h>
+
+APIENTRY DWORD
+modMessage(
+    DWORD DeviceId,
+    DWORD Message,
+    DWORD PrivateHandle,
+    DWORD Parameter1,
+    DWORD Parameter2)
+{
+    MMRESULT Result = MMSYSERR_NOERROR;
+
+    AcquireEntrypointMutex(MIDI_OUT_DEVICE_TYPE);
+
+    switch ( Message )
+    {
+        case MODM_GETNUMDEVS :
+        {
+            Result = GetSoundDeviceCount(MIDI_OUT_DEVICE_TYPE);
+            break;
+        }
+    }
+
+    ReleaseEntrypointMutex(MIDI_OUT_DEVICE_TYPE);
+
+    return Result;
+}

Propchange: branches/silverblade-audio/lib/drivers/sound/mmebuddy/midi/modMessage.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/silverblade-audio/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c?rev=34595&view=auto
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c (added)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -1,0 +1,44 @@
+/*
+ * PROJECT:     ReactOS Sound System "MME Buddy" Library
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        lib/sound/mmebuddy/mixer/mxdMessage.c
+ *
+ * PURPOSE:     Provides the mxdMessage exported function, as required by
+ *              the MME API, for mixer device support.
+ *
+ * PROGRAMMERS: Andrew Greenwood (silverblade at reactos.org)
+*/
+
+#include <windows.h>
+#include <mmsystem.h>
+#include <mmddk.h>
+
+#include <ntddsnd.h>
+
+#include <mmebuddy.h>
+
+APIENTRY DWORD
+mxdMessage(
+    DWORD DeviceId,
+    DWORD Message,
+    DWORD PrivateHandle,
+    DWORD Parameter1,
+    DWORD Parameter2)
+{
+    MMRESULT Result = MMSYSERR_NOERROR;
+
+    AcquireEntrypointMutex(MIXER_DEVICE_TYPE);
+
+    switch ( Message )
+    {
+        case MXDM_GETNUMDEVS :
+        {
+            Result = GetSoundDeviceCount(MIXER_DEVICE_TYPE);
+            break;
+        }
+    }
+
+    ReleaseEntrypointMutex(MIXER_DEVICE_TYPE);
+
+    return Result;
+}

Propchange: branches/silverblade-audio/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/silverblade-audio/lib/drivers/sound/mmebuddy/mmebuddy.rbuild
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/mmebuddy.rbuild?rev=34595&view=auto
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/mmebuddy.rbuild (added)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/mmebuddy.rbuild [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -1,0 +1,26 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
+<module name="mmebuddy" type="staticlibrary" allowwarnings="false" unicode="yes">
+	<include base="ReactOS">include/reactos/libs/sound</include>
+	<define name="DEBUG_NT4">1</define>
+	<file>devicelist.c</file>
+	<file>deviceinstance.c</file>
+	<file>reentrancy.c</file>
+	<file>utility.c</file>
+	<file>nt4.c</file>
+	<file>kernel.c</file>
+	<directory name="wave">
+		<file>widMessage.c</file>
+		<file>wodMessage.c</file>
+	</directory>
+	<directory name="midi">
+		<file>midMessage.c</file>
+		<file>modMessage.c</file>
+	</directory>
+	<directory name="mixer">
+		<file>mxdMessage.c</file>
+	</directory>
+	<directory name="auxiliary">
+		<file>auxMessage.c</file>
+	</directory>
+</module>

Propchange: branches/silverblade-audio/lib/drivers/sound/mmebuddy/mmebuddy.rbuild
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/silverblade-audio/lib/drivers/sound/mmebuddy/mmebuddy.rbuild~
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/mmebuddy.rbuild%7E?rev=34595&view=auto
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/mmebuddy.rbuild~ (added)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/mmebuddy.rbuild~ [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -1,0 +1,25 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
+<module name="mmebuddy" type="staticlibrary" allowwarnings="false" unicode="yes">
+	<include base="ReactOS">include/reactos/libs/sound</include>
+	<define name="DEBUG_NT4">1</define>
+	<file>devicelist.c</file>
+	<file>reentrancy.c</file>
+	<file>utility.c</file>
+	<file>nt4.c</file>
+	<file>kernel.c</file>
+	<directory name="wave">
+		<file>widMessage.c</file>
+		<file>wodMessage.c</file>
+	</directory>
+	<directory name="midi">
+		<file>midMessage.c</file>
+		<file>modMessage.c</file>
+	</directory>
+	<directory name="mixer">
+		<file>mxdMessage.c</file>
+	</directory>
+	<directory name="auxiliary">
+		<file>auxMessage.c</file>
+	</directory>
+</module>

Added: branches/silverblade-audio/lib/drivers/sound/mmebuddy/nt4.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/nt4.c?rev=34595&view=auto
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/nt4.c (added)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/nt4.c [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -1,0 +1,311 @@
+/*
+ * PROJECT:     ReactOS Sound System "MME Buddy" Library
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        lib/sound/mmebuddy/nt4.c
+ *
+ * PURPOSE:     Assists in locating Windows NT4 compatible sound devices,
+ *              which mostly use the same device naming convention and/or
+ *              store their created device names within their service key
+ *              within the registry.
+ *
+ * PROGRAMMERS: Andrew Greenwood (silverblade at reactos.org)
+*/
+
+#include <windows.h>
+#include <mmsystem.h>
+#include <ntddsnd.h>
+
+#include <mmebuddy.h>
+
+/*
+    Open the parameters key of a sound driver.
+    NT4 only.
+*/
+MMRESULT
+OpenSoundDriverParametersRegKey(
+    IN  LPWSTR ServiceName,
+    OUT PHKEY KeyHandle)
+{
+    ULONG KeyLength;
+    PWCHAR ParametersKeyName;
+
+    VALIDATE_MMSYS_PARAMETER( ServiceName );
+    VALIDATE_MMSYS_PARAMETER( KeyHandle );
+
+    /* Work out how long the string will be */
+    KeyLength = wcslen(REG_SERVICES_KEY_NAME_U) + 1
+              + wcslen(ServiceName) + 1
+              + wcslen(REG_PARAMETERS_KEY_NAME_U);
+
+    /* Allocate memory for the string */
+    ParametersKeyName = AllocateWideString(KeyLength);
+
+    if ( ! ParametersKeyName )
+        return MMSYSERR_NOMEM;
+
+    /* Construct the registry path */
+    wsprintf(ParametersKeyName,
+             L"%s\\%s\\%s",
+             REG_SERVICES_KEY_NAME_U,
+             ServiceName,
+             REG_PARAMETERS_KEY_NAME_U);
+
+    /* Perform the open */
+    if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                      ParametersKeyName,
+                      0,
+                      KEY_READ,
+                      KeyHandle) != ERROR_SUCCESS )
+    {
+        /* Couldn't open the key */
+        FreeMemory(ParametersKeyName);
+        return MMSYSERR_ERROR;
+    }
+
+    FreeMemory(ParametersKeyName);
+
+    return MMSYSERR_NOERROR;
+}
+
+/*
+    Open one of the Device sub-keys belonging to the sound driver.
+    NT4 only.
+*/
+MMRESULT
+OpenSoundDeviceRegKey(
+    IN  LPWSTR ServiceName,
+    IN  DWORD DeviceIndex,
+    OUT PHKEY KeyHandle)
+{
+    DWORD PathLength;
+    PWCHAR RegPath;
+
+    VALIDATE_MMSYS_PARAMETER( ServiceName );
+    VALIDATE_MMSYS_PARAMETER( KeyHandle );
+
+    /*
+        Work out the space required to hold the path:
+
+        HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
+            sndblst\
+                Parameters\
+                    Device123\
+    */
+    PathLength = wcslen(REG_SERVICES_KEY_NAME_U) + 1
+               + wcslen(ServiceName) + 1
+               + wcslen(REG_PARAMETERS_KEY_NAME_U) + 1
+               + wcslen(REG_DEVICE_KEY_NAME_U)
+               + GetDigitCount(DeviceIndex);
+
+    /* Allocate storage for the string */
+    RegPath = AllocateWideString(PathLength);
+
+    if ( ! RegPath )
+    {
+        return MMSYSERR_NOMEM;
+    }
+
+    /* Write the path */
+    wsprintf(RegPath,
+             L"%ls\\%ls\\%ls\\%ls%d",
+             REG_SERVICES_KEY_NAME_U,
+             ServiceName,
+             REG_PARAMETERS_KEY_NAME_U,
+             REG_DEVICE_KEY_NAME_U,
+             DeviceIndex);
+
+    /* Perform the open */
+    if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                      RegPath,
+                      0,
+                      KEY_READ,
+                      KeyHandle) != ERROR_SUCCESS )
+    {
+        /* Couldn't open the key */
+        FreeMemory(RegPath);
+        return MMSYSERR_ERROR;
+    }
+
+    FreeMemory(RegPath);
+
+    return MMSYSERR_NOERROR;
+}
+
+/*
+    This is the "nice" way to discover audio devices in NT4 - go into the
+    service registry key and enumerate the Parameters\Device*\Devices
+    values. The value names represent the device name, whereas the data
+    assigned to them identifies the type of device.
+*/
+MMRESULT
+EnumerateNt4ServiceSoundDevices(
+    IN  LPWSTR ServiceName,
+    IN  MMDEVICE_TYPE DeviceType,
+    IN  SOUND_DEVICE_DETECTED_PROC SoundDeviceDetectedProc)
+{
+    HKEY Key;
+    DWORD KeyIndex = 0;
+
+    VALIDATE_MMSYS_PARAMETER( ServiceName );
+
+    /* Device type zero means "all" */
+    VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceType(DeviceType) ||
+                              DeviceType == 0 );
+
+    while ( OpenSoundDeviceRegKey(ServiceName, KeyIndex, &Key) == MMSYSERR_NOERROR )
+    {
+        HKEY DevicesKey;
+        DWORD ValueType = REG_NONE, ValueIndex = 0;
+        DWORD MaxNameLength = 0, ValueNameLength = 0;
+        PWSTR DevicePath = NULL, ValueName = NULL;
+        DWORD ValueDataLength = sizeof(DWORD);
+        DWORD ValueData;
+
+        if ( RegOpenKeyEx(Key,
+                          REG_DEVICES_KEY_NAME_U,
+                          0,
+                          KEY_READ,
+                          &DevicesKey) == ERROR_SUCCESS )
+        {
+            /* Find out how much memory is needed for the key name */
+            if ( RegQueryInfoKey(DevicesKey,
+                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                 &MaxNameLength,
+                                 NULL, NULL, NULL) != ERROR_SUCCESS )
+            {
+                RegCloseKey(DevicesKey);
+                RegCloseKey(Key);
+
+                return MMSYSERR_ERROR;
+            }
+
+            DevicePath = AllocateWideString(MaxNameLength +
+                                            strlen("\\\\.\\"));
+
+            /* Check that the memory allocation was successful */
+            if ( ! DevicePath )
+            {
+                /* There's no point in going further */
+                RegCloseKey(DevicesKey);
+                RegCloseKey(Key);
+
+                return MMSYSERR_NOMEM;
+            }
+
+            /* Insert the device path prefix */
+            wsprintf(DevicePath, L"\\\\.\\");
+
+            /* The offset of the string following this prefix */
+            ValueName = DevicePath + strlen("\\\\.\\");
+
+            /* Copy this so that it may be overwritten - include NULL */
+            ValueNameLength = MaxNameLength + sizeof(WCHAR);
+
+            while ( RegEnumValue(DevicesKey,
+                                 ValueIndex,
+                                 ValueName,
+                                 &ValueNameLength,
+                                 NULL,
+                                 &ValueType,
+                                 (LPBYTE) &ValueData,
+                                 &ValueDataLength) == ERROR_SUCCESS )
+            {
+                /* Device types are stored as DWORDs */
+                if ( ( ValueType == REG_DWORD ) &&
+                     ( ValueDataLength == sizeof(DWORD) ) )
+                {
+                    if ( ( DeviceType == 0 ) ||
+                         ( DeviceType == ValueData ) )
+                    {
+                        SoundDeviceDetectedProc(ValueData, DevicePath);
+                    }
+                }
+
+                /* Reset variables for the next iteration */
+                ValueNameLength = MaxNameLength + sizeof(WCHAR);
+                ZeroMemory(ValueName, (MaxNameLength+1)*sizeof(WCHAR));
+                /*ZeroWideString(ValueName);*/
+                ValueDataLength = sizeof(DWORD);
+                ValueData = 0;
+                ValueType = REG_NONE;
+
+                ++ ValueIndex;
+            }
+
+            FreeMemory(DevicePath);
+
+            RegCloseKey(DevicesKey);
+        }
+
+        ++ KeyIndex;
+
+        RegCloseKey(Key);
+    }
+
+    return MMSYSERR_NOERROR;
+}
+
+/*
+    Brute-force device detection, using a base device name (eg: \\.\WaveOut).
+
+    This will add the device number as a suffix to the end of the string and
+    attempt to open the device based on that name. On success, it will
+    increment the device number and repeat this process.
+
+    When it runs out of devices, it will give up.
+*/
+MMRESULT
+DetectNt4SoundDevices(
+    IN  MMDEVICE_TYPE DeviceType,
+    IN  PWSTR BaseDeviceName,
+    IN  SOUND_DEVICE_DETECTED_PROC SoundDeviceDetectedProc)
+{
+    ULONG DeviceNameLength = 0;
+    PWSTR DeviceName = NULL;
+    ULONG Index = 0, Count = 0;
+    HANDLE DeviceHandle;
+    BOOLEAN DoSearch = TRUE;
+
+    VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceType(DeviceType) );
+
+    DeviceNameLength = wcslen(BaseDeviceName);
+    /* Consider the length of the number */
+    DeviceNameLength += GetDigitCount(Index);
+
+    DeviceName = AllocateWideString(DeviceNameLength);
+
+    if ( ! DeviceName )
+    {
+        return MMSYSERR_NOMEM;
+    }
+
+    while ( DoSearch )
+    {
+        /* Nothing like a nice clean device name */
+        ZeroWideString(DeviceName);
+        wsprintf(DeviceName, L"%ls%d", BaseDeviceName, Index);
+
+        if ( OpenKernelSoundDeviceByName(DeviceName,
+                                         TRUE,
+                                         &DeviceHandle) == MMSYSERR_NOERROR )
+        {
+            /* Notify the callback function */
+            if ( SoundDeviceDetectedProc(DeviceType, DeviceName) )
+            {
+                ++ Count;
+            }
+
+            CloseHandle(DeviceHandle);
+
+            ++ Index;
+        }
+        else
+        {
+            DoSearch = FALSE;
+        }
+    }
+
+    FreeMemory(DeviceName);
+
+    return MMSYSERR_NOERROR;
+}

Propchange: branches/silverblade-audio/lib/drivers/sound/mmebuddy/nt4.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/silverblade-audio/lib/drivers/sound/mmebuddy/reentrancy.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/reentrancy.c?rev=34595&view=auto
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/reentrancy.c (added)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/reentrancy.c [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -1,0 +1,90 @@
+/*
+ * PROJECT:     ReactOS Sound System "MME Buddy" Library
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        lib/sound/mmebuddy/reentrancy.c
+ *
+ * PURPOSE:     Provides entry-point mutex guards.
+ *
+ * PROGRAMMERS: Andrew Greenwood (silverblade at reactos.org)
+*/
+
+#include <windows.h>
+#include <ntddk.h>
+#include <ntddsnd.h>
+#include <mmebuddy.h>
+
+HANDLE EntrypointMutexes[SOUND_DEVICE_TYPES];
+
+MMRESULT
+InitEntrypointMutexes()
+{
+    UCHAR i;
+    MMRESULT Result = MMSYSERR_NOERROR;
+
+    /* Blank all entries ni the table first */
+    for ( i = 0; i < SOUND_DEVICE_TYPES; ++ i )
+    {
+        EntrypointMutexes[i] = NULL;
+    }
+
+    /* Now create the mutexes */
+    for ( i = 0; i < SOUND_DEVICE_TYPES; ++ i )
+    {
+        EntrypointMutexes[i] = CreateMutex(NULL, FALSE, NULL);
+
+        if ( ! EntrypointMutexes[i] )
+        {
+            Result = Win32ErrorToMmResult(GetLastError());
+
+            /* Clean up any mutexes we successfully created */
+            CleanupEntrypointMutexes();
+            break;
+        }
+    }
+
+    return Result;
+}
+
+VOID
+CleanupEntrypointMutexes()
+{
+    UCHAR i;
+
+    /* Only clean up a mutex if it actually exists */
+    for ( i = 0; i < SOUND_DEVICE_TYPES; ++ i )
+    {
+        if ( EntrypointMutexes[i] )
+        {
+            CloseHandle(EntrypointMutexes[i]);
+            EntrypointMutexes[i] = NULL;
+        }
+    }
+}
+
+VOID
+AcquireEntrypointMutex(
+    IN  MMDEVICE_TYPE DeviceType)
+{
+    UCHAR i;
+
+    ASSERT( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) );
+    i = SOUND_DEVICE_TYPE_TO_INDEX(DeviceType);
+
+    ASSERT( EntrypointMutexes[i] );
+
+    WaitForSingleObject(EntrypointMutexes[i], INFINITE);
+}
+
+VOID
+ReleaseEntrypointMutex(
+    IN  MMDEVICE_TYPE DeviceType)
+{
+    UCHAR i;
+
+    ASSERT( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) );
+    i = SOUND_DEVICE_TYPE_TO_INDEX(DeviceType);
+
+    ASSERT( EntrypointMutexes[i] );
+
+    ReleaseMutex(EntrypointMutexes[i]);
+}

Propchange: branches/silverblade-audio/lib/drivers/sound/mmebuddy/reentrancy.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/silverblade-audio/lib/drivers/sound/mmebuddy/utility.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/utility.c?rev=34595&view=auto
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/utility.c (added)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/utility.c [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -1,0 +1,137 @@
+/*
+ * PROJECT:     ReactOS Sound System "MME Buddy" Library
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        lib/sound/mmebuddy/utility.c
+ *
+ * PURPOSE:     Provides utility functions used by the library.
+ *
+ * PROGRAMMERS: Andrew Greenwood (silverblade at reactos.org)
+*/
+
+#include <windows.h>
+#include <mmsystem.h>
+
+#include <mmebuddy.h>
+
+static HANDLE ProcessHeapHandle = NULL;
+static UINT   CurrentAllocations = 0;
+
+/*
+    Memory allocation helper
+*/
+PVOID
+AllocateMemory(
+    IN  UINT Size)
+{
+    PVOID Pointer = NULL;
+
+    if ( ! ProcessHeapHandle )
+        ProcessHeapHandle = GetProcessHeap();
+
+    Pointer = HeapAlloc(ProcessHeapHandle, HEAP_ZERO_MEMORY, Size);
+
+    if ( ! Pointer )
+        return NULL;
+
+    ++ CurrentAllocations;
+
+    return Pointer;
+}
+
+VOID
+FreeMemory(
+    IN  PVOID Pointer)
+{
+    SND_ASSERT( ProcessHeapHandle );
+    SND_ASSERT( Pointer );
+
+    HeapFree(ProcessHeapHandle, 0, Pointer);
+
+    -- CurrentAllocations;
+}
+
+UINT
+GetMemoryAllocationCount()
+{
+    return CurrentAllocations;
+}
+
+
+/*
+    Count the number of digits in a UINT
+*/
+UINT
+GetDigitCount(
+    IN  UINT Number)
+{
+    UINT Value = Number;
+    ULONG Digits = 1;
+
+    while ( Value > 9 )
+    {
+        Value /= 10;
+        ++ Digits;
+    }
+
+    return Digits;
+}
+
+/*
+    Translate a Win32 error code into an MMRESULT code.
+*/
+MMRESULT
+Win32ErrorToMmResult(
+    IN  UINT ErrorCode)
+{
+    switch ( ErrorCode )
+    {
+        case NO_ERROR :
+        case ERROR_IO_PENDING :
+            return MMSYSERR_NOERROR;
+
+        case ERROR_BUSY :
+            return MMSYSERR_ALLOCATED;
+
+        case ERROR_NOT_SUPPORTED :
+        case ERROR_INVALID_FUNCTION :
+            return MMSYSERR_NOTSUPPORTED;
+
+        case ERROR_NOT_ENOUGH_MEMORY :
+            return MMSYSERR_NOMEM;
+
+        case ERROR_ACCESS_DENIED :
+            return MMSYSERR_BADDEVICEID;
+
+        case ERROR_INSUFFICIENT_BUFFER :
+            return MMSYSERR_INVALPARAM;
+
+        default :
+            return MMSYSERR_ERROR;
+    }
+}
+
+/*
+    If a function invokes another function, this aids in translating the
+    result code so that it is applicable in the context of the original caller.
+    For example, specifying that an invalid parameter was passed probably does
+    not make much sense if the parameter wasn't passed by the original caller!
+
+    This could potentially highlight internal logic problems.
+
+    However, things like MMSYSERR_NOMEM make sense to return to the caller.
+*/
+MMRESULT
+TranslateInternalMmResult(
+    IN  MMRESULT Result)
+{
+    switch ( Result )
+    {
+        case MMSYSERR_INVALPARAM :
+        case MMSYSERR_INVALFLAG :
+        {
+            return MMSYSERR_ERROR;
+        }
+    }
+
+    return Result;
+}

Propchange: branches/silverblade-audio/lib/drivers/sound/mmebuddy/utility.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/widMessage.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/widMessage.c?rev=34595&view=auto
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/widMessage.c (added)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/widMessage.c [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -1,0 +1,44 @@
+/*
+ * PROJECT:     ReactOS Sound System "MME Buddy" Library
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        lib/sound/mmebuddy/wave/widMessage.c
+ *
+ * PURPOSE:     Provides the widMessage exported function, as required by
+ *              the MME API, for wave input device support.
+ *
+ * PROGRAMMERS: Andrew Greenwood (silverblade at reactos.org)
+*/
+
+#include <windows.h>
+#include <mmsystem.h>
+#include <mmddk.h>
+
+#include <ntddsnd.h>
+
+#include <mmebuddy.h>
+
+APIENTRY DWORD
+widMessage(
+    DWORD DeviceId,
+    DWORD Message,
+    DWORD PrivateHandle,
+    DWORD Parameter1,
+    DWORD Parameter2)
+{
+    MMRESULT Result = MMSYSERR_NOERROR;
+
+    AcquireEntrypointMutex(WAVE_IN_DEVICE_TYPE);
+
+    switch ( Message )
+    {
+        case WIDM_GETNUMDEVS :
+        {
+            Result = GetSoundDeviceCount(WAVE_IN_DEVICE_TYPE);
+            break;
+        }
+    }
+
+    ReleaseEntrypointMutex(WAVE_IN_DEVICE_TYPE);
+
+    return Result;
+}

Propchange: branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/widMessage.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wodMessage.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wodMessage.c?rev=34595&view=auto
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wodMessage.c (added)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wodMessage.c [iso-8859-1] Sat Jul 19 17:17:17 2008
@@ -1,0 +1,44 @@
+/*
+ * PROJECT:     ReactOS Sound System "MME Buddy" Library
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        lib/sound/mmebuddy/wave/wodMessage.c
+ *
+ * PURPOSE:     Provides the wodMessage exported function, as required by
+ *              the MME API, for wave output device support.
+ *
+ * PROGRAMMERS: Andrew Greenwood (silverblade at reactos.org)
+*/
+
+#include <windows.h>
+#include <mmsystem.h>
+#include <mmddk.h>
+
+#include <ntddsnd.h>
+
+#include <mmebuddy.h>
+
+APIENTRY DWORD
+wodMessage(
+    DWORD DeviceId,
+    DWORD Message,
+    DWORD PrivateHandle,
+    DWORD Parameter1,
+    DWORD Parameter2)
+{
+    MMRESULT Result = MMSYSERR_NOERROR;
+
+    AcquireEntrypointMutex(WAVE_OUT_DEVICE_TYPE);
+
+    switch ( Message )
+    {
+        case WODM_GETNUMDEVS :
+        {
+            Result = GetSoundDeviceCount(WAVE_OUT_DEVICE_TYPE);
+            break;
+        }
+    }
+
+    ReleaseEntrypointMutex(WAVE_OUT_DEVICE_TYPE);
+
+    return Result;
+}

Propchange: branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wodMessage.c
------------------------------------------------------------------------------
    svn:eol-style = native



More information about the Ros-diffs mailing list