- 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:
parent
bc08f32742
commit
e14e101fed
|
@ -21,9 +21,11 @@
|
|||
* - Implements ICreateDevEnum interface which creates an IEnumMoniker
|
||||
* implementation
|
||||
* - Also creates the special registry keys created at run-time
|
||||
* - ...
|
||||
*/
|
||||
|
||||
#define NONAMELESSSTRUCT
|
||||
#define NONAMELESSUNION
|
||||
|
||||
#include "devenum_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
@ -36,8 +38,9 @@ extern ICOM_VTABLE(IEnumMoniker) IEnumMoniker_Vtbl;
|
|||
extern HINSTANCE DEVENUM_hInstance;
|
||||
|
||||
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','\\',
|
||||
'A','c','t','i','v','e','M','o','v','i','e','\\',
|
||||
'd','e','v','e','n','u','m','\\',0};
|
||||
|
@ -125,11 +128,9 @@ HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator(
|
|||
*ppEnumMoniker = NULL;
|
||||
|
||||
if (IsEqualGUID(clsidDeviceClass, &CLSID_AudioRendererCategory) ||
|
||||
IsEqualGUID(clsidDeviceClass, &CLSID_AudioInputDeviceCategory) ||
|
||||
IsEqualGUID(clsidDeviceClass, &CLSID_MidiRendererCategory))
|
||||
{
|
||||
if (FAILED(DEVENUM_CreateSpecialCategories()))
|
||||
return E_FAIL;
|
||||
|
||||
hbasekey = HKEY_CURRENT_USER;
|
||||
strcpyW(wszRegKey, wszActiveMovieKey);
|
||||
|
||||
|
@ -151,8 +152,25 @@ HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator(
|
|||
|
||||
if (RegOpenKeyW(hbasekey, wszRegKey, &hkey) != ERROR_SUCCESS)
|
||||
{
|
||||
FIXME("Category %s not found\n", debugstr_guid(clsidDeviceClass));
|
||||
return S_FALSE;
|
||||
if (IsEqualGUID(clsidDeviceClass, &CLSID_AudioRendererCategory) ||
|
||||
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));
|
||||
|
@ -186,23 +204,46 @@ static ICOM_VTABLE(ICreateDevEnum) ICreateDevEnum_Vtbl =
|
|||
*/
|
||||
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
|
||||
*/
|
||||
static HRESULT DEVENUM_CreateSpecialCategories()
|
||||
{
|
||||
HRESULT res = S_OK;
|
||||
/* this section below needs some attention - when it is enabled it appears to create
|
||||
* a circular dependency. IE IFilterMapper2_RegisterFilter calls back into this library
|
||||
* which again calls RegisterFilter.
|
||||
*/
|
||||
#if 0
|
||||
IMoniker * pMoniker = NULL;
|
||||
WCHAR szAltNameFormat[MAX_PATH + 1];
|
||||
WCHAR szAltName[MAX_PATH + 1];
|
||||
HRESULT res;
|
||||
WCHAR szDSoundNameFormat[MAX_PATH + 1];
|
||||
WCHAR szDSoundName[MAX_PATH + 1];
|
||||
DWORD iDefaultDevice = -1;
|
||||
UINT numDevs;
|
||||
IFilterMapper2 * pMapper = NULL;
|
||||
|
@ -219,10 +260,16 @@ static HRESULT DEVENUM_CreateSpecialCategories()
|
|||
rfp2.lpMedium = 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,
|
||||
&IID_IFilterMapper2, (void **) &pMapper);
|
||||
/*
|
||||
* Fill in info for out devices
|
||||
* Fill in info for devices
|
||||
*/
|
||||
if (SUCCEEDED(res))
|
||||
{
|
||||
|
@ -231,14 +278,20 @@ static HRESULT DEVENUM_CreateSpecialCategories()
|
|||
WAVEINCAPSW wicaps;
|
||||
MIDIOUTCAPSW mocaps;
|
||||
REGPINTYPES * pTypes;
|
||||
|
||||
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++)
|
||||
{
|
||||
LoadStringW(DEVENUM_hInstance, IDS_DEVENUM_DS, szAltNameFormat, MAX_PATH);
|
||||
if (waveOutGetDevCapsW(i, &wocaps, sizeof(WAVEOUTCAPSW))
|
||||
== MMSYSERR_NOERROR)
|
||||
{
|
||||
IMoniker * pMoniker = NULL;
|
||||
|
||||
rfp2.nMediaTypes = 1;
|
||||
pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES));
|
||||
if (!pTypes)
|
||||
|
@ -253,7 +306,7 @@ static HRESULT DEVENUM_CreateSpecialCategories()
|
|||
|
||||
rfp2.lpMediaType = pTypes;
|
||||
|
||||
IFilterMapper2_RegisterFilter(pMapper,
|
||||
res = IFilterMapper2_RegisterFilter(pMapper,
|
||||
&CLSID_AudioRender,
|
||||
wocaps.szPname,
|
||||
&pMoniker,
|
||||
|
@ -266,13 +319,13 @@ static HRESULT DEVENUM_CreateSpecialCategories()
|
|||
if (pMoniker)
|
||||
IMoniker_Release(pMoniker);
|
||||
|
||||
wsprintfW(szAltName, szAltNameFormat, wocaps.szPname);
|
||||
IFilterMapper2_RegisterFilter(pMapper,
|
||||
wsprintfW(szDSoundName, szDSoundNameFormat, wocaps.szPname);
|
||||
res = IFilterMapper2_RegisterFilter(pMapper,
|
||||
&CLSID_DSoundRender,
|
||||
szAltName,
|
||||
szDSoundName,
|
||||
&pMoniker,
|
||||
&CLSID_AudioRendererCategory,
|
||||
szAltName,
|
||||
szDSoundName,
|
||||
&rf2);
|
||||
|
||||
/* FIXME: do additional stuff with IMoniker here, depending on what RegisterFilter does */
|
||||
|
@ -291,11 +344,17 @@ static HRESULT DEVENUM_CreateSpecialCategories()
|
|||
|
||||
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++)
|
||||
{
|
||||
if (waveInGetDevCapsW(i, &wicaps, sizeof(WAVEINCAPSW))
|
||||
== MMSYSERR_NOERROR)
|
||||
{
|
||||
IMoniker * pMoniker = NULL;
|
||||
|
||||
rfp2.nMediaTypes = 1;
|
||||
pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES));
|
||||
if (!pTypes)
|
||||
|
@ -310,7 +369,7 @@ static HRESULT DEVENUM_CreateSpecialCategories()
|
|||
|
||||
rfp2.lpMediaType = pTypes;
|
||||
|
||||
IFilterMapper2_RegisterFilter(pMapper,
|
||||
res = IFilterMapper2_RegisterFilter(pMapper,
|
||||
&CLSID_AudioRecord,
|
||||
wicaps.szPname,
|
||||
&pMoniker,
|
||||
|
@ -326,13 +385,20 @@ static HRESULT DEVENUM_CreateSpecialCategories()
|
|||
CoTaskMemFree(pTypes);
|
||||
}
|
||||
}
|
||||
|
||||
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++)
|
||||
{
|
||||
if (midiOutGetDevCapsW(i, &mocaps, sizeof(MIDIOUTCAPSW))
|
||||
== MMSYSERR_NOERROR)
|
||||
{
|
||||
IMoniker * pMoniker = NULL;
|
||||
|
||||
rfp2.nMediaTypes = 1;
|
||||
pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES));
|
||||
if (!pTypes)
|
||||
|
@ -347,7 +413,7 @@ static HRESULT DEVENUM_CreateSpecialCategories()
|
|||
|
||||
rfp2.lpMediaType = pTypes;
|
||||
|
||||
IFilterMapper2_RegisterFilter(pMapper,
|
||||
res = IFilterMapper2_RegisterFilter(pMapper,
|
||||
&CLSID_AVIMIDIRender,
|
||||
mocaps.szPname,
|
||||
&pMoniker,
|
||||
|
@ -373,6 +439,5 @@ static HRESULT DEVENUM_CreateSpecialCategories()
|
|||
|
||||
if (pMapper)
|
||||
IFilterMapper2_Release(pMapper);
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ typedef struct
|
|||
} register_info;
|
||||
|
||||
static HRESULT register_clsids(int count, const register_info * pRegInfo, LPCWSTR pszThreadingModel);
|
||||
static void DEVENUM_RegisterQuartz(void);
|
||||
|
||||
/***********************************************************************
|
||||
* Global string constant definitions
|
||||
|
@ -100,20 +101,21 @@ HRESULT WINAPI DEVENUM_DllRegisterServer(void)
|
|||
HKEY hkey2 = NULL;
|
||||
LPOLESTR pszClsidDevMon = NULL;
|
||||
IFilterMapper2 * pMapper = NULL;
|
||||
const WCHAR threadingModel[] = {'B','o','t','h',0};
|
||||
const WCHAR sysdevenum[] = {'S','y','s','t','e','m',' ','D','e','v','i','c','e',' ','E','n','u','m',0};
|
||||
const WCHAR devmon[] = {'D','e','v','i','c','e','M','o','n','i','k','e','r',0};
|
||||
const WCHAR acmcat[] = {'A','C','M',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0};
|
||||
const WCHAR vidcat[] = {'I','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};
|
||||
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 wavein[] = {'W','a','v','e','I','n',' ','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};
|
||||
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 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[] = {'d','e','v','i','c','e',0};
|
||||
const WCHAR device_1[] = {'d','e','v','i','c','e','.','1',0};
|
||||
const register_info ri[] =
|
||||
LPVOID mapvptr;
|
||||
static const WCHAR threadingModel[] = {'B','o','t','h',0};
|
||||
static const WCHAR sysdevenum[] = {'S','y','s','t','e','m',' ','D','e','v','i','c','e',' ','E','n','u','m',0};
|
||||
static const WCHAR devmon[] = {'D','e','v','i','c','e','M','o','n','i','k','e','r',0};
|
||||
static const WCHAR acmcat[] = {'A','C','M',' ','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};
|
||||
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};
|
||||
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};
|
||||
static 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 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 midiout[] = {'M','i','d','i','O','u','t',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',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};
|
||||
static const WCHAR device[] = {'d','e','v','i','c','e',0};
|
||||
static const WCHAR device_1[] = {'d','e','v','i','c','e','.','1',0};
|
||||
static const register_info ri[] =
|
||||
{
|
||||
{&CLSID_SystemDeviceEnum, sysdevenum, FALSE},
|
||||
{&CLSID_CDeviceMoniker, devmon, FALSE},
|
||||
|
@ -131,37 +133,40 @@ HRESULT WINAPI DEVENUM_DllRegisterServer(void)
|
|||
|
||||
res = register_clsids(sizeof(ri) / sizeof(register_info), ri, threadingModel);
|
||||
|
||||
/* Quartz is needed for IFilterMapper2 */
|
||||
DEVENUM_RegisterQuartz();
|
||||
|
||||
/*** 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);
|
||||
|
||||
res = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC,
|
||||
&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);
|
||||
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);
|
||||
pMapper = (IFilterMapper2*)mapvptr;
|
||||
|
||||
IFilterMapper2_Release(pMapper);
|
||||
CoUninitialize();
|
||||
IFilterMapper2_CreateCategory(pMapper, &CLSID_VideoInputDeviceCategory, MERIT_DO_NOT_USE, friendlyvidcap);
|
||||
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 ***/
|
||||
|
@ -181,7 +186,7 @@ HRESULT WINAPI DEVENUM_DllRegisterServer(void)
|
|||
}
|
||||
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)
|
||||
== 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))
|
||||
== ERROR_SUCCESS ? S_OK : E_FAIL;
|
||||
}
|
||||
RegCloseKey(hkey2);
|
||||
|
||||
if (hkey2)
|
||||
{
|
||||
RegCloseKey(hkey2);
|
||||
hkey2 = NULL;
|
||||
}
|
||||
|
||||
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)
|
||||
== 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))
|
||||
== 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))
|
||||
{
|
||||
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))
|
||||
== 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))
|
||||
{
|
||||
|
@ -237,14 +268,21 @@ HRESULT WINAPI DEVENUM_DllRegisterServer(void)
|
|||
res = RegSetValueW(hkey2, NULL, REG_SZ, pszClsidDevMon, (lstrlenW(pszClsidDevMon) + 1) * sizeof(WCHAR))
|
||||
== 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)
|
||||
CoTaskMemFree(pszClsidDevMon);
|
||||
|
||||
CoUninitialize();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -329,3 +367,20 @@ static HRESULT register_clsids(int count, const register_info * pRegInfo, LPCWST
|
|||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,15 +130,15 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Read(
|
|||
switch (V_VT(pVar))
|
||||
{
|
||||
case VT_LPWSTR:
|
||||
V_UNION(pVar, bstrVal) = CoTaskMemAlloc(received * sizeof(WCHAR));
|
||||
strcpyW(V_UNION(pVar, bstrVal), (LPWSTR)pData);
|
||||
V_UNION(pVar, bstrVal) = CoTaskMemAlloc(received);
|
||||
memcpy(V_UNION(pVar, bstrVal), (LPWSTR)pData, received);
|
||||
res = S_OK;
|
||||
break;
|
||||
case VT_EMPTY:
|
||||
V_VT(pVar) = VT_BSTR;
|
||||
/* fall through */
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -90,8 +90,8 @@ static ULONG WINAPI DEVENUM_IParseDisplayName_Release(LPPARSEDISPLAYNAME iface)
|
|||
* Creates a moniker referenced to by the display string argument
|
||||
*
|
||||
* POSSIBLE BUGS:
|
||||
* Might not handle more complicated strings properly (ie not in
|
||||
* "@device:sw:{CLSID1}\{CLSID2}" format
|
||||
* Might not handle more complicated strings properly (ie anything
|
||||
* not in "@device:sw:{CLSID1}\<filter name or CLSID>" format
|
||||
*/
|
||||
static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(
|
||||
LPPARSEDISPLAYNAME iface,
|
||||
|
@ -106,6 +106,7 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(
|
|||
MediaCatMoniker * pMoniker = NULL;
|
||||
CLSID clsidDevice;
|
||||
HRESULT res = S_OK;
|
||||
|
||||
TRACE("(%p, %s, %p, %p)\n", pbc, debugstr_w(pszDisplayName), pchEaten, ppmkOut);
|
||||
|
||||
*ppmkOut = NULL;
|
||||
|
|
|
@ -628,7 +628,7 @@ static HRESULT WINAPI FilterMapper2_RegisterFilter(
|
|||
IBindCtx * pBindCtx = NULL;
|
||||
IMoniker * pMoniker = NULL;
|
||||
IPropertyBag * pPropBag = NULL;
|
||||
HRESULT hr = S_OK;
|
||||
HRESULT hr;
|
||||
LPWSTR pwszParseName = NULL;
|
||||
LPWSTR pCurrent;
|
||||
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),
|
||||
prf2);
|
||||
|
||||
if (ppMoniker)
|
||||
FIXME("ppMoniker != NULL not supported at the moment\n");
|
||||
|
||||
if (prf2->dwVersion != 2)
|
||||
{
|
||||
FIXME("dwVersion != 2 not supported at the moment\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if (ppMoniker)
|
||||
*ppMoniker = NULL;
|
||||
|
||||
if (!pclsidCategory)
|
||||
pclsidCategory = &CLSID_ActiveMovieCategories;
|
||||
|
||||
|
@ -667,8 +667,7 @@ static HRESULT WINAPI FilterMapper2_RegisterFilter(
|
|||
else
|
||||
nameLen += CHARS_IN_GUID - 1; /* CHARS_IN_GUID includes null terminator */
|
||||
|
||||
pwszParseName = CoTaskMemAlloc(nameLen);
|
||||
pCurrent = pwszParseName;
|
||||
pCurrent = pwszParseName = CoTaskMemAlloc(nameLen*sizeof(WCHAR));
|
||||
if (!pwszParseName)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
@ -676,12 +675,13 @@ static HRESULT WINAPI FilterMapper2_RegisterFilter(
|
|||
pCurrent += strlenW(wszDevice);
|
||||
|
||||
hr = StringFromCLSID(pclsidCategory, &szClsidTemp);
|
||||
strcpyW(pCurrent, szClsidTemp);
|
||||
pCurrent += CHARS_IN_GUID - 1;
|
||||
pCurrent[0] = '\\';
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
strncpyW(pCurrent, szClsidTemp, CHARS_IN_GUID);
|
||||
pCurrent += CHARS_IN_GUID - 1;
|
||||
pCurrent[0] = '\\';
|
||||
|
||||
if (szInstance)
|
||||
strcpyW(pCurrent+1, szInstance);
|
||||
else
|
||||
|
@ -692,7 +692,8 @@ static HRESULT WINAPI FilterMapper2_RegisterFilter(
|
|||
szClsidTemp = NULL;
|
||||
}
|
||||
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);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = IParseDisplayName_ParseDisplayName(pParser, pBindCtx, pwszParseName, &ulEaten, &pMoniker);
|
||||
}
|
||||
|
||||
if (pBindCtx)
|
||||
IBindCtx_Release(pBindCtx); pBindCtx = NULL;
|
||||
|
||||
if (pParser)
|
||||
IParseDisplayName_Release(pParser); pParser = NULL;
|
||||
|
||||
|
@ -725,15 +723,16 @@ static HRESULT WINAPI FilterMapper2_RegisterFilter(
|
|||
if (SUCCEEDED(hr))
|
||||
hr = FM2_WriteFilterData(pPropBag, prf2);
|
||||
|
||||
if (pMoniker)
|
||||
IMoniker_Release(pMoniker); pMoniker = NULL;
|
||||
|
||||
if (pPropBag)
|
||||
IPropertyBag_Release(pPropBag); pPropBag = NULL;
|
||||
|
||||
if (szClsidTemp)
|
||||
CoTaskMemFree(szClsidTemp);
|
||||
|
||||
if (SUCCEEDED(hr) && ppMoniker)
|
||||
*ppMoniker = pMoniker;
|
||||
else if (pMoniker)
|
||||
IMoniker_Release(pMoniker); pMoniker = NULL;
|
||||
|
||||
TRACE("-- returning %lx\n", hr);
|
||||
|
||||
return hr;
|
||||
|
|
Loading…
Reference in New Issue