devenum: Create the key in IPropertyBag::Write() instead of ParseDisplayName().

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
oldstable
Zebediah Figura 2018-03-06 20:57:11 -06:00 committed by Alexandre Julliard
parent b0300ce564
commit 38482b326a
4 changed files with 48 additions and 41 deletions

View File

@ -70,7 +70,6 @@ typedef struct
{ {
IMoniker IMoniker_iface; IMoniker IMoniker_iface;
LONG ref; LONG ref;
HKEY hkey;
CLSID class; CLSID class;
BOOL has_class; BOOL has_class;
enum device_type type; enum device_type type;

View File

@ -45,7 +45,8 @@ typedef struct
{ {
IPropertyBag IPropertyBag_iface; IPropertyBag IPropertyBag_iface;
LONG ref; LONG ref;
HKEY hkey; enum device_type type;
WCHAR path[MAX_PATH];
} RegPropBagImpl; } RegPropBagImpl;
@ -101,7 +102,6 @@ static ULONG WINAPI DEVENUM_IPropertyBag_Release(LPPROPERTYBAG iface)
ref = InterlockedDecrement(&This->ref); ref = InterlockedDecrement(&This->ref);
if (ref == 0) { if (ref == 0) {
RegCloseKey(This->hkey);
CoTaskMemFree(This); CoTaskMemFree(This);
DEVENUM_UnlockModule(); DEVENUM_UnlockModule();
} }
@ -119,22 +119,32 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Read(
DWORD type = 0; DWORD type = 0;
RegPropBagImpl *This = impl_from_IPropertyBag(iface); RegPropBagImpl *This = impl_from_IPropertyBag(iface);
HRESULT res = S_OK; HRESULT res = S_OK;
LONG reswin32; LONG reswin32 = ERROR_SUCCESS;
HKEY hkey;
TRACE("(%p)->(%s, %p, %p)\n", This, debugstr_w(pszPropName), pVar, pErrorLog); TRACE("(%p)->(%s, %p, %p)\n", This, debugstr_w(pszPropName), pVar, pErrorLog);
if (!pszPropName || !pVar) if (!pszPropName || !pVar)
return E_POINTER; 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); res = HRESULT_FROM_WIN32(reswin32);
if (SUCCEEDED(res))
{
reswin32 = RegQueryValueExW(hkey, pszPropName, NULL, NULL, NULL, &received);
res = HRESULT_FROM_WIN32(reswin32);
}
if (SUCCEEDED(res)) if (SUCCEEDED(res))
{ {
pData = HeapAlloc(GetProcessHeap(), 0, received); pData = HeapAlloc(GetProcessHeap(), 0, received);
/* work around a GCC bug that occurs here unless we use the reswin32 variable as well */ /* 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); res = HRESULT_FROM_WIN32(reswin32);
} }
@ -215,6 +225,8 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Read(
HeapFree(GetProcessHeap(), 0, pData); HeapFree(GetProcessHeap(), 0, pData);
RegCloseKey(hkey);
TRACE("<- %x\n", res); TRACE("<- %x\n", res);
return res; return res;
} }
@ -229,6 +241,8 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Write(
DWORD cbData = 0; DWORD cbData = 0;
DWORD dwType = 0; DWORD dwType = 0;
HRESULT res = S_OK; HRESULT res = S_OK;
LONG lres = ERROR_SUCCESS;
HKEY hkey;
TRACE("(%p)->(%s, %p)\n", This, debugstr_w(pszPropName), pVar); TRACE("(%p)->(%s, %p)\n", This, debugstr_w(pszPropName), pVar);
@ -265,10 +279,18 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Write(
return E_FAIL; return E_FAIL;
} }
if (RegSetValueExW(This->hkey, if (This->type == DEVICE_FILTER)
pszPropName, 0, lres = RegCreateKeyW(HKEY_CLASSES_ROOT, This->path, &hkey);
dwType, lpData, cbData) != ERROR_SUCCESS) else if (This->type == DEVICE_CODEC)
res = E_FAIL; 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) if (V_VT(pVar) & VT_ARRAY)
res = SafeArrayUnaccessData(V_ARRAY(pVar)); res = SafeArrayUnaccessData(V_ARRAY(pVar));
@ -285,14 +307,28 @@ static const IPropertyBagVtbl IPropertyBag_Vtbl =
DEVENUM_IPropertyBag_Write 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)); RegPropBagImpl * rpb = CoTaskMemAlloc(sizeof(RegPropBagImpl));
if (!rpb) if (!rpb)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
rpb->IPropertyBag_iface.lpVtbl = &IPropertyBag_Vtbl; rpb->IPropertyBag_iface.lpVtbl = &IPropertyBag_Vtbl;
rpb->ref = 1; 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; *ppBag = &rpb->IPropertyBag_iface;
DEVENUM_LockModule(); DEVENUM_LockModule();
return S_OK; return S_OK;
@ -345,7 +381,6 @@ static ULONG WINAPI DEVENUM_IMediaCatMoniker_Release(IMoniker *iface)
TRACE("(%p) ref=%d\n", This, ref); TRACE("(%p) ref=%d\n", This, ref);
if (ref == 0) { if (ref == 0) {
RegCloseKey(This->hkey);
CoTaskMemFree(This->name); CoTaskMemFree(This->name);
CoTaskMemFree(This); CoTaskMemFree(This);
DEVENUM_UnlockModule(); DEVENUM_UnlockModule();
@ -487,9 +522,7 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_BindToStorage(IMoniker *iface, IB
if (IsEqualGUID(riid, &IID_IPropertyBag)) if (IsEqualGUID(riid, &IID_IPropertyBag))
{ {
HANDLE hkey; return create_PropertyBag(This, (IPropertyBag**)ppvObj);
DuplicateHandle(GetCurrentProcess(), This->hkey, GetCurrentProcess(), &hkey, 0, 0, DUPLICATE_SAME_ACCESS);
return DEVENUM_IPropertyBag_Construct(hkey, (IPropertyBag**)ppvObj);
} }
return MK_E_NOSTORAGE; return MK_E_NOSTORAGE;
@ -707,7 +740,6 @@ MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct(void)
pMoniker->IMoniker_iface.lpVtbl = &IMoniker_Vtbl; pMoniker->IMoniker_iface.lpVtbl = &IMoniker_Vtbl;
pMoniker->ref = 0; pMoniker->ref = 0;
pMoniker->hkey = NULL;
pMoniker->has_class = FALSE; pMoniker->has_class = FALSE;
pMoniker->name = NULL; pMoniker->name = NULL;
@ -824,7 +856,6 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
strcpyW(pMoniker->name, buffer); strcpyW(pMoniker->name, buffer);
pMoniker->has_class = TRUE; pMoniker->has_class = TRUE;
pMoniker->class = This->class; pMoniker->class = This->class;
pMoniker->hkey = hkey;
rgelt[fetched] = &pMoniker->IMoniker_iface; rgelt[fetched] = &pMoniker->IMoniker_iface;
fetched++; fetched++;

View File

@ -81,9 +81,7 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayNa
WCHAR buffer[MAX_PATH]; WCHAR buffer[MAX_PATH];
enum device_type type; enum device_type type;
MediaCatMoniker *mon; MediaCatMoniker *mon;
HKEY hbasekey;
CLSID class; CLSID class;
LRESULT res;
TRACE("(%p, %s, %p, %p)\n", pbc, debugstr_w(name), eaten, ret); TRACE("(%p, %s, %p, %p)\n", pbc, debugstr_w(name), eaten, ret);
@ -96,15 +94,11 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayNa
if (name[0] == 's' && name[1] == 'w' && name[2] == ':') if (name[0] == 's' && name[1] == 'w' && name[2] == ':')
{ {
type = DEVICE_FILTER; type = DEVICE_FILTER;
if ((res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsidW, 0, 0, &hbasekey)))
return HRESULT_FROM_WIN32(res);
name += 3; name += 3;
} }
else if (name[0] == 'c' && name[1] == 'm' && name[2] == ':') else if (name[0] == 'c' && name[1] == 'm' && name[2] == ':')
{ {
type = DEVICE_CODEC; type = DEVICE_CODEC;
if ((res = RegOpenKeyExW(HKEY_CURRENT_USER, wszActiveMovieKey, 0, 0, &hbasekey)))
return HRESULT_FROM_WIN32(res);
name += 3; name += 3;
} }
else else
@ -133,21 +127,6 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayNa
} }
strcpyW(mon->name, name); strcpyW(mon->name, name);
buffer[0] = 0;
if (mon->has_class)
{
StringFromGUID2(&mon->class, buffer, CHARS_IN_GUID);
if (mon->type == DEVICE_FILTER)
strcatW(buffer, instanceW);
strcatW(buffer, backslashW);
}
strcatW(buffer, mon->name);
if (RegCreateKeyW(hbasekey, buffer, &mon->hkey))
{
IMoniker_Release(&mon->IMoniker_iface);
return MK_E_NOOBJECT;
}
*ret = &mon->IMoniker_iface; *ret = &mon->IMoniker_iface;
return S_OK; return S_OK;

View File

@ -326,7 +326,6 @@ static void test_directshow_filter(void)
mon = check_display_name(parser, buffer); mon = check_display_name(parser, buffer);
/* Test writing and reading from the property bag */ /* Test writing and reading from the property bag */
todo_wine
ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "filter should not be registered\n"); ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "filter should not be registered\n");
hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
@ -425,7 +424,6 @@ static void test_codec(void)
mon = check_display_name(parser, buffer); mon = check_display_name(parser, buffer);
/* Test writing and reading from the property bag */ /* Test writing and reading from the property bag */
todo_wine
ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "codec should not be registered\n"); ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "codec should not be registered\n");
hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);