[DEVENUM] Sync with Wine Staging 3.9. CORE-14656

This commit is contained in:
Amine Khaldi 2018-05-27 03:56:13 +01:00
parent e00ccd4551
commit 5e3341f4bb
8 changed files with 866 additions and 729 deletions

View File

@ -4,6 +4,7 @@ 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
@ -23,6 +24,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 msvcrt kernel32 ntdll)
add_importlibs(devenum advapi32 advapi32_vista ole32 oleaut32 winmm user32 avicap32 msacm32 dsound msvcrt kernel32 ntdll)
add_dependencies(devenum devenum_fil_data_header)
add_pch(devenum precomp.h SOURCE)
add_cd_file(TARGET devenum DESTINATION reactos/system32 FOR all)

File diff suppressed because it is too large Load Diff

View File

@ -23,18 +23,6 @@
#include "winnls.h"
#include "devenum_private.h"
#pragma makedep po
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
STRINGTABLE
{
IDS_DEVENUM_DSDEFAULT "Default DirectSound"
IDS_DEVENUM_DS "DirectSound: %s"
IDS_DEVENUM_WODEFAULT "Default WaveOut Device"
IDS_DEVENUM_MIDEFAULT "Default MidiOut Device"
}
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#define WINE_FILEDESCRIPTION_STR "Wine Device Enumerator Library"

View File

@ -62,38 +62,40 @@ typedef struct
IClassFactory IClassFactory_iface;
} ClassFactoryImpl;
enum device_type
{
DEVICE_FILTER,
DEVICE_CODEC,
};
typedef struct
{
IMoniker IMoniker_iface;
LONG ref;
HKEY hkey;
CLSID class;
BOOL has_class;
enum device_type type;
WCHAR *name;
} MediaCatMoniker;
MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct(void) DECLSPEC_HIDDEN;
HRESULT DEVENUM_IEnumMoniker_Construct(HKEY hkey, HKEY special_hkey, IEnumMoniker ** ppEnumMoniker) 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;
/**********************************************************************
* Private helper function to get AM filter category key location
*/
HRESULT DEVENUM_GetCategoryKey(REFCLSID clsidDeviceClass, HKEY *pBaseKey, WCHAR *wszRegKeyName, UINT maxLen) DECLSPEC_HIDDEN;
/**********************************************************************
* Global string constant declarations
*/
extern const WCHAR clsid_keyname[6] DECLSPEC_HIDDEN;
extern const WCHAR wszInstanceKeyName[] DECLSPEC_HIDDEN;
#define CLSID_STR_LEN (sizeof(clsid_keyname) / sizeof(WCHAR))
/**********************************************************************
* Resource IDs
*/
#define IDS_DEVENUM_DSDEFAULT 7
#define IDS_DEVENUM_DS 8
#define IDS_DEVENUM_WODEFAULT 9
#define IDS_DEVENUM_MIDEFAULT 10
#define IDS_DEVENUM_KSDEFAULT 11
#define IDS_DEVENUM_KS 12
static const WCHAR backslashW[] = {'\\',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;

View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2009 Vitaliy Margolen
*
* 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
*/
#pragma makedep header
import "objidl.idl";
import "strmif.idl";
import "unknwn.idl";
/*****************************************************************************
* IAMFilterData interface
*/
[
object,
uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d),
pointer_default(unique)
]
interface IAMFilterData : IUnknown
{
typedef [unique] IAMFilterData *LPIAMFILTERDATA;
HRESULT ParseFilterData(
[in] BYTE * rgbFilterData,
[in] ULONG cb,
[out] BYTE ** prgbRegFilter2);
HRESULT CreateFilterData(
[in] REGFILTER2 * prf2,
[out] BYTE ** prgbFilterData,
[out] ULONG * pcb);
}

View File

