Fixed GETDEVCAPS message handling (bad macros) and implemented some primitive memory leak detection.
Added: trunk/reactos/lib/wdmaud/callbacks.c
Modified: trunk/reactos/lib/wdmaud/devices.c
Added: trunk/reactos/lib/wdmaud/memtrack.c
Modified: trunk/reactos/lib/wdmaud/user.c
Modified: trunk/reactos/lib/wdmaud/wdmaud.def
Modified: trunk/reactos/lib/wdmaud/wdmaud.h
Modified: trunk/reactos/lib/wdmaud/wdmaud.xml

Added: trunk/reactos/lib/wdmaud/callbacks.c
--- trunk/reactos/lib/wdmaud/callbacks.c	2005-11-25 03:41:24 UTC (rev 19539)
+++ trunk/reactos/lib/wdmaud/callbacks.c	2005-11-25 03:50:49 UTC (rev 19540)
@@ -0,0 +1,86 @@
+/*
+ *
+ * COPYRIGHT:            See COPYING in the top level directory
+ * PROJECT:              ReactOS Multimedia
+ * FILE:                 lib/wdmaud/wdmaud.h
+ * PURPOSE:              WDM Audio Support - Callbacks
+ * PROGRAMMER:           Andrew Greenwood
+ * UPDATE HISTORY:
+ *                       Nov 24, 2005: Started
+ */
+
+#include <windows.h>
+#include "wdmaud.h"
+
+
+/*
+    CheckCallbacks
+
+    This appears to just be used by the mixer stuff.
+
+    If the global callback file mapping handle isn't set, return FALSE.
+
+    Check the first parameter. If the value is below that of the first
+    DWORD in the mapped view, return FALSE.
+
+    TODO: Finish analysis
+*/
+
+BOOL CheckCallbacks()
+{
+    return FALSE;
+}
+
+/*
+    CreateWdmaudCallbacks
+
+    The original appears to use a security descriptor... We won't bother
+    with that for now.
+
+    Create a file mapping with the name "Global\WDMAUD_Callbacks".
+    The current process is used as the file handle for the file mapping. The
+    file mapping attributes should be set to a length of 12 bytes, the
+    security descriptor we ignore and the handle doesn't need to be
+    inheritable.
+
+    The maximum size should be set to 1028 bytes, and the file view
+    protection should be set to PAGE_READWRITE.
+
+    The result of the file mapping creation is stored in the global callback
+    handle.
+
+    If the creation succeeded, try and map a view of the file, from offset 0
+    for 1028 bytes, with READ and WRITE access.
+
+    If this succeeds, close the created file mapping handle, and set the
+    global handle to the one returned by the file mapping function.
+*/
+
+BOOL CreateWdmaudCallbacks()
+{
+    return FALSE;
+}
+
+
+/*
+    GetWdmaudCallbacks
+
+    If the global callback handle is already set, do nothing.
+
+    Open the file mapping to "Global\WDMAUD_Callbacks" with READ and WRITE
+    access. The handle doesn't need to be inherited.
+
+    The handle is stored as the global callback handle.
+
+    If the file was opened successfully, map the view of 1028 bytes from
+    offset 0 with READ and WRITE access.
+
+    If this fails, close the global callback handle and set it to NULL.
+
+    ...and then return
+*/
+
+BOOL GetWdmaudCallbacks()
+{
+    return FALSE;
+}
Property changes on: trunk/reactos/lib/wdmaud/callbacks.c
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/reactos/lib/wdmaud/devices.c
--- trunk/reactos/lib/wdmaud/devices.c	2005-11-25 03:41:24 UTC (rev 19539)
+++ trunk/reactos/lib/wdmaud/devices.c	2005-11-25 03:50:49 UTC (rev 19540)
@@ -17,6 +17,7 @@
 
 const char WDMAUD_DEVICE_INFO_SIG[4] = "WADI";
 const char WDMAUD_DEVICE_STATE_SIG[4] = "WADS";
+const char WDMAUD_NULL_SIGNATURE[4] = {0,0,0,0};
 
 
 BOOL IsValidDevicePath(WCHAR* path)
