[DEVENUM] Sync with Wine Staging 4.18. CORE-16441
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 20 Oct 2019 17:56:05 +0000 (18:56 +0100)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 20 Oct 2019 17:56:05 +0000 (18:56 +0100)
dll/directx/wine/devenum/CMakeLists.txt
dll/directx/wine/devenum/createdevenum.c
dll/directx/wine/devenum/devenum_main.c
dll/directx/wine/devenum/devenum_private.h
dll/directx/wine/devenum/factory.c [deleted file]
dll/directx/wine/devenum/mediacatenum.c
dll/directx/wine/devenum/parsedisplayname.c
media/doc/README.WINE
sdk/include/reactos/wine/CMakeLists.txt
sdk/include/reactos/wine/fil_data.idl [moved from dll/directx/wine/devenum/fil_data.idl with 69% similarity]

index 6719217..d147a1b 100644 (file)
@@ -4,13 +4,11 @@ add_definitions(-D_WIN32_WINNT=0x600 -DWINVER=0x600)
 
 add_definitions(-D__WINESRC__)
 include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine)
-add_idl_headers(devenum_fil_data_header fil_data.idl)
 spec2def(devenum.dll devenum.spec)
 
 list(APPEND SOURCE
     createdevenum.c
     devenum_main.c
-    factory.c
     mediacatenum.c
     parsedisplayname.c
     precomp.h)
@@ -24,7 +22,7 @@ set_source_files_properties(devenum.rc PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT
 set_module_type(devenum win32dll UNICODE)
 target_link_libraries(devenum strmiids uuid wine)
 add_delay_importlibs(devenum msvfw32)
-add_importlibs(devenum advapi32 advapi32_vista ole32 oleaut32 winmm user32 avicap32 msacm32 dsound msvcrt kernel32 ntdll)
-add_dependencies(devenum devenum_fil_data_header)
+add_importlibs(devenum advapi32 advapi32_vista ole32 oleaut32 winmm user32 avicap32 msacm32 dsound msdmo msvcrt kernel32 ntdll)
+add_dependencies(devenum wineheaders)
 add_pch(devenum precomp.h SOURCE)
 add_cd_file(TARGET devenum DESTINATION reactos/system32 FOR all)
index 1f00050..be6a814 100644 (file)
 #include "dsound.h"
 
 #include "wine/debug.h"
-#include "wine/unicode.h"
 #include "wine/heap.h"
 #include "mmddk.h"
 
 #include "initguid.h"
-#include "fil_data.h"
+#include "wine/fil_data.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(devenum);
 
-extern HINSTANCE DEVENUM_hInstance;
-
 static const WCHAR wszFilterKeyName[] = {'F','i','l','t','e','r',0};
 static const WCHAR wszMeritName[] = {'M','e','r','i','t',0};
 static const WCHAR wszPins[] = {'P','i','n','s',0};
@@ -55,7 +52,6 @@ static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a',
 static const WCHAR wszFilterData[] = {'F','i','l','t','e','r','D','a','t','a',0};
 
 static ULONG WINAPI DEVENUM_ICreateDevEnum_AddRef(ICreateDevEnum * iface);
-static HRESULT register_codecs(void);
 static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory);
 
 /**********************************************************************
@@ -106,11 +102,16 @@ static ULONG WINAPI DEVENUM_ICreateDevEnum_Release(ICreateDevEnum * iface)
     return 1; /* non-heap based object */
 }
 
-static HRESULT register_codec(const CLSID *class, const WCHAR *name, IMoniker **ret)
+static HRESULT register_codec(const GUID *class, const WCHAR *name,
+        const GUID *clsid, const WCHAR *friendly_name, IPropertyBag **ret)
 {
     static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':','c','m',':',0};
+    WCHAR guidstr[CHARS_IN_GUID];
     IParseDisplayName *parser;
+    IPropertyBag *propbag;
+    IMoniker *mon;
     WCHAR *buffer;
+    VARIANT var;
     ULONG eaten;
     HRESULT hr;
 
@@ -118,22 +119,48 @@ static HRESULT register_codec(const CLSID *class, const WCHAR *name, IMoniker **
     if (FAILED(hr))
         return hr;
 
-    buffer = heap_alloc((strlenW(deviceW) + CHARS_IN_GUID + strlenW(name) + 1) * sizeof(WCHAR));
+    buffer = heap_alloc((lstrlenW(deviceW) + CHARS_IN_GUID + lstrlenW(name) + 1) * sizeof(WCHAR));
     if (!buffer)
     {
         IParseDisplayName_Release(parser);
         return E_OUTOFMEMORY;
     }
 
-    strcpyW(buffer, deviceW);
-    StringFromGUID2(class, buffer + strlenW(buffer), CHARS_IN_GUID);
-    strcatW(buffer, backslashW);
-    strcatW(buffer, name);
+    lstrcpyW(buffer, deviceW);
+    StringFromGUID2(class, buffer + lstrlenW(buffer), CHARS_IN_GUID);
+    lstrcatW(buffer, backslashW);
+    lstrcatW(buffer, name);
 
-    hr = IParseDisplayName_ParseDisplayName(parser, NULL, buffer, &eaten, ret);
+    IParseDisplayName_ParseDisplayName(parser, NULL, buffer, &eaten, &mon);
     IParseDisplayName_Release(parser);
     heap_free(buffer);
-    return hr;
+
+    IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&propbag);
+    IMoniker_Release(mon);
+
+    V_VT(&var) = VT_BSTR;
+    V_BSTR(&var) = SysAllocString(friendly_name);
+    hr = IPropertyBag_Write(propbag, wszFriendlyName, &var);
+    VariantClear(&var);
+    if (FAILED(hr))
+    {
+        IPropertyBag_Release(propbag);
+        return hr;
+    }
+
+    V_VT(&var) = VT_BSTR;
+    StringFromGUID2(clsid, guidstr, ARRAY_SIZE(guidstr));
+    V_BSTR(&var) = SysAllocString(guidstr);
+    hr = IPropertyBag_Write(propbag, clsidW, &var);
+    VariantClear(&var);
+    if (FAILED(hr))
+    {
+        IPropertyBag_Release(propbag);
+        return hr;
+    }
+
+    *ret = propbag;
+    return S_OK;
 }
 
 static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2 *rgPin)