@ -33,18 +33,20 @@ WINE_DEFAULT_DEBUG_CHANNEL(devenum);
typedef struct
{
IEnumMoniker IEnumMoniker_iface;
CLSID class;
LONG ref;
DWORD index;
DWORD subkey_cnt;
HKEY hkey;
HKEY special_hkey;
HKEY sw_key;
DWORD sw_index;
HKEY cm_key;
DWORD cm_index;
} EnumMonikerImpl;
typedef struct
{
IPropertyBag IPropertyBag_iface;
LONG ref;
HKEY hkey;
enum device_type type;
WCHAR path[MAX_PATH];
} RegPropBagImpl;
@ -100,7 +102,6 @@ static ULONG WINAPI DEVENUM_IPropertyBag_Release(LPPROPERTYBAG iface)
ref = InterlockedDecrement(&This->ref);
if (ref == 0) {
RegCloseKey(This->hkey);
CoTaskMemFree(This);
DEVENUM_UnlockModule();
}
@ -118,22 +119,32 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Read(
DWORD type = 0;
RegPropBagImpl *This = impl_from_IPropertyBag(iface);
HRESULT res = S_OK;
LONG reswin32;
LONG reswin32 = ERROR_SUCCESS;
HKEY hkey;
TRACE("(%p)->(%s, %p, %p)\n", This, debugstr_w(pszPropName), pVar, pErrorLog);
if (!pszPropName || !pVar)
return E_POINTER;
reswin32 = RegQueryValueExW(This->hkey, pszPropName, NULL, NULL, NULL, &received);
if (This->type == DEVICE_FILTER)
reswin32 = RegOpenKeyW(HKEY_CLASSES_ROOT, This->path, &hkey);
else if (This->type == DEVICE_CODEC)
reswin32 = RegOpenKeyW(HKEY_CURRENT_USER, This->path, &hkey);
res = HRESULT_FROM_WIN32(reswin32);
if (SUCCEEDED(res))
{
reswin32 = RegQueryValueExW(hkey, pszPropName, NULL, NULL, NULL, &received);
res = HRESULT_FROM_WIN32(reswin32);
}
if (SUCCEEDED(res))
{
pData = HeapAlloc(GetProcessHeap(), 0, received);
/* work around a GCC bug that occurs here unless we use the reswin32 variable as well */
reswin32 = RegQueryValueExW(This->hkey, pszPropName, NULL, &type, pData, &received);
reswin32 = RegQueryValueExW(hkey, pszPropName, NULL, &type, pData, &received);
res = HRESULT_FROM_WIN32(reswin32);
}
@ -214,6 +225,8 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Read(
HeapFree(GetProcessHeap(), 0, pData);
RegCloseKey(hkey);
TRACE("<- %x\n", res);
return res;
}
@ -228,6 +241,8 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Write(
DWORD cbData = 0;
DWORD dwType = 0;
HRESULT res = S_OK;
LONG lres = ERROR_SUCCESS;
HKEY hkey;
TRACE("(%p)->(%s, %p)\n", This, debugstr_w(pszPropName), pVar);
@ -264,10 +279,18 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Write(
return E_FAIL;
}
if (RegSetValueExW(This->hkey,
pszPropName, 0,
dwType, lpData, cbData) != ERROR_SUCCESS)
res = E_FAIL;
if (This->type == DEVICE_FILTER)
lres = RegCreateKeyW(HKEY_CLASSES_ROOT, This->path, &hkey);
else if (This->type == DEVICE_CODEC)
lres = RegCreateKeyW(HKEY_CURRENT_USER, This->path, &hkey);
res = HRESULT_FROM_WIN32(lres);
if (SUCCEEDED(res))
{
lres = RegSetValueExW(hkey, pszPropName, 0, dwType, lpData, cbData);
res = HRESULT_FROM_WIN32(lres);
RegCloseKey(hkey);
}
if (V_VT(pVar) & VT_ARRAY)
res = SafeArrayUnaccessData(V_ARRAY(pVar));
@ -284,14 +307,28 @@ static const IPropertyBagVtbl IPropertyBag_Vtbl =
DEVENUM_IPropertyBag_Write
};
static HRESULT DEVENUM_IPropertyBag_Construct(HANDLE hkey, IPropertyBag **ppBag)
static HRESULT create_PropertyBag(MediaCatMoniker *mon, IPropertyBag **ppBag)
{
RegPropBagImpl * rpb = CoTaskMemAlloc(sizeof(RegPropBagImpl));
if (!rpb)
return E_OUTOFMEMORY;
rpb->IPropertyBag_iface.lpVtbl = &IPropertyBag_Vtbl;
rpb->ref = 1;
rpb->hkey = hkey;
rpb->type = mon->type;
if (rpb->type == DEVICE_FILTER)
strcpyW(rpb->path, clsidW);
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);
}
strcatW(rpb->path, mon->name);
*ppBag = &rpb->IPropertyBag_iface;
DEVENUM_LockModule();
return S_OK;
@ -344,7 +381,7 @@ static ULONG WINAPI DEVENUM_IMediaCatMoniker_Release(IMoniker *iface)
TRACE("(%p) ref=%d\n", This, ref);
if (ref == 0) {
RegCloseKey(This->hkey);
CoTaskMemFree(This->name);
CoTaskMemFree(This);
DEVENUM_UnlockModule();
}
@ -407,6 +444,9 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_BindToObject(IMoniker *iface, IBi
TRACE("(%p)->(%p, %p, %s, %p)\n", This, pbc, pmkToLeft, debugstr_guid(riidResult), ppvResult);
if (!ppvResult)
return E_POINTER;
VariantInit(&var);
*ppvResult = NULL;
@ -485,9 +525,7 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_BindToStorage(IMoniker *iface, IB
if (IsEqualGUID(riid, &IID_IPropertyBag))
{
HANDLE hkey;
DuplicateHandle(GetCurrentProcess(), This->hkey, GetCurrentProcess(), &hkey, 0, 0, DUPLICATE_SAME_ACCESS);
return DEVENUM_IPropertyBag_Construct(hkey, (IPropertyBag**)ppvObj);
return create_PropertyBag(This, (IPropertyBag**)ppvObj);
}
return MK_E_NOSTORAGE;
@ -620,24 +658,35 @@ 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 wszBuffer[MAX_PATH];
static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
DWORD received = sizeof(wszBuffer);
WCHAR *buffer;
TRACE("(%p)->(%p, %p, %p)\n", iface, pbc, pmkToLeft, ppszDisplayName);
*ppszDisplayName = NULL;
/* FIXME: should this be the weird stuff we have to parse in IParseDisplayName? */
if (RegQueryValueExW(This->hkey, wszFriendlyName, NULL, NULL, (LPBYTE)wszBuffer, &received) == ERROR_SUCCESS)
{
*ppszDisplayName = CoTaskMemAlloc(received);
strcpyW(*ppszDisplayName, wszBuffer);
return S_OK;
}
buffer = CoTaskMemAlloc((strlenW(deviceW) + 4 + (This->has_class ? CHARS_IN_GUID : 0)
+ strlenW(This->name) + 1) * sizeof(WCHAR));
if (!buffer)
return E_OUTOFMEMORY;
return E_FAIL;
strcpyW(buffer, deviceW);
if (This->type == DEVICE_FILTER)
strcatW(buffer, swW);
else if (This->type == DEVICE_CODEC)
strcatW(buffer, cmW);
if (This->has_class)
{
StringFromGUID2(&This->class, buffer + strlenW(buffer), CHARS_IN_GUID);
strcatW(buffer, backslashW);
}
strcatW(buffer, This->name);
*ppszDisplayName = buffer;
return S_OK;
}
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc,
@ -694,7 +743,8 @@ MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct(void)
pMoniker->IMoniker_iface.lpVtbl = &IMoniker_Vtbl;
pMoniker->ref = 0;
pMoniker->hkey = NULL;
pMoniker->has_class = FALSE;
pMoniker->name = NULL;
DEVENUM_IMediaCatMoniker_AddRef(&pMoniker->IMoniker_iface);
@ -748,9 +798,8 @@ static ULONG WINAPI DEVENUM_IEnumMoniker_Release(IEnumMoniker *iface)
if (!ref)
{
if(This->special_hkey)
RegCloseKey(This->special_hkey);
RegCloseKey(This->hkey);
RegCloseKey(This->sw_key);
RegCloseKey(This->cm_key);
CoTaskMemFree(This);
DEVENUM_UnlockModule();
return 0;
@ -766,37 +815,55 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
LONG res;
ULONG fetched = 0;
MediaCatMoniker * pMoniker;
HKEY hkey;
TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched);
while (fetched < celt)
{
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));
/* FIXME: try PNP devices and DMOs first */
/* try DirectShow filters */
if (!(res = RegEnumKeyW(This->sw_key, This->sw_index, buffer, sizeof(buffer)/sizeof(WCHAR))))
{
This->sw_index++;
if ((res = RegOpenKeyExW(This->sw_key, buffer, 0, KEY_QUERY_VALUE, &hkey)))
break;
if (!(pMoniker = DEVENUM_IMediaCatMoniker_Construct()))
return E_OUTOFMEMORY;
pMoniker->type = DEVICE_FILTER;
}
/* then try codecs */
else if (!(res = RegEnumKeyW(This->cm_key, This->cm_index, buffer, sizeof(buffer)/sizeof(WCHAR))))
{
This->cm_index++;
if ((res = RegOpenKeyExW(This->cm_key, buffer, 0, KEY_QUERY_VALUE, &hkey)))
break;
if (!(pMoniker = DEVENUM_IMediaCatMoniker_Construct()))
return E_OUTOFMEMORY;
pMoniker->type = DEVICE_CODEC;
}
else
break;
if (res != ERROR_SUCCESS)
{
break;
}
pMoniker = DEVENUM_IMediaCatMoniker_Construct();
if (!pMoniker)
return E_OUTOFMEMORY;
if (RegOpenKeyW(This->index+fetched < This->subkey_cnt ? This->hkey : This->special_hkey,
buffer, &pMoniker->hkey) != ERROR_SUCCESS)
if (!(pMoniker->name = CoTaskMemAlloc((strlenW(buffer) + 1) * sizeof(WCHAR))))
{
IMoniker_Release(&pMoniker->IMoniker_iface);
break;
return E_OUTOFMEMORY;
}
strcpyW(pMoniker->name, buffer);
pMoniker->has_class = TRUE;
pMoniker->class = This->class;
rgelt[fetched] = &pMoniker->IMoniker_iface;
fetched++;
}
This->index += fetched;
TRACE("-- fetched %d\n", fetched);
if (pceltFetched)
@ -811,21 +878,26 @@ 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 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(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)
while (celt--)
{
return S_FALSE;
}
/* FIXME: try PNP devices and DMOs first */
This->index += celt;
/* try DirectShow filters */
if (RegEnumKeyW(This->sw_key, This->sw_index, NULL, 0) != ERROR_NO_MORE_ITEMS)
{
This->sw_index++;
}
/* then try codecs */
else if (RegEnumKeyW(This->cm_key, This->cm_index, NULL, 0) != ERROR_NO_MORE_ITEMS)
{
This->cm_index++;
}
else
return S_FALSE;
}
return S_OK;
}
@ -836,7 +908,8 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Reset(IEnumMoniker *iface)
TRACE("(%p)->()\n", iface);
This->index = 0;
This->sw_index = 0;
This->cm_index = 0;
return S_OK;
}
@ -862,24 +935,33 @@ static const IEnumMonikerVtbl IEnumMoniker_Vtbl =
DEVENUM_IEnumMoniker_Clone
};
HRESULT DEVENUM_IEnumMoniker_Construct(HKEY hkey, HKEY special_hkey, IEnumMoniker ** ppEnumMoniker)
HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **ppEnumMoniker)
{
EnumMonikerImpl * pEnumMoniker = CoTaskMemAlloc(sizeof(EnumMonikerImpl));
WCHAR buffer[78];
if (!pEnumMoniker)
return E_OUTOFMEMORY;
pEnumMoniker->IEnumMoniker_iface.lpVtbl = &IEnumMoniker_Vtbl;
pEnumMoniker->ref = 1;
pEnumMoniker->index = 0;
pEnumMoniker->hkey = hkey;
pEnumMoniker->special_hkey = special_hkey;
pEnumMoniker->sw_index = 0;
pEnumMoniker->cm_index = 0;
pEnumMoniker->class = *class;
strcpyW(buffer, clsidW);
StringFromGUID2(class, buffer + strlenW(buffer), CHARS_IN_GUID);
strcatW(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);
if (RegOpenKeyExW(HKEY_CURRENT_USER, buffer, 0, KEY_ENUMERATE_SUB_KEYS, &pEnumMoniker->cm_key))
pEnumMoniker->cm_key = NULL;
*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;

View File

@ -76,69 +76,60 @@ static ULONG WINAPI DEVENUM_IParseDisplayName_Release(IParseDisplayName *iface)
* not in "@device:sw:{CLSID1}\<filter name or CLSID>" format
*/
static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayName *iface,
IBindCtx *pbc, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
IBindCtx *pbc, LPOLESTR name, ULONG *eaten, IMoniker **ret)
{
LPOLESTR pszBetween = NULL;
LPOLESTR pszClass = NULL;
MediaCatMoniker * pMoniker = NULL;
CLSID clsidDevice;
HRESULT res = S_OK;
WCHAR wszRegKeyName[MAX_PATH];
HKEY hbasekey;
int classlen;
static const WCHAR wszRegSeparator[] = {'\\', 0 };
WCHAR buffer[MAX_PATH];
enum device_type type;
MediaCatMoniker *mon;
CLSID class;
TRACE("(%p, %s, %p, %p)\n", pbc, debugstr_w(pszDisplayName), pchEaten, ppmkOut);
TRACE("(%p, %s, %p, %p)\n", pbc, debugstr_w(name), eaten, ret);
*ppmkOut = NULL;
if (pchEaten)
*pchEaten = strlenW(pszDisplayName);
*ret = NULL;
if (eaten)
*eaten = strlenW(name);
pszDisplayName = strchrW(pszDisplayName, '{');
pszBetween = strchrW(pszDisplayName, '}') + 2;
name = strchrW(name, ':') + 1;
/* size = pszBetween - pszDisplayName - 1 (for '\\' after CLSID)
* + 1 (for NULL character)
*/
classlen = (int)(pszBetween - pszDisplayName - 1);
pszClass = CoTaskMemAlloc((classlen + 1) * sizeof(WCHAR));
if (!pszClass)
if (name[0] == 's' && name[1] == 'w' && name[2] == ':')
{
type = DEVICE_FILTER;
name += 3;
}
else if (name[0] == 'c' && name[1] == 'm' && name[2] == ':')
{
type = DEVICE_CODEC;
name += 3;
}
else
{
FIXME("unhandled device type %s\n", debugstr_w(name));
return MK_E_SYNTAX;
}
if (!(mon = DEVENUM_IMediaCatMoniker_Construct()))
return E_OUTOFMEMORY;
memcpy(pszClass, pszDisplayName, classlen * sizeof(WCHAR));
pszClass[classlen] = 0;
TRACE("Device CLSID: %s\n", debugstr_w(pszClass));
res = CLSIDFromString(pszClass, &clsidDevice);
if (SUCCEEDED(res))
lstrcpynW(buffer, name, CHARS_IN_GUID);
if (CLSIDFromString(buffer, &class) == S_OK)
{
res = DEVENUM_GetCategoryKey(&clsidDevice, &hbasekey, wszRegKeyName, MAX_PATH);
mon->has_class = TRUE;
mon->class = class;
name += CHARS_IN_GUID;
}
if (SUCCEEDED(res))
mon->type = type;
if (!(mon->name = CoTaskMemAlloc((strlenW(name) + 1) * sizeof(WCHAR))))
{
pMoniker = DEVENUM_IMediaCatMoniker_Construct();
if (pMoniker)
{
strcatW(wszRegKeyName, wszRegSeparator);
strcatW(wszRegKeyName, pszBetween);
if (RegCreateKeyW(hbasekey, wszRegKeyName, &pMoniker->hkey) == ERROR_SUCCESS)
*ppmkOut = &pMoniker->IMoniker_iface;
else
{
IMoniker_Release(&pMoniker->IMoniker_iface);
res = MK_E_NOOBJECT;
}
}
IMoniker_Release(&mon->IMoniker_iface);
return E_OUTOFMEMORY;
}
strcpyW(mon->name, name);
CoTaskMemFree(pszClass);
*ret = &mon->IMoniker_iface;
TRACE("-- returning: %x\n", res);
return res;
return S_OK;
}
/**********************************************************************

View File

@ -29,7 +29,7 @@ reactos/dll/directx/wine/d3drm # Synced to WineStaging-3.9
reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-3.9
reactos/dll/directx/wine/d3dxof # Synced to WineStaging-3.3
reactos/dll/directx/wine/ddraw # Synced to WineStaging-3.9
reactos/dll/directx/wine/devenum # Synced to WineStaging-3.3
reactos/dll/directx/wine/devenum # Synced to WineStaging-3.9
reactos/dll/directx/wine/dinput # Synced to WineStaging-3.3
reactos/dll/directx/wine/dinput8 # Synced to WineStaging-3.3
reactos/dll/directx/wine/dmusic # Synced to WineStaging-3.3