[DEVENUM]
authorAmine Khaldi <amine.khaldi@reactos.org>
Sat, 19 Apr 2014 19:30:15 +0000 (19:30 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sat, 19 Apr 2014 19:30:15 +0000 (19:30 +0000)
* Sync with Wine 1.7.17.
CORE-8080

svn path=/trunk/; revision=62821

reactos/dll/directx/wine/devenum/CMakeLists.txt
reactos/dll/directx/wine/devenum/createdevenum.c
reactos/dll/directx/wine/devenum/devenum_classes.idl
reactos/dll/directx/wine/devenum/devenum_private.h
reactos/dll/directx/wine/devenum/mediacatenum.c
reactos/media/doc/README.WINE

index 52d6f4a..5768de2 100644 (file)
@@ -23,5 +23,6 @@ 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_importlibs(devenum advapi32 ole32 oleaut32 winmm user32 avicap32 msvcrt kernel32 ntdll)
+add_delay_importlibs(devenum msvfw32)
 add_pch(devenum devenum_private.h SOURCE)
 add_cd_file(TARGET devenum DESTINATION reactos/system32 FOR all)
index c69849b..29ba0e8 100644 (file)
 #include "devenum_private.h"
 
 #include <vfw.h>
+#include <aviriff.h>
 
 #include "resource.h"
 
 extern HINSTANCE DEVENUM_hInstance;
 
-const WCHAR wszInstanceKeyName[] ={'I','n','s','t','a','n','c','e',0};
+const WCHAR wszInstanceKeyName[] ={'\\','I','n','s','t','a','n','c','e',0};
 
 static const WCHAR wszRegSeparator[] =   {'\\', 0 };
 static const WCHAR wszActiveMovieKey[] = {'S','o','f','t','w','a','r','e','\\',
@@ -101,12 +102,18 @@ static ULONG WINAPI DEVENUM_ICreateDevEnum_Release(ICreateDevEnum * iface)
     return 1; /* non-heap based object */
 }
 
+static BOOL IsSpecialCategory(const CLSID *clsid)
+{
+    return IsEqualGUID(clsid, &CLSID_AudioRendererCategory) ||
+        IsEqualGUID(clsid, &CLSID_AudioInputDeviceCategory) ||
+        IsEqualGUID(clsid, &CLSID_VideoInputDeviceCategory) ||
+        IsEqualGUID(clsid, &CLSID_VideoCompressorCategory) ||
+        IsEqualGUID(clsid, &CLSID_MidiRendererCategory);
+}
+
 HRESULT DEVENUM_GetCategoryKey(REFCLSID clsidDeviceClass, HKEY *pBaseKey, WCHAR *wszRegKeyName, UINT maxLen)
 {
-    if (IsEqualGUID(clsidDeviceClass, &CLSID_AudioRendererCategory) ||
-        IsEqualGUID(clsidDeviceClass, &CLSID_AudioInputDeviceCategory) ||
-        IsEqualGUID(clsidDeviceClass, &CLSID_VideoInputDeviceCategory) ||
-        IsEqualGUID(clsidDeviceClass, &CLSID_MidiRendererCategory))
+    if (IsSpecialCategory(clsidDeviceClass))
     {
         *pBaseKey = HKEY_CURRENT_USER;
         strcpyW(wszRegKeyName, wszActiveMovieKey);
@@ -123,13 +130,57 @@ HRESULT DEVENUM_GetCategoryKey(REFCLSID clsidDeviceClass, HKEY *pBaseKey, WCHAR
         if (!StringFromGUID2(clsidDeviceClass, wszRegKeyName + CLSID_STR_LEN, maxLen - CLSID_STR_LEN))
             return E_OUTOFMEMORY;
 
-        strcatW(wszRegKeyName, wszRegSeparator);
         strcatW(wszRegKeyName, wszInstanceKeyName);
     }
 
     return S_OK;
 }
 
+static HKEY open_category_key(const CLSID *clsid)
+{
+    WCHAR key_name[sizeof(wszInstanceKeyName)/sizeof(WCHAR) + CHARS_IN_GUID-1 + 6 /* strlen("CLSID\") */], *ptr;
+    HKEY ret;
+
+    strcpyW(key_name, clsid_keyname);
+    ptr = key_name + strlenW(key_name);
+    *ptr++ = '\\';
+
+    if (!StringFromGUID2(clsid, ptr, CHARS_IN_GUID))
+        return NULL;
+
+    ptr += strlenW(ptr);
+    strcpyW(ptr, wszInstanceKeyName);
+
+    if (RegOpenKeyExW(HKEY_CLASSES_ROOT, key_name, 0, KEY_READ, &ret) != ERROR_SUCCESS) {
+        WARN("Could not open %s\n", debugstr_w(key_name));
+        return NULL;
+    }
+
+    return ret;
+}
+
+static HKEY open_special_category_key(const CLSID *clsid, BOOL create)
+{
+    WCHAR key_name[sizeof(wszActiveMovieKey)/sizeof(WCHAR) + CHARS_IN_GUID-1];
+    HKEY ret;
+    LONG res;
+
+    strcpyW(key_name, wszActiveMovieKey);
+    if (!StringFromGUID2(clsid, key_name + sizeof(wszActiveMovieKey)/sizeof(WCHAR)-1, CHARS_IN_GUID))
+        return NULL;
+
+    if(create)
+        res = RegCreateKeyW(HKEY_CURRENT_USER, key_name, &ret);
+    else
+        res = RegOpenKeyExW(HKEY_CURRENT_USER, key_name, 0, KEY_READ, &ret);
+    if (res != ERROR_SUCCESS) {
+        WARN("Could not open %s\n", debugstr_w(key_name));
+        return NULL;
+    }
+
+    return ret;
+}
+
 static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS *rgPin)
 {
     HKEY hkeyTypes = NULL;
@@ -455,9 +506,7 @@ static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator(
     IEnumMoniker **ppEnumMoniker,
     DWORD dwFlags)
 {
-    WCHAR wszRegKey[MAX_PATH];
-    HKEY hkey;
-    HKEY hbasekey;
+    HKEY hkey, special_hkey = NULL;
     HRESULT hr;
 
     TRACE("(%p)->(%s, %p, %x)\n", iface, debugstr_guid(clsidDeviceClass), ppEnumMoniker, dwFlags);
@@ -472,32 +521,29 @@ static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator(
         DEVENUM_RegisterLegacyAmFilters();
     }
 
-    hr = DEVENUM_GetCategoryKey(clsidDeviceClass, &hbasekey, wszRegKey, MAX_PATH);
-    if (FAILED(hr))
-        return hr;
-
-    if (IsEqualGUID(clsidDeviceClass, &CLSID_AudioRendererCategory) ||
-        IsEqualGUID(clsidDeviceClass, &CLSID_AudioInputDeviceCategory) ||
-        IsEqualGUID(clsidDeviceClass, &CLSID_VideoInputDeviceCategory) ||
-        IsEqualGUID(clsidDeviceClass, &CLSID_MidiRendererCategory))
+    if (IsSpecialCategory(clsidDeviceClass))
     {
          hr = DEVENUM_CreateSpecialCategories();
          if (FAILED(hr))
              return hr;
-         if (RegOpenKeyW(hbasekey, wszRegKey, &hkey) != ERROR_SUCCESS)
+
+         special_hkey = open_special_category_key(clsidDeviceClass, FALSE);
+         if (!special_hkey)
          {
              ERR("Couldn't open registry key for special device: %s\n",
                  debugstr_guid(clsidDeviceClass));
              return S_FALSE;
          }
     }
-    else if (RegOpenKeyW(hbasekey, wszRegKey, &hkey) != ERROR_SUCCESS)
+
+    hkey = open_category_key(clsidDeviceClass);
+    if (!hkey && !special_hkey)
     {
         FIXME("Category %s not found\n", debugstr_guid(clsidDeviceClass));
         return S_FALSE;
     }
 
-    return DEVENUM_IEnumMoniker_Construct(hkey, ppEnumMoniker);
+    return DEVENUM_IEnumMoniker_Construct(hkey, special_hkey, ppEnumMoniker);
 }
 
 /**********************************************************************
@@ -548,6 +594,44 @@ static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory)
     return res;
 }
 
+static void register_vfw_codecs(void)
+{
+    WCHAR avico_clsid_str[CHARS_IN_GUID];
+    HKEY basekey, key;
+    ICINFO icinfo;
+    DWORD i, res;
+
+    static const WCHAR CLSIDW[] = {'C','L','S','I','D',0};
+    static const WCHAR FccHandlerW[] = {'F','c','c','H','a','n','d','l','e','r',0};
+    static const WCHAR FriendlyNameW[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
+
+    StringFromGUID2(&CLSID_AVICo, avico_clsid_str, sizeof(avico_clsid_str)/sizeof(WCHAR));
+
+    basekey = open_special_category_key(&CLSID_VideoCompressorCategory, TRUE);
+    if(!basekey) {
+        ERR("Could not create key\n");
+        return;
+    }
+
+    for(i=0; ICInfo(FCC('v','i','d','c'), i, &icinfo); i++) {
+        WCHAR fcc_str[5] = {LOBYTE(LOWORD(icinfo.fccHandler)), HIBYTE(LOWORD(icinfo.fccHandler)),
+                            LOBYTE(HIWORD(icinfo.fccHandler)), HIBYTE(HIWORD(icinfo.fccHandler))};
+
+        res = RegCreateKeyW(basekey, fcc_str, &key);
+        if(res != ERROR_SUCCESS)
+            continue;
+
+        RegSetValueExW(key, CLSIDW, 0, REG_SZ, (const BYTE*)avico_clsid_str, sizeof(avico_clsid_str));
+        RegSetValueExW(key, FccHandlerW, 0, REG_SZ, (const BYTE*)fcc_str, sizeof(fcc_str));
+        RegSetValueExW(key, FriendlyNameW, 0, REG_SZ, (const BYTE*)icinfo.szName, (strlenW(icinfo.szName)+1)*sizeof(WCHAR));
+        /* FIXME: Set ClassManagerFlags and FilterData values */
+
+        RegCloseKey(key);
+    }
+
+    RegCloseKey(basekey);
+}
+
 static HANDLE DEVENUM_populate_handle;
 static const WCHAR DEVENUM_populate_handle_nameW[] =
     {'_','_','W','I','N','E','_',
@@ -598,6 +682,8 @@ static HRESULT DEVENUM_CreateSpecialCategories(void)
         RegDeleteTreeW(basekey, path);
     if (SUCCEEDED(DEVENUM_GetCategoryKey(&CLSID_MidiRendererCategory, &basekey, path, MAX_PATH)))
         RegDeleteTreeW(basekey, path);
+    if (SUCCEEDED(DEVENUM_GetCategoryKey(&CLSID_VideoCompressorCategory, &basekey, path, MAX_PATH)))
+        RegDeleteTreeW(basekey, path);
 
     rf2.dwVersion = 2;
     rf2.dwMerit = MERIT_PREFERRED;
@@ -877,6 +963,9 @@ static HRESULT DEVENUM_CreateSpecialCategories(void)
 
     if (pMapper)
         IFilterMapper2_Release(pMapper);
+
+    register_vfw_codecs();
+
     SetEvent(DEVENUM_populate_handle);
     return res;
 }
