/* * DirectX DLL registration and unregistration * * Copyright (C) 2005 Rolf Kalbermatter * * 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 */ #include "config.h" #include #include #define COBJMACROS #define NONAMELESSSTRUCT #define NONAMELESSUNION #include "windef.h" #include "winbase.h" #include "wingdi.h" #include "winerror.h" #include "winreg.h" #include "objbase.h" #include "uuids.h" #include "dllsetup.h" #include "wine/unicode.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(qcap); /* * defines and constants */ #define MAX_KEY_LEN 260 static WCHAR const clsid_keyname[6] = {'C','L','S','I','D',0 }; static WCHAR const ips32_keyname[15] = {'I','n','P','r','o','c','S','e','r','v','e','r','3','2',0}; static WCHAR const tmodel_keyname[15] = {'T','h','r','e','a','d','i','n','g','M','o','d','e','l',0}; static WCHAR const tmodel_both[] = {'B','o','t','h',0}; /* * SetupRegisterClass() */ static HRESULT SetupRegisterClass(HKEY clsid, LPCWSTR szCLSID, LPCWSTR szDescription, LPCWSTR szFileName, LPCWSTR szServerType, LPCWSTR szThreadingModel) { HKEY hkey, hsubkey = NULL; LONG ret = RegCreateKeyW(clsid, szCLSID, &hkey); if (ERROR_SUCCESS != ret) return HRESULT_FROM_WIN32(ret); /* set description string */ ret = RegSetValueW(hkey, NULL, REG_SZ, szDescription, sizeof(WCHAR) * (lstrlenW(szDescription) + 1)); if (ERROR_SUCCESS != ret) goto err_out; /* create CLSID\\{"CLSID"}\\"ServerType" key, using key to CLSID\\{"CLSID"} passed back by last call to RegCreateKeyW(). */ ret = RegCreateKeyW(hkey, szServerType, &hsubkey); if (ERROR_SUCCESS != ret) goto err_out; /* set server path */ ret = RegSetValueW(hsubkey, NULL, REG_SZ, szFileName, sizeof(WCHAR) * (lstrlenW(szFileName) + 1)); if (ERROR_SUCCESS != ret) goto err_out; /* set threading model */ ret = RegSetValueExW(hsubkey, tmodel_keyname, 0L, REG_SZ, (const BYTE*)szThreadingModel, sizeof(WCHAR) * (lstrlenW(szThreadingModel) + 1)); err_out: if (hsubkey) RegCloseKey(hsubkey); RegCloseKey(hkey); return HRESULT_FROM_WIN32(ret); } /* * RegisterAllClasses() */ static HRESULT SetupRegisterAllClasses(const CFactoryTemplate * pList, int num, LPCWSTR szFileName, BOOL bRegister) { HRESULT hr = NOERROR; HKEY hkey; OLECHAR szCLSID[CHARS_IN_GUID]; LONG i, ret = RegCreateKeyW(HKEY_CLASSES_ROOT, clsid_keyname, &hkey); if (ERROR_SUCCESS != ret) return HRESULT_FROM_WIN32(ret); for (i = 0; i < num; i++, pList++) { /* (un)register CLSID and InprocServer32 */ hr = StringFromGUID2(pList->m_ClsID, szCLSID, CHARS_IN_GUID); if (SUCCEEDED(hr)) { if (bRegister ) hr = SetupRegisterClass(hkey, szCLSID, pList->m_Name, szFileName, ips32_keyname, tmodel_both); else hr = RegDeleteTreeW(hkey, szCLSID); } } RegCloseKey(hkey); return hr; } /**************************************************************************** * SetupRegisterServers * * This function is table driven using the static members of the * CFactoryTemplate class defined in the Dll. * * It registers the Dll as the InprocServer32 for all the classes in * CFactoryTemplate * ****************************************************************************/ HRESULT SetupRegisterServers(const CFactoryTemplate * pList, int num, BOOL bRegister) { static const WCHAR szFileName[] = {'q','c','a','p','.','d','l','l',0}; HRESULT hr = NOERROR; IFilterMapper2 *pIFM2 = NULL; /* first register all server classes, just to make sure */ if (bRegister) hr = SetupRegisterAllClasses(pList, num, szFileName, TRUE ); /* next, register/unregister all filters */ if (SUCCEEDED(hr)) { hr = CoInitialize(NULL); TRACE("Getting IFilterMapper2\r\n"); hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (void **)&pIFM2); if (SUCCEEDED(hr)) { int i; /* scan through array of CFactoryTemplates registering all filters */ for (i = 0; i < num; i++, pList++) { if (pList->m_pAMovieSetup_Filter.dwVersion) { hr = IFilterMapper2_RegisterFilter(pIFM2, pList->m_ClsID, pList->m_Name, NULL, &CLSID_LegacyAmFilterCategory, NULL, &pList->m_pAMovieSetup_Filter); } /* check final error for this pass and break loop if we failed */ if (FAILED(hr)) break; } /* release interface */ IFilterMapper2_Release(pIFM2); } /* and clear up */ CoFreeUnusedLibraries(); CoUninitialize(); } /* if unregistering, unregister all OLE servers */ if (SUCCEEDED(hr) && !bRegister) hr = SetupRegisterAllClasses(pList, num, szFileName, FALSE); return hr; } /**************************************************************************** * SetupInitializeServers * * This function is table driven using the static members of the * CFactoryTemplate class defined in the Dll. * * It calls the initialize function for any class in CFactoryTemplate with * one defined. * ****************************************************************************/ void SetupInitializeServers(const CFactoryTemplate * pList, int num, BOOL bLoading) { int i; for (i = 0; i < num; i++, pList++) { if (pList->m_lpfnInit) pList->m_lpfnInit(bLoading, pList->m_ClsID); } }