@@ -102,6 +103,8 @@
     PWDMAUD_DEVICE_INFO device_data = 0;
     int path_size = 0;
 
+    DPRINT("Creating device data for device type %d\n", (int) device_type);
+
     if ( ! IsValidDevicePath(device_path) )
     {
         DPRINT1("No valid device interface given!\n");
@@ -110,7 +113,7 @@
 
     /* Take into account this is a unicode string... */
     path_size = (lstrlen(device_path) + 1) * sizeof(WCHAR);
-    DPRINT("Size of path is %d\n", (int) path_size);
+    /* DPRINT("Size of path is %d\n", (int) path_size); */
 
     heap = GetProcessHeap();
 
@@ -123,11 +126,15 @@
 
     DPRINT("Allocating %d bytes\n",
            path_size + sizeof(WDMAUD_DEVICE_INFO));
-
+/*
     device_data = (PWDMAUD_DEVICE_INFO) HeapAlloc(heap,
                                                   HEAP_ZERO_MEMORY,
                                                   path_size + sizeof(WDMAUD_DEVICE_INFO));
+*/
 
+    device_data = (PWDMAUD_DEVICE_INFO)
+        AllocMem(path_size + sizeof(WDMAUD_DEVICE_INFO));
+
     if ( ! device_data )
     {
         DPRINT1("Unable to allocate memory for device data (error %d)\n",
@@ -152,6 +159,19 @@
     }
 }
 
+/*
+    CloneDeviceData
+
+    This isn't all that great... Maybe some macros would be better:
+    BEGIN_CLONING_STRUCT(source, target)
+        CLONE_MEMBER(member)
+    END_CLONING_STRUCT()
+
+    The main problem is that sometimes we'll want to copy more than
+    the data presented here. I guess we could blindly copy EVERYTHING
+    but that'd be excessive.
+*/
+
 PWDMAUD_DEVICE_INFO CloneDeviceData(PWDMAUD_DEVICE_INFO original)
 {
     PWDMAUD_DEVICE_INFO clone = NULL;
@@ -181,8 +201,33 @@
 
 void DeleteDeviceData(PWDMAUD_DEVICE_INFO device_data)
 {
+    HANDLE heap;
+
     ASSERT( device_data );
-    /* TODO */
+
+    /* Erase the signature to prevent any possible future mishaps */
+    *device_data->signature = *WDMAUD_NULL_SIGNATURE;
+
+    heap = GetProcessHeap();
+
+    if ( ! heap )
+    {
+        DPRINT1("Couldn't get the process heap (error %d)\n",
+                (int) GetLastError());
+        goto exit;
+    }
+
+    FreeMem(device_data);
+    /*
+    {
+        DPRINT1("Couldn't free device data memory (error %d)\n",
+                (int) GetLastError());
+    }
+    */
+
+    exit :
+        /* We just return */
+        return;
 }
 
 MMRESULT ModifyDevicePresence(
@@ -198,11 +243,9 @@
     DPRINT("ModifyDevicePresence - %s a device\n",
            adding ? "adding" : "removing");
 
-    DPRINT("Topology path %S\n", device_path);
+    /* DPRINT("Topology path %S\n", device_path); */
+    DPRINT("Devtype %d\n", (int) device_type);
 
-    /* FIXME: DeviceType! */
-    /* TODO: Assert on device type? */
-
     ASSERT( IsValidDeviceType(device_type) );
     ASSERT( device_path );
 
@@ -215,8 +258,6 @@
         goto cleanup;
     }
 
-/*    device_data->type = device_type; */
-
     ioctl = adding ? IOCTL_WDMAUD_ADD_DEVICE : IOCTL_WDMAUD_REMOVE_DEVICE;
 
     kernel_result = CallKernelDevice(device_data,
@@ -268,7 +309,6 @@
 
     DPRINT("Getting num devs\n");
 
-    /*device_data->type = device_type;*/
     device_data->with_critical_section = FALSE;
 
     if ( CallKernelDevice(device_data,
@@ -294,14 +334,19 @@
 }
 
 /*
-    This is a bit messed up
+    GetDeviceCapabilities
+
+    This uses a different structure to the traditional documentation, because
+    we handle plug and play devices.
+
+    Much sleep was lost over implementing this.
 */
 
 MMRESULT GetDeviceCapabilities(
     CHAR device_type,
     DWORD device_id,
     WCHAR* device_path,
-    LPCOMMONCAPS caps
+    LPMDEVICECAPSEX caps
 )
 {
     PWDMAUD_DEVICE_INFO device = NULL;
@@ -309,39 +354,13 @@
 
     DPRINT("Device path %S\n", device_path);
 
-    /* Hmm - caps->wMid seems to be 0x54 (84) from XP's winmm.dll */
-    if (caps->wMid == 0)
+    /* Is this right? */
+    if (caps->cbSize == 0)
     {
-        return MMSYSERR_NOERROR;
-
-        DPRINT("caps->wMid == 0\n");
-
-        DPRINT("Manufacturer: 0x%x (%d)\n", caps->wMid, caps->wMid);
-        DPRINT("Product: 0x%x (%d)\n", caps->wPid, caps->wPid);
-        DPRINT("Device is: %S\n", caps->szPname);
-
-        if ( IsWaveOutDeviceType(device_type) )
-        {
-        LPWAVEOUTCAPS woc = (LPWAVEOUTCAPS) caps;
-        DPRINT("Formats: %d\n", (int) woc->dwFormats);
-        DPRINT("Channels: %d\n", woc->wChannels);
-        DPRINT("Reserved: %d\n", woc->wReserved1);
-        DPRINT("Support: %d\n", (int) woc->dwSupport);
-        }
-
-        return MMSYSERR_NOERROR;
+        DPRINT1("We appear to have been given an invalid parameter\n");
+        return MMSYSERR_INVALPARAM;
     }
 
-#if 0
-    int i;
-    for (i = 0; i < 64; i ++)
-    {
-        DPRINT("0x%x\n", *(((UCHAR*)caps) + i));
-    }
-
-    return MMSYSERR_NOERROR;
-#endif
-
     DPRINT("Going to have to query the kernel-mode part\n");
 
     device = CreateDeviceData(device_type, device_path);
@@ -356,23 +375,13 @@
     device->id = device_id;
     device->with_critical_section = FALSE;
 
-    /* ? */
-    DPRINT("Caps wMid is 0x%x\n", (int) caps->wMid);
-    DPRINT("Driver version is 0x%x\n", (int) caps->vDriverVersion);
+    *(LPWORD)caps->pCaps = (WORD) 0x43;
 
-    DPRINT("%S\n", (WCHAR*) caps->vDriverVersion);
-
-    LPWORD theword;
-    theword = (LPWORD) caps->vDriverVersion;
-    *theword = 0x43;
-    //caps->vDriverVersion=0x4300;
-
-
     DPRINT("Calling kernel device\n");
     result = CallKernelDevice(device,
                               IOCTL_WDMAUD_GET_CAPABILITIES,
-                              (DWORD)caps->wMid,
-                              (DWORD)caps->vDriverVersion);
+                              (DWORD)caps->cbSize,
+                              (DWORD)caps->pCaps);
 
     if ( result != MMSYSERR_NOERROR )
     {
@@ -380,11 +389,8 @@
         goto cleanup;
     }
 
-    
+    /* Return code will already be MMSYSERR_NOERROR by now */
 
-    /* What do we return? */
-    /*return MMSYSERR_NOERROR; */ /* already set by now */
-
     cleanup :
     {
         if ( device )
@@ -515,7 +521,7 @@
         DPRINT("You actually want me to open the device, huh?\n");
 
         /* Allocate memory for the "queue" critical section */
-        
+
         device->state->queue_critical_section =
             HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(CRITICAL_SECTION));
 
@@ -526,7 +532,7 @@
             result = MMSYSERR_NOMEM;
             goto cleanup;
         }
-        
+
         /* Initialize the critical section */
         InitializeCriticalSection(device->state->queue_critical_section);
 
@@ -537,7 +543,7 @@
         /* Reset state */
         device->state->open_descriptor = NULL;
         device->state->unknown_24 = 0;
-        
+
         device->state->is_running = FALSE;
         device->state->is_paused =
             device->type == WDMAUD_WAVE_IN ? TRUE : FALSE;
@@ -547,7 +553,7 @@
         DPRINT("All systems are go...\n");
 
         result = TryOpenDevice(device, open_details->lpFormat);
-        
+
         if ( result != MMSYSERR_NOERROR )
         {
             DPRINT1("Format not supported?\n");
@@ -585,7 +591,8 @@
     }
 
     /*
-        This cleanup may need checking for memory leakage :/
+        This cleanup may need checking for memory leakage. It's not very pretty
+        to look at, either...
     */
 
     cleanup :
@@ -601,7 +608,7 @@
                         DeleteCriticalSection(device->state->queue_critical_section);
                         HeapFree(heap, 0, device->state->queue_critical_section);
                     }
-                    
+
                     HeapFree(heap, 0, device->state);
                 }
 

Added: trunk/reactos/lib/wdmaud/memtrack.c
--- trunk/reactos/lib/wdmaud/memtrack.c	2005-11-25 03:41:24 UTC (rev 19539)
+++ trunk/reactos/lib/wdmaud/memtrack.c	2005-11-25 03:50:49 UTC (rev 19540)
@@ -0,0 +1,72 @@
+/*
+ *
+ * COPYRIGHT:            See COPYING in the top level directory
+ * PROJECT:              ReactOS Multimedia
+ * FILE:                 lib/wdmaud/memtrack.c
+ * PURPOSE:              WDM Audio Support - Memory Tracking
+ * PROGRAMMER:           Andrew Greenwood
+ * UPDATE HISTORY:
+ *                       Nov 18, 2005: Created
+ * 
+ */
+
+#include "wdmaud.h"
+
+static int alloc_count = 0;
+
+LPVOID AllocMem(DWORD size)
+{
+    HANDLE heap;
+    LPVOID pointer;
+
+    heap = GetProcessHeap();
+
+    if ( ! heap )
+    {
+        DPRINT1("SEVERE ERROR! Couldn't get process heap! (error %d)\n",
+                (int) GetLastError());
+        return NULL;
+    }
+
+    pointer = HeapAlloc(heap, HEAP_ZERO_MEMORY, size);
+
+    if ( pointer )
+        alloc_count ++;
+
+    ReportMem();
+
+    return pointer;
+}
+
+VOID FreeMem(LPVOID pointer)
+{
+    HANDLE heap;
+
+    if ( ! pointer )
+    {
+        DPRINT1("Trying to free a NULL pointer!\n");
+        return;
+    }
+
+    heap = GetProcessHeap();
+
+    if ( ! heap )
+    {
+        DPRINT1("SEVERE ERROR! Couldn't get process heap! (error %d)\n",
+                (int) GetLastError());
+        return;
+    }
+
+    if ( ! HeapFree(heap, 0, pointer) )
+        alloc_count --;
+
+    ReportMem();
+}
+
+VOID ReportMem()
+{
+    DPRINT("Memory blocks allocated: %d\n", (int) alloc_count);
+
+    if ( alloc_count < 0 )
+        DPRINT1("FREEMEM HAS BEEN CALLED TOO MANY TIMES!\n");
+}
Property changes on: trunk/reactos/lib/wdmaud/memtrack.c
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/reactos/lib/wdmaud/user.c
--- trunk/reactos/lib/wdmaud/user.c	2005-11-25 03:41:24 UTC (rev 19539)
+++ trunk/reactos/lib/wdmaud/user.c	2005-11-25 03:50:49 UTC (rev 19540)
@@ -47,23 +47,24 @@
         case DRV_LOAD :
             DPRINT("DRV_LOAD\n");
             /* We should initialize the device list */
-            return DRV_OK; // dont need to do any more
+            return TRUE; // dont need to do any more
 
         case DRV_FREE :
             /* We should stop all wave and MIDI playback */
             DPRINT("DRV_FREE\n");
-            return DRV_OK;
+            return TRUE;
 
 		/*
 			DRV_OPEN is sent when WINMM wishes to open the driver. Param1
 			can specify configuration information, but we don't need any.
 		*/
         case DRV_OPEN :
-            return DRV_OK;
+            DPRINT("DRV_OPEN\n");
+            return TRUE;
 
         case DRV_CLOSE :
             DPRINT("DRV_CLOSE\n");
-            return DRV_OK;
+            return TRUE;
 
 		/*
             Enabling this driver causes the kernel-mode portion of WDMAUD to
@@ -84,7 +85,7 @@
         case DRV_DISABLE :
             DPRINT("DRV_DISABLE\n");
             DisableKernelInterface();
-            return DRV_OK;
+            return TRUE;
 
         /*
             We don't actually support configuration or installation, so these
@@ -155,7 +156,7 @@
 	
         case WIDM_GETDEVCAPS :
             DPRINT("WIDM_GETDEVCAPS\n");
-            return GetWaveInCapabilities(id, (WCHAR*) p2, (LPCOMMONCAPS) p1);
+            return GetWaveInCapabilities(id, (WCHAR*) p2, (LPMDEVICECAPSEX) p1);
    };
 
 	return MMSYSERR_NOERROR;
@@ -185,7 +186,7 @@
 
 		case DRVM_EXIT :
             DPRINT("DRVM_EXIT\n");
-            return RemoveWaveInDevice((WCHAR*) p2); /* FIXME? */
+            return RemoveWaveOutDevice((WCHAR*) p2); /* FIXME? */
 
         /*
          *  WODM_GETNUMDEVS
@@ -203,7 +204,7 @@
          */
         case WODM_GETDEVCAPS :
 			DPRINT("WODM_GETDEVCAPS\n");
-			return GetWaveOutCapabilities(id, (WCHAR*) p2, (LPCOMMONCAPS) p1);
+			return GetWaveOutCapabilities(id, (WCHAR*) p2, (LPMDEVICECAPSEX) p1);
 
         /*
          *  WODM_OPEN
@@ -264,7 +265,7 @@
     
         case MIDM_GETDEVCAPS :
             DPRINT("MIDM_GETDEVCAPS\n");
-            return GetMidiInCapabilities(id, (WCHAR*) p2, (LPCOMMONCAPS) p1);
+            return GetMidiInCapabilities(id, (WCHAR*) p2, (LPMDEVICECAPSEX) p1);
 	};
 
     DPRINT("* NOT IMPLEMENTED *\n");
@@ -297,7 +298,7 @@
     
         case MODM_GETDEVCAPS :
             DPRINT("MODM_GETDEVCAPS\n");
-            return GetMidiOutCapabilities(id, (WCHAR*) p2, (LPCOMMONCAPS) p1);
+            return GetMidiOutCapabilities(id, (WCHAR*) p2, (LPMDEVICECAPSEX) p1);
 	};
 
     DPRINT("* NOT IMPLEMENTED *\n");
@@ -330,7 +331,7 @@
 
         case MXDM_GETDEVCAPS :
             DPRINT("MXDM_GETDEVCAPS\n");
-            return GetMixerCapabilities(id, (WCHAR*) p2, (LPCOMMONCAPS) p1);
+            return GetMixerCapabilities(id, (WCHAR*) p2, (LPMDEVICECAPSEX) p1);
 
         /* ... */
 	};
