You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
524 lines
13 KiB
524 lines
13 KiB
//+--------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1999
|
|
//
|
|
// File: regd.cpp
|
|
//
|
|
// Contents: registry functions for DCOM services
|
|
//
|
|
// History: July-97 xtan created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
#include <pch.cpp>
|
|
#pragma hdrstop
|
|
|
|
#include <objbase.h>
|
|
|
|
#include "regd.h"
|
|
|
|
|
|
#define __dwFILE__ __dwFILE_OCMSETUP_REGD_CPP__
|
|
|
|
|
|
extern WCHAR g_wszServicePath[MAX_PATH];
|
|
|
|
BYTE g_pNoOneLaunchPermission[] = {
|
|
0x01,0x00,0x04,0x80,0x34,0x00,0x00,0x00,
|
|
0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x14,0x00,0x00,0x00,0x02,0x00,0x20,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x3c,0x00,0xb9,0x00,0x07,0x00,0x03,0x00,
|
|
0x00,0x23,0x10,0x00,0x01,0x05,0x00,0x00,
|
|
0x00,0x00,0x00,0x05,0x01,0x05,0x00,0x00,
|
|
0x00,0x00,0x00,0x05,0x15,0x00,0x00,0x00,
|
|
0xa0,0x5f,0x84,0x1f,0x5e,0x2e,0x6b,0x49,
|
|
0xce,0x12,0x03,0x03,0xf4,0x01,0x00,0x00,
|
|
0x01,0x05,0x00,0x00,0x00,0x00,0x00,0x05,
|
|
0x15,0x00,0x00,0x00,0xa0,0x5f,0x84,0x1f,
|
|
0x5e,0x2e,0x6b,0x49,0xce,0x12,0x03,0x03,
|
|
0xf4,0x01,0x00,0x00};
|
|
|
|
BYTE g_pEveryOneAccessPermission[] = {
|
|
0x01,0x00,0x04,0x80,0x34,0x00,0x00,0x00,
|
|
0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x14,0x00,0x00,0x00,0x02,0x00,0x20,0x00,
|
|
0x01,0x00,0x00,0x00,0x00,0x00,0x18,0x00,
|
|
0x01,0x00,0x00,0x00,0x01,0x01,0x00,0x00,
|
|
0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x01,0x05,0x00,0x00,
|
|
0x00,0x00,0x00,0x05,0x15,0x00,0x00,0x00,
|
|
0xa0,0x65,0xcf,0x7e,0x78,0x4b,0x9b,0x5f,
|
|
0xe7,0x7c,0x87,0x70,0x36,0xbb,0x00,0x00,
|
|
0x01,0x05,0x00,0x00,0x00,0x00,0x00,0x05,
|
|
0x15,0x00,0x00,0x00,0xa0,0x65,0xcf,0x7e,
|
|
0x78,0x4b,0x9b,0x5f,0xe7,0x7c,0x87,0x70,
|
|
0x36,0xbb,0x00,0x00 };
|
|
|
|
|
|
//
|
|
// Create a key and set its value.
|
|
// - This helper function was borrowed and modifed from
|
|
// Kraig Brockschmidt's book Inside OLE.
|
|
//
|
|
|
|
HRESULT
|
|
setKeyAndValue(
|
|
const WCHAR *wszKey,
|
|
const WCHAR *wszSubkey,
|
|
const WCHAR *wszValueName,
|
|
const WCHAR *wszValue)
|
|
{
|
|
HKEY hKey = NULL;
|
|
HRESULT hr;
|
|
WCHAR wszKeyBuf[MAX_PATH];
|
|
|
|
// Copy keyname into buffer.
|
|
if (wcslen(wszKey) >= ARRAYSIZE(wszKeyBuf))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
|
|
_JumpErrorStr(hr, error, "wszKeyBuf", wszKey);
|
|
}
|
|
wcscpy(wszKeyBuf, wszKey);
|
|
|
|
// Add subkey name to buffer.
|
|
if (wszSubkey != NULL)
|
|
{
|
|
if (wcslen(wszKeyBuf) + 1 + wcslen(wszSubkey) >= ARRAYSIZE(wszKeyBuf))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
|
|
_JumpErrorStr(hr, error, "wszKeyBuf", wszKey);
|
|
}
|
|
wcscat(wszKeyBuf, L"\\");
|
|
wcscat(wszKeyBuf, wszSubkey);
|
|
}
|
|
|
|
// Create and open key and subkey.
|
|
hr = RegCreateKeyEx(
|
|
HKEY_CLASSES_ROOT,
|
|
wszKeyBuf,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hKey,
|
|
NULL);
|
|
_JumpIfError(hr, error, "RegCreateKeyEx");
|
|
|
|
// Set the Value.
|
|
if (NULL != wszValue)
|
|
{
|
|
RegSetValueEx(
|
|
hKey,
|
|
wszValueName,
|
|
0,
|
|
REG_SZ,
|
|
(BYTE *) wszValue,
|
|
(wcslen(wszValue) + 1) * sizeof(WCHAR));
|
|
_JumpIfError(hr, error, "RegSetValueEx");
|
|
}
|
|
|
|
error:
|
|
if (NULL != hKey)
|
|
{
|
|
RegCloseKey(hKey);
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
setCertSrvPermission(
|
|
const WCHAR *wszKey)
|
|
{
|
|
HKEY hKey = NULL;
|
|
HRESULT hr;
|
|
|
|
// create and open key
|
|
hr = RegCreateKeyEx(
|
|
HKEY_CLASSES_ROOT,
|
|
wszKey,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hKey,
|
|
NULL);
|
|
_JumpIfError(hr, error, "RegCreateKeyEx");
|
|
|
|
// set access permission
|
|
hr = RegSetValueEx(
|
|
hKey,
|
|
L"AccessPermission",
|
|
0,
|
|
REG_BINARY,
|
|
g_pEveryOneAccessPermission,
|
|
sizeof(g_pEveryOneAccessPermission));
|
|
_JumpIfError(hr, error, "RegSetValueEx");
|
|
|
|
// set access permission
|
|
hr = RegSetValueEx(
|
|
hKey,
|
|
L"LaunchPermission",
|
|
0,
|
|
REG_BINARY,
|
|
g_pNoOneLaunchPermission,
|
|
sizeof(g_pNoOneLaunchPermission));
|
|
_JumpIfError(hr, error, "RegSetValueEx");
|
|
|
|
error:
|
|
if (NULL != hKey)
|
|
{
|
|
RegCloseKey(hKey);
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
|
|
// Convert a CLSID to a char string.
|
|
|
|
HRESULT
|
|
CLSIDtochar(
|
|
IN const CLSID& clsid,
|
|
OUT WCHAR *pwszOut,
|
|
IN DWORD cwcOut)
|
|
{
|
|
HRESULT hr;
|
|
WCHAR *pwszTmp = NULL;
|
|
|
|
if (1 <= cwcOut)
|
|
{
|
|
pwszOut[0] = L'\0';
|
|
}
|
|
hr = StringFromCLSID(clsid, &pwszTmp);
|
|
_JumpIfError(hr, error, "StringFromCLSID");
|
|
|
|
if (wcslen(pwszTmp) >= cwcOut)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
|
|
_JumpError(hr, error, "pwszTmp");
|
|
}
|
|
wcscpy(pwszOut, pwszTmp);
|
|
hr = S_OK;
|
|
|
|
error:
|
|
if (NULL != pwszTmp)
|
|
{
|
|
CoTaskMemFree(pwszTmp);
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
|
|
// Determine if a particular subkey exists.
|
|
//
|
|
BOOL
|
|
SubkeyExists(
|
|
const WCHAR *wszPath, // Path of key to check
|
|
const WCHAR *wszSubkey) // Key to check
|
|
{
|
|
HRESULT hr;
|
|
HKEY hKey;
|
|
WCHAR wszKeyBuf[MAX_PATH];
|
|
|
|
// Copy keyname into buffer.
|
|
if (wcslen(wszPath) >= ARRAYSIZE(wszKeyBuf))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
|
|
_JumpErrorStr(hr, error, "wszKeyBuf", wszPath);
|
|
}
|
|
wcscpy(wszKeyBuf, wszPath);
|
|
|
|
// Add subkey name to buffer.
|
|
if (wszSubkey != NULL)
|
|
{
|
|
if (wcslen(wszKeyBuf) + 1 + wcslen(wszSubkey) >= ARRAYSIZE(wszKeyBuf))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
|
|
_JumpErrorStr(hr, error, "wszKeyBuf", wszPath);
|
|
}
|
|
wcscat(wszKeyBuf, L"\\");
|
|
wcscat(wszKeyBuf, wszSubkey);
|
|
}
|
|
|
|
// Determine if key exists by trying to open it.
|
|
hr = RegOpenKeyEx(
|
|
HKEY_CLASSES_ROOT,
|
|
wszKeyBuf,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKey);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
error:
|
|
return(S_OK == hr);
|
|
}
|
|
|
|
|
|
// Delete a key and all of its descendents.
|
|
//
|
|
|
|
HRESULT
|
|
recursiveDeleteKey(
|
|
HKEY hKeyParent, // Parent of key to delete
|
|
const WCHAR *wszKeyChild) // Key to delete
|
|
{
|
|
HRESULT hr;
|
|
FILETIME time;
|
|
WCHAR wszBuffer[MAX_PATH];
|
|
DWORD dwSize;
|
|
|
|
HKEY hKeyChild = NULL;
|
|
|
|
// Open the child.
|
|
hr = RegOpenKeyEx(hKeyParent, wszKeyChild, 0, KEY_ALL_ACCESS, &hKeyChild);
|
|
_JumpIfError2(hr, error, "RegOpenKeyEx", ERROR_FILE_NOT_FOUND);
|
|
|
|
// Enumerate all of the decendents of this child.
|
|
|
|
for (;;)
|
|
{
|
|
dwSize = sizeof(wszBuffer)/sizeof(wszBuffer[0]);
|
|
hr = RegEnumKeyEx(
|
|
hKeyChild,
|
|
0,
|
|
wszBuffer,
|
|
&dwSize,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&time);
|
|
if (S_OK != hr)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Delete the decendents of this child.
|
|
hr = recursiveDeleteKey(hKeyChild, wszBuffer);
|
|
_JumpIfError(hr, error, "recursiveDeleteKey");
|
|
}
|
|
|
|
// Delete this child.
|
|
hr = RegDeleteKey(hKeyParent, wszKeyChild);
|
|
_JumpIfError(hr, error, "RegDeleteKey");
|
|
|
|
error:
|
|
if (NULL != hKeyChild)
|
|
{
|
|
// Close the child.
|
|
RegCloseKey(hKeyChild);
|
|
}
|
|
return(myHError(hr));
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////
|
|
//
|
|
// RegisterDcomServer -- Register the component in the registry.
|
|
//
|
|
|
|
HRESULT
|
|
RegisterDcomServer(
|
|
IN BOOL fCreateAppIdInfo,
|
|
IN const CLSID& clsidAppId, // AppId Class ID
|
|
IN const CLSID& clsid, // Class ID
|
|
IN const WCHAR *wszFriendlyName, // Friendly Name
|
|
IN const WCHAR *wszVerIndProgID, // Programmatic
|
|
IN const WCHAR *wszProgID) // IDs
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Convert the CLSID into a char.
|
|
WCHAR wszCLSID[CLSID_STRING_SIZE];
|
|
WCHAR wszCLSIDAppId[CLSID_STRING_SIZE];
|
|
|
|
CLSIDtochar(clsid, wszCLSID, ARRAYSIZE(wszCLSID));
|
|
CLSIDtochar(clsidAppId, wszCLSIDAppId, ARRAYSIZE(wszCLSIDAppId));
|
|
|
|
// Build the key CLSID\\{...}
|
|
WCHAR wszKey[64];
|
|
|
|
if (fCreateAppIdInfo)
|
|
{
|
|
//--------------------------------------
|
|
// AppID\{ClassIdAppId}\(Default) = wszFriendlyName
|
|
// AppID\{ClassIdAppId}\LocalService = wszSERVICE_NAME
|
|
// AppID\{ClassIdAppId}\AccessPermission = ???
|
|
// AppID\{ClassIdAppId}\LaunchPermission = ???
|
|
|
|
wcscpy(wszKey, L"AppID\\");
|
|
wcscat(wszKey, wszCLSIDAppId);
|
|
|
|
// Add App IDs
|
|
hr = setKeyAndValue(wszKey, NULL, NULL, wszFriendlyName);
|
|
_JumpIfError(hr, error, "setKeyAndValue");
|
|
|
|
// run as a service
|
|
hr = setKeyAndValue(wszKey, NULL, L"LocalService", wszSERVICE_NAME);
|
|
_JumpIfError(hr, error, "setKeyAndValue");
|
|
|
|
hr = setCertSrvPermission(wszKey);
|
|
_JumpIfError(hr, error, "setCertSrvPermission");
|
|
}
|
|
|
|
//--------------------------------------
|
|
// CLSID\{ClassId}\(Default) = wszFriendlyName
|
|
// CLSID\{ClassId}\AppID = {ClassIdAppId}
|
|
// CLSID\{ClassId}\ProgID = wszProgID
|
|
// CLSID\{ClassId}\VersionIndependentProgID = wszVerIndProgID
|
|
|
|
wcscpy(wszKey, L"CLSID\\");
|
|
wcscat(wszKey, wszCLSID);
|
|
|
|
// Add the CLSID to the registry.
|
|
hr = setKeyAndValue(wszKey, NULL, NULL, wszFriendlyName);
|
|
_JumpIfError(hr, error, "setKeyAndValue");
|
|
|
|
// Add application ID
|
|
hr = setKeyAndValue(wszKey, NULL, L"AppID", wszCLSIDAppId);
|
|
_JumpIfError(hr, error, "setKeyAndValue");
|
|
|
|
// Add the ProgID subkey under the CLSID key.
|
|
hr = setKeyAndValue(wszKey, L"ProgID", NULL, wszProgID);
|
|
_JumpIfError(hr, error, "setKeyAndValue");
|
|
|
|
// Add the version-independent ProgID subkey under CLSID key.
|
|
hr = setKeyAndValue(wszKey, L"VersionIndependentProgID", NULL, wszVerIndProgID);
|
|
_JumpIfError(hr, error, "setKeyAndValue");
|
|
|
|
//--------------------------------------
|
|
// delete obsolete key: CLSID\{ClassId}\LocalServer32
|
|
|
|
wcscat(wszKey, L"\\LocalServer32");
|
|
|
|
hr = recursiveDeleteKey(HKEY_CLASSES_ROOT, L"LocalServer32");
|
|
_PrintIfError(hr, "recursiveDeleteKey");
|
|
|
|
//--------------------------------------
|
|
// wszVerIndProgID\(Default) = wszFriendlyName
|
|
// wszVerIndProgID\CLSID\(Default) = {ClassId}
|
|
// wszVerIndProgID\CurVer\(Default) = wszProgID
|
|
|
|
// Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
|
|
hr = setKeyAndValue(wszVerIndProgID, NULL, NULL, wszFriendlyName);
|
|
_JumpIfError(hr, error, "setKeyAndValue");
|
|
|
|
hr = setKeyAndValue(wszVerIndProgID, L"CLSID", NULL, wszCLSID);
|
|
_JumpIfError(hr, error, "setKeyAndValue");
|
|
|
|
hr = setKeyAndValue(wszVerIndProgID, L"CurVer", NULL, wszProgID);
|
|
_JumpIfError(hr, error, "setKeyAndValue");
|
|
|
|
//--------------------------------------
|
|
// wszProgID\(Default) = wszFriendlyName
|
|
// wszProgID\CLSID\(Default) = {ClassId}
|
|
|
|
// Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
|
|
hr = setKeyAndValue(wszProgID, NULL, NULL, wszFriendlyName);
|
|
_JumpIfError(hr, error, "setKeyAndValue");
|
|
|
|
hr = setKeyAndValue(wszProgID, L"CLSID", NULL, wszCLSID);
|
|
_JumpIfError(hr, error, "setKeyAndValue");
|
|
|
|
error:
|
|
return(hr);
|
|
}
|
|
|
|
|
|
//
|
|
// Remove the component from the registry.
|
|
//
|
|
|
|
HRESULT
|
|
UnregisterDcomServer(
|
|
IN const CLSID& clsid, // Class ID
|
|
IN const WCHAR *wszVerIndProgID, // Programmatic
|
|
IN const WCHAR *wszProgID) // IDs
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Convert the CLSID into a char.
|
|
WCHAR wszCLSID[CLSID_STRING_SIZE];
|
|
CLSIDtochar(clsid, wszCLSID, ARRAYSIZE(wszCLSID));
|
|
|
|
// Build the key CLSID\\{...}
|
|
WCHAR wszKey[6 + ARRAYSIZE(wszCLSID)];
|
|
wcscpy(wszKey, L"CLSID\\");
|
|
wcscat(wszKey, wszCLSID);
|
|
|
|
// Check for a another server for this component.
|
|
if (SubkeyExists(wszKey, L"InprocServer32"))
|
|
{
|
|
// Delete only the path for this server.
|
|
wcscat(wszKey, L"\\LocalServer32");
|
|
hr = recursiveDeleteKey(HKEY_CLASSES_ROOT, wszKey);
|
|
CSASSERT(hr == S_OK);
|
|
}
|
|
else
|
|
{
|
|
// Delete all related keys.
|
|
// Delete the CLSID Key - CLSID\{...}
|
|
hr = recursiveDeleteKey(HKEY_CLASSES_ROOT, wszKey);
|
|
CSASSERT(S_OK == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr);
|
|
|
|
// Delete the version-independent ProgID Key.
|
|
hr = recursiveDeleteKey(HKEY_CLASSES_ROOT, wszVerIndProgID);
|
|
CSASSERT(S_OK == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr);
|
|
|
|
// Delete the ProgID key.
|
|
hr = recursiveDeleteKey(HKEY_CLASSES_ROOT, wszProgID);
|
|
CSASSERT(S_OK == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr);
|
|
}
|
|
wcscpy(wszKey, L"AppID\\");
|
|
wcscat(wszKey, wszCLSID);
|
|
hr = recursiveDeleteKey(HKEY_CLASSES_ROOT, wszKey);
|
|
CSASSERT(S_OK == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
RegisterDcomApp(
|
|
IN const CLSID& clsid)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Convert the CLSID into a char.
|
|
WCHAR wszCLSID[CLSID_STRING_SIZE];
|
|
CLSIDtochar(clsid, wszCLSID, sizeof(wszCLSID)/sizeof(WCHAR));
|
|
|
|
WCHAR wszKey[64];
|
|
|
|
wcscpy(wszKey, L"AppID\\");
|
|
wcscat(wszKey, wszCERTSRVEXENAME);
|
|
|
|
// Add App IDs
|
|
hr = setKeyAndValue(wszKey, NULL, NULL, NULL);
|
|
_JumpIfError(hr, error, "setKeyAndValue");
|
|
|
|
hr = setKeyAndValue(wszKey, NULL, L"AppId", wszCLSID);
|
|
_JumpIfError(hr, error, "setKeyAndValue");
|
|
|
|
error:
|
|
return(hr);
|
|
}
|
|
|
|
|
|
void
|
|
UnregisterDcomApp()
|
|
{
|
|
HRESULT hr;
|
|
WCHAR wszKey[MAX_PATH];
|
|
|
|
wcscpy(wszKey, L"AppID\\");
|
|
wcscat(wszKey, wszCERTSRVEXENAME);
|
|
hr = recursiveDeleteKey(HKEY_CLASSES_ROOT, wszKey);
|
|
CSASSERT(S_OK == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr);
|
|
}
|