- Fixed buffer overflow in IFilterMapper2::RegisterFilter.

- Fixed buffer overflow in DEVENUM_IPropertyBag_Read.
- Fixed NULL pointer de-ref in DllRegisterServer when IFilterMapper2
  is not registered.
- Allowed returning the moniker in IFilterMapper2::RegisterFilter.
- Enumerate special categories without causing infinite loop.
This commit is contained in:
Robert Shearman 2003-12-30 21:52:45 +00:00 committed by Alexandre Julliard
parent bc08f32742
commit e14e101fed
5 changed files with 217 additions and 97 deletions

View File

@ -21,9 +21,11 @@
* - Implements ICreateDevEnum interface which creates an IEnumMoniker * - Implements ICreateDevEnum interface which creates an IEnumMoniker
* implementation * implementation
* - Also creates the special registry keys created at run-time * - Also creates the special registry keys created at run-time
* - ...
*/ */
#define NONAMELESSSTRUCT
#define NONAMELESSUNION
#include "devenum_private.h" #include "devenum_private.h"
#include "wine/debug.h" #include "wine/debug.h"
@ -36,8 +38,9 @@ extern ICOM_VTABLE(IEnumMoniker) IEnumMoniker_Vtbl;
extern HINSTANCE DEVENUM_hInstance; 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};
const WCHAR wszRegSeperator[] = {'\\', 0 };
const WCHAR wszActiveMovieKey[] = {'S','o','f','t','w','a','r','e','\\', static const WCHAR wszRegSeperator[] = {'\\', 0 };
static const WCHAR wszActiveMovieKey[] = {'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\', 'M','i','c','r','o','s','o','f','t','\\',
'A','c','t','i','v','e','M','o','v','i','e','\\', 'A','c','t','i','v','e','M','o','v','i','e','\\',
'd','e','v','e','n','u','m','\\',0}; 'd','e','v','e','n','u','m','\\',0};
@ -125,11 +128,9 @@ HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator(
*ppEnumMoniker = NULL; *ppEnumMoniker = NULL;
if (IsEqualGUID(clsidDeviceClass, &CLSID_AudioRendererCategory) || if (IsEqualGUID(clsidDeviceClass, &CLSID_AudioRendererCategory) ||
IsEqualGUID(clsidDeviceClass, &CLSID_AudioInputDeviceCategory) ||
IsEqualGUID(clsidDeviceClass, &CLSID_MidiRendererCategory)) IsEqualGUID(clsidDeviceClass, &CLSID_MidiRendererCategory))
{ {
if (FAILED(DEVENUM_CreateSpecialCategories()))
return E_FAIL;
hbasekey = HKEY_CURRENT_USER; hbasekey = HKEY_CURRENT_USER;
strcpyW(wszRegKey, wszActiveMovieKey); strcpyW(wszRegKey, wszActiveMovieKey);
@ -151,8 +152,25 @@ HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator(
if (RegOpenKeyW(hbasekey, wszRegKey, &hkey) != ERROR_SUCCESS) if (RegOpenKeyW(hbasekey, wszRegKey, &hkey) != ERROR_SUCCESS)
{ {
FIXME("Category %s not found\n", debugstr_guid(clsidDeviceClass)); if (IsEqualGUID(clsidDeviceClass, &CLSID_AudioRendererCategory) ||
return S_FALSE; IsEqualGUID(clsidDeviceClass, &CLSID_AudioInputDeviceCategory) ||
IsEqualGUID(clsidDeviceClass, &CLSID_MidiRendererCategory))
{
HRESULT hr = DEVENUM_CreateSpecialCategories();
if (FAILED(hr))
return hr;
if (RegOpenKeyW(hbasekey, wszRegKey, &hkey) != ERROR_SUCCESS)
{
ERR("Couldn't open registry key for special device: %s\n",
debugstr_guid(clsidDeviceClass));
return S_FALSE;
}
}
else
{
FIXME("Category %s not found\n", debugstr_guid(clsidDeviceClass));
return S_FALSE;
}
} }
pEnumMoniker = (EnumMonikerImpl *)CoTaskMemAlloc(sizeof(EnumMonikerImpl)); pEnumMoniker = (EnumMonikerImpl *)CoTaskMemAlloc(sizeof(EnumMonikerImpl));
@ -186,23 +204,46 @@ static ICOM_VTABLE(ICreateDevEnum) ICreateDevEnum_Vtbl =
*/ */
CreateDevEnumImpl DEVENUM_CreateDevEnum = { &ICreateDevEnum_Vtbl, 0 }; CreateDevEnumImpl DEVENUM_CreateDevEnum = { &ICreateDevEnum_Vtbl, 0 };
/**********************************************************************
* DEVENUM_CreateAMCategoryKey (INTERNAL)
*
* Creates a registry key for a category at HKEY_CURRENT_USER\Software\
* Microsoft\ActiveMovie\devenum\{clsid}
*/
static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory)
{
WCHAR wszRegKey[MAX_PATH];
HRESULT res = S_OK;
HKEY hkeyDummy = NULL;
strcpyW(wszRegKey, wszActiveMovieKey);
if (!StringFromGUID2(clsidCategory, wszRegKey + strlenW(wszRegKey), sizeof(wszRegKey)/sizeof(wszRegKey[0]) - strlenW(wszRegKey)))
res = E_INVALIDARG;
if (SUCCEEDED(res))
res = HRESULT_FROM_WIN32(
RegCreateKeyW(HKEY_CURRENT_USER, wszRegKey, &hkeyDummy));
if (hkeyDummy)
RegCloseKey(hkeyDummy);
if (FAILED(res))
ERR("Failed to create key HKEY_CURRENT_USER\\%s\n", debugstr_w(wszRegKey));
return res;
}
/********************************************************************** /**********************************************************************
* CreateSpecialCategories (INTERNAL) * DEVENUM_CreateSpecialCategories (INTERNAL)
* *
* Creates the keys in the registry for the dynamic categories * Creates the keys in the registry for the dynamic categories
*/ */
static HRESULT DEVENUM_CreateSpecialCategories() static HRESULT DEVENUM_CreateSpecialCategories()
{ {
HRESULT res = S_OK; HRESULT res;
/* this section below needs some attention - when it is enabled it appears to create WCHAR szDSoundNameFormat[MAX_PATH + 1];
* a circular dependency. IE IFilterMapper2_RegisterFilter calls back into this library WCHAR szDSoundName[MAX_PATH + 1];
* which again calls RegisterFilter.
*/
#if 0
IMoniker * pMoniker = NULL;
WCHAR szAltNameFormat[MAX_PATH + 1];
WCHAR szAltName[MAX_PATH + 1];
DWORD iDefaultDevice = -1; DWORD iDefaultDevice = -1;
UINT numDevs; UINT numDevs;
IFilterMapper2 * pMapper = NULL; IFilterMapper2 * pMapper = NULL;
@ -219,10 +260,16 @@ static HRESULT DEVENUM_CreateSpecialCategories()
rfp2.lpMedium = NULL; rfp2.lpMedium = NULL;
rfp2.clsPinCategory = &IID_NULL; rfp2.clsPinCategory = &IID_NULL;
if (!LoadStringW(DEVENUM_hInstance, IDS_DEVENUM_DS, szDSoundNameFormat, sizeof(szDSoundNameFormat)/sizeof(szDSoundNameFormat[0])-1))
{
ERR("Couldn't get string resource (GetLastError() is %ld)\n", GetLastError());
return HRESULT_FROM_WIN32(GetLastError());
}
res = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, res = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC,
&IID_IFilterMapper2, (void **) &pMapper); &IID_IFilterMapper2, (void **) &pMapper);
/* /*
* Fill in info for out devices * Fill in info for devices
*/ */
if (SUCCEEDED(res)) if (SUCCEEDED(res))
{ {
@ -231,14 +278,20 @@ static HRESULT DEVENUM_CreateSpecialCategories()
WAVEINCAPSW wicaps; WAVEINCAPSW wicaps;
MIDIOUTCAPSW mocaps; MIDIOUTCAPSW mocaps;
REGPINTYPES * pTypes; REGPINTYPES * pTypes;
numDevs = waveOutGetNumDevs(); numDevs = waveOutGetNumDevs();
res = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory);
if (FAILED(res)) /* can't register any devices in this category */
numDevs = 0;
for (i = 0; i < numDevs; i++) for (i = 0; i < numDevs; i++)
{ {
LoadStringW(DEVENUM_hInstance, IDS_DEVENUM_DS, szAltNameFormat, MAX_PATH);
if (waveOutGetDevCapsW(i, &wocaps, sizeof(WAVEOUTCAPSW)) if (waveOutGetDevCapsW(i, &wocaps, sizeof(WAVEOUTCAPSW))
== MMSYSERR_NOERROR) == MMSYSERR_NOERROR)
{ {
IMoniker * pMoniker = NULL;
rfp2.nMediaTypes = 1; rfp2.nMediaTypes = 1;
pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES)); pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES));
if (!pTypes) if (!pTypes)
@ -253,7 +306,7 @@ static HRESULT DEVENUM_CreateSpecialCategories()
rfp2.lpMediaType = pTypes; rfp2.lpMediaType = pTypes;
IFilterMapper2_RegisterFilter(pMapper, res = IFilterMapper2_RegisterFilter(pMapper,
&CLSID_AudioRender, &CLSID_AudioRender,
wocaps.szPname, wocaps.szPname,
&pMoniker, &pMoniker,
@ -266,13 +319,13 @@ static HRESULT DEVENUM_CreateSpecialCategories()
if (pMoniker) if (pMoniker)
IMoniker_Release(pMoniker); IMoniker_Release(pMoniker);
wsprintfW(szAltName, szAltNameFormat, wocaps.szPname); wsprintfW(szDSoundName, szDSoundNameFormat, wocaps.szPname);
IFilterMapper2_RegisterFilter(pMapper, res = IFilterMapper2_RegisterFilter(pMapper,
&CLSID_DSoundRender, &CLSID_DSoundRender,
szAltName, szDSoundName,
&pMoniker, &pMoniker,
&CLSID_AudioRendererCategory, &CLSID_AudioRendererCategory,
szAltName, szDSoundName,
&rf2); &rf2);
/* FIXME: do additional stuff with IMoniker here, depending on what RegisterFilter does */ /* FIXME: do additional stuff with IMoniker here, depending on what RegisterFilter does */
@ -291,11 +344,17 @@ static HRESULT DEVENUM_CreateSpecialCategories()
numDevs = waveInGetNumDevs(); numDevs = waveInGetNumDevs();
res = DEVENUM_CreateAMCategoryKey(&CLSID_AudioInputDeviceCategory);
if (FAILED(res)) /* can't register any devices in this category */
numDevs = 0;
for (i = 0; i < numDevs; i++) for (i = 0; i < numDevs; i++)
{ {
if (waveInGetDevCapsW(i, &wicaps, sizeof(WAVEINCAPSW)) if (waveInGetDevCapsW(i, &wicaps, sizeof(WAVEINCAPSW))
== MMSYSERR_NOERROR) == MMSYSERR_NOERROR)
{ {
IMoniker * pMoniker = NULL;
rfp2.nMediaTypes = 1; rfp2.nMediaTypes = 1;
pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES)); pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES));
if (!pTypes) if (!pTypes)
@ -310,7 +369,7 @@ static HRESULT DEVENUM_CreateSpecialCategories()
rfp2.lpMediaType = pTypes; rfp2.lpMediaType = pTypes;
IFilterMapper2_RegisterFilter(pMapper, res = IFilterMapper2_RegisterFilter(pMapper,
&CLSID_AudioRecord, &CLSID_AudioRecord,
wicaps.szPname, wicaps.szPname,
&pMoniker, &pMoniker,
@ -326,13 +385,20 @@ static HRESULT DEVENUM_CreateSpecialCategories()
CoTaskMemFree(pTypes); CoTaskMemFree(pTypes);
} }
} }
numDevs = midiOutGetNumDevs(); numDevs = midiOutGetNumDevs();
res = DEVENUM_CreateAMCategoryKey(&CLSID_MidiRendererCategory);
if (FAILED(res)) /* can't register any devices in this category */
numDevs = 0;
for (i = 0; i < numDevs; i++) for (i = 0; i < numDevs; i++)
{ {
if (midiOutGetDevCapsW(i, &mocaps, sizeof(MIDIOUTCAPSW)) if (midiOutGetDevCapsW(i, &mocaps, sizeof(MIDIOUTCAPSW))
== MMSYSERR_NOERROR) == MMSYSERR_NOERROR)
{ {
IMoniker * pMoniker = NULL;
rfp2.nMediaTypes = 1; rfp2.nMediaTypes = 1;
pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES)); pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES));
if (!pTypes) if (!pTypes)
@ -347,7 +413,7 @@ static HRESULT DEVENUM_CreateSpecialCategories()
rfp2.lpMediaType = pTypes; rfp2.lpMediaType = pTypes;
IFilterMapper2_RegisterFilter(pMapper, res = IFilterMapper2_RegisterFilter(pMapper,
&CLSID_AVIMIDIRender, &CLSID_AVIMIDIRender,
mocaps.szPname, mocaps.szPname,
&pMoniker, &pMoniker,
@ -373,6 +439,5 @@ static HRESULT DEVENUM_CreateSpecialCategories()
if (pMapper) if (pMapper)
IFilterMapper2_Release(pMapper); IFilterMapper2_Release(pMapper);
#endif
return res; return res;
} }

View File

@ -36,6 +36,7 @@ typedef struct
} register_info; } register_info;
static HRESULT register_clsids(int count, const register_info * pRegInfo, LPCWSTR pszThreadingModel); static HRESULT register_clsids(int count, const register_info * pRegInfo, LPCWSTR pszThreadingModel);
static void DEVENUM_RegisterQuartz(void);
/*********************************************************************** /***********************************************************************
* Global string constant definitions * Global string constant definitions
@ -100,20 +101,21 @@ HRESULT WINAPI DEVENUM_DllRegisterServer(void)
HKEY hkey2 = NULL; HKEY hkey2 = NULL;
LPOLESTR pszClsidDevMon = NULL; LPOLESTR pszClsidDevMon = NULL;
IFilterMapper2 * pMapper = NULL; IFilterMapper2 * pMapper = NULL;
const WCHAR threadingModel[] = {'B','o','t','h',0}; LPVOID mapvptr;
const WCHAR sysdevenum[] = {'S','y','s','t','e','m',' ','D','e','v','i','c','e',' ','E','n','u','m',0}; static const WCHAR threadingModel[] = {'B','o','t','h',0};
const WCHAR devmon[] = {'D','e','v','i','c','e','M','o','n','i','k','e','r',0}; static const WCHAR sysdevenum[] = {'S','y','s','t','e','m',' ','D','e','v','i','c','e',' ','E','n','u','m',0};
const WCHAR acmcat[] = {'A','C','M',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0}; static const WCHAR devmon[] = {'D','e','v','i','c','e','M','o','n','i','k','e','r',0};
const WCHAR vidcat[] = {'I','C','M',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0}; static const WCHAR acmcat[] = {'A','C','M',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0};
const WCHAR filtcat[] = {'A','c','t','i','v','e','M','o','v','i','e',' ','F','i','l','t','e','r',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0}; static const WCHAR vidcat[] = {'I','C','M',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0};
const WCHAR vfwcat[] = {'V','F','W',' ','C','a','p','t','u','r','e',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0}; static const WCHAR filtcat[] = {'A','c','t','i','v','e','M','o','v','i','e',' ','F','i','l','t','e','r',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0};
const WCHAR wavein[] = {'W','a','v','e','I','n',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r', 0}; static const WCHAR vfwcat[] = {'V','F','W',' ','C','a','p','t','u','r','e',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0};
const WCHAR waveout[] = {'W','a','v','e','O','u','t',' ','a','n','d',' ','D','S','o','u','n','d',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0}; static const WCHAR wavein[] = {'W','a','v','e','I','n',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r', 0};
const WCHAR midiout[] = {'M','i','d','i','O','u','t',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0}; static const WCHAR waveout[] = {'W','a','v','e','O','u','t',' ','a','n','d',' ','D','S','o','u','n','d',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0};
const WCHAR amcat[] = {'A','c','t','i','v','e','M','o','v','i','e',' ','F','i','l','t','e','r',' ','C','a','t','e','g','o','r','i','e','s',0}; static const WCHAR midiout[] = {'M','i','d','i','O','u','t',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0};
const WCHAR device[] = {'d','e','v','i','c','e',0}; static const WCHAR amcat[] = {'A','c','t','i','v','e','M','o','v','i','e',' ','F','i','l','t','e','r',' ','C','a','t','e','g','o','r','i','e','s',0};
const WCHAR device_1[] = {'d','e','v','i','c','e','.','1',0}; static const WCHAR device[] = {'d','e','v','i','c','e',0};
const register_info ri[] = static const WCHAR device_1[] = {'d','e','v','i','c','e','.','1',0};
static const register_info ri[] =
{ {
{&CLSID_SystemDeviceEnum, sysdevenum, FALSE}, {&CLSID_SystemDeviceEnum, sysdevenum, FALSE},
{&CLSID_CDeviceMoniker, devmon, FALSE}, {&CLSID_CDeviceMoniker, devmon, FALSE},
@ -131,37 +133,40 @@ HRESULT WINAPI DEVENUM_DllRegisterServer(void)
res = register_clsids(sizeof(ri) / sizeof(register_info), ri, threadingModel); res = register_clsids(sizeof(ri) / sizeof(register_info), ri, threadingModel);
/* Quartz is needed for IFilterMapper2 */
DEVENUM_RegisterQuartz();
/*** ActiveMovieFilter Categories ***/ /*** ActiveMovieFilter Categories ***/
{
const WCHAR friendlyvidcap[] = {'V','i','d','e','o',' ','C','a','p','t','u','r','e',' ','S','o','u','r','c','e','s',0};
const WCHAR friendlydshow[] = {'D','i','r','e','c','t','S','h','o','w',' ','F','i','l','t','e','r','s',0};
const WCHAR friendlyvidcomp[] = {'V','i','d','e','o',' ','C','o','m','p','r','e','s','s','o','r','s',0};
const WCHAR friendlyaudcap[] = {'A','u','d','i','o',' ','C','a','p','t','u','r','e',' ','S','o','u','r','c','e','s',0};
const WCHAR friendlyaudcomp[] = {'A','u','d','i','o',' ','C','o','m','p','r','e','s','s','o','r','s',0};
const WCHAR friendlyaudrend[] = {'A','u','d','i','o',' ','R','e','n','d','e','r','e','r','s',0};
const WCHAR friendlymidirend[] = {'M','i','d','i',' ','R','e','n','d','e','r','e','r','s',0};
const WCHAR friendlyextrend[] = {'E','x','t','e','r','n','a','l',' ','R','e','n','d','e','r','e','r','s',0};
const WCHAR friendlydevctrl[] = {'D','e','v','i','c','e',' ','C','o','n','t','r','o','l',' ','F','i','l','t','e','r','s',0};
LPVOID mapvptr;
CoInitialize(NULL); CoInitialize(NULL);
res = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, res = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC,
&IID_IFilterMapper2, &mapvptr); &IID_IFilterMapper2, &mapvptr);
pMapper = (IFilterMapper2*)mapvptr; if (SUCCEEDED(res))
{
static const WCHAR friendlyvidcap[] = {'V','i','d','e','o',' ','C','a','p','t','u','r','e',' ','S','o','u','r','c','e','s',0};
static const WCHAR friendlydshow[] = {'D','i','r','e','c','t','S','h','o','w',' ','F','i','l','t','e','r','s',0};
static const WCHAR friendlyvidcomp[] = {'V','i','d','e','o',' ','C','o','m','p','r','e','s','s','o','r','s',0};
static const WCHAR friendlyaudcap[] = {'A','u','d','i','o',' ','C','a','p','t','u','r','e',' ','S','o','u','r','c','e','s',0};
static const WCHAR friendlyaudcomp[] = {'A','u','d','i','o',' ','C','o','m','p','r','e','s','s','o','r','s',0};
static const WCHAR friendlyaudrend[] = {'A','u','d','i','o',' ','R','e','n','d','e','r','e','r','s',0};
static const WCHAR friendlymidirend[] = {'M','i','d','i',' ','R','e','n','d','e','r','e','r','s',0};
static const WCHAR friendlyextrend[] = {'E','x','t','e','r','n','a','l',' ','R','e','n','d','e','r','e','r','s',0};
static const WCHAR friendlydevctrl[] = {'D','e','v','i','c','e',' ','C','o','n','t','r','o','l',' ','F','i','l','t','e','r','s',0};
IFilterMapper2_CreateCategory(pMapper, &CLSID_VideoInputDeviceCategory, MERIT_DO_NOT_USE, friendlyvidcap); pMapper = (IFilterMapper2*)mapvptr;
IFilterMapper2_CreateCategory(pMapper, &CLSID_LegacyAmFilterCategory, MERIT_NORMAL, friendlydshow);
IFilterMapper2_CreateCategory(pMapper, &CLSID_VideoCompressorCategory, MERIT_DO_NOT_USE, friendlyvidcomp);
IFilterMapper2_CreateCategory(pMapper, &CLSID_AudioInputDeviceCategory, MERIT_DO_NOT_USE, friendlyaudcap);
IFilterMapper2_CreateCategory(pMapper, &CLSID_AudioCompressorCategory, MERIT_DO_NOT_USE, friendlyaudcomp);
IFilterMapper2_CreateCategory(pMapper, &CLSID_AudioRendererCategory, MERIT_NORMAL, friendlyaudrend);
IFilterMapper2_CreateCategory(pMapper, &CLSID_MidiRendererCategory, MERIT_NORMAL, friendlymidirend);
IFilterMapper2_CreateCategory(pMapper, &CLSID_TransmitCategory, MERIT_DO_NOT_USE, friendlyextrend);
IFilterMapper2_CreateCategory(pMapper, &CLSID_DeviceControlCategory, MERIT_DO_NOT_USE, friendlydevctrl);
IFilterMapper2_Release(pMapper); IFilterMapper2_CreateCategory(pMapper, &CLSID_VideoInputDeviceCategory, MERIT_DO_NOT_USE, friendlyvidcap);
CoUninitialize(); IFilterMapper2_CreateCategory(pMapper, &CLSID_LegacyAmFilterCategory, MERIT_NORMAL, friendlydshow);
IFilterMapper2_CreateCategory(pMapper, &CLSID_VideoCompressorCategory, MERIT_DO_NOT_USE, friendlyvidcomp);
IFilterMapper2_CreateCategory(pMapper, &CLSID_AudioInputDeviceCategory, MERIT_DO_NOT_USE, friendlyaudcap);
IFilterMapper2_CreateCategory(pMapper, &CLSID_AudioCompressorCategory, MERIT_DO_NOT_USE, friendlyaudcomp);
IFilterMapper2_CreateCategory(pMapper, &CLSID_AudioRendererCategory, MERIT_NORMAL, friendlyaudrend);
IFilterMapper2_CreateCategory(pMapper, &CLSID_MidiRendererCategory, MERIT_NORMAL, friendlymidirend);
IFilterMapper2_CreateCategory(pMapper, &CLSID_TransmitCategory, MERIT_DO_NOT_USE, friendlyextrend);
IFilterMapper2_CreateCategory(pMapper, &CLSID_DeviceControlCategory, MERIT_DO_NOT_USE, friendlydevctrl);
IFilterMapper2_Release(pMapper);
} }
/*** CDeviceMoniker ***/ /*** CDeviceMoniker ***/
@ -181,7 +186,7 @@ HRESULT WINAPI DEVENUM_DllRegisterServer(void)
} }
if (SUCCEEDED(res)) if (SUCCEEDED(res))
{ {
const WCHAR wszProgID[] = {'P','r','o','g','I','D',0}; static const WCHAR wszProgID[] = {'P','r','o','g','I','D',0};
res = RegCreateKeyW(hkey1, wszProgID, &hkey2) res = RegCreateKeyW(hkey1, wszProgID, &hkey2)
== ERROR_SUCCESS ? S_OK : E_FAIL; == ERROR_SUCCESS ? S_OK : E_FAIL;
} }
@ -190,10 +195,16 @@ HRESULT WINAPI DEVENUM_DllRegisterServer(void)
res = RegSetValueW(hkey2, NULL, REG_SZ, device_1, (lstrlenW(device_1) + 1) * sizeof(WCHAR)) res = RegSetValueW(hkey2, NULL, REG_SZ, device_1, (lstrlenW(device_1) + 1) * sizeof(WCHAR))
== ERROR_SUCCESS ? S_OK : E_FAIL; == ERROR_SUCCESS ? S_OK : E_FAIL;
} }
RegCloseKey(hkey2);
if (hkey2)
{
RegCloseKey(hkey2);
hkey2 = NULL;
}
if (SUCCEEDED(res)) if (SUCCEEDED(res))
{ {
const WCHAR wszVProgID[] = {'V','e','r','s','i','o','n','I','n','d','e','p','e','d','e','n','t','P','r','o','g','I','D',0}; static const WCHAR wszVProgID[] = {'V','e','r','s','i','o','n','I','n','d','e','p','e','d','e','n','t','P','r','o','g','I','D',0};
res = RegCreateKeyW(hkey1, wszVProgID, &hkey2) res = RegCreateKeyW(hkey1, wszVProgID, &hkey2)
== ERROR_SUCCESS ? S_OK : E_FAIL; == ERROR_SUCCESS ? S_OK : E_FAIL;
} }
@ -202,8 +213,19 @@ HRESULT WINAPI DEVENUM_DllRegisterServer(void)
res = RegSetValueW(hkey2, NULL, REG_SZ, device, (lstrlenW(device) + 1) * sizeof(WCHAR)) res = RegSetValueW(hkey2, NULL, REG_SZ, device, (lstrlenW(device) + 1) * sizeof(WCHAR))
== ERROR_SUCCESS ? S_OK : E_FAIL; == ERROR_SUCCESS ? S_OK : E_FAIL;
} }
RegCloseKey(hkey2);
RegCloseKey(hkey1); if (hkey2)
{
RegCloseKey(hkey2);
hkey2 = NULL;
}
if (hkey1)
{
RegCloseKey(hkey1);
hkey1 = NULL;
}
if (SUCCEEDED(res)) if (SUCCEEDED(res))
{ {
res = RegCreateKeyW(HKEY_CLASSES_ROOT, device, &hkey1) res = RegCreateKeyW(HKEY_CLASSES_ROOT, device, &hkey1)
@ -219,8 +241,17 @@ HRESULT WINAPI DEVENUM_DllRegisterServer(void)
res = RegSetValueW(hkey2, NULL, REG_SZ, pszClsidDevMon, (lstrlenW(pszClsidDevMon) + 1) * sizeof(WCHAR)) res = RegSetValueW(hkey2, NULL, REG_SZ, pszClsidDevMon, (lstrlenW(pszClsidDevMon) + 1) * sizeof(WCHAR))
== ERROR_SUCCESS ? S_OK : E_FAIL; == ERROR_SUCCESS ? S_OK : E_FAIL;
} }
RegCloseKey(hkey2); if (hkey2)
RegCloseKey(hkey1); {
RegCloseKey(hkey2);
hkey2 = NULL;
}
if (hkey1)
{
RegCloseKey(hkey1);
hkey1 = NULL;
}
if (SUCCEEDED(res)) if (SUCCEEDED(res))
{ {
@ -237,14 +268,21 @@ HRESULT WINAPI DEVENUM_DllRegisterServer(void)
res = RegSetValueW(hkey2, NULL, REG_SZ, pszClsidDevMon, (lstrlenW(pszClsidDevMon) + 1) * sizeof(WCHAR)) res = RegSetValueW(hkey2, NULL, REG_SZ, pszClsidDevMon, (lstrlenW(pszClsidDevMon) + 1) * sizeof(WCHAR))
== ERROR_SUCCESS ? S_OK : E_FAIL; == ERROR_SUCCESS ? S_OK : E_FAIL;
} }
RegCloseKey(hkey2);
RegCloseKey(hkey1);
RegCloseKey(hkeyClsid); if (hkey2)
RegCloseKey(hkey2);
if (hkey1)
RegCloseKey(hkey1);
if (hkeyClsid)
RegCloseKey(hkeyClsid);
if (pszClsidDevMon) if (pszClsidDevMon)
CoTaskMemFree(pszClsidDevMon); CoTaskMemFree(pszClsidDevMon);
CoUninitialize();
return res; return res;
} }
@ -329,3 +367,20 @@ static HRESULT register_clsids(int count, const register_info * pRegInfo, LPCWST
return res; return res;
} }
typedef HRESULT (WINAPI *DllRegisterServer_func)(void);
/* calls DllRegisterServer() for the Quartz DLL */
static void DEVENUM_RegisterQuartz()
{
HANDLE hDLL = LoadLibraryA("quartz.dll");
DllRegisterServer_func pDllRegisterServer = NULL;
if (hDLL)
pDllRegisterServer = (DllRegisterServer_func)GetProcAddress(hDLL, "DllRegisterServer");
if (pDllRegisterServer)
{
HRESULT hr = pDllRegisterServer();
if (FAILED(hr))
ERR("Failed to register Quartz. Error was 0x%lx)\n", hr);
}
}

