Commit 8e4eb3ab authored by John K. Hohm's avatar John K. Hohm Committed by Alexandre Julliard

Completed implementation of comcat.dll, incl. Dll[Un]RegisterServer.

parent 336185a8
......@@ -12,9 +12,10 @@ SYMBOLFILE = $(MODULE).tmp.o
C_SRCS = \
comcat_main.c \
factory.c \
information.c \
manager.c \
register.c \
information.c
regsvr.c
@MAKE_DLL_RULES@
......
......@@ -20,6 +20,7 @@
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "winerror.h"
......@@ -61,3 +62,8 @@ typedef struct
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];
name comcat
init COMCAT_DllEntryPoint
@ stdcall DllCanUnloadNow() COMCAT_DllCanUnloadNow
@ stdcall DllGetClassObject(ptr ptr ptr) COMCAT_DllGetClassObject
......
......@@ -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 @@ HRESULT WINAPI COMCAT_DllCanUnloadNow()
/***********************************************************************
* 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);
}
......@@ -21,7 +21,6 @@
#include <string.h>
#include "comcat.h"
#include "winuser.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
......@@ -548,7 +547,7 @@ static HRESULT COMCAT_IsClassOfCategories(
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 };
WCHAR req_keyname[20] = { 'R', 'e', 'q', 'u', 'i', 'r', 'e', 'd',
WCHAR req_keyname[20] = { 'R', 'e', 'q', 'u', 'i', 'r', 'e', 'd',
' ', 'C', 'a', 't', 'e', 'g', 'o', 'r',
'i', 'e', 's', 0 };
HKEY subkey;
......
......@@ -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 ULONG WINAPI COMCAT_ICatRegister_Release(LPCATREGISTER iface)
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");
if (iface == NULL || (cCategories && rgci == NULL))
return E_POINTER;
return E_NOTIMPL;
/* 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 @@ static HRESULT WINAPI COMCAT_ICatRegister_UnRegisterCategories(
CATID *rgcatid)
{
/* ICOM_THIS_MULTI(ComCatMgrImpl, regVtbl, iface); */
FIXME("(): stub\n");
HKEY comcat_key;
HRESULT res;
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];
return E_NOTIMPL;
/* 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 @@ static HRESULT WINAPI COMCAT_ICatRegister_RegisterClassImplCategories(
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 @@ static HRESULT WINAPI COMCAT_ICatRegister_UnRegisterClassImplCategories(
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 @@ static HRESULT WINAPI COMCAT_ICatRegister_RegisterClassReqCategories(
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 @@ static HRESULT WINAPI COMCAT_ICatRegister_UnRegisterClassReqCategories(
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 @@ ICOM_VTABLE(ICatRegister) COMCAT_ICatRegister_Vtbl =
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;
}
/*
* 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;
}
/*
* 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);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment