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.
902 lines
23 KiB
902 lines
23 KiB
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1996-1997 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// RegExt.cpp
|
|
//
|
|
// Abstract:
|
|
// Implementation of routines for extension registration.
|
|
//
|
|
// Author:
|
|
// David Potter (davidp) April 9, 1997
|
|
//
|
|
// Revision History:
|
|
//
|
|
// Notes:
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include <stdafx.h>
|
|
#include <ole2.h>
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define REG_VALUE_ADMIN_EXTENSIONS L"AdminExtensions"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Static Function Prototypes
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static HRESULT RegisterAnyCluAdminExtension(
|
|
IN HCLUSTER hCluster,
|
|
IN LPCWSTR pwszKeyName,
|
|
IN const CLSID * pClsid
|
|
);
|
|
static HRESULT RegisterAnyCluAdminExtension(
|
|
IN HKEY hkey,
|
|
IN const CLSID * pClsid
|
|
);
|
|
static HRESULT UnregisterAnyCluAdminExtension(
|
|
IN HCLUSTER hCluster,
|
|
IN LPCWSTR pwszKeyName,
|
|
IN const CLSID * pClsid
|
|
);
|
|
static HRESULT UnregisterAnyCluAdminExtension(
|
|
IN HKEY hkey,
|
|
IN const CLSID * pClsid
|
|
);
|
|
static DWORD ReadValue(
|
|
IN HKEY hkey,
|
|
IN LPCWSTR pwszValueName,
|
|
OUT LPWSTR * ppwszValue,
|
|
OUT DWORD * pcbSize
|
|
);
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// RegisterCluAdminClusterExtension
|
|
//
|
|
// Routine Description:
|
|
// Register with the cluster database a Cluster Administrator Extension
|
|
// DLL that extends the cluster object.
|
|
//
|
|
// Arguments:
|
|
// hCluster [IN] Handle to the cluster to modify.
|
|
// pClsid [IN] Extension's CLSID.
|
|
//
|
|
// Return Value:
|
|
// S_OK Extension registered successfully.
|
|
// Win32 error code if another failure occurred.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDAPI RegisterCluAdminClusterExtension(
|
|
IN HCLUSTER hCluster,
|
|
IN const CLSID * pClsid
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
HKEY hkey;
|
|
|
|
// Get the cluster registry key.
|
|
hkey = GetClusterKey(hCluster, KEY_ALL_ACCESS);
|
|
if (hkey == NULL)
|
|
hr = GetLastError();
|
|
else
|
|
{
|
|
// Register the extension.
|
|
hr = RegisterAnyCluAdminExtension(hkey, pClsid);
|
|
|
|
ClusterRegCloseKey(hkey);
|
|
} // else: GetClusterKey succeeded
|
|
|
|
return hr;
|
|
|
|
} //*** RegisterCluAdminClusterExtension()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// RegisterCluAdminAllNodesExtension
|
|
//
|
|
// Routine Description:
|
|
// Register with the cluster database a Cluster Administrator Extension
|
|
// DLL that extends all nodes.
|
|
//
|
|
// Arguments:
|
|
// hCluster [IN] Handle to the cluster to modify.
|
|
// pClsid [IN] Extension's CLSID.
|
|
//
|
|
// Return Value:
|
|
// S_OK Extension registered successfully.
|
|
// Win32 error code if another failure occurred.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDAPI RegisterCluAdminAllNodesExtension(
|
|
IN HCLUSTER hCluster,
|
|
IN const CLSID * pClsid
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = RegisterAnyCluAdminExtension(hCluster, L"Nodes", pClsid);
|
|
|
|
return hr;
|
|
|
|
} //*** RegisterCluAdminAllNodesExtension()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// RegisterCluAdminAllGroupsExtension
|
|
//
|
|
// Routine Description:
|
|
// Register with the cluster database a Cluster Administrator Extension
|
|
// DLL that extends all groups.
|
|
//
|
|
// Arguments:
|
|
// hCluster [IN] Handle to the cluster to modify.
|
|
// pClsid [IN] Extension's CLSID.
|
|
//
|
|
// Return Value:
|
|
// S_OK Extension registered successfully.
|
|
// Win32 error code if another failure occurred.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDAPI RegisterCluAdminAllGroupsExtension(
|
|
IN HCLUSTER hCluster,
|
|
IN const CLSID * pClsid
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = RegisterAnyCluAdminExtension(hCluster, L"Groups", pClsid);
|
|
|
|
return hr;
|
|
|
|
} //*** RegisterCluAdminAllGroupsExtension()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// RegisterCluAdminAllResourcesExtension
|
|
//
|
|
// Routine Description:
|
|
// Register with the cluster database a Cluster Administrator Extension
|
|
// DLL that extends all resources.
|
|
//
|
|
// Arguments:
|
|
// hCluster [IN] Handle to the cluster to modify.
|
|
// pClsid [IN] Extension's CLSID.
|
|
//
|
|
// Return Value:
|
|
// S_OK Extension registered successfully.
|
|
// Win32 error code if another failure occurred.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDAPI RegisterCluAdminAllResourcesExtension(
|
|
IN HCLUSTER hCluster,
|
|
IN const CLSID * pClsid
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = RegisterAnyCluAdminExtension(hCluster, L"Resources", pClsid);
|
|
|
|
return hr;
|
|
|
|
} //*** RegisterCluAdminAllResourcesExtension()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// RegisterCluAdminAllResourceTypesExtension
|
|
//
|
|
// Routine Description:
|
|
// Register with the cluster database a Cluster Administrator Extension
|
|
// DLL that extends all resource types.
|
|
//
|
|
// Arguments:
|
|
// hCluster [IN] Handle to the cluster to modify.
|
|
// pClsid [IN] Extension's CLSID.
|
|
//
|
|
// Return Value:
|
|
// S_OK Extension registered successfully.
|
|
// Win32 error code if another failure occurred.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDAPI RegisterCluAdminAllResourceTypesExtension(
|
|
IN HCLUSTER hCluster,
|
|
IN const CLSID * pClsid
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = RegisterAnyCluAdminExtension(hCluster, L"ResourceTypes", pClsid);
|
|
|
|
return hr;
|
|
|
|
} //*** RegisterCluAdminAllResourceTypesExtension()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// RegisterCluAdminResourceTypeExtension
|
|
//
|
|
// Routine Description:
|
|
// Register with the cluster database a Cluster Administrator Extension
|
|
// DLL that extends resources of a specific type, or the resource type
|
|
// itself.
|
|
//
|
|
// Arguments:
|
|
// hCluster [IN] Handle to the cluster to modify.
|
|
// pwszResourceType [IN] Resource type name.
|
|
// pClsid [IN] Extension's CLSID.
|
|
//
|
|
// Return Value:
|
|
// S_OK Extension registered successfully.
|
|
// Win32 error code if another failure occurred.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDAPI RegisterCluAdminResourceTypeExtension(
|
|
IN HCLUSTER hCluster,
|
|
IN LPCWSTR pwszResourceType,
|
|
IN const CLSID * pClsid
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
HKEY hkey;
|
|
|
|
// Get the resource type registry key.
|
|
hkey = GetClusterResourceTypeKey(hCluster, pwszResourceType, KEY_ALL_ACCESS);
|
|
if (hkey == NULL)
|
|
hr = GetLastError();
|
|
else
|
|
{
|
|
// Register the extension.
|
|
hr = RegisterAnyCluAdminExtension(hkey, pClsid);
|
|
|
|
ClusterRegCloseKey(hkey);
|
|
} // else: GetClusterResourceTypeKey succeeded
|
|
|
|
return hr;
|
|
|
|
} //*** RegisterCluAdminResourceTypeExtension()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// UnregisterCluAdminClusterExtension
|
|
//
|
|
// Routine Description:
|
|
// Unregister with the cluster database a Cluster Administrator Extension
|
|
// DLL that extends the cluster object.
|
|
//
|
|
// Arguments:
|
|
// hCluster [IN] Handle to the cluster to modify.
|
|
// pClsid [IN] Extension's CLSID.
|
|
//
|
|
// Return Value:
|
|
// S_OK Extension registered successfully.
|
|
// Win32 error code if another failure occurred.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDAPI UnregisterCluAdminClusterExtension(
|
|
IN HCLUSTER hCluster,
|
|
IN const CLSID * pClsid
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
HKEY hkey;
|
|
|
|
// Get the cluster registry key.
|
|
hkey = GetClusterKey(hCluster, KEY_ALL_ACCESS);
|
|
if (hkey == NULL)
|
|
hr = GetLastError();
|
|
else
|
|
{
|
|
// Unregister the extension.
|
|
hr = UnregisterAnyCluAdminExtension(hkey, pClsid);
|
|
|
|
ClusterRegCloseKey(hkey);
|
|
} // else: GetClusterKey succeeded
|
|
|
|
return hr;
|
|
|
|
} //*** UnregisterCluAdminClusterExtension()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// UnregisterCluAdminAllNodesExtension
|
|
//
|
|
// Routine Description:
|
|
// Unregister with the cluster database a Cluster Administrator Extension
|
|
// DLL that extends all nodes.
|
|
//
|
|
// Arguments:
|
|
// hCluster [IN] Handle to the cluster to modify.
|
|
// pClsid [IN] Extension's CLSID.
|
|
//
|
|
// Return Value:
|
|
// S_OK Extension unregistered successfully.
|
|
// Win32 error code if another failure occurred.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDAPI UnregisterCluAdminAllNodesExtension(
|
|
IN HCLUSTER hCluster,
|
|
IN const CLSID * pClsid
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = UnregisterAnyCluAdminExtension(hCluster, L"Nodes", pClsid);
|
|
|
|
return hr;
|
|
|
|
} //*** UnregisterCluAdminAllNodesExtension()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// UnregisterCluAdminAllGroupsExtension
|
|
//
|
|
// Routine Description:
|
|
// Unregister with the cluster database a Cluster Administrator Extension
|
|
// DLL that extends all groups.
|
|
//
|
|
// Arguments:
|
|
// hCluster [IN] Handle to the cluster to modify.
|
|
// pClsid [IN] Extension's CLSID.
|
|
//
|
|
// Return Value:
|
|
// S_OK Extension unregistered successfully.
|
|
// Win32 error code if another failure occurred.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDAPI UnregisterCluAdminAllGroupsExtension(
|
|
IN HCLUSTER hCluster,
|
|
IN const CLSID * pClsid
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = UnregisterAnyCluAdminExtension(hCluster, L"Groups", pClsid);
|
|
|
|
return hr;
|
|
|
|
} //*** UnregisterCluAdminAllGroupsExtension()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// UnregisterCluAdminAllResourcesExtension
|
|
//
|
|
// Routine Description:
|
|
// Unregister with the cluster database a Cluster Administrator Extension
|
|
// DLL that extends all resources.
|
|
//
|
|
// Arguments:
|
|
// hCluster [IN] Handle to the cluster to modify.
|
|
// pClsid [IN] Extension's CLSID.
|
|
//
|
|
// Return Value:
|
|
// S_OK Extension unregistered successfully.
|
|
// Win32 error code if another failure occurred.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDAPI UnregisterCluAdminAllResourcesExtension(
|
|
IN HCLUSTER hCluster,
|
|
IN const CLSID * pClsid
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = UnregisterAnyCluAdminExtension(hCluster, L"Resources", pClsid);
|
|
|
|
return hr;
|
|
|
|
} //*** UnregisterCluAdminAllResourcesExtension()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// UnregisterCluAdminAllResourceTypesExtension
|
|
//
|
|
// Routine Description:
|
|
// Unregister with the cluster database a Cluster Administrator Extension
|
|
// DLL that extends all resource types.
|
|
//
|
|
// Arguments:
|
|
// hCluster [IN] Handle to the cluster to modify.
|
|
// pClsid [IN] Extension's CLSID.
|
|
//
|
|
// Return Value:
|
|
// S_OK Extension unregistered successfully.
|
|
// Win32 error code if another failure occurred.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDAPI UnregisterCluAdminAllResourceTypesExtension(
|
|
IN HCLUSTER hCluster,
|
|
IN const CLSID * pClsid
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = UnregisterAnyCluAdminExtension(hCluster, L"ResourceTypes", pClsid);
|
|
|
|
return hr;
|
|
|
|
} //*** UnregisterCluAdminAllResourceTypesExtension()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// UnregisterCluAdminResourceTypeExtension
|
|
//
|
|
// Routine Description:
|
|
// Unregister with the cluster database a Cluster Administrator Extension
|
|
// DLL that extends resources of a specific type, or the resource type
|
|
// itself.
|
|
//
|
|
// Arguments:
|
|
// hCluster [IN] Handle to the cluster to modify.
|
|
// pwszResourceType [IN] Resource type name.
|
|
// pClsid [IN] Extension's CLSID.
|
|
//
|
|
// Return Value:
|
|
// S_OK Extension unregistered successfully.
|
|
// Win32 error code if another failure occurred.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDAPI UnregisterCluAdminResourceTypeExtension(
|
|
IN HCLUSTER hCluster,
|
|
IN LPCWSTR pwszResourceType,
|
|
IN const CLSID * pClsid
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
HKEY hkey;
|
|
|
|
// Get the resource type registry key.
|
|
hkey = GetClusterResourceTypeKey(hCluster, pwszResourceType, KEY_ALL_ACCESS);
|
|
if (hkey == NULL)
|
|
hr = GetLastError();
|
|
else
|
|
{
|
|
// Unregister the extension.
|
|
hr = UnregisterAnyCluAdminExtension(hkey, pClsid);
|
|
|
|
ClusterRegCloseKey(hkey);
|
|
} // else: GetClusterResourceTypeKey succeeded
|
|
|
|
return hr;
|
|
|
|
} //*** UnregisterCluAdminResourceTypeExtension()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// RegisterAnyCluAdminExtension
|
|
//
|
|
// Routine Description:
|
|
// Register any Cluster Administrator Extension DLL with the cluster
|
|
// database.
|
|
//
|
|
// Arguments:
|
|
// hCluster [IN] Handle to the cluster to modify.
|
|
// pwszKeyName [IN] Key name.
|
|
// pClsid [IN] Extension's CLSID.
|
|
//
|
|
// Return Value:
|
|
// S_OK Extension registered successfully.
|
|
// Win32 error code if another failure occurred.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
static HRESULT RegisterAnyCluAdminExtension(
|
|
IN HCLUSTER hCluster,
|
|
IN LPCWSTR pwszKeyName,
|
|
IN const CLSID * pClsid
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
HKEY hkeyCluster;
|
|
HKEY hkey;
|
|
|
|
// Get the cluster key.
|
|
hkeyCluster = GetClusterKey(hCluster, KEY_ALL_ACCESS);
|
|
if (hkeyCluster == NULL)
|
|
hr = GetLastError();
|
|
else
|
|
{
|
|
// Get the specified key.
|
|
hr = ClusterRegOpenKey(hkeyCluster, pwszKeyName, KEY_ALL_ACCESS, &hkey);
|
|
if (hr == ERROR_SUCCESS)
|
|
{
|
|
// Register the extension.
|
|
hr = RegisterAnyCluAdminExtension(hkey, pClsid);
|
|
|
|
ClusterRegCloseKey(hkey);
|
|
} // else: GetClusterResourceTypeKey succeeded
|
|
|
|
ClusterRegCloseKey(hkeyCluster);
|
|
} // if: CLSID converted to a string successfully
|
|
|
|
return hr;
|
|
|
|
} //*** RegisterAnyCluAdminExtension()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// RegisterAnyCluAdminExtension
|
|
//
|
|
// Routine Description:
|
|
// Register any Cluster Administrator Extension DLL with the cluster
|
|
// database.
|
|
//
|
|
// Arguments:
|
|
// hkey [IN] Cluster database key.
|
|
// pClsid [IN] Extension's CLSID.
|
|
//
|
|
// Return Value:
|
|
// S_OK Extension registered successfully.
|
|
// Win32 error code if another failure occurred.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
static HRESULT RegisterAnyCluAdminExtension(
|
|
IN HKEY hkey,
|
|
IN const CLSID * pClsid
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
LPOLESTR pwszClsid;
|
|
DWORD cbSize;
|
|
DWORD cbNewSize;
|
|
LPWSTR pwszValue;
|
|
LPWSTR pwszNewValue;
|
|
BOOL bAlreadyRegistered;
|
|
|
|
// Convert the CLSID to a string.
|
|
hr = StringFromCLSID(*pClsid, &pwszClsid);
|
|
if (hr == S_OK)
|
|
{
|
|
// Read the current value.
|
|
hr = ReadValue(hkey, REG_VALUE_ADMIN_EXTENSIONS, &pwszValue, &cbSize);
|
|
if (hr == S_OK)
|
|
{
|
|
// Check to see if the extension has been registered yet.
|
|
if (pwszValue == NULL)
|
|
bAlreadyRegistered = FALSE;
|
|
else
|
|
{
|
|
LPCWSTR pwszValueBuf = pwszValue;
|
|
|
|
while (*pwszValueBuf != L'\0')
|
|
{
|
|
if (lstrcmpW(pwszClsid, pwszValueBuf) == 0)
|
|
break;
|
|
pwszValueBuf += lstrlenW(pwszValueBuf) + 1;
|
|
} // while: more strings in the extension list
|
|
bAlreadyRegistered = (*pwszValue != L'\0');
|
|
} // else: extension value exists
|
|
|
|
// Register the extension.
|
|
if (!bAlreadyRegistered)
|
|
{
|
|
// Allocate a new buffer.
|
|
cbNewSize = cbSize + (cbSize ? 0 : sizeof(WCHAR)) + (lstrlenW(pwszClsid) + 1) * sizeof(WCHAR);
|
|
pwszNewValue = (LPWSTR) LocalAlloc(LMEM_FIXED, cbNewSize);
|
|
if (pwszNewValue == NULL)
|
|
hr = GetLastError();
|
|
else
|
|
{
|
|
LPCWSTR pwszValueBuf = pwszValue;
|
|
LPWSTR pwszNewValueBuf = pwszNewValue;
|
|
DWORD cch;
|
|
DWORD dwType;
|
|
|
|
// Copy the existing extensions to the new buffer.
|
|
if (pwszValue != NULL)
|
|
{
|
|
while (*pwszValueBuf != L'\0')
|
|
{
|
|
lstrcpyW(pwszNewValueBuf, pwszValueBuf);
|
|
cch = lstrlenW(pwszValueBuf);
|
|
pwszValueBuf += cch + 1;
|
|
pwszNewValueBuf += cch + 1;
|
|
} // while: more strings in the extension list
|
|
} // if: previous value buffer existed
|
|
|
|
// Add the new CLSID to the list.
|
|
lstrcpyW(pwszNewValueBuf, pwszClsid);
|
|
pwszNewValueBuf += lstrlenW(pwszClsid) + 1;
|
|
*pwszNewValueBuf = L'\0';
|
|
|
|
// Write the value to the cluster database.
|
|
dwType = REG_MULTI_SZ;
|
|
hr = ClusterRegSetValue(
|
|
hkey,
|
|
REG_VALUE_ADMIN_EXTENSIONS,
|
|
dwType,
|
|
(LPBYTE) pwszNewValue,
|
|
cbNewSize
|
|
);
|
|
|
|
LocalFree(pwszNewValue);
|
|
} // else: new buffer allocated successfully
|
|
|
|
} // if: extension not registered yet
|
|
|
|
LocalFree(pwszValue);
|
|
} // if: value read successfully
|
|
|
|
CoTaskMemFree(pwszClsid);
|
|
} // if: CLSID converted to a string successfully
|
|
|
|
return hr;
|
|
|
|
} //*** RegisterAnyCluAdminExtension()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// UnregisterAnyCluAdminExtension
|
|
//
|
|
// Routine Description:
|
|
// Unregister any Cluster Administrator Extension DLL with the cluster
|
|
// database.
|
|
//
|
|
// Arguments:
|
|
// hCluster [IN] Handle to the cluster to modify.
|
|
// pwszKeyName [IN] Key name.
|
|
// pClsid [IN] Extension's CLSID.
|
|
//
|
|
// Return Value:
|
|
// S_OK Extension unregistered successfully.
|
|
// Win32 error code if another failure occurred.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
static HRESULT UnregisterAnyCluAdminExtension(
|
|
IN HCLUSTER hCluster,
|
|
IN LPCWSTR pwszKeyName,
|
|
IN const CLSID * pClsid
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
HKEY hkeyCluster;
|
|
HKEY hkey;
|
|
|
|
// Get the cluster key.
|
|
hkeyCluster = GetClusterKey(hCluster, KEY_ALL_ACCESS);
|
|
if (hkeyCluster == NULL)
|
|
hr = GetLastError();
|
|
else
|
|
{
|
|
// Get the specified key.
|
|
hr = ClusterRegOpenKey(hkeyCluster, pwszKeyName, KEY_ALL_ACCESS, &hkey);
|
|
if (hr == ERROR_SUCCESS)
|
|
{
|
|
// Unregister the extension.
|
|
hr = UnregisterAnyCluAdminExtension(hkey, pClsid);
|
|
|
|
ClusterRegCloseKey(hkey);
|
|
} // else: GetClusterResourceTypeKey succeeded
|
|
|
|
ClusterRegCloseKey(hkeyCluster);
|
|
} // if: CLSID converted to a string successfully
|
|
|
|
return hr;
|
|
|
|
} //*** UnregisterAnyCluAdminExtension()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// UnregisterAnyCluAdminExtension
|
|
//
|
|
// Routine Description:
|
|
// Unregister any Cluster Administrator Extension DLL with the cluster
|
|
// database.
|
|
//
|
|
// Arguments:
|
|
// hkey [IN] Cluster database key.
|
|
// pClsid [IN] Extension's CLSID.
|
|
//
|
|
// Return Value:
|
|
// S_OK Extension unregistered successfully.
|
|
// Win32 error code if another failure occurred.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
static HRESULT UnregisterAnyCluAdminExtension(
|
|
IN HKEY hkey,
|
|
IN const CLSID * pClsid
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
LPOLESTR pwszClsid;
|
|
DWORD cbSize;
|
|
DWORD cbNewSize;
|
|
LPWSTR pwszValue;
|
|
LPWSTR pwszNewValue;
|
|
BOOL bAlreadyUnregistered;
|
|
|
|
// Convert the CLSID to a string.
|
|
hr = StringFromCLSID(*pClsid, &pwszClsid);
|
|
if (hr == S_OK)
|
|
{
|
|
// Read the current value.
|
|
hr = ReadValue(hkey, REG_VALUE_ADMIN_EXTENSIONS, &pwszValue, &cbSize);
|
|
if (hr == S_OK)
|
|
{
|
|
// Check to see if the extension has been unregistered yet.
|
|
if (pwszValue == NULL)
|
|
bAlreadyUnregistered = TRUE;
|
|
else
|
|
{
|
|
LPCWSTR pwszValueBuf = pwszValue;
|
|
|
|
while (*pwszValueBuf != L'\0')
|
|
{
|
|
if (lstrcmpW(pwszClsid, pwszValueBuf) == 0)
|
|
break;
|
|
pwszValueBuf += lstrlenW(pwszValueBuf) + 1;
|
|
} // while: more strings in the extension list
|
|
bAlreadyUnregistered = (*pwszValue != L'\0');
|
|
} // else: extension value exists
|
|
|
|
// Unregister the extension.
|
|
if (!bAlreadyUnregistered)
|
|
{
|
|
// Allocate a new buffer.
|
|
cbNewSize = cbSize - (lstrlenW(pwszClsid) + 1) * sizeof(WCHAR);
|
|
pwszNewValue = (LPWSTR) LocalAlloc(LMEM_FIXED, cbNewSize);
|
|
if (pwszNewValue == NULL)
|
|
hr = GetLastError();
|
|
else
|
|
{
|
|
LPCWSTR pwszValueBuf = pwszValue;
|
|
LPWSTR pwszNewValueBuf = pwszNewValue;
|
|
DWORD dwType;
|
|
|
|
// Copy the existing extensions to the new buffer.
|
|
if (pwszValue != NULL)
|
|
{
|
|
while (*pwszValueBuf != L'\0')
|
|
{
|
|
if (lstrcmpW(pwszClsid, pwszValueBuf) != 0)
|
|
{
|
|
lstrcpyW(pwszNewValueBuf, pwszValueBuf);
|
|
pwszNewValueBuf += lstrlen(pwszNewValueBuf) + 1;
|
|
} // if: not CLSID being removed
|
|
pwszValueBuf += lstrlenW(pwszValueBuf) + 1;
|
|
} // while: more strings in the extension list
|
|
} // if: previous value buffer existed
|
|
|
|
// Write the value to the cluster database.
|
|
dwType = REG_MULTI_SZ;
|
|
hr = ClusterRegSetValue(
|
|
hkey,
|
|
REG_VALUE_ADMIN_EXTENSIONS,
|
|
dwType,
|
|
(LPBYTE) pwszNewValue,
|
|
cbNewSize
|
|
);
|
|
|
|
LocalFree(pwszNewValue);
|
|
} // else: new buffer allocated successfully
|
|
|
|
} // if: extension not unregistered yet
|
|
|
|
LocalFree(pwszValue);
|
|
} // if: value read successfully
|
|
|
|
CoTaskMemFree(pwszClsid);
|
|
} // if: CLSID converted to a string successfully
|
|
|
|
return hr;
|
|
|
|
} //*** UnregisterAnyCluAdminExtension()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// ReadValue
|
|
//
|
|
// Routine Description:
|
|
// Reads a value from the cluster database.
|
|
//
|
|
// Arguments:
|
|
// hkey [IN] Handle for the key to read from.
|
|
// pwszValueName [IN] Name of value to read.
|
|
// ppwszValue [OUT] Address of pointer in which to return data.
|
|
// The string is allocated using LocalAlloc and must
|
|
// be deallocated by the calling LocalFree.
|
|
// pcbSize [OUT] Size in bytes of the allocated value buffer.
|
|
//
|
|
// Return Value:
|
|
// Any return values from ClusterRegQueryValue or errors from new.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static DWORD ReadValue(
|
|
IN HKEY hkey,
|
|
IN LPCWSTR pwszValueName,
|
|
OUT LPWSTR * ppwszValue,
|
|
OUT DWORD * pcbSize
|
|
)
|
|
{
|
|
DWORD dwStatus;
|
|
DWORD cbSize;
|
|
DWORD dwType;
|
|
LPWSTR pwszValue;
|
|
|
|
*ppwszValue = NULL;
|
|
*pcbSize = 0;
|
|
|
|
// Get the length of the value.
|
|
dwStatus = ClusterRegQueryValue(
|
|
hkey,
|
|
pwszValueName,
|
|
&dwType,
|
|
NULL,
|
|
&cbSize
|
|
);
|
|
if ( (dwStatus != ERROR_SUCCESS)
|
|
&& (dwStatus != ERROR_MORE_DATA))
|
|
{
|
|
if (dwStatus == ERROR_FILE_NOT_FOUND)
|
|
dwStatus = ERROR_SUCCESS;
|
|
return dwStatus;
|
|
} // if: error occurred
|
|
|
|
// Allocate a value string.
|
|
pwszValue = (LPWSTR) LocalAlloc(LMEM_FIXED, cbSize);
|
|
if (pwszValue == NULL)
|
|
{
|
|
dwStatus = GetLastError();
|
|
return dwStatus;
|
|
} // if: error allocating memory
|
|
|
|
// Read the the value.
|
|
dwStatus = ClusterRegQueryValue(
|
|
hkey,
|
|
pwszValueName,
|
|
&dwType,
|
|
(LPBYTE) pwszValue,
|
|
&cbSize
|
|
);
|
|
if (dwStatus != ERROR_SUCCESS)
|
|
{
|
|
LocalFree(pwszValue);
|
|
pwszValue = NULL;
|
|
cbSize = 0;
|
|
} // if: error occurred
|
|
|
|
*ppwszValue = pwszValue;
|
|
*pcbSize = cbSize;
|
|
return dwStatus;
|
|
|
|
} //*** ReadValue()
|