@@ -359,7 +360,7 @@
 
         case AUXDM_GETDEVCAPS :
             DPRINT("AUXDM_GETDEVCAPS\n");
-            return GetAuxCapabilities(id, (WCHAR*) p2, (LPCOMMONCAPS) p1);
+            return GetAuxCapabilities(id, (WCHAR*) p2, (LPMDEVICECAPSEX) p1);
 
         /* ... */
     };
@@ -379,6 +380,8 @@
 
     else if (Reason == DLL_PROCESS_DETACH)
     {
+        DPRINT("*** wdmaud.drv is being closed ***\n");
+        ReportMem();
     }
 
     return TRUE;

Modified: trunk/reactos/lib/wdmaud/wdmaud.def
--- trunk/reactos/lib/wdmaud/wdmaud.def	2005-11-25 03:41:24 UTC (rev 19539)
+++ trunk/reactos/lib/wdmaud/wdmaud.def	2005-11-25 03:50:49 UTC (rev 19540)
@@ -4,12 +4,23 @@
 ;
 ; ReactOS Operating System
 ;
+; Each of the "message" functions can be commented out to stop the
+; corresponding device type from being supported. This is mainly so we can
+; focus on debugging a particular device type.
+;
 LIBRARY wdmaud.drv
 EXPORTS