@@ -157,7 +184,7 @@ static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2 *rgPin)
     {
         HKEY hkeyMajorType = NULL;
         WCHAR wszMajorTypeName[64];
-        DWORD cName = sizeof(wszMajorTypeName) / sizeof(WCHAR);
+        DWORD cName = ARRAY_SIZE(wszMajorTypeName);
         DWORD dwMinorTypes, i1;
 
         if (RegEnumKeyExW(hkeyTypes, i, wszMajorTypeName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
@@ -177,7 +204,7 @@ static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2 *rgPin)
             CLSID *clsMajorType = NULL, *clsMinorType = NULL;
             HRESULT hr;
 
-            cName = sizeof(wszMinorTypeName) / sizeof(WCHAR);
+            cName = ARRAY_SIZE(wszMinorTypeName);
             if (RegEnumKeyExW(hkeyMajorType, i1, wszMinorTypeName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
 
             clsMinorType = CoTaskMemAlloc(sizeof(CLSID));
@@ -263,7 +290,7 @@ static void DEVENUM_ReadPins(HKEY hkeyFilterClass, REGFILTER2 *rgf2)
     {
         HKEY hkeyPinKey = NULL;
         WCHAR wszPinName[MAX_PATH];
-        DWORD cName = sizeof(wszPinName) / sizeof(WCHAR);
+        DWORD cName = ARRAY_SIZE(wszPinName);
         REGFILTERPINS2 *rgPin = &rgPins[rgf2->u.s2.cPins2];
         DWORD value, size, Type;
         LONG lRet;
@@ -352,9 +379,9 @@ static void free_regfilter2(REGFILTER2 *rgf)
 
 static void write_filter_data(IPropertyBag *prop_bag, REGFILTER2 *rgf)
 {
+    BYTE *data = NULL, *array;
     IAMFilterData *fildata;
     SAFEARRAYBOUND sabound;
-    BYTE *data, *array;
     VARIANT var;
     ULONG size;
     HRESULT hr;
@@ -410,59 +437,53 @@ static void register_legacy_filters(void)
         for (i = 0; i < dwFilterSubkeys; i++)
         {
             WCHAR wszFilterSubkeyName[64];
-            DWORD cName = sizeof(wszFilterSubkeyName) / sizeof(WCHAR);
+            DWORD cName = ARRAY_SIZE(wszFilterSubkeyName);
             IPropertyBag *prop_bag = NULL;
             WCHAR wszRegKey[MAX_PATH];
             HKEY classkey = NULL;
-            IMoniker *mon = NULL;
-            VARIANT var;
             REGFILTER2 rgf2;
             DWORD Type, len;
+            GUID clsid;
 
             if (RegEnumKeyExW(hkeyFilter, i, wszFilterSubkeyName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
 
             TRACE("Registering %s\n", debugstr_w(wszFilterSubkeyName));
 
-            strcpyW(wszRegKey, clsidW);
-            strcatW(wszRegKey, wszFilterSubkeyName);
-
-            if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszRegKey, 0, KEY_READ, &classkey) != ERROR_SUCCESS)
+            hr = CLSIDFromString(wszFilterSubkeyName, &clsid);
+            if (FAILED(hr))
                 continue;
 
-            hr = register_codec(&CLSID_LegacyAmFilterCategory, wszFilterSubkeyName, &mon);
-            if (FAILED(hr)) goto cleanup;
+            lstrcpyW(wszRegKey, clsidW);
+            lstrcatW(wszRegKey, backslashW);
+            lstrcatW(wszRegKey, wszFilterSubkeyName);
 
-            hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
-            if (FAILED(hr)) goto cleanup;
+            if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszRegKey, 0, KEY_READ, &classkey) != ERROR_SUCCESS)
+                continue;
 
-            /* write friendly name */
             len = 0;
-            V_VT(&var) = VT_BSTR;
             if (!RegQueryValueExW(classkey, NULL, NULL, &Type, NULL, &len))
             {
                 WCHAR *friendlyname = heap_alloc(len);
                 if (!friendlyname)
-                    goto cleanup;
+                {
+                    RegCloseKey(classkey);
+                    continue;
+                }
                 RegQueryValueExW(classkey, NULL, NULL, &Type, (BYTE *)friendlyname, &len);
-                V_BSTR(&var) = SysAllocStringLen(friendlyname, len/sizeof(WCHAR));
+
+                hr = register_codec(&CLSID_LegacyAmFilterCategory, wszFilterSubkeyName,
+                        &clsid, friendlyname, &prop_bag);
+
                 heap_free(friendlyname);
             }
             else
-                V_BSTR(&var) = SysAllocString(wszFilterSubkeyName);
-
-            if (!V_BSTR(&var))
-                goto cleanup;
-            hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
-            if (FAILED(hr)) goto cleanup;
-            VariantClear(&var);
-
-            /* write clsid */
-            V_VT(&var) = VT_BSTR;
-            if (!(V_BSTR(&var) = SysAllocString(wszFilterSubkeyName)))
-                goto cleanup;
-            hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
-            if (FAILED(hr)) goto cleanup;
-            VariantClear(&var);
+                hr = register_codec(&CLSID_LegacyAmFilterCategory, wszFilterSubkeyName,
+                        &clsid, wszFilterSubkeyName, &prop_bag);
+            if (FAILED(hr))
+            {
+                RegCloseKey(classkey);
+                continue;
+            }
 
             /* write filter data */
             rgf2.dwMerit = MERIT_NORMAL;
@@ -474,11 +495,8 @@ static void register_legacy_filters(void)
 
             write_filter_data(prop_bag, &rgf2);
 
-cleanup:
-            if (prop_bag) IPropertyBag_Release(prop_bag);
-            if (mon) IMoniker_Release(mon);
+            IPropertyBag_Release(prop_bag);
             RegCloseKey(classkey);
-            VariantClear(&var);
             free_regfilter2(&rgf2);
         }
     }
@@ -496,50 +514,30 @@ static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR *desc, cons
     REGPINTYPES rgtypes = {0};
     REGFILTER2 rgf = {0};
     WCHAR clsid[CHARS_IN_GUID];
-    IMoniker *mon = NULL;
     VARIANT var;
     HRESULT hr;
 
     hr = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory);
-    if (FAILED(hr)) goto cleanup;
+    if (FAILED(hr))
+        return FALSE;
 
-    V_VT(&var) = VT_BSTR;
     if (guid)
     {
-        WCHAR *name = heap_alloc(sizeof(defaultW) + strlenW(desc) * sizeof(WCHAR));
+        WCHAR *name = heap_alloc(sizeof(defaultW) + lstrlenW(desc) * sizeof(WCHAR));
         if (!name)
-            goto cleanup;
-        strcpyW(name, directsoundW);
-        strcatW(name, desc);
+            return FALSE;
+        lstrcpyW(name, directsoundW);
+        lstrcatW(name, desc);
 
-        V_BSTR(&var) = SysAllocString(name);
+        hr = register_codec(&CLSID_AudioRendererCategory, name,
+                &CLSID_DSoundRender, name, &prop_bag);
         heap_free(name);
     }
     else
-        V_BSTR(&var) = SysAllocString(defaultW);
-
-    if (!V_BSTR(&var))
-        goto cleanup;
-
-    hr = register_codec(&CLSID_AudioRendererCategory, V_BSTR(&var), &mon);
-    if (FAILED(hr)) goto cleanup;
-
-    hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
-    if (FAILED(hr)) goto cleanup;
-
-    /* write friendly name */
-    hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
-    if (FAILED(hr)) goto cleanup;
-    VariantClear(&var);
-
-    /* write clsid */
-    V_VT(&var) = VT_BSTR;
-    StringFromGUID2(&CLSID_DSoundRender, clsid, CHARS_IN_GUID);
-    if (!(V_BSTR(&var) = SysAllocString(clsid)))
-        goto cleanup;
-    hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
-    if (FAILED(hr)) goto cleanup;
-    VariantClear(&var);
+        hr = register_codec(&CLSID_AudioRendererCategory, defaultW,
+                &CLSID_DSoundRender, defaultW, &prop_bag);
+    if (FAILED(hr))
+        return FALSE;
 
     /* write filter data */
     rgf.dwVersion = 2;
@@ -558,16 +556,11 @@ static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR *desc, cons
     /* write DSound guid */
     V_VT(&var) = VT_BSTR;
     StringFromGUID2(guid ? guid : &GUID_NULL, clsid, CHARS_IN_GUID);
-    if (!(V_BSTR(&var) = SysAllocString(clsid)))
-        goto cleanup;
-    hr = IPropertyBag_Write(prop_bag, dsguidW, &var);
-    if (FAILED(hr)) goto cleanup;
+    if ((V_BSTR(&var) = SysAllocString(clsid)))
+        hr = IPropertyBag_Write(prop_bag, dsguidW, &var);
 
-cleanup:
     VariantClear(&var);
-    if (prop_bag) IPropertyBag_Release(prop_bag);
-    if (mon) IMoniker_Release(mon);
-
+    IPropertyBag_Release(prop_bag);
     return TRUE;
 }
 
@@ -579,9 +572,8 @@ static void register_waveout_devices(void)
     REGFILTERPINS2 rgpins = {0};
     REGPINTYPES rgtypes = {0};
     REGFILTER2 rgf = {0};
-    WCHAR clsid[CHARS_IN_GUID];
-    IMoniker *mon = NULL;
     WAVEOUTCAPSW caps;
+    const WCHAR *name;
     int i, count;
     VARIANT var;
     HRESULT hr;
@@ -595,34 +587,12 @@ static void register_waveout_devices(void)
     {
         waveOutGetDevCapsW(i, &caps, sizeof(caps));
 
-        V_VT(&var) = VT_BSTR;
-
-        if (i == -1)    /* WAVE_MAPPER */
-            V_BSTR(&var) = SysAllocString(defaultW);
-        else
-            V_BSTR(&var) = SysAllocString(caps.szPname);
-        if (!(V_BSTR(&var)))
-            goto cleanup;
+        name = (i == -1) ? defaultW : caps.szPname;
 
-        hr = register_codec(&CLSID_AudioRendererCategory, V_BSTR(&var), &mon);
-        if (FAILED(hr)) goto cleanup;
-
-        hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
-        if (FAILED(hr)) goto cleanup;
-
-        /* write friendly name */
-        hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
-        if (FAILED(hr)) goto cleanup;
-        VariantClear(&var);
-
-        /* write clsid */
-        V_VT(&var) = VT_BSTR;
-        StringFromGUID2(&CLSID_AudioRender, clsid, CHARS_IN_GUID);
-        if (!(V_BSTR(&var) = SysAllocString(clsid)))
-            goto cleanup;
-        hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
-        if (FAILED(hr)) goto cleanup;
-        VariantClear(&var);
+        hr = register_codec(&CLSID_AudioRendererCategory, name,
+                &CLSID_AudioRender, name, &prop_bag);
+        if (FAILED(hr))
+            continue;
 
         /* write filter data */
         rgf.dwVersion = 2;
@@ -640,13 +610,10 @@ static void register_waveout_devices(void)
         /* write WaveOutId */
         V_VT(&var) = VT_I4;
         V_I4(&var) = i;
-        hr = IPropertyBag_Write(prop_bag, waveoutidW, &var);
-        if (FAILED(hr)) goto cleanup;
+        IPropertyBag_Write(prop_bag, waveoutidW, &var);
 
-cleanup:
         VariantClear(&var);
         if (prop_bag) IPropertyBag_Release(prop_bag);
-        if (mon) IMoniker_Release(mon);
     }
 }
 
