I believe I have a workable method for defining the registration data needed to register and unregister self-registerable COM server dlls like ole32 et. al. that is easy enough to maintain and reasonably efficient. The only real objection I can anticipate is that I use char's instead of WCHAR's, and my reason is that the infrequency of use of these functions makes ease of maintenance more important than performance.
I have attached (hopefully as text/plain) the header for the regsvr helper, and the comcat_main.c to give a feel for usage. Comments, please?
/* * self-registerable dll helper functions * * Copyright (C) 2002 John K. Hohm * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* regsvr_register and regsvr_unregister take a pointer to registration data. The format of that data is as such (in RFC2234 ABNF):
reg_data := LWSP "[" *"!" predef_key "\0" [ "=" value "\0" ] *sub_data "]" ; ! means delete (recursively) when unregistering
sub_data := key_data / value_data
key_data := LWSP "[" *"!" key "\0" [ "=" value "\0" ] *sub_data "]" ; ! means delete (recursively) when unregistering
value_data := LWSP *"!" value_name "\0" "=" value "\0" ; ! means delete when unregistering
predef_key := "HKCR" ; others could be added as necessary
key := +CHAR
value_name := +CHAR
value := +CHAR
*/
HRESULT regsvr_register(char const *data); HRESULT regsvr_unregister(char const *data);
/* * exported dll functions for comcat.dll * * Copyright (C) 2002 John K. Hohm * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "comcat.h" #include "regsvr.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
DWORD dll_ref = 0; HINSTANCE COMCAT_hInstance = 0;
/*********************************************************************** * Global string constant definitions */ const WCHAR clsid_keyname[6] = { 'C', 'L', 'S', 'I', 'D', 0 };
/*********************************************************************** * Registration data */ static char const regsvr_data[] = "[HKCR\0 [CLSID\0 [!{0002E005-0000-0000-C000-000000000046}\0=StdComponentCategoriesMgr\0 [InProcServer32\0=comcat.dll\0 ThreadingModel\0=Both\0 ] ] ] ]";
/*********************************************************************** * DllMain */ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) { TRACE("%p 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad);
switch(fdwReason) { case DLL_PROCESS_ATTACH: COMCAT_hInstance = hinstDLL; break;
case DLL_PROCESS_DETACH: COMCAT_hInstance = 0; break; } return TRUE; }
/*********************************************************************** * DllGetClassObject (COMCAT.@) */ HRESULT WINAPI COMCAT_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) { *ppv = NULL; if (IsEqualGUID(rclsid, &CLSID_StdComponentCategoriesMgr)) { return IClassFactory_QueryInterface((LPCLASSFACTORY)&COMCAT_ClassFactory, iid, ppv); } FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid)); return CLASS_E_CLASSNOTAVAILABLE; }
/*********************************************************************** * DllCanUnloadNow (COMCAT.@) */ HRESULT WINAPI COMCAT_DllCanUnloadNow() { return dll_ref != 0 ? S_FALSE : S_OK; }
/*********************************************************************** * DllRegisterServer (COMCAT.@) */ HRESULT WINAPI COMCAT_DllRegisterServer() { TRACE("\n"); return regsvr_register(regsvr_data); }
/*********************************************************************** * DllUnregisterServer (COMCAT.@) */ HRESULT WINAPI COMCAT_DllUnregisterServer() { TRACE("\n"); return regsvr_unregister(regsvr_data); }