From e14e101fede272a8aeec233e4c92f48f4a86d46c Mon Sep 17 00:00:00 2001 From: Robert Shearman Date: Tue, 30 Dec 2003 21:52:45 +0000 Subject: [PATCH] - 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. --- dlls/devenum/createdevenum.c | 121 +++++++++++++++++++------ dlls/devenum/devenum_main.c | 153 ++++++++++++++++++++++---------- dlls/devenum/mediacatenum.c | 6 +- dlls/devenum/parsedisplayname.c | 5 +- dlls/quartz/filtermapper.c | 33 ++++--- 5 files changed, 219 insertions(+), 99 deletions(-) diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c index c84857c990..af2d097183 100644 --- a/dlls/devenum/createdevenum.c +++ b/dlls/devenum/createdevenum.c @@ -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; } diff --git a/dlls/devenum/devenum_main.c b/dlls/devenum/devenum_main.c index 621802e9b8..946f102490 100644 --- a/dlls/devenum/devenum_main.c +++ b/dlls/devenum/devenum_main.c @@ -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; - - 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); - CoUninitialize(); + 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}; + + pMapper = (IFilterMapper2*)mapvptr; + + 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); + } +} diff --git a/dlls/devenum/mediacatenum.c b/dlls/devenum/mediacatenum.c index 9dfb057443..62f54452a2 100644 --- a/dlls/devenum/mediacatenum.c +++ b/dlls/devenum/mediacatenum.c @@ -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; } diff --git a/dlls/devenum/parsedisplayname.c b/dlls/devenum/parsedisplayname.c index 306671cd94..c51e538c94 100644 --- a/dlls/devenum/parsedisplayname.c +++ b/dlls/devenum/parsedisplayname.c @@ -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}\" 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; diff --git a/dlls/quartz/filtermapper.c b/dlls/quartz/filtermapper.c index 0fb959c905..cd2b8141f6 100644 --- a/dlls/quartz/filtermapper.c +++ b/dlls/quartz/filtermapper.c @@ -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; -- 2.33.8