@@ -655,8 +622,6 @@ static void register_wavein_devices(void)
     static const WCHAR waveinidW[] = {'W','a','v','e','I','n','I','d',0};
     IPropertyBag *prop_bag = NULL;
     REGFILTER2 rgf = {0};
-    WCHAR clsid[CHARS_IN_GUID];
-    IMoniker *mon = NULL;
     WAVEINCAPSW caps;
     int i, count;
     VARIANT var;
@@ -671,31 +636,10 @@ static void register_wavein_devices(void)
     {
         waveInGetDevCapsW(i, &caps, sizeof(caps));
 
-        V_VT(&var) = VT_BSTR;
-
-        V_BSTR(&var) = SysAllocString(caps.szPname);
-        if (!(V_BSTR(&var)))
-            goto cleanup;
-
-        hr = register_codec(&CLSID_AudioInputDeviceCategory, V_BSTR(&var), &mon);
-        if (FAILED(hr)) goto cleanup;
-
-        hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
-        if (FAILED(hr)) goto cleanup;
-
-        /* write friendly name */
-        hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
-        if (FAILED(hr)) goto cleanup;
-        VariantClear(&var);
-
-        /* write clsid */
-        V_VT(&var) = VT_BSTR;
-        StringFromGUID2(&CLSID_AudioRecord, clsid, CHARS_IN_GUID);
-        if (!(V_BSTR(&var) = SysAllocString(clsid)))
-            goto cleanup;
-        hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
-        if (FAILED(hr)) goto cleanup;
-        VariantClear(&var);
+        hr = register_codec(&CLSID_AudioInputDeviceCategory, caps.szPname,
+                &CLSID_AudioRecord, caps.szPname, &prop_bag);
+        if (FAILED(hr))
+            continue;
 
         /* write filter data */
         rgf.dwVersion = 2;
@@ -706,13 +650,10 @@ static void register_wavein_devices(void)
         /* write WaveInId */
         V_VT(&var) = VT_I4;
         V_I4(&var) = i;
-        hr = IPropertyBag_Write(prop_bag, waveinidW, &var);
-        if (FAILED(hr)) goto cleanup;
+        IPropertyBag_Write(prop_bag, waveinidW, &var);
 
-cleanup:
         VariantClear(&var);
-        if (prop_bag) IPropertyBag_Release(prop_bag);
-        if (mon) IMoniker_Release(mon);
+        IPropertyBag_Release(prop_bag);
     }
 }
 
@@ -724,9 +665,8 @@ static void register_midiout_devices(void)
     REGFILTERPINS2 rgpins = {0};
     REGPINTYPES rgtypes = {0};
     REGFILTER2 rgf = {0};
-    WCHAR clsid[CHARS_IN_GUID];
-    IMoniker *mon = NULL;
     MIDIOUTCAPSW caps;
+    const WCHAR *name;
     int i, count;
     VARIANT var;
     HRESULT hr;
@@ -740,34 +680,12 @@ static void register_midiout_devices(void)
     {
         midiOutGetDevCapsW(i, &caps, sizeof(caps));
 
-        V_VT(&var) = VT_BSTR;
-
-        if (i == -1)    /* MIDI_MAPPER */
-            V_BSTR(&var) = SysAllocString(defaultW);
-        else
-            V_BSTR(&var) = SysAllocString(caps.szPname);
-        if (!(V_BSTR(&var)))
-            goto cleanup;
+        name = (i == -1) ? defaultW : caps.szPname;
 
-        hr = register_codec(&CLSID_MidiRendererCategory, V_BSTR(&var), &mon);
-        if (FAILED(hr)) goto cleanup;
-
-        hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
-        if (FAILED(hr)) goto cleanup;
-
-        /* write friendly name */
-        hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
-        if (FAILED(hr)) goto cleanup;
-        VariantClear(&var);
-
-        /* write clsid */
-        V_VT(&var) = VT_BSTR;
-        StringFromGUID2(&CLSID_AVIMIDIRender, clsid, CHARS_IN_GUID);
-        if (!(V_BSTR(&var) = SysAllocString(clsid)))
-            goto cleanup;
-        hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
-        if (FAILED(hr)) goto cleanup;
-        VariantClear(&var);
+        hr = register_codec(&CLSID_MidiRendererCategory, name,
+                &CLSID_AVIMIDIRender, name, &prop_bag);
+        if (FAILED(hr))
+            continue;
 
         /* write filter data */
         rgf.dwVersion = 2;
@@ -785,13 +703,10 @@ static void register_midiout_devices(void)
         /* write MidiOutId */
         V_VT(&var) = VT_I4;
         V_I4(&var) = i;
-        hr = IPropertyBag_Write(prop_bag, midioutidW, &var);
-        if (FAILED(hr)) goto cleanup;
+        IPropertyBag_Write(prop_bag, midioutidW, &var);
 
-cleanup:
         VariantClear(&var);
-        if (prop_bag) IPropertyBag_Release(prop_bag);
-        if (mon) IMoniker_Release(mon);
+        IPropertyBag_Release(prop_bag);
     }
 }
 
@@ -802,8 +717,6 @@ static void register_vfw_codecs(void)
     IPropertyBag *prop_bag = NULL;
     REGPINTYPES rgtypes[2];
     REGFILTER2 rgf;
-    WCHAR clsid[CHARS_IN_GUID];
-    IMoniker *mon = NULL;
     GUID typeguid;
     ICINFO info;
     VARIANT var;
@@ -823,40 +736,10 @@ static void register_vfw_codecs(void)
         ICGetInfo(hic, &info, sizeof(info));
         ICClose(hic);
 
-        V_VT(&var) = VT_BSTR;
-
-        V_BSTR(&var) = SysAllocString(name);
-        if (!(V_BSTR(&var)))
-            goto cleanup;
-
-        hr = register_codec(&CLSID_VideoCompressorCategory, V_BSTR(&var), &mon);
-        if (FAILED(hr)) goto cleanup;
-
-        hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
-        if (FAILED(hr)) goto cleanup;
-
-        /* write WaveInId */
-        hr = IPropertyBag_Write(prop_bag, fcchandlerW, &var);
-        if (FAILED(hr)) goto cleanup;
-        VariantClear(&var);
-
-        /* write friendly name */
-        V_VT(&var) = VT_BSTR;
-        if (!(V_BSTR(&var) = SysAllocString(info.szDescription)))
-            goto cleanup;
-
-        hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
-        if (FAILED(hr)) goto cleanup;
-        VariantClear(&var);
-
-        /* write clsid */
-        V_VT(&var) = VT_BSTR;
-        StringFromGUID2(&CLSID_AVICo, clsid, CHARS_IN_GUID);
-        if (!(V_BSTR(&var) = SysAllocString(clsid)))
-            goto cleanup;
-        hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
-        if (FAILED(hr)) goto cleanup;
-        VariantClear(&var);
+        hr = register_codec(&CLSID_VideoCompressorCategory, name,
+                &CLSID_AVICo, info.szDescription, &prop_bag);
+        if (FAILED(hr))
+            continue;
 
         /* write filter data */
         rgf.dwVersion = 2;
@@ -878,10 +761,65 @@ static void register_vfw_codecs(void)
 
         write_filter_data(prop_bag, &rgf);
 
-cleanup:
+        /* write WaveInId */
+        V_VT(&var) = VT_BSTR;
+        V_BSTR(&var) = SysAllocString(name);
+        IPropertyBag_Write(prop_bag, fcchandlerW, &var);
+
         VariantClear(&var);