index 8722910..81052e1 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#pragma makedep register
+
 [
     helpstring("System Device Enum"),
     threading(both),
index 35d4d46..32e71da 100644 (file)
@@ -77,7 +77,7 @@ typedef struct
 } MediaCatMoniker;
 
 MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct(void) DECLSPEC_HIDDEN;
-HRESULT DEVENUM_IEnumMoniker_Construct(HKEY hkey, IEnumMoniker ** ppEnumMoniker) DECLSPEC_HIDDEN;
+HRESULT DEVENUM_IEnumMoniker_Construct(HKEY hkey, HKEY special_hkey, IEnumMoniker ** ppEnumMoniker) DECLSPEC_HIDDEN;
 
 extern ClassFactoryImpl DEVENUM_ClassFactory DECLSPEC_HIDDEN;
 extern ICreateDevEnum DEVENUM_CreateDevEnum DECLSPEC_HIDDEN;
index 5802209..3f28d26 100644 (file)
@@ -32,7 +32,9 @@ typedef struct
     IEnumMoniker IEnumMoniker_iface;
     LONG ref;
     DWORD index;
+    DWORD subkey_cnt;
     HKEY hkey;
+    HKEY special_hkey;
 } EnumMonikerImpl;
 
 typedef struct
@@ -714,6 +716,8 @@ static ULONG WINAPI DEVENUM_IEnumMoniker_Release(IEnumMoniker *iface)
 
     if (!ref)
     {
+        if(This->special_hkey)
+            RegCloseKey(This->special_hkey);
         RegCloseKey(This->hkey);
         CoTaskMemFree(This);
         DEVENUM_UnlockModule();
@@ -735,7 +739,12 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
 
     while (fetched < celt)
     {
-        res = RegEnumKeyW(This->hkey, This->index, buffer, sizeof(buffer) / sizeof(WCHAR));
+        if(This->index+fetched < This->subkey_cnt)
+            res = RegEnumKeyW(This->hkey, This->index+fetched, buffer, sizeof(buffer) / sizeof(WCHAR));
+        else if(This->special_hkey)
+            res = RegEnumKeyW(This->special_hkey, This->index+fetched-This->subkey_cnt, buffer, sizeof(buffer) / sizeof(WCHAR));
+        else
+            break;
         if (res != ERROR_SUCCESS)
         {
             break;
@@ -744,7 +753,8 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
         if (!pMoniker)
             return E_OUTOFMEMORY;
 
-        if (RegOpenKeyW(This->hkey, buffer, &pMoniker->hkey) != ERROR_SUCCESS)
+        if (RegOpenKeyW(This->index+fetched < This->subkey_cnt ? This->hkey : This->special_hkey,
+                        buffer, &pMoniker->hkey) != ERROR_SUCCESS)
         {
             IMoniker_Release(&pMoniker->IMoniker_iface);
             break;
@@ -769,17 +779,16 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
 static HRESULT WINAPI DEVENUM_IEnumMoniker_Skip(IEnumMoniker *iface, ULONG celt)
 {
     EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
-    DWORD subKeys;
+    DWORD special_subkeys = 0;
 
     TRACE("(%p)->(%d)\n", iface, celt);
 
     /* Before incrementing, check if there are any more values to run through.
        Some programs use the Skip() function to get the number of devices */
-    if(RegQueryInfoKeyW(This->hkey, NULL, NULL, NULL, &subKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
-    {
-        return S_FALSE;
-    }
-    if((This->index + celt) >= subKeys)
+    if(This->special_hkey)
+        RegQueryInfoKeyW(This->special_hkey, NULL, NULL, NULL, &special_subkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+
+    if((This->index + celt) >= This->subkey_cnt + special_subkeys)
     {
         return S_FALSE;
     }
@@ -821,7 +830,7 @@ static const IEnumMonikerVtbl IEnumMoniker_Vtbl =
     DEVENUM_IEnumMoniker_Clone
 };
 
-HRESULT DEVENUM_IEnumMoniker_Construct(HKEY hkey, IEnumMoniker ** ppEnumMoniker)
+HRESULT DEVENUM_IEnumMoniker_Construct(HKEY hkey, HKEY special_hkey, IEnumMoniker ** ppEnumMoniker)
 {
     EnumMonikerImpl * pEnumMoniker = CoTaskMemAlloc(sizeof(EnumMonikerImpl));
     if (!pEnumMoniker)
@@ -831,9 +840,14 @@ HRESULT DEVENUM_IEnumMoniker_Construct(HKEY hkey, IEnumMoniker ** ppEnumMoniker)
     pEnumMoniker->ref = 1;
     pEnumMoniker->index = 0;
     pEnumMoniker->hkey = hkey;
+    pEnumMoniker->special_hkey = special_hkey;
 
     *ppEnumMoniker = &pEnumMoniker->IEnumMoniker_iface;
 
+    if(RegQueryInfoKeyW(pEnumMoniker->hkey, NULL, NULL, NULL, &pEnumMoniker->subkey_cnt, NULL, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
+        pEnumMoniker->subkey_cnt = 0;
+
+
     DEVENUM_LockModule();
 
     return S_OK;
index 6b716b8..3184dde 100644 (file)
@@ -34,7 +34,7 @@ reactos/dll/directx/wine/d3dcompiler_43 # Synced to Wine-1.7.17
 reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to Wine-1.7.17
 reactos/dll/directx/wine/d3dxof         # Synced to Wine-1.7.17
 reactos/dll/directx/wine/ddraw          # Synced to Wine-1.7.17
-reactos/dll/directx/wine/devenum        # Synced to Wine-1.7.1
+reactos/dll/directx/wine/devenum        # Synced to Wine-1.7.17
 reactos/dll/directx/wine/dinput         # Synced to Wine-1.7.1
 reactos/dll/directx/wine/dinput8        # Synced to Wine-1.7.1
 reactos/dll/directx/wine/dmusic         # Synced to Wine-1.7.1