+; DriverProc is needed so the driver can startup and shutdown
 DriverProc@20
+; Wave input support
 ;widMessage@20
+; Wave output support
 wodMessage@20
+; Midi input support
 ;midMessage@20
+; Midi output support
 ;modMessage@20
+; Mixer support
 ;mxdMessage@20
+; Auxiliary device support
 ;auxMessage@20

Modified: trunk/reactos/lib/wdmaud/wdmaud.h
--- trunk/reactos/lib/wdmaud/wdmaud.h	2005-11-25 03:41:24 UTC (rev 19539)
+++ trunk/reactos/lib/wdmaud/wdmaud.h	2005-11-25 03:50:49 UTC (rev 19540)
@@ -31,49 +31,7 @@
 /* HACK! */
 #define DbgPrint printf
 
-/* TODO: Put elsewhere */
-#if 0
-typedef struct tagWAVEOUTCAPS2A {
-    WORD    wMid;                  /* manufacturer ID */
-    WORD    wPid;                  /* product ID */
-    MMVERSION vDriverVersion;      /* version of the driver */
-    CHAR    szPname[MAXPNAMELEN];  /* product name (NULL terminated string) */
-    DWORD   dwFormats;             /* formats supported */
-    WORD    wChannels;             /* number of sources supported */
-    WORD    wReserved1;            /* packing */
-    DWORD   dwSupport;             /* functionality supported by driver */
-    GUID    ManufacturerGuid;      /* for extensible MID mapping */
-    GUID    ProductGuid;           /* for extensible PID mapping */
-    GUID    NameGuid;              /* for name lookup in registry */
-} WAVEOUTCAPS2A, *PWAVEOUTCAPS2A, *NPWAVEOUTCAPS2A, *LPWAVEOUTCAPS2A;
-typedef struct tagWAVEOUTCAPS2W {
-    WORD    wMid;                  /* manufacturer ID */
-    WORD    wPid;                  /* product ID */
-    MMVERSION vDriverVersion;      /* version of the driver */
-    WCHAR   szPname[MAXPNAMELEN];  /* product name (NULL terminated string) */
-    DWORD   dwFormats;             /* formats supported */
-    WORD    wChannels;             /* number of sources supported */
-    WORD    wReserved1;            /* packing */
-    DWORD   dwSupport;             /* functionality supported by driver */
-    GUID    ManufacturerGuid;      /* for extensible MID mapping */
-    GUID    ProductGuid;           /* for extensible PID mapping */
-    GUID    NameGuid;              /* for name lookup in registry */
-} WAVEOUTCAPS2W, *PWAVEOUTCAPS2W, *NPWAVEOUTCAPS2W, *LPWAVEOUTCAPS2W;
-#ifdef UNICODE
-typedef WAVEOUTCAPS2W WAVEOUTCAPS2;
-typedef PWAVEOUTCAPS2W PWAVEOUTCAPS2;
-typedef NPWAVEOUTCAPS2W NPWAVEOUTCAPS2;
-typedef LPWAVEOUTCAPS2W LPWAVEOUTCAPS2;
-#else
-typedef WAVEOUTCAPS2A WAVEOUTCAPS2;
-typedef PWAVEOUTCAPS2A PWAVEOUTCAPS2;
-typedef NPWAVEOUTCAPS2A NPWAVEOUTCAPS2;
-typedef LPWAVEOUTCAPS2A LPWAVEOUTCAPS2;
-#endif // UNICODE
-#endif
 