-        if (prop_bag) IPropertyBag_Release(prop_bag);
-        if (mon) IMoniker_Release(mon);
+        IPropertyBag_Release(prop_bag);
+    }
+}
+
+static void register_avicap_devices(void)
+{
+    static const WCHAR vfwindexW[] = {'V','F','W','I','n','d','e','x',0};
+    WCHAR name[] = {'v','i','d','e','o','0',0};
+    WCHAR friendlyname[32], version[32];
+    IPropertyBag *prop_bag = NULL;
+    REGFILTERPINS2 rgpins = {0};
+    REGPINTYPES rgtypes;
+    REGFILTER2 rgf;
+    VARIANT var;
+    HRESULT hr;
+    int i = 0;
+
+    hr = DEVENUM_CreateAMCategoryKey(&CLSID_VideoInputDeviceCategory);
+    if (FAILED(hr))
+        return;
+
+    for (i = 0; i < 10; ++i)
+    {
+        if (!capGetDriverDescriptionW(i, friendlyname, ARRAY_SIZE(friendlyname),
+                version, ARRAY_SIZE(version)))
+            continue;
+
+        name[5] = '0' + i;
+
+        hr = register_codec(&CLSID_VideoInputDeviceCategory, name,
+                &CLSID_VfwCapture, friendlyname, &prop_bag);
+        if (FAILED(hr))
+            continue;
+
+        rgf.dwVersion = 2;
+        rgf.dwMerit = MERIT_DO_NOT_USE;
+        rgf.u.s2.cPins2 = 1;
+        rgf.u.s2.rgPins2 = &rgpins;
+        rgpins.dwFlags = 0;
+        rgpins.nMediaTypes = 1;
+        rgpins.lpMediaType = &rgtypes;
+        rgtypes.clsMajorType = &MEDIATYPE_Video;
+        rgtypes.clsMinorType = &MEDIASUBTYPE_None;
+
+        write_filter_data(prop_bag, &rgf);
+
+        /* write VFWIndex */
+        V_VT(&var) = VT_I4;
+        V_I4(&var) = i;
+        IPropertyBag_Write(prop_bag, vfwindexW, &var);
+
+        VariantClear(&var);
+        IPropertyBag_Release(prop_bag);
     }
 }
 
@@ -889,30 +827,58 @@ cleanup:
  * DEVENUM_ICreateDevEnum_CreateClassEnumerator
  */
 static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator(
-    ICreateDevEnum * iface,
-    REFCLSID clsidDeviceClass,
-    IEnumMoniker **ppEnumMoniker,
-    DWORD dwFlags)
+    ICreateDevEnum *iface, REFCLSID class, IEnumMoniker **out, DWORD flags)
 {
+    WCHAR guidstr[CHARS_IN_GUID];
     HRESULT hr;
+    HKEY key;
 
-    TRACE("(%p)->(%s, %p, %x)\n", iface, debugstr_guid(clsidDeviceClass), ppEnumMoniker, dwFlags);
+    TRACE("iface %p, class %s, out %p, flags %#x.\n", iface, debugstr_guid(class), out, flags);
 
-    if (!ppEnumMoniker)
+    if (!out)
         return E_POINTER;
 
-    *ppEnumMoniker = NULL;
+    *out = NULL;
 
-    register_codecs();
-    register_legacy_filters();
-    hr = DirectSoundEnumerateW(&register_dsound_devices, NULL);
-    if (FAILED(hr)) return hr;
-    register_waveout_devices();
-    register_wavein_devices();
-    register_midiout_devices();
-    register_vfw_codecs();
+    if (!RegOpenKeyW(HKEY_CURRENT_USER, wszActiveMovieKey, &key))
+    {
+        StringFromGUID2(class, guidstr, ARRAY_SIZE(guidstr));
+        RegDeleteTreeW(key, guidstr);
+    }
 
-    return create_EnumMoniker(clsidDeviceClass, ppEnumMoniker);
+    if (IsEqualGUID(class, &CLSID_LegacyAmFilterCategory))
+        register_legacy_filters();
+    else if (IsEqualGUID(class, &CLSID_AudioRendererCategory))
+    {
+        hr = DirectSoundEnumerateW(&register_dsound_devices, NULL);
+        if (FAILED(hr)) return hr;
+        register_waveout_devices();
+        register_midiout_devices();
+    }
+    else if (IsEqualGUID(class, &CLSID_AudioInputDeviceCategory))
+        register_wavein_devices();
+    else if (IsEqualGUID(class, &CLSID_VideoCompressorCategory))
+        register_vfw_codecs();
+    else if (IsEqualGUID(class, &CLSID_VideoInputDeviceCategory))
+        register_avicap_devices();
+
+    if (SUCCEEDED(hr = create_EnumMoniker(class, out)))
+    {
+        IMoniker *mon;
+        hr = IEnumMoniker_Next(*out, 1, &mon, NULL);
+        if (hr == S_OK)
+        {
+            IMoniker_Release(mon);
+            IEnumMoniker_Reset(*out);
+        }
+        else
+        {
+            IEnumMoniker_Release(*out);
+            *out = NULL;
+        }
+    }
+
+    return hr;
 }
 
 /**********************************************************************
@@ -943,9 +909,9 @@ static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory)
     HRESULT res = S_OK;
     HKEY hkeyDummy = NULL;
 
-    strcpyW(wszRegKey, wszActiveMovieKey);
+    lstrcpyW(wszRegKey, wszActiveMovieKey);
 
-    if (!StringFromGUID2(clsidCategory, wszRegKey + strlenW(wszRegKey), sizeof(wszRegKey)/sizeof(wszRegKey[0]) - strlenW(wszRegKey)))
+    if (!StringFromGUID2(clsidCategory, wszRegKey + lstrlenW(wszRegKey), ARRAY_SIZE(wszRegKey) - lstrlenW(wszRegKey)))
         res = E_INVALIDARG;
 
     if (SUCCEEDED(res))
@@ -962,111 +928,3 @@ static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory)
 
     return res;
 }
-
-static HRESULT register_codecs(void)
-{
-    HRESULT res;
-    WCHAR class[CHARS_IN_GUID];
-    DWORD iDefaultDevice = -1;
-    IFilterMapper2 * pMapper = NULL;
-    REGFILTER2 rf2;
-    REGFILTERPINS2 rfp2;
-    HKEY basekey;
-
-    /* Since devices can change between session, for example because you just plugged in a webcam
-     * or switched from pulseaudio to alsa, delete all old devices first
-     */
-    RegOpenKeyW(HKEY_CURRENT_USER, wszActiveMovieKey, &basekey);
-    StringFromGUID2(&CLSID_LegacyAmFilterCategory, class, CHARS_IN_GUID);
-    RegDeleteTreeW(basekey, class);
-    StringFromGUID2(&CLSID_AudioRendererCategory, class, CHARS_IN_GUID);
-    RegDeleteTreeW(basekey, class);
-    StringFromGUID2(&CLSID_AudioInputDeviceCategory, class, CHARS_IN_GUID);
-    RegDeleteTreeW(basekey, class);
-    StringFromGUID2(&CLSID_VideoInputDeviceCategory, class, CHARS_IN_GUID);
-    RegDeleteTreeW(basekey, class);
-    StringFromGUID2(&CLSID_MidiRendererCategory, class, CHARS_IN_GUID);
-    RegDeleteTreeW(basekey, class);
-    StringFromGUID2(&CLSID_VideoCompressorCategory, class, CHARS_IN_GUID);
-    RegDeleteTreeW(basekey, class);
-    RegCloseKey(basekey);
-
-    rf2.dwVersion = 2;
-    rf2.dwMerit = MERIT_PREFERRED;
-    rf2.u.s2.cPins2 = 1;
-    rf2.u.s2.rgPins2 = &rfp2;
-    rfp2.cInstances = 1;
-    rfp2.nMediums = 0;
-    rfp2.lpMedium = NULL;
-    rfp2.clsPinCategory = &IID_NULL;
-
-    res = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC,
-                           &IID_IFilterMapper2, (void **) &pMapper);
-    /*
-     * Fill in info for devices
-     */
-    if (SUCCEEDED(res))
-    {
-        UINT i;
-        REGPINTYPES * pTypes;
-        IPropertyBag * pPropBag = NULL;
-
-        res = DEVENUM_CreateAMCategoryKey(&CLSID_VideoInputDeviceCategory);
-        if (SUCCEEDED(res))
-            for (i = 0; i < 10; i++)
-            {
-                WCHAR szDeviceName[32], szDeviceVersion[32], szDevicePath[10];
-
-                if (capGetDriverDescriptionW ((WORD) i,
-                                              szDeviceName, sizeof(szDeviceName)/sizeof(WCHAR),
-                                              szDeviceVersion, sizeof(szDeviceVersion)/sizeof(WCHAR)))
-                {
-                    IMoniker * pMoniker = NULL;
-                    WCHAR dprintf[] = { 'v','i','d','e','o','%','d',0 };
-                    snprintfW(szDevicePath, sizeof(szDevicePath)/sizeof(WCHAR), dprintf, i);
-                    /* The above code prevents 1 device with a different ID overwriting another */
-
-                    rfp2.nMediaTypes = 1;
-                    pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES));
-                    if (!pTypes) {
-                        IFilterMapper2_Release(pMapper);
-                        return E_OUTOFMEMORY;
-                    }
-
-                    pTypes[0].clsMajorType = &MEDIATYPE_Video;
-                    pTypes[0].clsMinorType = &MEDIASUBTYPE_None;
-
-                    rfp2.lpMediaType = pTypes;
-
-                    res = IFilterMapper2_RegisterFilter(pMapper,
-                                                        &CLSID_VfwCapture,
-                                                        szDeviceName,
-                                                        &pMoniker,
-                                                        &CLSID_VideoInputDeviceCategory,
-                                                        szDevicePath,
-                                                        &rf2);
-
-                    if (pMoniker) {
-                       OLECHAR wszVfwIndex[] = { 'V','F','W','I','n','d','e','x',0 };
-                       VARIANT var;
-                       V_VT(&var) = VT_I4;
-                       V_I4(&var) = i;
-                       res = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID)&pPropBag);
-                       if (SUCCEEDED(res)) {
-                           res = IPropertyBag_Write(pPropBag, wszVfwIndex, &var);
-                           IPropertyBag_Release(pPropBag);
-                       }
-                       IMoniker_Release(pMoniker);
-                    }
-
-                    if (i == iDefaultDevice) FIXME("Default device\n");
-                    CoTaskMemFree(pTypes);
-                }
-            }
-    }
-
-    if (pMapper)
-        IFilterMapper2_Release(pMapper);
-
-    return res;
-}
index 5596358..3f60c29 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *     exported dll functions for devenum.dll
+ * Device Enumeration
  *
  * Copyright (C) 2002 John K. Hohm
  * Copyright (C) 2002 Robert Shearman
 WINE_DEFAULT_DEBUG_CHANNEL(devenum);
 
 DECLSPEC_HIDDEN LONG dll_refs;