View File

@ -130,15 +130,15 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Read(
switch (V_VT(pVar)) switch (V_VT(pVar))
{ {
case VT_LPWSTR: case VT_LPWSTR:
V_UNION(pVar, bstrVal) = CoTaskMemAlloc(received * sizeof(WCHAR)); V_UNION(pVar, bstrVal) = CoTaskMemAlloc(received);
strcpyW(V_UNION(pVar, bstrVal), (LPWSTR)pData); memcpy(V_UNION(pVar, bstrVal), (LPWSTR)pData, received);
res = S_OK; res = S_OK;
break; break;
case VT_EMPTY: case VT_EMPTY:
V_VT(pVar) = VT_BSTR; V_VT(pVar) = VT_BSTR;
/* fall through */ /* fall through */
case VT_BSTR: case VT_BSTR:
V_UNION(pVar, bstrVal) = SysAllocStringLen((LPWSTR)pData, received - 1); V_UNION(pVar, bstrVal) = SysAllocStringLen((LPWSTR)pData, received/sizeof(WCHAR) - 1);
res = S_OK; res = S_OK;
break; break;
} }

View File

@ -90,8 +90,8 @@ static ULONG WINAPI DEVENUM_IParseDisplayName_Release(LPPARSEDISPLAYNAME iface)
* Creates a moniker referenced to by the display string argument * Creates a moniker referenced to by the display string argument
* *
* POSSIBLE BUGS: * POSSIBLE BUGS:
* Might not handle more complicated strings properly (ie not in * Might not handle more complicated strings properly (ie anything
* "@device:sw:{CLSID1}\{CLSID2}" format * not in "@device:sw:{CLSID1}\<filter name or CLSID>" format
*/ */
static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName( static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(
LPPARSEDISPLAYNAME iface, LPPARSEDISPLAYNAME iface,
@ -106,6 +106,7 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(
MediaCatMoniker * pMoniker = NULL; MediaCatMoniker * pMoniker = NULL;
CLSID clsidDevice; CLSID clsidDevice;
HRESULT res = S_OK; HRESULT res = S_OK;
TRACE("(%p, %s, %p, %p)\n", pbc, debugstr_w(pszDisplayName), pchEaten, ppmkOut); TRACE("(%p, %s, %p, %p)\n", pbc, debugstr_w(pszDisplayName), pchEaten, ppmkOut);
*ppmkOut = NULL; *ppmkOut = NULL;

View File

@ -628,7 +628,7 @@ static HRESULT WINAPI FilterMapper2_RegisterFilter(
IBindCtx * pBindCtx = NULL; IBindCtx * pBindCtx = NULL;
IMoniker * pMoniker = NULL; IMoniker * pMoniker = NULL;
IPropertyBag * pPropBag = NULL; IPropertyBag * pPropBag = NULL;
HRESULT hr = S_OK; HRESULT hr;
LPWSTR pwszParseName = NULL; LPWSTR pwszParseName = NULL;
LPWSTR pCurrent; LPWSTR pCurrent;
static const WCHAR wszDevice[] = {'@','d','e','v','i','c','e',':','s','w',':',0}; static const WCHAR wszDevice[] = {'@','d','e','v','i','c','e',':','s','w',':',0};
@ -644,15 +644,15 @@ static HRESULT WINAPI FilterMapper2_RegisterFilter(
debugstr_w(szInstance), debugstr_w(szInstance),
prf2); prf2);
if (ppMoniker)
FIXME("ppMoniker != NULL not supported at the moment\n");
if (prf2->dwVersion != 2) if (prf2->dwVersion != 2)
{ {
FIXME("dwVersion != 2 not supported at the moment\n"); FIXME("dwVersion != 2 not supported at the moment\n");
return E_NOTIMPL; return E_NOTIMPL;
} }
if (ppMoniker)
*ppMoniker = NULL;
if (!pclsidCategory) if (!pclsidCategory)
pclsidCategory = &CLSID_ActiveMovieCategories; pclsidCategory = &CLSID_ActiveMovieCategories;
@ -667,8 +667,7 @@ static HRESULT WINAPI FilterMapper2_RegisterFilter(
else else
nameLen += CHARS_IN_GUID - 1; /* CHARS_IN_GUID includes null terminator */ nameLen += CHARS_IN_GUID - 1; /* CHARS_IN_GUID includes null terminator */
pwszParseName = CoTaskMemAlloc(nameLen); pCurrent = pwszParseName = CoTaskMemAlloc(nameLen*sizeof(WCHAR));
pCurrent = pwszParseName;
if (!pwszParseName) if (!pwszParseName)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
@ -676,12 +675,13 @@ static HRESULT WINAPI FilterMapper2_RegisterFilter(
pCurrent += strlenW(wszDevice); pCurrent += strlenW(wszDevice);
hr = StringFromCLSID(pclsidCategory, &szClsidTemp); hr = StringFromCLSID(pclsidCategory, &szClsidTemp);
strcpyW(pCurrent, szClsidTemp);
pCurrent += CHARS_IN_GUID - 1;
pCurrent[0] = '\\';
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
strncpyW(pCurrent, szClsidTemp, CHARS_IN_GUID);
pCurrent += CHARS_IN_GUID - 1;
pCurrent[0] = '\\';
if (szInstance) if (szInstance)
strcpyW(pCurrent+1, szInstance); strcpyW(pCurrent+1, szInstance);
else else
@ -692,7 +692,8 @@ static HRESULT WINAPI FilterMapper2_RegisterFilter(
szClsidTemp = NULL; szClsidTemp = NULL;
} }
hr = StringFromCLSID(clsidFilter, &szClsidTemp); hr = StringFromCLSID(clsidFilter, &szClsidTemp);
strcpyW(pCurrent+1, szClsidTemp); if (SUCCEEDED(hr))
strcpyW(pCurrent+1, szClsidTemp);
} }
} }
@ -703,13 +704,10 @@ static HRESULT WINAPI FilterMapper2_RegisterFilter(
hr = CreateBindCtx(0, &pBindCtx); hr = CreateBindCtx(0, &pBindCtx);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{
hr = IParseDisplayName_ParseDisplayName(pParser, pBindCtx, pwszParseName, &ulEaten, &pMoniker); hr = IParseDisplayName_ParseDisplayName(pParser, pBindCtx, pwszParseName, &ulEaten, &pMoniker);
}
if (pBindCtx) if (pBindCtx)
IBindCtx_Release(pBindCtx); pBindCtx = NULL; IBindCtx_Release(pBindCtx); pBindCtx = NULL;
if (pParser) if (pParser)
IParseDisplayName_Release(pParser); pParser = NULL; IParseDisplayName_Release(pParser); pParser = NULL;
@ -725,15 +723,16 @@ static HRESULT WINAPI FilterMapper2_RegisterFilter(
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
hr = FM2_WriteFilterData(pPropBag, prf2); hr = FM2_WriteFilterData(pPropBag, prf2);
if (pMoniker)
IMoniker_Release(pMoniker); pMoniker = NULL;
if (pPropBag) if (pPropBag)
IPropertyBag_Release(pPropBag); pPropBag = NULL; IPropertyBag_Release(pPropBag); pPropBag = NULL;
if (szClsidTemp) if (szClsidTemp)
CoTaskMemFree(szClsidTemp); CoTaskMemFree(szClsidTemp);
if (SUCCEEDED(hr) && ppMoniker)
*ppMoniker = pMoniker;
else if (pMoniker)
IMoniker_Release(pMoniker); pMoniker = NULL;
TRACE("-- returning %lx\n", hr); TRACE("-- returning %lx\n", hr);
return hr; return hr;