-
-
 /*
     Handy macros
 */
@@ -82,6 +40,10 @@
     DPRINT("%s %s\n", message, success == MMSYSERR_NOERROR ? "succeeded" : "failed")
 
 
+
+#define GOBAL_CALLBACKS_PATH L"Global\\WDMAUD_Callbacks"
+
+
 /*
 	Private IOCTLs shared between wdmaud.sys and wdmaud.drv
     
@@ -201,19 +163,17 @@
     of a device type.
 */
 
+/*
+    This is used as a general-purpose structure to retrieve capabilities
+    from the driver.
+*/
 typedef struct
 {
-    WORD wMid;
-    WORD wPid;
-    MMVERSION vDriverVersion;
-    WCHAR szPname[MAXPNAMELEN];
-} COMMONCAPSW, *LPCOMMONCAPSW;
+    DWORD cbSize;
+    LPVOID pCaps;
+} MDEVICECAPSEX, *LPMDEVICECAPSEX;
 
-/* Unicode, anyone? */
-typedef COMMONCAPSW COMMONCAPS;
-typedef LPCOMMONCAPSW LPCOMMONCAPS;
-
-/* More abstraction */
+/* Abstraction */
 typedef LPVOID PWDMAUD_HEADER;
 
 /*
@@ -440,20 +400,20 @@
     CHAR device_type,
     DWORD device_id,
     WCHAR* device_path,
-    LPCOMMONCAPS caps);
+    LPMDEVICECAPSEX caps);
 
 #define GetWaveInCapabilities(id, device_path, caps) \
-        GetDeviceCapabilities(id, WDMAUD_WAVE_IN, device_path, caps);
+        GetDeviceCapabilities(WDMAUD_WAVE_IN, id, device_path, caps);
 #define GetWaveOutCapabilities(id, device_path, caps) \
-        GetDeviceCapabilities(id, WDMAUD_WAVE_OUT, device_path, caps);
+        GetDeviceCapabilities(WDMAUD_WAVE_OUT, id, device_path, caps);
 #define GetMidiInCapabilities(id, device_path, caps) \
-        GetDeviceCapabilities(id, WDMAUD_MIDI_IN, device_path, caps);
+        GetDeviceCapabilities(WDMAUD_MIDI_IN, id, device_path, caps);
 #define GetMidiOutCapabilities(id, device_path, caps) \
-        GetDeviceCapabilities(id, WDMAUD_MIDI_OUT, device_path, caps);
+        GetDeviceCapabilities(WDMAUD_MIDI_OUT, id, device_path, caps);
 #define GetMixerCapabilities(id, device_path, caps) \
-        GetDeviceCapabilities(id, WDMAUD_MIXER, device_path, caps);
+        GetDeviceCapabilities(WDMAUD_MIXER, id, device_path, caps);
 #define GetAuxCapabilities(id, device_path, caps) \
-        GetDeviceCapabilities(id, WDMAUD_AUX, device_path, caps);
+        GetDeviceCapabilities(WDMAUD_AUX, id, device_path, caps);
 
 MMRESULT OpenWaveDevice(
     CHAR device_type,
@@ -504,4 +464,15 @@
 
 /* MORE... */
 
+/*
+    DEBUGGING + RESOURCE TRACKING
+*/
+
+LPVOID AllocMem(DWORD size);
+VOID FreeMem(LPVOID pointer);
+VOID ReportMem();
+
+#define AutoAlloc(type) \
+    (type*) MemAlloc(sizeof(type));
+
 #endif

Modified: trunk/reactos/lib/wdmaud/wdmaud.xml
--- trunk/reactos/lib/wdmaud/wdmaud.xml	2005-11-25 03:41:24 UTC (rev 19539)
+++ trunk/reactos/lib/wdmaud/wdmaud.xml	2005-11-25 03:50:49 UTC (rev 19540)
@@ -16,5 +16,6 @@
 	<file>wavehdr.c</file>
 	<file>threads.c</file>
 	<file>helper.c</file>
+	<file>memtrack.c</file>
 	<file>wdmaud.rc</file>
 </module>