-DECLSPEC_HIDDEN HINSTANCE DEVENUM_hInstance;
-
-typedef struct
-{
-    REFCLSID clsid;
-    LPCWSTR friendly_name;
-    BOOL instance;
-} register_info;
+static HINSTANCE devenum_instance;
 
 #ifdef __REACTOS__
 static void DEVENUM_RegisterQuartz(void);
 #endif
 
-/***********************************************************************
- *             Global string constant definitions
- */
-const WCHAR clsid_keyname[6] = { 'C', 'L', 'S', 'I', 'D', 0 };
-
 /***********************************************************************
  *             DllEntryPoint
  */
@@ -53,29 +41,101 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
 
     switch(fdwReason) {
     case DLL_PROCESS_ATTACH:
-        DEVENUM_hInstance = hinstDLL;
+        devenum_instance = hinstDLL;
         DisableThreadLibraryCalls(hinstDLL);
        break;
     }
     return TRUE;
 }
 
+struct class_factory
+{
+    IClassFactory IClassFactory_iface;
+    IUnknown *obj;
+};
+
+static inline struct class_factory *impl_from_IClassFactory( IClassFactory *iface )
+{
+    return CONTAINING_RECORD( iface, struct class_factory, IClassFactory_iface );
+}
+
+static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID iid, void **obj)
+{
+    TRACE("(%p, %s, %p)\n", iface, debugstr_guid(iid), obj);
+
+    if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory))
+    {
+        IClassFactory_AddRef(iface);
+        *obj = iface;
+        return S_OK;
+    }
+
+    *obj = NULL;
+    WARN("no interface for %s\n", debugstr_guid(iid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
+{
+    DEVENUM_LockModule();
+    return 2;
+}
+
+static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
+{
+    DEVENUM_UnlockModule();
+    return 1;
+}
+
+static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface,
+    IUnknown *outer, REFIID iid, void **obj)
+{
+    struct class_factory *This = impl_from_IClassFactory( iface );
+
+    TRACE("(%p, %s, %p)\n", outer, debugstr_guid(iid), obj);
+
+    if (!obj) return E_POINTER;
+
+    if (outer) return CLASS_E_NOAGGREGATION;
+
+    return IUnknown_QueryInterface(This->obj, iid, obj);
+}
+
+static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL lock)
+{
+    if (lock)
+        DEVENUM_LockModule();
+    else
+        DEVENUM_UnlockModule();
+    return S_OK;
+}
+
+static const IClassFactoryVtbl ClassFactory_vtbl = {
+    ClassFactory_QueryInterface,
+    ClassFactory_AddRef,
+    ClassFactory_Release,
+    ClassFactory_CreateInstance,
+    ClassFactory_LockServer
+};
+
+static struct class_factory create_devenum_cf = { { &ClassFactory_vtbl }, (IUnknown *)&DEVENUM_CreateDevEnum };
+static struct class_factory device_moniker_cf = { { &ClassFactory_vtbl }, (IUnknown *)&DEVENUM_ParseDisplayName };
+
 /***********************************************************************
  *             DllGetClassObject (DEVENUM.@)
  */
-HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
+HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **obj)
 {
-    TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
+    TRACE("(%s, %s, %p)\n", debugstr_guid(clsid), debugstr_guid(iid), obj);
 
-    *ppv = NULL;
+    *obj = NULL;
 
-    /* FIXME: we should really have two class factories.
-     * Oh well - works just fine as it is */
-    if (IsEqualGUID(rclsid, &CLSID_SystemDeviceEnum) ||
-        IsEqualGUID(rclsid, &CLSID_CDeviceMoniker))
-        return IClassFactory_QueryInterface(&DEVENUM_ClassFactory.IClassFactory_iface, iid, ppv);
+    if (IsEqualGUID(clsid, &CLSID_SystemDeviceEnum))
+        return IClassFactory_QueryInterface(&create_devenum_cf.IClassFactory_iface, iid, obj);
+    else if (IsEqualGUID(clsid, &CLSID_CDeviceMoniker))
+        return IClassFactory_QueryInterface(&device_moniker_cf.IClassFactory_iface, iid, obj);
 
-    FIXME("CLSID: %s, IID: %s\n", debugstr_guid(rclsid), debugstr_guid(iid));
+    FIXME("class %s not available\n", debugstr_guid(clsid));
     return CLASS_E_CLASSNOTAVAILABLE;
 }
 
@@ -98,7 +158,7 @@ HRESULT WINAPI DllRegisterServer(void)
 
     TRACE("\n");
 
-    res = __wine_register_resources( DEVENUM_hInstance );
+    res = __wine_register_resources( devenum_instance );
     if (FAILED(res))
         return res;
 
@@ -151,7 +211,7 @@ HRESULT WINAPI DllRegisterServer(void)
 HRESULT WINAPI DllUnregisterServer(void)
 {
     FIXME("stub!\n");
-    return __wine_unregister_resources( DEVENUM_hInstance );
+    return __wine_unregister_resources( devenum_instance );
 }
 
 #ifdef __REACTOS__
index 005f0b5..61287ef 100644 (file)
 #include "olectl.h"
 #include "uuids.h"
 
-#ifndef RC_INVOKED
-#include "wine/unicode.h"
-#endif
-
 /**********************************************************************
  * Dll lifetime tracking declaration for devenum.dll
  */
@@ -53,19 +49,11 @@ extern LONG dll_refs DECLSPEC_HIDDEN;
 static inline void DEVENUM_LockModule(void) { InterlockedIncrement(&dll_refs); }
 static inline void DEVENUM_UnlockModule(void) { InterlockedDecrement(&dll_refs); }
 
-
-/**********************************************************************
- * ClassFactory declaration for devenum.dll
- */
-typedef struct
-{
-    IClassFactory IClassFactory_iface;
-} ClassFactoryImpl;
-
 enum device_type
 {
     DEVICE_FILTER,
     DEVICE_CODEC,
+    DEVICE_DMO,
 };
 
 typedef struct
