226 lines
6.7 KiB
C++
226 lines
6.7 KiB
C++
|
//=--------------------------------------------------------------------------=
|
||
|
// RegUnReg.cpp
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// Copyright 1995-1996 Microsoft Corporation. All Rights Reserved.
|
||
|
//
|
||
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||
|
// PARTICULAR PURPOSE.
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
//
|
||
|
#include "ulsp.h"
|
||
|
#include "regunreg.h"
|
||
|
|
||
|
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// miscellaneous [useful] numerical constants
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// the length of a guid once printed out with -'s, leading and trailing bracket,
|
||
|
// plus 1 for NULL
|
||
|
//
|
||
|
#define GUID_STR_LEN 40
|
||
|
|
||
|
#define CLEANUP_ON_ERROR(l) if (l != ERROR_SUCCESS) goto CleanUp
|
||
|
|
||
|
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// StringFromGuid
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// returns a string from a CLSID or GUID
|
||
|
//
|
||
|
// Parameters:
|
||
|
// REFIID - [in] clsid to make string out of.
|
||
|
// LPTSTR - [in] buffer in which to place resultant GUID.
|
||
|
//
|
||
|
// Output:
|
||
|
// int - number of chars written out.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
static int StringFromGuid
|
||
|
(
|
||
|
REFIID riid,
|
||
|
LPTSTR pszBuf
|
||
|
)
|
||
|
{
|
||
|
return wsprintf(pszBuf, TEXT("{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
|
||
|
riid.Data1,
|
||
|
riid.Data2, riid.Data3, riid.Data4[0], riid.Data4[1], riid.Data4[2],
|
||
|
riid.Data4[3], riid.Data4[4], riid.Data4[5], riid.Data4[6], riid.Data4[7]);
|
||
|
|
||
|
}
|
||
|
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// RegisterUnknownObject
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// registers a simple CoCreatable object. nothing terribly serious.
|
||
|
// we add the following information to the registry:
|
||
|
//
|
||
|
// HKEY_CLASSES_ROOT\CLSID\<CLSID> = <ObjectName> Object
|
||
|
// HKEY_CLASSES_ROOT\CLSID\<CLSID>\InprocServer32 = <path to local server>
|
||
|
//
|
||
|
// Parameters:
|
||
|
// LPCSTR - [in] Object Name
|
||
|
// REFCLSID - [in] CLSID of the object
|
||
|
//
|
||
|
// Output:
|
||
|
// BOOL - FALSE means couldn't register it all
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
BOOL RegisterUnknownObject
|
||
|
(
|
||
|
LPCTSTR pszObjectName,
|
||
|
REFCLSID riidObject
|
||
|
)
|
||
|
{
|
||
|
HKEY hk = NULL, hkSub = NULL;
|
||
|
TCHAR szGuidStr[GUID_STR_LEN];
|
||
|
DWORD dwPathLen, dwDummy;
|
||
|
TCHAR szScratch[MAX_PATH];
|
||
|
long l;
|
||
|
|
||
|
// clean out any garbage
|
||
|
//
|
||
|
UnregisterUnknownObject(riidObject);
|
||
|
|
||
|
// HKEY_CLASSES_ROOT\CLSID\<CLSID> = <ObjectName> Object
|
||
|
// HKEY_CLASSES_ROOT\CLSID\<CLSID>\InprocServer32 = <path to local server>
|
||
|
// HKEY_CLASSES_ROOT\CLSID\<CLSID>\InprocServer32 @ThreadingModel = Apartment
|
||
|
//
|
||
|
if (!StringFromGuid(riidObject, szGuidStr)) goto CleanUp;
|
||
|
wsprintf(szScratch, TEXT("CLSID\\%s"), szGuidStr);
|
||
|
l = RegCreateKeyEx(HKEY_CLASSES_ROOT, szScratch, 0, TEXT(""), REG_OPTION_NON_VOLATILE,
|
||
|
KEY_READ | KEY_WRITE, NULL, &hk, &dwDummy);
|
||
|
CLEANUP_ON_ERROR(l);
|
||
|
|
||
|
wsprintf(szScratch, TEXT("%s Object"), pszObjectName);
|
||
|
l = RegSetValueEx(hk, NULL, 0, REG_SZ, (BYTE *)szScratch,
|
||
|
(lstrlen(szScratch) + 1)*sizeof(TCHAR));
|
||
|
CLEANUP_ON_ERROR(l);
|
||
|
|
||
|
l = RegCreateKeyEx(hk, TEXT("InprocServer32"), 0, TEXT(""), REG_OPTION_NON_VOLATILE,
|
||
|
KEY_READ | KEY_WRITE, NULL, &hkSub, &dwDummy);
|
||
|
CLEANUP_ON_ERROR(l);
|
||
|
|
||
|
dwPathLen = GetModuleFileName(g_hInstance, szScratch, sizeof(szScratch)/sizeof(TCHAR));
|
||
|
if (!dwPathLen) goto CleanUp;
|
||
|
|
||
|
l = RegSetValueEx(hkSub, NULL, 0, REG_SZ, (BYTE *)szScratch, (dwPathLen + 1)*sizeof(TCHAR));
|
||
|
CLEANUP_ON_ERROR(l);
|
||
|
|
||
|
l = RegSetValueEx(hkSub, TEXT("ThreadingModel"), 0, REG_SZ, (BYTE *)TEXT("Apartment"),
|
||
|
sizeof(TEXT("Apartment")));
|
||
|
CLEANUP_ON_ERROR(l);
|
||
|
|
||
|
RegCloseKey(hkSub);
|
||
|
RegCloseKey(hk);
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
// we are not very happy!
|
||
|
//
|
||
|
CleanUp:
|
||
|
if (hk) RegCloseKey(hk);
|
||
|
if (hkSub) RegCloseKey(hkSub);
|
||
|
return FALSE;
|
||
|
|
||
|
}
|
||
|
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// UnregisterUnknownObject
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// cleans up all the stuff that RegisterUnknownObject puts in the
|
||
|
// registry.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// REFCLSID - [in] CLSID of the object
|
||
|
//
|
||
|
// Output:
|
||
|
// BOOL - FALSE means not all of it was registered
|
||
|
//
|
||
|
// Notes:
|
||
|
// - WARNING: this routine will blow away all other keys under the CLSID
|
||
|
// for this object. mildly anti-social, but likely not a problem.
|
||
|
//
|
||
|
BOOL UnregisterUnknownObject
|
||
|
(
|
||
|
REFCLSID riidObject
|
||
|
)
|
||
|
{
|
||
|
TCHAR szScratch[MAX_PATH];
|
||
|
HKEY hk;
|
||
|
BOOL f;
|
||
|
long l;
|
||
|
|
||
|
// delete everybody of the form
|
||
|
// HKEY_CLASSES_ROOT\CLSID\<CLSID> [\] *
|
||
|
//
|
||
|
if (!StringFromGuid(riidObject, szScratch))
|
||
|
return FALSE;
|
||
|
|
||
|
l = RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_ALL_ACCESS, &hk);
|
||
|
if (l != ERROR_SUCCESS) return FALSE;
|
||
|
|
||
|
f = DeleteKeyAndSubKeys(hk, szScratch);
|
||
|
RegCloseKey(hk);
|
||
|
|
||
|
return f;
|
||
|
}
|
||
|
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// DeleteKeyAndSubKeys
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// delete's a key and all of it's subkeys.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// HKEY - [in] delete the descendant specified
|
||
|
// LPTSTR - [in] i'm the descendant specified
|
||
|
//
|
||
|
// Output:
|
||
|
// BOOL - TRUE OK, FALSE baaaad.
|
||
|
//
|
||
|
// Notes:
|
||
|
// - I don't feel too bad about implementing this recursively, since the
|
||
|
// depth isn't likely to get all the great.
|
||
|
// - Despite the win32 docs claiming it does, RegDeleteKey doesn't seem to
|
||
|
// work with sub-keys under windows 95.
|
||
|
//
|
||
|
BOOL DeleteKeyAndSubKeys
|
||
|
(
|
||
|
HKEY hkIn,
|
||
|
LPTSTR pszSubKey
|
||
|
)
|
||
|
{
|
||
|
HKEY hk;
|
||
|
TCHAR szTmp[MAX_PATH];
|
||
|
DWORD dwTmpSize;
|
||
|
long l;
|
||
|
BOOL f;
|
||
|
int x;
|
||
|
|
||
|
l = RegOpenKeyEx(hkIn, pszSubKey, 0, KEY_ALL_ACCESS, &hk);
|
||
|
if (l != ERROR_SUCCESS) return FALSE;
|
||
|
|
||
|
// loop through all subkeys, blowing them away.
|
||
|
//
|
||
|
f = TRUE;
|
||
|
x = 0;
|
||
|
while (f) {
|
||
|
dwTmpSize = MAX_PATH;
|
||
|
l = RegEnumKeyEx(hk, x, szTmp, &dwTmpSize, 0, NULL, NULL, NULL);
|
||
|
if (l != ERROR_SUCCESS) break;
|
||
|
f = DeleteKeyAndSubKeys(hk, szTmp);
|
||
|
x++;
|
||
|
}
|
||
|
|
||
|
// there are no subkeys left, [or we'll just generate an error and return FALSE].
|
||
|
// let's go blow this dude away.
|
||
|
//
|
||
|
RegCloseKey(hk);
|
||
|
l = RegDeleteKey(hkIn, pszSubKey);
|
||
|
|
||
|
return (l == ERROR_SUCCESS) ? TRUE : FALSE;
|
||
|
}
|