Maarten Lankhorst : mmdevapi: Add code to enumerate NOTPRESENT devices.

Alexandre Julliard julliard at winehq.org
Mon Jan 18 10:58:57 CST 2010


Module: wine
Branch: master
Commit: abd9627d9228070db1f6671b90ac33d940d4f773
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=abd9627d9228070db1f6671b90ac33d940d4f773

Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date:   Sun Jan 17 13:38:31 2010 +0100

mmdevapi: Add code to enumerate NOTPRESENT devices.

---

 dlls/mmdevapi/devenum.c |   83 ++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 78 insertions(+), 5 deletions(-)

diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c
index 40e296e..a708573 100644
--- a/dlls/mmdevapi/devenum.c
+++ b/dlls/mmdevapi/devenum.c
@@ -24,6 +24,8 @@
 #define COBJMACROS
 #include "windef.h"
 #include "winbase.h"
+#include "winnls.h"
+#include "winreg.h"
 #include "wine/debug.h"
 
 #include "ole2.h"
@@ -33,6 +35,24 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi);
 
+static const WCHAR software_mmdevapi[] =
+    { 'S','o','f','t','w','a','r','e','\\',
+      'M','i','c','r','o','s','o','f','t','\\',
+      'W','i','n','d','o','w','s','\\',
+      'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+      'M','M','D','e','v','i','c','e','s','\\',
+      'A','u','d','i','o',0};
+static const WCHAR reg_render[] =
+    { 'R','e','n','d','e','r',0 };
+static const WCHAR reg_capture[] =
+    { 'C','a','p','t','u','r','e',0 };
+static const WCHAR reg_devicestate[] =
+    { 'D','e','v','i','c','e','S','t','a','t','e',0 };
+static const WCHAR reg_alname[] =
+    { 'A','L','N','a','m','e',0 };
+static const WCHAR reg_properties[] =
+    { 'P','r','o','p','e','r','t','i','e','s',0 };
+
 typedef struct MMDevEnumImpl
 {
     const IMMDeviceEnumeratorVtbl *lpVtbl;
@@ -41,27 +61,35 @@ typedef struct MMDevEnumImpl
 
 static MMDevEnumImpl *MMDevEnumerator;
 static const IMMDeviceEnumeratorVtbl MMDevEnumVtbl;
+static const IMMDeviceCollectionVtbl MMDevColVtbl;
 
 typedef struct MMDevColImpl
 {
     const IMMDeviceCollectionVtbl *lpVtbl;
     LONG ref;
-    MMDevEnumImpl *parent;
     EDataFlow flow;
     DWORD state;
 } MMDevColImpl;
-static const IMMDeviceCollectionVtbl MMDevColVtbl;
 
-static HRESULT MMDevCol_Create(IMMDeviceCollection **ppv, MMDevEnumImpl *parent, EDataFlow flow, DWORD state)
+/* Creates or updates the state of a device
+ * If GUID is null, a random guid will be assigned
+ * and the device will be created
+ */
+static void MMDevice_Create(WCHAR *name, GUID *id, EDataFlow flow, DWORD state)
+{
+    FIXME("stub\n");
+}
+
+static HRESULT MMDevCol_Create(IMMDeviceCollection **ppv, EDataFlow flow, DWORD state)
 {
     MMDevColImpl *This;
+
     This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
     *ppv = NULL;
     if (!This)
         return E_OUTOFMEMORY;
     This->lpVtbl = &MMDevColVtbl;
     This->ref = 1;
-    This->parent = parent;
     This->flow = flow;
     This->state = state;
     *ppv = (IMMDeviceCollection*)This;
@@ -143,6 +171,10 @@ HRESULT MMDevEnum_Create(REFIID riid, void **ppv)
 
     if (!This)
     {
+        DWORD i = 0;
+        HKEY root, cur, key_capture = NULL, key_render = NULL;
+        LONG ret;
+
         This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
         *ppv = NULL;
         if (!This)
@@ -150,6 +182,47 @@ HRESULT MMDevEnum_Create(REFIID riid, void **ppv)
         This->ref = 1;
         This->lpVtbl = &MMDevEnumVtbl;
         MMDevEnumerator = This;
+
+        ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, software_mmdevapi, 0, KEY_READ, &root);
+        if (ret == ERROR_SUCCESS)
+            ret = RegOpenKeyExW(root, reg_capture, 0, KEY_READ, &key_capture);
+        if (ret == ERROR_SUCCESS)
+            ret = RegOpenKeyExW(root, reg_render, 0, KEY_READ, &key_render);
+        cur = key_capture;
+        if (ret != ERROR_SUCCESS)
+        {
+            RegCloseKey(key_capture);
+            RegCloseKey(key_render);
+            TRACE("Couldn't open key: %u\n", ret);
+        }
+        else do {
+            WCHAR guidvalue[39];
+            WCHAR alname[128];
+            GUID guid;
+            DWORD len;
+
+            len = sizeof(guidvalue);
+            ret = RegEnumKeyExW(cur, i++, guidvalue, &len, NULL, NULL, NULL, NULL);
+            if (ret == ERROR_NO_MORE_ITEMS)
+            {
+                if (cur == key_capture)
+                {
+                    cur = key_render;
+                    i = 0;
+                    continue;
+                }
+                break;
+            }
+            if (ret != ERROR_SUCCESS)
+                continue;
+            len = sizeof(alname);
+            RegGetValueW(cur, guidvalue, reg_alname, RRF_RT_REG_SZ, NULL, alname, &len);
+            if (SUCCEEDED(CLSIDFromString(guidvalue, &guid)))
+                MMDevice_Create(alname, &guid,
+                                cur == key_capture ? eCapture : eRender,
+                                DEVICE_STATE_NOTPRESENT);
+        } while (1);
+        RegCloseKey(root);
     }
     return IUnknown_QueryInterface((IUnknown*)This, riid, ppv);
 }
@@ -206,7 +279,7 @@ static HRESULT WINAPI MMDevEnum_EnumAudioEndpoints(IMMDeviceEnumerator *iface, E
         return E_INVALIDARG;
     if (mask & ~DEVICE_STATEMASK_ALL)
         return E_INVALIDARG;
-    return MMDevCol_Create(devices, This, flow, mask);
+    return MMDevCol_Create(devices, flow, mask);
 }
 
 static HRESULT WINAPI MMDevEnum_GetDefaultAudioEndpoint(IMMDeviceEnumerator *iface, EDataFlow flow, ERole role, IMMDevice **device)




More information about the wine-cvs mailing list