@@ -75,13 +63,16 @@ typedef struct
     CLSID class;
     BOOL has_class;
     enum device_type type;
-    WCHAR *name;
+    union
+    {
+        WCHAR *name;    /* for filters and codecs */
+        CLSID clsid;    /* for DMOs */
+    };
 } MediaCatMoniker;
 
 MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct(void) DECLSPEC_HIDDEN;
 HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **enum_mon) DECLSPEC_HIDDEN;
 
-extern ClassFactoryImpl DEVENUM_ClassFactory DECLSPEC_HIDDEN;
 extern ICreateDevEnum DEVENUM_CreateDevEnum DECLSPEC_HIDDEN;
 extern IParseDisplayName DEVENUM_ParseDisplayName DECLSPEC_HIDDEN;
 
@@ -90,12 +81,13 @@ extern IParseDisplayName DEVENUM_ParseDisplayName DECLSPEC_HIDDEN;
  */
 
 static const WCHAR backslashW[] = {'\\',0};
-static const WCHAR clsidW[] = {'C','L','S','I','D','\\',0};
+static const WCHAR clsidW[] = {'C','L','S','I','D',0};
 static const WCHAR instanceW[] = {'\\','I','n','s','t','a','n','c','e',0};
 static const WCHAR wszActiveMovieKey[] = {'S','o','f','t','w','a','r','e','\\',
                                           'M','i','c','r','o','s','o','f','t','\\',
                                           'A','c','t','i','v','e','M','o','v','i','e','\\',
                                           'd','e','v','e','n','u','m','\\',0};
 static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':',0};
-
-extern const WCHAR clsid_keyname[6] DECLSPEC_HIDDEN;
+static const WCHAR dmoW[] = {'d','m','o',':',0};
+static const WCHAR swW[] = {'s','w',':',0};
+static const WCHAR cmW[] = {'c','m',':',0};
diff --git a/dll/directx/wine/devenum/factory.c b/dll/directx/wine/devenum/factory.c
deleted file mode 100644 (file)
index c808fa5..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *     ClassFactory implementation for DEVENUM.dll
- *
- * Copyright (C) 2002 John K. Hohm
- * Copyright (C) 2002 Robert Shearman
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "devenum_private.h"
-
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(devenum);
-
-/**********************************************************************
- * DEVENUM_IClassFactory_QueryInterface (also IUnknown)
- */
-static HRESULT WINAPI DEVENUM_IClassFactory_QueryInterface(IClassFactory *iface, REFIID riid,
-    void **ppvObj)
-{
-    TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObj);
-
-    if (ppvObj == NULL) return E_POINTER;
-
-    if (IsEqualGUID(riid, &IID_IUnknown) ||
-       IsEqualGUID(riid, &IID_IClassFactory))
-    {
-        *ppvObj = iface;
-       IClassFactory_AddRef(iface);
-       return S_OK;
-    }
-    else if (IsEqualGUID(riid, &IID_IParseDisplayName))
-    {
-        return IClassFactory_CreateInstance(iface, NULL, riid, ppvObj);
-    }
-
-    FIXME("- no interface IID: %s\n", debugstr_guid(riid));
-    return E_NOINTERFACE;
-}
-
-/**********************************************************************
- * DEVENUM_IClassFactory_AddRef (also IUnknown)
- */
-static ULONG WINAPI DEVENUM_IClassFactory_AddRef(IClassFactory *iface)
-{
-    TRACE("\n");
-
-    DEVENUM_LockModule();
-
-    return 2; /* non-heap based object */
-}
-
-/**********************************************************************
- * DEVENUM_IClassFactory_Release (also IUnknown)
- */
-static ULONG WINAPI DEVENUM_IClassFactory_Release(IClassFactory *iface)
-{
-    TRACE("\n");
-
-    DEVENUM_UnlockModule();
-
-    return 1; /* non-heap based object */
-}
-
-/**********************************************************************
- * DEVENUM_IClassFactory_CreateInstance
- */
-static HRESULT WINAPI DEVENUM_IClassFactory_CreateInstance(IClassFactory *iface,
-        IUnknown *pUnkOuter, REFIID riid, void **ppvObj)
-{
-    TRACE("(%p)->(%p, %s, %p)\n", iface, pUnkOuter, debugstr_guid(riid), ppvObj);
-
-    if (ppvObj == NULL) return E_POINTER;
-
-    /* Don't support aggregation (Windows doesn't) */
-    if (pUnkOuter != NULL) return CLASS_E_NOAGGREGATION;
-
-    if (IsEqualGUID(&IID_ICreateDevEnum, riid))
-    {
-        *ppvObj = &DEVENUM_CreateDevEnum;
-        return S_OK;
-    }
-    if (IsEqualGUID(&IID_IParseDisplayName, riid))
-    {
-        *ppvObj = &DEVENUM_ParseDisplayName;
-        return S_OK;
-    }
-
-    return CLASS_E_CLASSNOTAVAILABLE;
-}
-
-/**********************************************************************
- * DEVENUM_IClassFactory_LockServer
- */
-static HRESULT WINAPI DEVENUM_IClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
-{
-    TRACE("\n");
-
-    if (fLock)
-        DEVENUM_LockModule();
-    else
-        DEVENUM_UnlockModule();
-    return S_OK;
-}
-
-/**********************************************************************
- * IClassFactory_Vtbl
- */
-static const IClassFactoryVtbl IClassFactory_Vtbl =
-{
-    DEVENUM_IClassFactory_QueryInterface,
-    DEVENUM_IClassFactory_AddRef,
-    DEVENUM_IClassFactory_Release,
-    DEVENUM_IClassFactory_CreateInstance,
-    DEVENUM_IClassFactory_LockServer
-};
-
-/**********************************************************************
- * static ClassFactory instance
- */
-ClassFactoryImpl DEVENUM_ClassFactory = { { &IClassFactory_Vtbl } };
index a76c7be..e728be3 100644 (file)
@@ -25,6 +25,7 @@
 #include "devenum_private.h"
 #include "oleauto.h"
 #include "ocidl.h"
+#include "dmoreg.h"
 
 #include "wine/debug.h"
 
@@ -35,6 +36,7 @@ typedef struct
     IEnumMoniker IEnumMoniker_iface;
     CLSID class;
     LONG ref;
+    IEnumDMO *dmo_enum;
     HKEY sw_key;
     DWORD sw_index;
     HKEY cm_key;
@@ -46,7 +48,11 @@ typedef struct
     IPropertyBag IPropertyBag_iface;
     LONG ref;
     enum device_type type;
-    WCHAR path[MAX_PATH];
+    union
+    {
+        WCHAR path[MAX_PATH];   /* for filters and codecs */
+        CLSID clsid;            /* for DMOs */
+    };
 } RegPropBagImpl;
 
 
