wine dlls/comcat
John K. Hohm
jhohm at acm.org
Wed Jun 12 00:08:57 CDT 2002
Changelog:
John K. Hohm <jhohm at acm.org>
Completed implementation of comcat.dll, incl. Dll[Un]RegisterServer
-------------- next part --------------
? dlls/comcat/regsvr.c
? dlls/comcat/regsvr.h
Index: dlls/comcat/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/comcat/Makefile.in,v
retrieving revision 1.4
diff -u -r1.4 Makefile.in
--- dlls/comcat/Makefile.in 2 Jun 2002 21:25:08 -0000 1.4
+++ dlls/comcat/Makefile.in 12 Jun 2002 05:00:24 -0000
@@ -14,7 +14,8 @@
factory.c \
manager.c \
register.c \
- information.c
+ information.c \
+ regsvr.c
@MAKE_DLL_RULES@
Index: dlls/comcat/comcat.h
===================================================================
RCS file: /home/wine/wine/dlls/comcat/comcat.h,v
retrieving revision 1.4
diff -u -r1.4 comcat.h
--- dlls/comcat/comcat.h 2 Jun 2002 21:25:08 -0000 1.4
+++ dlls/comcat/comcat.h 12 Jun 2002 05:00:24 -0000
@@ -20,6 +20,7 @@
#include "windef.h"
#include "winbase.h"
+#include "winuser.h"
#include "winreg.h"
#include "winerror.h"
@@ -61,3 +62,8 @@
extern ComCatMgrImpl COMCAT_ComCatMgr;
extern ICOM_VTABLE(ICatRegister) COMCAT_ICatRegister_Vtbl;
extern ICOM_VTABLE(ICatInformation) COMCAT_ICatInformation_Vtbl;
+
+/**********************************************************************
+ * Global string constant declarations
+ */
+extern const WCHAR clsid_keyname[6];
Index: dlls/comcat/comcat.spec
===================================================================
RCS file: /home/wine/wine/dlls/comcat/comcat.spec,v
retrieving revision 1.1
diff -u -r1.1 comcat.spec
--- dlls/comcat/comcat.spec 14 May 2002 21:50:56 -0000 1.1
+++ dlls/comcat/comcat.spec 12 Jun 2002 05:00:24 -0000
@@ -1,4 +1,5 @@
name comcat
+init COMCAT_DllEntryPoint
@ stdcall DllCanUnloadNow() COMCAT_DllCanUnloadNow
@ stdcall DllGetClassObject(ptr ptr ptr) COMCAT_DllGetClassObject
Index: dlls/comcat/comcat_main.c
===================================================================
RCS file: /home/wine/wine/dlls/comcat/comcat_main.c,v
retrieving revision 1.1
diff -u -r1.1 comcat_main.c
--- dlls/comcat/comcat_main.c 14 May 2002 21:50:56 -0000 1.1
+++ dlls/comcat/comcat_main.c 12 Jun 2002 05:00:24 -0000
@@ -19,12 +19,66 @@
*/
#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 entries
+ */
+static const WCHAR class_keyname[39] = {
+ '{', '0', '0', '0', '2', 'E', '0', '0', '5', '-', '0', '0',
+ '0', '0', '-', '0', '0', '0', '0', '-', 'C', '0', '0', '0',
+ '-', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '4',
+ '6', '}', 0 };
+static const WCHAR class_name[26] = {
+ 'S', 't', 'd', 'C', 'o', 'm', 'p', 'o', 'n', 'e', 'n', 't',
+ 'C', 'a', 't', 'e', 'g', 'o', 'r', 'i', 'e', 's', 'M', 'g',
+ 'r', 0 };
+static const WCHAR ips32_keyname[15] = {
+ 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
+ '3', '2', 0 };
+static const WCHAR tm_valname[15] = {
+ 'T', 'h', 'r', 'e', 'a', 'd', 'i', 'n', 'g', 'M', 'o', 'd',
+ 'e', 'l', 0 };
+static const WCHAR tm_value[5] = { 'B', 'o', 't', 'h', 0 };
+static struct regsvr_entry regsvr_entries[6] = {
+ { HKEY_CLASSES_ROOT, 0, clsid_keyname },
+ { 0, 1, class_keyname },
+ { 1, 1, NULL, class_name },
+ { 1, 1, ips32_keyname },
+ { 3, 1, NULL, /*dynamic, path to dll module*/ },
+ { 3, 1, tm_valname, tm_value }
+};
+
+/***********************************************************************
+ * DllEntryPoint
+ */
+BOOL WINAPI COMCAT_DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
+{
+ TRACE("0x%x 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.@)
@@ -50,19 +104,33 @@
/***********************************************************************
* DllRegisterServer (COMCAT.@)
*/
-
HRESULT WINAPI COMCAT_DllRegisterServer()
{
- FIXME("(): stub\n");
- return E_FAIL;
+ WCHAR dll_module[MAX_PATH];
+
+ TRACE("\n");
+
+ if (!GetModuleFileNameW(COMCAT_hInstance, dll_module,
+ sizeof dll_module / sizeof(WCHAR)))
+ return HRESULT_FROM_WIN32(GetLastError());
+
+ regsvr_entries[4].value = dll_module;
+ return regsvr_register(regsvr_entries, 6);
}
/***********************************************************************
* DllUnregisterServer (COMCAT.@)
*/
-
HRESULT WINAPI COMCAT_DllUnregisterServer()
{
- FIXME("(): stub\n");
- return E_FAIL;
+ WCHAR dll_module[MAX_PATH];
+
+ TRACE("\n");
+
+ if (!GetModuleFileNameW(COMCAT_hInstance, dll_module,
+ sizeof dll_module / sizeof(WCHAR)))
+ return HRESULT_FROM_WIN32(GetLastError());
+
+ regsvr_entries[4].value = dll_module;
+ return regsvr_unregister(regsvr_entries, 6);
}
Index: dlls/comcat/information.c
===================================================================
RCS file: /home/wine/wine/dlls/comcat/information.c,v
retrieving revision 1.4
diff -u -r1.4 information.c
--- dlls/comcat/information.c 2 Jun 2002 21:25:08 -0000 1.4
+++ dlls/comcat/information.c 12 Jun 2002 05:00:24 -0000
@@ -21,7 +21,6 @@
#include <string.h>
#include "comcat.h"
-#include "winuser.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
Index: dlls/comcat/register.c
===================================================================
RCS file: /home/wine/wine/dlls/comcat/register.c,v
retrieving revision 1.2
diff -u -r1.2 register.c
--- dlls/comcat/register.c 19 May 2002 22:27:41 -0000 1.2
+++ dlls/comcat/register.c 12 Jun 2002 05:00:24 -0000
@@ -25,6 +25,28 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
/**********************************************************************
+ * File-scope string constants
+ */
+static const WCHAR comcat_keyname[21] = {
+ 'C', 'o', 'm', 'p', 'o', 'n', 'e', 'n', 't', ' ', 'C', 'a',
+ 't', 'e', 'g', 'o', 'r', 'i', 'e', 's', 0 };
+static const WCHAR impl_keyname[23] = {
+ 'I', 'm', 'p', 'l', 'e', 'm', 'e', 'n',
+ 't', 'e', 'd', ' ', 'C', 'a', 't', 'e',
+ 'g', 'o', 'r', 'i', 'e', 's', 0 };
+static const WCHAR req_keyname[20] = {
+ 'R', 'e', 'q', 'u', 'i', 'r', 'e', 'd',
+ ' ', 'C', 'a', 't', 'e', 'g', 'o', 'r',
+ 'i', 'e', 's', 0 };
+
+static HRESULT COMCAT_RegisterClassCategories(
+ REFCLSID rclsid, LPCWSTR type,
+ ULONG cCategories, CATID *rgcatid);
+static HRESULT COMCAT_UnRegisterClassCategories(
+ REFCLSID rclsid, LPCWSTR type,
+ ULONG cCategories, CATID *rgcatid);
+
+/**********************************************************************
* COMCAT_ICatRegister_QueryInterface
*/
static HRESULT WINAPI COMCAT_ICatRegister_QueryInterface(
@@ -72,12 +94,45 @@
static HRESULT WINAPI COMCAT_ICatRegister_RegisterCategories(
LPCATREGISTER iface,
ULONG cCategories,
- CATEGORYINFO *rgCategoryInfo)
+ CATEGORYINFO *rgci)
{
/* ICOM_THIS_MULTI(ComCatMgrImpl, regVtbl, iface); */
- FIXME("(): stub\n");
+ HKEY comcat_key;
+ HRESULT res;
+
+ TRACE("\n");
- return E_NOTIMPL;
+ if (iface == NULL || (cCategories && rgci == NULL))
+ return E_POINTER;
+
+ /* Create (or open) the component categories key. */
+ res = RegCreateKeyExW(HKEY_CLASSES_ROOT, comcat_keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &comcat_key, NULL);
+ if (res != ERROR_SUCCESS) return E_FAIL;
+
+ for (; cCategories; --cCategories, ++rgci) {
+ WCHAR fmt[4] = { '%', 'l', 'X', 0 };
+ WCHAR keyname[39];
+ WCHAR valname[9];
+ HKEY cat_key;
+
+ /* Create (or open) the key for this category. */
+ if (!StringFromGUID2(&rgci->catid, keyname, 39)) continue;
+ res = RegCreateKeyExW(comcat_key, keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &cat_key, NULL);
+ if (res != ERROR_SUCCESS) continue;
+
+ /* Set the value for this locale's description. */
+ wsprintfW(valname, fmt, rgci->lcid);
+ RegSetValueExW(cat_key, valname, 0, REG_SZ,
+ (CONST BYTE*)(rgci->szDescription),
+ (lstrlenW(rgci->szDescription) + 1) * sizeof(WCHAR));
+
+ RegCloseKey(cat_key);
+ }
+
+ RegCloseKey(comcat_key);
+ return S_OK;
}
/**********************************************************************
@@ -89,9 +144,29 @@
CATID *rgcatid)
{
/* ICOM_THIS_MULTI(ComCatMgrImpl, regVtbl, iface); */
- FIXME("(): stub\n");
+ HKEY comcat_key;
+ HRESULT res;
- return E_NOTIMPL;
+ TRACE("\n");
+
+ if (iface == NULL || (cCategories && rgcatid == NULL))
+ return E_POINTER;
+
+ /* Open the component categories key. */
+ res = RegOpenKeyExW(HKEY_CLASSES_ROOT, comcat_keyname, 0,
+ KEY_READ | KEY_WRITE, &comcat_key);
+ if (res != ERROR_SUCCESS) return E_FAIL;
+
+ for (; cCategories; --cCategories, ++rgcatid) {
+ WCHAR keyname[39];
+
+ /* Delete the key for this category. */
+ if (!StringFromGUID2(rgcatid, keyname, 39)) continue;
+ RegDeleteKeyW(comcat_key, keyname);
+ }
+
+ RegCloseKey(comcat_key);
+ return S_OK;
}
/**********************************************************************
@@ -104,9 +179,10 @@
CATID *rgcatid)
{
/* ICOM_THIS_MULTI(ComCatMgrImpl, regVtbl, iface); */
- FIXME("(): stub\n");
+ TRACE("\n");
- return E_NOTIMPL;
+ return COMCAT_RegisterClassCategories(
+ rclsid, impl_keyname, cCategories, rgcatid);
}
/**********************************************************************
@@ -119,9 +195,10 @@
CATID *rgcatid)
{
/* ICOM_THIS_MULTI(ComCatMgrImpl, regVtbl, iface); */
- FIXME("(): stub\n");
+ TRACE("\n");
- return E_NOTIMPL;
+ return COMCAT_UnRegisterClassCategories(
+ rclsid, impl_keyname, cCategories, rgcatid);
}
/**********************************************************************
@@ -134,9 +211,10 @@
CATID *rgcatid)
{
/* ICOM_THIS_MULTI(ComCatMgrImpl, regVtbl, iface); */
- FIXME("(): stub\n");
+ TRACE("\n");
- return E_NOTIMPL;
+ return COMCAT_RegisterClassCategories(
+ rclsid, req_keyname, cCategories, rgcatid);
}
/**********************************************************************
@@ -149,9 +227,10 @@
CATID *rgcatid)
{
/* ICOM_THIS_MULTI(ComCatMgrImpl, regVtbl, iface); */
- FIXME("(): stub\n");
+ TRACE("\n");
- return E_NOTIMPL;
+ return COMCAT_UnRegisterClassCategories(
+ rclsid, req_keyname, cCategories, rgcatid);
}
/**********************************************************************
@@ -170,3 +249,95 @@
COMCAT_ICatRegister_RegisterClassReqCategories,
COMCAT_ICatRegister_UnRegisterClassReqCategories
};
+
+/**********************************************************************
+ * COMCAT_RegisterClassCategories
+ */
+static HRESULT COMCAT_RegisterClassCategories(
+ REFCLSID rclsid,
+ LPCWSTR type,
+ ULONG cCategories,
+ CATID *rgcatid)
+{
+ WCHAR keyname[39];
+ HRESULT res;
+ HKEY clsid_key, class_key, type_key;
+
+ if (cCategories && rgcatid == NULL) return E_POINTER;
+
+ /* Format the class key name. */
+ res = StringFromGUID2(rclsid, keyname, 39);
+ if (FAILED(res)) return res;
+
+ /* Create (or open) the CLSID key. */
+ res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
+ if (res != ERROR_SUCCESS) return E_FAIL;
+
+ /* Create (or open) the class key. */
+ res = RegCreateKeyExW(clsid_key, keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &class_key, NULL);
+ if (res == ERROR_SUCCESS) {
+ /* Create (or open) the category type key. */
+ res = RegCreateKeyExW(class_key, type, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &type_key, NULL);
+ if (res == ERROR_SUCCESS) {
+ for (; cCategories; --cCategories, ++rgcatid) {
+ HKEY key;
+
+ /* Format the category key name. */
+ res = StringFromGUID2(rgcatid, keyname, 39);
+ if (FAILED(res)) continue;
+
+ /* Do the register. */
+ res = RegCreateKeyExW(type_key, keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &key, NULL);
+ if (res == ERROR_SUCCESS) RegCloseKey(key);
+ }
+ res = S_OK;
+ } else res = E_FAIL;
+ RegCloseKey(class_key);
+ } else res = E_FAIL;
+ RegCloseKey(clsid_key);
+
+ return res;
+}
+
+/**********************************************************************
+ * COMCAT_UnRegisterClassCategories
+ */
+static HRESULT COMCAT_UnRegisterClassCategories(
+ REFCLSID rclsid,
+ LPCWSTR type,
+ ULONG cCategories,
+ CATID *rgcatid)
+{
+ WCHAR keyname[68] = { 'C', 'L', 'S', 'I', 'D', '\\' };
+ HRESULT res;
+ HKEY type_key;
+
+ if (cCategories && rgcatid == NULL) return E_POINTER;
+
+ /* Format the class category type key name. */
+ res = StringFromGUID2(rclsid, keyname + 6, 39);
+ if (FAILED(res)) return res;
+ keyname[44] = '\\';
+ lstrcpyW(keyname + 45, type);
+
+ /* Open the class category type key. */
+ res = RegOpenKeyExW(HKEY_CLASSES_ROOT, keyname, 0,
+ KEY_READ | KEY_WRITE, &type_key);
+ if (res != ERROR_SUCCESS) return E_FAIL;
+
+ for (; cCategories; --cCategories, ++rgcatid) {
+ /* Format the category key name. */
+ res = StringFromGUID2(rgcatid, keyname, 39);
+ if (FAILED(res)) continue;
+
+ /* Do the unregister. */
+ RegDeleteKeyW(type_key, keyname);
+ }
+ RegCloseKey(type_key);
+
+ return S_OK;
+}
--- /dev/null Fri Mar 15 21:55:30 2002
+++ dlls/comcat/regsvr.h Tue Jun 11 22:33:02 2002
@@ -0,0 +1,29 @@
+/*
+ * 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
+ */
+
+struct regsvr_entry {
+ int parent; /* entry number, or predefined HKEY_ */
+ int unreg_del; /* recursively delete key on unregister? */
+ LPCWSTR name; /* key or value name */
+ LPCWSTR value; /* NULL for key */
+};
+
+HRESULT regsvr_register(struct regsvr_entry const *entries, size_t count);
+HRESULT regsvr_unregister(struct regsvr_entry const *entries, size_t count);
--- /dev/null Fri Mar 15 21:55:30 2002
+++ dlls/comcat/regsvr.c Tue Jun 11 23:40:06 2002
@@ -0,0 +1,130 @@
+/*
+ * 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
+ */
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winreg.h"
+#include "winerror.h"
+
+#include "regsvr.h"
+
+static HRESULT recursive_delete_key(HKEY key);
+
+/***********************************************************************
+ * regsvr_register
+ */
+HRESULT regsvr_register(struct regsvr_entry const *entries, size_t count)
+{
+ HKEY keys[count];
+ struct regsvr_entry const *e;
+ int i;
+ HRESULT res = S_OK;
+
+ /* Create keys and set values. */
+ for (i = 0, e = entries; i < count; ++i, ++e) {
+ /* predefined HKEY_'s are all >= 0x80000000 */
+ HKEY parent_key = e->parent < 0x80000000 ?
+ keys[e->parent] : (HKEY)e->parent;
+ if (e->value == NULL) {
+ res = RegCreateKeyExW(parent_key, e->name, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &keys[i], NULL);
+ } else {
+ res = RegSetValueExW(parent_key, e->name, 0, REG_SZ,
+ (CONST BYTE*)e->value,
+ (lstrlenW(e->value) + 1) * sizeof(WCHAR));
+ }
+ if (res != ERROR_SUCCESS) break;
+ }
+
+ /* Close keys. */
+ for (--i, --e; 0 <= i; --i, --e) {
+ if (e->value == NULL) RegCloseKey(keys[i]);
+ }
+
+ return res == ERROR_SUCCESS ? S_OK : HRESULT_FROM_WIN32(res);
+}
+
+/***********************************************************************
+ * regsvr_unregister
+ */
+HRESULT regsvr_unregister(struct regsvr_entry const *entries, size_t count)
+{
+ HKEY keys[count];
+ struct regsvr_entry const *e;
+ int i;
+ HRESULT res = S_OK;
+
+ /* Open (and possibly delete) keys. */
+ for (i = 0, e = entries; i < count; ++i, ++e) {
+ /* predefined HKEY_'s are all >= 0x80000000 */
+ HKEY parent_key = e->parent < 0x80000000 ?
+ keys[e->parent] : (HKEY)e->parent;
+ if (e->value == NULL && parent_key) {
+ res = RegOpenKeyExW(parent_key, e->name, 0,
+ KEY_READ | KEY_WRITE, &keys[i]);
+ if (res == ERROR_SUCCESS && e->unreg_del)
+ res = recursive_delete_key(keys[i]);
+ if (res == ERROR_FILE_NOT_FOUND) continue;
+ if (res != ERROR_SUCCESS) break;
+ } else keys[i] = 0;
+ }
+
+ /* Close keys. */
+ for (--i; 0 <= i; --i) {
+ if (keys[i]) RegCloseKey(keys[i]);
+ }
+
+ return res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND ?
+ HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ * recursive_delete_key
+ */
+static LONG recursive_delete_key(HKEY key)
+{
+ LONG res;
+ DWORD index;
+ WCHAR subkey_name[MAX_PATH];
+ DWORD cName;
+ HKEY subkey;
+
+ for (index = 0; ; ++index) {
+ cName = sizeof subkey_name / sizeof(WCHAR);
+ res = RegEnumKeyExW(key, index, subkey_name, &cName,
+ NULL, NULL, NULL, NULL);
+ if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) {
+ res = ERROR_SUCCESS; /* presumably we're done enumerating */
+ break;
+ }
+ res = RegOpenKeyExW(key, subkey_name, 0,
+ KEY_READ | KEY_WRITE, &subkey);
+ if (res == ERROR_FILE_NOT_FOUND) continue;
+ if (res != ERROR_SUCCESS) break;
+
+ res = recursive_delete_key(subkey);
+ RegCloseKey(subkey);
+ if (res != ERROR_SUCCESS) break;
+ }
+
+ if (res == ERROR_SUCCESS) res = RegDeleteKeyW(key, 0);
+ return res;
+}
More information about the wine-patches
mailing list