@@ -114,12 +120,14 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Read(
     VARIANT* pVar,
     IErrorLog* pErrorLog)
 {
+    static const WCHAR FriendlyNameW[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
     LPVOID pData = NULL;
     DWORD received;
     DWORD type = 0;
     RegPropBagImpl *This = impl_from_IPropertyBag(iface);
     HRESULT res = S_OK;
     LONG reswin32 = ERROR_SUCCESS;
+    WCHAR name[80];
     HKEY hkey;
 
     TRACE("(%p)->(%s, %p, %p)\n", This, debugstr_w(pszPropName), pVar, pErrorLog);
@@ -127,6 +135,21 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Read(
     if (!pszPropName || !pVar)
         return E_POINTER;
 
+    if (This->type == DEVICE_DMO)
+    {
+        if (!lstrcmpW(pszPropName, FriendlyNameW))
+        {
+            res = DMOGetName(&This->clsid, name);
+            if (SUCCEEDED(res))
+            {
+                V_VT(pVar) = VT_BSTR;
+                V_BSTR(pVar) = SysAllocString(name);
+            }
+            return res;
+        }
+        return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
+    }
+
     if (This->type == DEVICE_FILTER)
         reswin32 = RegOpenKeyW(HKEY_CLASSES_ROOT, This->path, &hkey);
     else if (This->type == DEVICE_CODEC)
@@ -246,6 +269,9 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Write(
 
     TRACE("(%p)->(%s, %p)\n", This, debugstr_w(pszPropName), pVar);
 
+    if (This->type == DEVICE_DMO)
+        return E_ACCESSDENIED;
+
     switch (V_VT(pVar))
     {
     case VT_BSTR:
@@ -316,18 +342,30 @@ static HRESULT create_PropertyBag(MediaCatMoniker *mon, IPropertyBag **ppBag)
     rpb->ref = 1;
     rpb->type = mon->type;
 
-    if (rpb->type == DEVICE_FILTER)
-        strcpyW(rpb->path, clsidW);
+    if (rpb->type == DEVICE_DMO)
+        rpb->clsid = mon->clsid;
+    else if (rpb->type == DEVICE_FILTER)
+    {
+        lstrcpyW(rpb->path, clsidW);
+        lstrcatW(rpb->path, backslashW);
+        if (mon->has_class)
+        {
+            StringFromGUID2(&mon->class, rpb->path + lstrlenW(rpb->path), CHARS_IN_GUID);
+            lstrcatW(rpb->path, instanceW);
+            lstrcatW(rpb->path, backslashW);
+        }
+        lstrcatW(rpb->path, mon->name);
+    }
     else if (rpb->type == DEVICE_CODEC)
-        strcpyW(rpb->path, wszActiveMovieKey);
-    if (mon->has_class)
     {
-        StringFromGUID2(&mon->class, rpb->path + strlenW(rpb->path), CHARS_IN_GUID);
-        if (rpb->type == DEVICE_FILTER)
-            strcatW(rpb->path, instanceW);
-        strcatW(rpb->path, backslashW);
+        lstrcpyW(rpb->path, wszActiveMovieKey);
+        if (mon->has_class)
+        {
+            StringFromGUID2(&mon->class, rpb->path + lstrlenW(rpb->path), CHARS_IN_GUID);
+            lstrcatW(rpb->path, backslashW);
+        }
+        lstrcatW(rpb->path, mon->name);
     }
-    strcatW(rpb->path, mon->name);
 
     *ppBag = &rpb->IPropertyBag_iface;
     DEVENUM_LockModule();
@@ -459,7 +497,7 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_BindToObject(IMoniker *iface, IBi
             if (SUCCEEDED(res))
             {
                 V_VT(&var) = VT_LPWSTR;
-                res = IPropertyBag_Read(pProp, clsid_keyname, &var, NULL);
+                res = IPropertyBag_Read(pProp, clsidW, &var, NULL);
             }
             if (SUCCEEDED(res))
             {
@@ -658,8 +696,6 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_RelativePathTo(IMoniker *iface, I
 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
         IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
 {
-    static const WCHAR swW[] = {'s','w',':',0};
-    static const WCHAR cmW[] = {'c','m',':',0};
     MediaCatMoniker *This = impl_from_IMoniker(iface);
     WCHAR *buffer;
 
@@ -667,23 +703,36 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetDisplayName(IMoniker *iface, I
 
     *ppszDisplayName = NULL;
 
-    buffer = CoTaskMemAlloc((strlenW(deviceW) + 4 + (This->has_class ? CHARS_IN_GUID : 0)
-                            + strlenW(This->name) + 1) * sizeof(WCHAR));
-    if (!buffer)
-        return E_OUTOFMEMORY;
+    if (This->type == DEVICE_DMO)
+    {
+        buffer = CoTaskMemAlloc((lstrlenW(deviceW) + lstrlenW(dmoW)
+                                 + 2 * CHARS_IN_GUID + 1) * sizeof(WCHAR));
+        if (!buffer) return E_OUTOFMEMORY;
+
+        lstrcpyW(buffer, deviceW);
+        lstrcatW(buffer, dmoW);
+        StringFromGUID2(&This->clsid, buffer + lstrlenW(buffer), CHARS_IN_GUID);
+        StringFromGUID2(&This->class, buffer + lstrlenW(buffer), CHARS_IN_GUID);
+    }
+    else
+    {
+        buffer = CoTaskMemAlloc((lstrlenW(deviceW) + 3 + (This->has_class ? CHARS_IN_GUID : 0)
+                                 + lstrlenW(This->name) + 1) * sizeof(WCHAR));
+        if (!buffer) return E_OUTOFMEMORY;
 
-    strcpyW(buffer, deviceW);
-    if (This->type == DEVICE_FILTER)
-        strcatW(buffer, swW);
-    else if (This->type == DEVICE_CODEC)
-        strcatW(buffer, cmW);
+        lstrcpyW(buffer, deviceW);
+        if (This->type == DEVICE_FILTER)
+            lstrcatW(buffer, swW);
+        else if (This->type == DEVICE_CODEC)
+            lstrcatW(buffer, cmW);
 
-    if (This->has_class)
-    {
-        StringFromGUID2(&This->class, buffer + strlenW(buffer), CHARS_IN_GUID);
-        strcatW(buffer, backslashW);
+        if (This->has_class)
+        {
+            StringFromGUID2(&This->class, buffer + lstrlenW(buffer), CHARS_IN_GUID);
+            lstrcatW(buffer, backslashW);
+        }
+        lstrcatW(buffer, This->name);
     }
-    strcatW(buffer, This->name);
 
     *ppszDisplayName = buffer;
     return S_OK;
@@ -798,6 +847,7 @@ static ULONG WINAPI DEVENUM_IEnumMoniker_Release(IEnumMoniker *iface)
 
     if (!ref)
     {
+        IEnumDMO_Release(This->dmo_enum);
         RegCloseKey(This->sw_key);
         RegCloseKey(This->cm_key);
         CoTaskMemFree(This);
@@ -815,16 +865,30 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
     LONG res;
     ULONG fetched = 0;
     MediaCatMoniker * pMoniker;
+    CLSID clsid;
+    HRESULT hr;
     HKEY hkey;
 
     TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched);
 
     while (fetched < celt)
     {
-        /* FIXME: try PNP devices and DMOs first */
+        /* FIXME: try PNP devices first */
+
+        /* try DMOs */
+        if ((hr = IEnumDMO_Next(This->dmo_enum, 1, &clsid, NULL, NULL)) == S_OK)
+        {
+            if (!(pMoniker = DEVENUM_IMediaCatMoniker_Construct()))
+                return E_OUTOFMEMORY;
+
+            pMoniker->type = DEVICE_DMO;
+            pMoniker->clsid = clsid;
 
+            StringFromGUID2(&clsid, buffer, CHARS_IN_GUID);
+            StringFromGUID2(&This->class, buffer + CHARS_IN_GUID - 1, CHARS_IN_GUID);
+        }
         /* try DirectShow filters */
-        if (!(res = RegEnumKeyW(This->sw_key, This->sw_index, buffer, sizeof(buffer)/sizeof(WCHAR))))
+        else if (!(res = RegEnumKeyW(This->sw_key, This->sw_index, buffer, ARRAY_SIZE(buffer))))
         {
             This->sw_index++;
             if ((res = RegOpenKeyExW(This->sw_key, buffer, 0, KEY_QUERY_VALUE, &hkey)))
@@ -834,9 +898,16 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
                 return E_OUTOFMEMORY;
 
             pMoniker->type = DEVICE_FILTER;
+
+            if (!(pMoniker->name = CoTaskMemAlloc((lstrlenW(buffer) + 1) * sizeof(WCHAR))))
+            {
+                IMoniker_Release(&pMoniker->IMoniker_iface);
+                return E_OUTOFMEMORY;
+            }
+            lstrcpyW(pMoniker->name, buffer);
         }
         /* then try codecs */
-        else if (!(res = RegEnumKeyW(This->cm_key, This->cm_index, buffer, sizeof(buffer)/sizeof(WCHAR))))
+        else if (!(res = RegEnumKeyW(This->cm_key, This->cm_index, buffer, ARRAY_SIZE(buffer))))
         {
             This->cm_index++;
 
@@ -847,16 +918,17 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
                 return E_OUTOFMEMORY;
 
             pMoniker->type = DEVICE_CODEC;
+
+            if (!(pMoniker->name = CoTaskMemAlloc((lstrlenW(buffer) + 1) * sizeof(WCHAR))))
+            {
+                IMoniker_Release(&pMoniker->IMoniker_iface);
+                return E_OUTOFMEMORY;
+            }
+            lstrcpyW(pMoniker->name, buffer);
         }
         else
             break;
 
-        if (!(pMoniker->name = CoTaskMemAlloc((strlenW(buffer) + 1) * sizeof(WCHAR))))
-        {
-            IMoniker_Release(&pMoniker->IMoniker_iface);
-            return E_OUTOFMEMORY;
-        }
-        strcpyW(pMoniker->name, buffer);
         pMoniker->has_class = TRUE;
         pMoniker->class = This->class;
 
@@ -883,10 +955,13 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Skip(IEnumMoniker *iface, ULONG celt)
 
     while (celt--)
     {
-        /* FIXME: try PNP devices and DMOs first */
+        /* FIXME: try PNP devices first */
 
+        /* try DMOs */
+        if (IEnumDMO_Skip(This->dmo_enum, 1) == S_OK)
+            ;
         /* try DirectShow filters */
-        if (RegEnumKeyW(This->sw_key, This->sw_index, NULL, 0) != ERROR_NO_MORE_ITEMS)
+        else if (RegEnumKeyW(This->sw_key, This->sw_index, NULL, 0) != ERROR_NO_MORE_ITEMS)
         {
             This->sw_index++;
         }
@@ -908,6 +983,7 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Reset(IEnumMoniker *iface)
 
     TRACE("(%p)->()\n", iface);
 
+    IEnumDMO_Reset(This->dmo_enum);
     This->sw_index = 0;
     This->cm_index = 0;
 
@@ -939,6 +1015,7 @@ HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **ppEnumMoniker)
 {
     EnumMonikerImpl * pEnumMoniker = CoTaskMemAlloc(sizeof(EnumMonikerImpl));
     WCHAR buffer[78];
+    HRESULT hr;
 
     if (!pEnumMoniker)
         return E_OUTOFMEMORY;
@@ -949,17 +1026,25 @@ HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **ppEnumMoniker)
     pEnumMoniker->cm_index = 0;
     pEnumMoniker->class = *class;
 
-    strcpyW(buffer, clsidW);
-    StringFromGUID2(class, buffer + strlenW(buffer), CHARS_IN_GUID);
-    strcatW(buffer, instanceW);
+    lstrcpyW(buffer, clsidW);
+    lstrcatW(buffer, backslashW);
+    StringFromGUID2(class, buffer + lstrlenW(buffer), CHARS_IN_GUID);
+    lstrcatW(buffer, instanceW);
     if (RegOpenKeyExW(HKEY_CLASSES_ROOT, buffer, 0, KEY_ENUMERATE_SUB_KEYS, &pEnumMoniker->sw_key))
         pEnumMoniker->sw_key = NULL;
 
-    strcpyW(buffer, wszActiveMovieKey);
-    StringFromGUID2(class, buffer + strlenW(buffer), CHARS_IN_GUID);
+    lstrcpyW(buffer, wszActiveMovieKey);
+    StringFromGUID2(class, buffer + lstrlenW(buffer), CHARS_IN_GUID);
     if (RegOpenKeyExW(HKEY_CURRENT_USER, buffer, 0, KEY_ENUMERATE_SUB_KEYS, &pEnumMoniker->cm_key))
         pEnumMoniker->cm_key = NULL;
 
+    hr = DMOEnum(class, 0, 0, NULL, 0, NULL, &pEnumMoniker->dmo_enum);
+    if (FAILED(hr))
+    {
+        IEnumMoniker_Release(&pEnumMoniker->IEnumMoniker_iface);
+        return hr;
+    }
+
     *ppEnumMoniker = &pEnumMoniker->IEnumMoniker_iface;
 
     DEVENUM_LockModule();
index 0f3ef3b..62523c0 100644 (file)
@@ -87,20 +87,25 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayNa
 
     *ret = NULL;
     if (eaten)
-        *eaten = strlenW(name);
+        *eaten = lstrlenW(name);
 
-    name = strchrW(name, ':') + 1;
+    name = wcschr(name, ':') + 1;
 
-    if (name[0] == 's' && name[1] == 'w' && name[2] == ':')
+    if (!wcsncmp(name, swW, 3))
     {
         type = DEVICE_FILTER;
         name += 3;
     }
-    else if (name[0] == 'c' && name[1] == 'm' && name[2] == ':')
+    else if (!wcsncmp(name, cmW, 3))
     {
         type = DEVICE_CODEC;
         name += 3;
     }
+    else if (!wcsncmp(name, dmoW, 4))
+    {
+        type = DEVICE_DMO;
+        name += 4;
+    }
     else
     {
         FIXME("unhandled device type %s\n", debugstr_w(name));
@@ -110,22 +115,41 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayNa
     if (!(mon = DEVENUM_IMediaCatMoniker_Construct()))
         return E_OUTOFMEMORY;
 
-    lstrcpynW(buffer, name, CHARS_IN_GUID);
-    if (CLSIDFromString(buffer, &class) == S_OK)
+    if (type == DEVICE_DMO)
     {
-        mon->has_class = TRUE;
-        mon->class = class;
-        name += CHARS_IN_GUID;
+        lstrcpynW(buffer, name, CHARS_IN_GUID);
+        if (FAILED(CLSIDFromString(buffer, &mon->clsid)))
+        {
+            IMoniker_Release(&mon->IMoniker_iface);
+            return MK_E_SYNTAX;
+        }
+
+        lstrcpynW(buffer, name + CHARS_IN_GUID - 1, CHARS_IN_GUID);
+        if (FAILED(CLSIDFromString(buffer, &mon->class)))
+        {
+            IMoniker_Release(&mon->IMoniker_iface);
+            return MK_E_SYNTAX;
+        }
     }
-
-    mon->type = type;
-
-    if (!(mon->name = CoTaskMemAlloc((strlenW(name) + 1) * sizeof(WCHAR))))
+    else
     {
-        IMoniker_Release(&mon->IMoniker_iface);
-        return E_OUTOFMEMORY;
+        lstrcpynW(buffer, name, CHARS_IN_GUID);
+        if (CLSIDFromString(buffer, &class) == S_OK)
+        {
+            mon->has_class = TRUE;
+            mon->class = class;
+            name += CHARS_IN_GUID;
+        }
+
+        if (!(mon->name = CoTaskMemAlloc((lstrlenW(name) + 1) * sizeof(WCHAR))))
+        {
+            IMoniker_Release(&mon->IMoniker_iface);
+            return E_OUTOFMEMORY;
+        }
+        lstrcpyW(mon->name, name);
     }
-    strcpyW(mon->name, name);
+
+    mon->type = type;
 
     *ret = &mon->IMoniker_iface;
 
index c6f0d42..a94f3ca 100644 (file)
@@ -29,7 +29,7 @@ dll/directx/wine/d3drm          # Synced to WineStaging-4.0
 dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-4.0
 dll/directx/wine/d3dxof         # Synced to WineStaging-3.17
 dll/directx/wine/ddraw          # Synced to WineStaging-3.3
-dll/directx/wine/devenum        # Synced to WineStaging-3.9
+dll/directx/wine/devenum        # Synced to WineStaging-4.18
 dll/directx/wine/dinput         # Synced to WineStaging-4.0
 dll/directx/wine/dinput8        # Synced to WineStaging-3.3
 dll/directx/wine/dmusic         # Synced to WineStaging-4.0
index 5a5b709..709ed1b 100644 (file)
@@ -1,2 +1,2 @@
 
-add_idl_headers(wineheaders itss.idl)
+add_idl_headers(wineheaders fil_data.idl itss.idl)
similarity index 69%
rename from dll/directx/wine/devenum/fil_data.idl
rename to sdk/include/reactos/wine/fil_data.idl
index 7e37a75..2475163 100644 (file)
 
 #pragma makedep header
 
-import "objidl.idl";
-import "strmif.idl";
 import "unknwn.idl";
+import "strmif.idl";
 
-
-/*****************************************************************************
- * IAMFilterData interface
- */
 [
     object,
     uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d),
@@ -33,15 +28,7 @@ import "unknwn.idl";
 ]
 interface IAMFilterData : IUnknown
 {
-    typedef [unique] IAMFilterData *LPIAMFILTERDATA;
-
-    HRESULT ParseFilterData(
-        [in] BYTE * rgbFilterData,
-        [in] ULONG cb,
-        [out] BYTE ** prgbRegFilter2);
+    HRESULT ParseFilterData( [in] BYTE *data, [in] ULONG size, [out] BYTE **regfilter );
 
-    HRESULT CreateFilterData(
-        [in] REGFILTER2 * prf2,
-        [out] BYTE ** prgbFilterData,
-        [out] ULONG * pcb);
+    HRESULT CreateFilterData( [in] REGFILTER2 *regfilter, [out] BYTE **data, [out] ULONG *size );
 }