windows-nt/Source/XPSP1/NT/com/rpc/runtime/trans/rpcproxy/registry.cpp
2020-09-26 16:20:57 +08:00

1096 lines
30 KiB
C++

//---------------------------------------------------------------------
// Copyright (C)1998 Microsoft Corporation, All Rights Reserved.
//
// registry.cpp
//
//---------------------------------------------------------------------
#define UNICODE
#define INITGUID
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <malloc.h>
#include <winsock2.h>
#include <olectl.h> // for: SELFREG_E_CLASS
#include <iadmw.h> // COM Interface header
#include <iiscnfg.h> // MD_ & IIS_MD_ #defines
#include <httpfilt.h>
#include "registry.h"
//----------------------------------------------------------------
// Externals:
//----------------------------------------------------------------
extern "C" void *MemAllocate( DWORD dwSize );
extern "C" void *MemFree( VOID *pMem );
//----------------------------------------------------------------
// Globals:
//----------------------------------------------------------------
// static HINSTANCE g_hInst = 0;
//----------------------------------------------------------------
// AnsiToUnicode()
//
// Convert an ANSI string to a UNICODE string.
//----------------------------------------------------------------
DWORD AnsiToUnicode( IN UCHAR *pszString,
IN ULONG ulStringLen,
OUT WCHAR *pwsString )
{
if (!pszString)
{
if (!pwsString)
{
return NO_ERROR;
}
else
{
pwsString[0] = 0;
return NO_ERROR;
}
}
if (!MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,
(char*)pszString, 1+ulStringLen,
pwsString, 1+ulStringLen ))
{
return ERROR_NO_UNICODE_TRANSLATION;
}
return NO_ERROR;
}
//---------------------------------------------------------------------
// RegSetKeyAndValue()
//
// Private helper function for SetupRegistry() that creates
// a key, sets a value, then closes the key.
//
// Parameters:
// pwsKey WCHAR* The name of the key
// pwsSubkey WCHAR* The name of a subkey
// pwsValueName WCHAR* The value name.
// pwsValue WCHAR* The data value to store
// dwType The type for the new registry value.
// dwDataSize The size for non-REG_SZ registry entry types.
//
// Return:
// BOOL TRUE if successful, FALSE otherwise.
//---------------------------------------------------------------------
BOOL RegSetKeyAndValue( const WCHAR *pwsKey,
const WCHAR *pwsSubKey,
const WCHAR *pwsValueName,
const WCHAR *pwsValue,
const DWORD dwType = REG_SZ,
DWORD dwDataSize = 0 )
{
HKEY hKey;
DWORD dwSize = 0;
WCHAR *pwsCompleteKey;
if (pwsKey)
dwSize = wcslen(pwsKey);
if (pwsSubKey)
dwSize += wcslen(pwsSubKey);
dwSize = (1+1+dwSize)*sizeof(WCHAR); // Extra +1 for the backslash...
pwsCompleteKey = (WCHAR*)_alloca(dwSize);
if (!pwsCompleteKey)
{
return FALSE; // Out of stack memory.
}
wcscpy(pwsCompleteKey,pwsKey);
if (NULL!=pwsSubKey)
{
wcscat(pwsCompleteKey, TEXT("\\"));
wcscat(pwsCompleteKey, pwsSubKey);
}
if (ERROR_SUCCESS!=RegCreateKeyEx( HKEY_LOCAL_MACHINE,
pwsCompleteKey,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hKey, NULL))
{
return FALSE;
}
if (pwsValue)
{
if ((dwType == REG_SZ)||(dwType == REG_EXPAND_SZ))
dwDataSize = (1+wcslen(pwsValue))*sizeof(WCHAR);
RegSetValueEx( hKey,
pwsValueName, 0, dwType, (BYTE *)pwsValue, dwDataSize );
}
else
{
RegSetValueEx( hKey,
pwsValueName, 0, dwType, (BYTE *)pwsValue, 0 );
}
RegCloseKey(hKey);
return TRUE;
}
//---------------------------------------------------------------------
// SetupRegistry()
//
// Add RPC proxy specific registry entries to contol its operation.
//
// \HKEY_LOCAL_MACHINE
// \Software
// \Microsoft
// \Rpc
// \RpcProxy
// \Enabled:REG_DWORD:0x00000001
// \ValidPorts:REG_SZ:<hostname>:1-5000
//
//---------------------------------------------------------------------
HRESULT SetupRegistry()
{
DWORD dwEnabled = 0x01;
DWORD dwSize;
DWORD dwStatus;
WCHAR *pwsValidPorts = 0;
char szHostName[MAX_TCPIP_HOST_NAME];
// Note that gethostname() is an ANSI (non-unicode) function:
if (SOCKET_ERROR == gethostname(szHostName,sizeof(szHostName)))
{
dwStatus = WSAGetLastError();
return SELFREG_E_CLASS;
}
dwSize = 1 + _mbstrlen(szHostName);
pwsValidPorts = (WCHAR*)MemAllocate( sizeof(WCHAR)
* (dwSize + wcslen(REG_PORT_RANGE)) );
if (!pwsValidPorts)
{
return E_OUTOFMEMORY;
}
dwStatus = AnsiToUnicode((unsigned char*)szHostName,dwSize,pwsValidPorts);
if (dwStatus != NO_ERROR)
{
MemFree(pwsValidPorts);
return SELFREG_E_CLASS;
}
wcscat(pwsValidPorts,REG_PORT_RANGE);
if ( !RegSetKeyAndValue( REG_RPC_PATH,
REG_RPCPROXY,
REG_ENABLED,
(unsigned short *)&dwEnabled,
REG_DWORD,
sizeof(DWORD))
|| !RegSetKeyAndValue( REG_RPC_PATH,
REG_RPCPROXY,
REG_VALID_PORTS,
pwsValidPorts,
REG_SZ) )
{
MemFree(pwsValidPorts);
return SELFREG_E_CLASS;
}
MemFree(pwsValidPorts);
return S_OK;
}
//---------------------------------------------------------------------
// CleanupRegistry()
//
// Delete the RpcProxy specific registry entries.
//---------------------------------------------------------------------
HRESULT CleanupRegistry()
{
HRESULT hr;
LONG lStatus;
DWORD dwLength = sizeof(WCHAR) + sizeof(REG_RPC_PATH)
+ sizeof(REG_RPCPROXY);
WCHAR *pwsSubKey;
pwsSubKey = (WCHAR*)_alloca(sizeof(WCHAR)*dwLength);
if (pwsSubKey)
{
wcscpy(pwsSubKey,REG_RPC_PATH);
wcscat(pwsSubKey,TEXT("\\"));
wcscat(pwsSubKey,REG_RPCPROXY);
lStatus = RegDeleteKey( HKEY_LOCAL_MACHINE,
pwsSubKey );
}
return S_OK;
}
//---------------------------------------------------------------------
// GetMetaBaseString()
//
// Retrieve a string value from the metabase.
//---------------------------------------------------------------------
HRESULT GetMetaBaseString( IN IMSAdminBase *pIMeta,
IN METADATA_HANDLE hMetaBase,
IN WCHAR *pwsKeyPath,
IN DWORD dwIdent,
OUT WCHAR *pwsBuffer,
IN OUT DWORD *pdwBufferSize )
{
HRESULT hr;
DWORD dwSize;
METADATA_RECORD *pmbRecord;
dwSize = sizeof(METADATA_RECORD);
pmbRecord = (METADATA_RECORD*)MemAllocate(dwSize);
if (!pmbRecord)
{
return ERROR_OUTOFMEMORY;
}
memset(pmbRecord,0,dwSize);
pmbRecord->dwMDIdentifier = dwIdent;
pmbRecord->dwMDAttributes = 0; // METADATA_INHERIT;
pmbRecord->dwMDUserType = IIS_MD_UT_SERVER;
pmbRecord->dwMDDataType = STRING_METADATA;
pmbRecord->dwMDDataLen = *pdwBufferSize;
pmbRecord->pbMDData = (BYTE*)pwsBuffer;
hr = pIMeta->GetData( hMetaBase,
pwsKeyPath,
pmbRecord,
&dwSize );
#ifdef DBG_REG
if (FAILED(hr))
{
DbgPrint("pIMeta->GetData(): Failed: 0x%x\n",hr);
}
#endif
MemFree(pmbRecord);
return hr;
}
//---------------------------------------------------------------------
// SetMetaBaseString()
//
// Store a string value into the metabase.
//---------------------------------------------------------------------
HRESULT SetMetaBaseString( IMSAdminBase *pIMeta,
METADATA_HANDLE hMetaBase,
WCHAR *pwsKeyPath,
DWORD dwIdent,
WCHAR *pwsBuffer,
DWORD dwAttributes,
DWORD dwUserType )
{
HRESULT hr;
METADATA_RECORD MbRecord;
memset(&MbRecord,0,sizeof(MbRecord));
MbRecord.dwMDIdentifier = dwIdent;
MbRecord.dwMDAttributes = dwAttributes;
MbRecord.dwMDUserType = dwUserType;
MbRecord.dwMDDataType = STRING_METADATA;
MbRecord.dwMDDataLen = sizeof(WCHAR) * (1 + wcslen(pwsBuffer));
MbRecord.pbMDData = (BYTE*)pwsBuffer;
hr = pIMeta->SetData( hMetaBase,
pwsKeyPath,
&MbRecord );
return hr;
}
//---------------------------------------------------------------------
// GetMetaBaseDword()
//
// Get a DWORD value from the metabase.
//---------------------------------------------------------------------
HRESULT GetMetaBaseDword( IMSAdminBase *pIMeta,
METADATA_HANDLE hMetaBase,
WCHAR *pwsKeyPath,
DWORD dwIdent,
DWORD *pdwValue )
{
HRESULT hr;
DWORD dwSize;
METADATA_RECORD MbRecord;
memset(&MbRecord,0,sizeof(MbRecord));
*pdwValue = 0;
MbRecord.dwMDIdentifier = dwIdent;
MbRecord.dwMDAttributes = 0;
MbRecord.dwMDUserType = IIS_MD_UT_SERVER;
MbRecord.dwMDDataType = DWORD_METADATA;
MbRecord.dwMDDataLen = sizeof(DWORD);
MbRecord.pbMDData = (unsigned char *)pdwValue;
hr = pIMeta->GetData( hMetaBase,
pwsKeyPath,
&MbRecord,
&dwSize );
return hr;
}
//---------------------------------------------------------------------
// SetMetaBaseDword()
//
// Store a DWORD value into the metabase.
//---------------------------------------------------------------------
HRESULT SetMetaBaseDword( IMSAdminBase *pIMeta,
METADATA_HANDLE hMetaBase,
WCHAR *pwsKeyPath,
DWORD dwIdent,
DWORD dwValue,
DWORD dwAttributes,
DWORD dwUserType )
{
HRESULT hr;
DWORD dwSize;
METADATA_RECORD MbRecord;
memset(&MbRecord,0,sizeof(MbRecord));
MbRecord.dwMDIdentifier = dwIdent;
MbRecord.dwMDAttributes = dwAttributes;
MbRecord.dwMDUserType = dwUserType;
MbRecord.dwMDDataType = DWORD_METADATA;
MbRecord.dwMDDataLen = sizeof(DWORD);
MbRecord.pbMDData = (unsigned char *)&dwValue;
hr = pIMeta->SetData( hMetaBase,
pwsKeyPath,
&MbRecord );
return hr;
}
//---------------------------------------------------------------------
// SetupMetaBase()
//
// Setup entries in the metabase for both the filter and ISAPI parts
// of the RPC proxy. Note that these entries used to be in the registry.
//
// W3Svc/Filters/FilterLoadOrder "...,RpcProxy"
// W3Svc/Filters/RpcProxy/FilterImagePath "%SystemRoot%\System32\RpcProxy"
// W3Svc/Filters/RpcProxy/KeyType "IIsFilter"
// W3Svc/Filters/RpcProxy/FilterDescription "Microsoft RPC Proxy Filter, v1.0"
//
// W3Svc/1/ROOT/Rpc/KeyType "IIsWebVirtualDir"
// W3Svc/1/ROOT/Rpc/VrPath "%SystemRoot%\System32\RpcProxy"
// W3Svc/1/ROOT/Rpc/AccessPerm 0x205
// W3Svc/1/ROOT/Rpc/Win32Error 0x0
// W3Svc/1/ROOT/Rpc/DirectoryBrowsing 0x4000001E
// W3Svc/1/ROOT/Rpc/AppIsolated 0x0
// W3Svc/1/ROOT/Rpc/AppRoot "/LM/W3SVC/1/Root/rpc"
// W3Svc/1/ROOT/Rpc/AppWamClsid "{BF285648-0C5C-11D2-A476-0000F8080B50}"
// W3Svc/1/ROOT/Rpc/AppFriendlyName "rpc"
//
//---------------------------------------------------------------------
HRESULT SetupMetaBase()
{
HRESULT hr = 0;
DWORD dwValue = 0;
DWORD dwSize = 0;
DWORD dwBufferSize = sizeof(WCHAR) * ORIGINAL_BUFFER_SIZE;
WCHAR *pwsBuffer = (WCHAR*)MemAllocate(dwBufferSize);
WCHAR *pwsSystemRoot = _wgetenv(SYSTEM_ROOT);
WCHAR wsPath[METADATA_MAX_NAME_LEN];
IMSAdminBase *pIMeta;
METADATA_HANDLE hMetaBase;
//
// Name of this DLL (and where it is):
//
// WCHAR wszModule[256];
//
// if (!GetModuleFileName( g_hInst, wszModule,
// sizeof(wszModule)/sizeof(WCHAR)))
// {
// return SELFREG_E_CLASS;
// }
if (!pwsBuffer)
{
return E_OUTOFMEMORY;
}
hr = CoCreateInstance( CLSID_MSAdminBase,
NULL,
CLSCTX_ALL,
IID_IMSAdminBase,
(void **)&pIMeta );
if (FAILED(hr))
{
#ifdef DBG_REG
DbgPrint("CoCreateInstance(): Failed: 0x%x\n",hr);
#endif
MemFree(pwsBuffer);
return hr;
}
// Get a handle to the Web service:
hr = pIMeta->OpenKey( METADATA_MASTER_ROOT_HANDLE,
LOCAL_MACHINE_W3SVC,
(METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE),
20,
&hMetaBase );
if (FAILED(hr))
{
#ifdef DBG_REG
DbgPrint("pIMeta->OpenKey(): Failed: 0x%x\n",hr);
#endif
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
//
// IIS Filter: FilterLoadOrder
//
dwSize = dwBufferSize;
hr = GetMetaBaseString( pIMeta,
hMetaBase,
MD_KEY_FILTERS, // See iiscnfg.h
MD_FILTER_LOAD_ORDER, // See iiscnfg.h
pwsBuffer,
&dwSize );
if (FAILED(hr))
{
#ifdef DBG_REG
DbgPrint("GetMetaBaseString(): Failed: 0x%x\n",hr);
#endif
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
else
{
if (!wcsstr(pwsBuffer,RPCPROXY))
{
// RpcProxy is not in FilterLoadOrder, so add it:
wcscat(pwsBuffer,TEXT(","));
wcscat(pwsBuffer,RPCPROXY);
hr = SetMetaBaseString( pIMeta,
hMetaBase,
MD_KEY_FILTERS,
MD_FILTER_LOAD_ORDER,
pwsBuffer,
0,
IIS_MD_UT_SERVER );
}
if (FAILED(hr))
{
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
}
//
// IIS Filter: RpcProxy/FilterImagePath
//
hr = pIMeta->AddKey( hMetaBase, MD_KEY_FILTERS_RPCPROXY );
if ( (FAILED(hr)) && (hr != 0x800700b7))
{
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
wcscpy(pwsBuffer,pwsSystemRoot);
wcscat(pwsBuffer,RPCPROXY_PATH);
wcscat(pwsBuffer,TEXT("\\"));
wcscat(pwsBuffer,RPCPROXY_DLL);
hr = SetMetaBaseString( pIMeta,
hMetaBase,
MD_KEY_FILTERS_RPCPROXY,
MD_FILTER_IMAGE_PATH,
pwsBuffer,
0,
IIS_MD_UT_SERVER );
if (FAILED(hr))
{
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
//
// IIS Filter: Filters/RpcProxy/KeyType
//
wcscpy(pwsBuffer,IISFILTER);
hr = SetMetaBaseString( pIMeta,
hMetaBase,
MD_KEY_FILTERS_RPCPROXY,
MD_KEY_TYPE,
pwsBuffer,
0,
IIS_MD_UT_SERVER );
if (FAILED(hr))
{
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
wcscpy(pwsBuffer,FILTER_DESCRIPTION);
hr = SetMetaBaseString( pIMeta,
hMetaBase,
MD_KEY_FILTERS_RPCPROXY,
MD_FILTER_DESCRIPTION,
pwsBuffer,
0,
IIS_MD_UT_SERVER );
if (FAILED(hr))
{
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
hr = SetMetaBaseDword( pIMeta,
hMetaBase,
MD_KEY_FILTERS_RPCPROXY,
MD_FILTER_FLAGS,
SF_NOTIFY_ORDER_LOW
| SF_NOTIFY_READ_RAW_DATA
| SF_NOTIFY_END_OF_NET_SESSION
| SF_NOTIFY_PREPROC_HEADERS,
0,
IIS_MD_UT_SERVER );
if (FAILED(hr))
{
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
//
// Set: /W3Svc/1/ROOT/rpc/AccessPerm
//
dwValue = ACCESS_PERM_FLAGS;
hr = SetMetaBaseDword( pIMeta,
hMetaBase,
MD_KEY_ROOT_RPC,
MD_ACCESS_PERM,
dwValue,
METADATA_INHERIT,
IIS_MD_UT_FILE );
if (FAILED(hr))
{
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
//
// Disable entity body preload for this ISAPI
//
dwValue = 0;
hr = SetMetaBaseDword( pIMeta,
hMetaBase,
MD_KEY_ROOT_RPC,
MD_UPLOAD_READAHEAD_SIZE,
dwValue,
METADATA_INHERIT,
IIS_MD_UT_FILE );
if (FAILED(hr))
{
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
//
// Set: /W3Svc/1/ROOT/rpc/Win32Error
//
dwValue = 0;
hr = SetMetaBaseDword( pIMeta,
hMetaBase,
MD_KEY_ROOT_RPC,
MD_WIN32_ERROR,
dwValue,
METADATA_INHERIT,
IIS_MD_UT_SERVER );
if (FAILED(hr))
{
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
//
// Set: /W3Svc/1/ROOT/rpc/DirectroyBrowsing
//
dwValue = DIRECTORY_BROWSING_FLAGS;
hr = SetMetaBaseDword( pIMeta,
hMetaBase,
MD_KEY_ROOT_RPC,
MD_DIRECTORY_BROWSING,
dwValue,
METADATA_INHERIT,
IIS_MD_UT_FILE );
if (FAILED(hr))
{
pIMeta->Release();
CoUninitialize();
return hr;
}
//
// Set: /W3Svc/1/ROOT/rpc/KeyType
//
wcscpy(pwsBuffer,IIS_WEB_VIRTUAL_DIR);
hr = SetMetaBaseString( pIMeta,
hMetaBase,
MD_KEY_ROOT_RPC,
MD_KEY_TYPE,
pwsBuffer,
0,
IIS_MD_UT_SERVER );
if (FAILED(hr))
{
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
//
// Set: /W3Svc/1/ROOT/rpc/VrPath
//
wcscpy(pwsBuffer,pwsSystemRoot);
wcscat(pwsBuffer,RPCPROXY_PATH);
hr = SetMetaBaseString( pIMeta,
hMetaBase,
MD_KEY_ROOT_RPC,
MD_VR_PATH,
pwsBuffer,
METADATA_INHERIT,
IIS_MD_UT_FILE );
if (FAILED(hr))
{
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
#if FALSE
//
// Set: /W3Svc/1/ROOT/rpc/AppIsolated
//
dwValue = 0;
hr = SetMetaBaseDword( pIMeta,
hMetaBase,
MD_KEY_ROOT_RPC,
MD_APP_ISOLATED,
dwValue,
METADATA_INHERIT,
IIS_MD_UT_WAM );
if (FAILED(hr))
{
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
//
// Set: /W3Svc/1/ROOT/rpc/AppRoot
//
wcscpy(pwsBuffer,APP_ROOT_PATH);
hr = SetMetaBaseString( pIMeta,
hMetaBase,
MD_KEY_ROOT_RPC,
MD_APP_ROOT,
pwsBuffer,
METADATA_INHERIT,
IIS_MD_UT_FILE );
if (FAILED(hr))
{
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
//
// Set: /W3Svc/1/ROOT/rpc/AppWamClsid
//
wcscpy(pwsBuffer,APP_WAM_CLSID);
hr = SetMetaBaseString( pIMeta,
hMetaBase,
MD_KEY_ROOT_RPC,
MD_APP_WAM_CLSID,
pwsBuffer,
METADATA_INHERIT,
IIS_MD_UT_WAM );
if (FAILED(hr))
{
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
//
// Set: /W3Svc/1/ROOT/rpc/AppFriendlyName
//
wcscpy(pwsBuffer,APP_FRIENDLY_NAME);
hr = SetMetaBaseString( pIMeta,
hMetaBase,
MD_KEY_ROOT_RPC,
MD_APP_FRIENDLY_NAME,
pwsBuffer,
METADATA_INHERIT,
IIS_MD_UT_WAM );
if (FAILED(hr))
{
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
#endif
//
// Release the handle and buffer:
//
MemFree(pwsBuffer);
pIMeta->CloseKey(hMetaBase);
pIMeta->Release();
CoUninitialize();
return 0;
}
//---------------------------------------------------------------------
// CleanupMetaBase()
//
//---------------------------------------------------------------------
HRESULT CleanupMetaBase()
{
HRESULT hr = 0;
DWORD dwSize = 0;
WCHAR *pwsRpcProxy;
WCHAR *pws;
DWORD dwBufferSize = sizeof(WCHAR) * ORIGINAL_BUFFER_SIZE;
WCHAR *pwsBuffer = (WCHAR*)MemAllocate(dwBufferSize);
// CComPtr <IMSAdminBase> pIMeta;
IMSAdminBase *pIMeta;
METADATA_HANDLE hMetaBase;
if (!pwsBuffer)
{
return ERROR_OUTOFMEMORY;
}
hr = CoCreateInstance( CLSID_MSAdminBase,
NULL,
CLSCTX_ALL,
IID_IMSAdminBase,
(void **)&pIMeta );
if (FAILED(hr))
{
MemFree(pwsBuffer);
return hr;
}
//
// Get a handle to the Web service:
//
hr = pIMeta->OpenKey( METADATA_MASTER_ROOT_HANDLE,
TEXT("/LM/W3SVC"),
(METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE),
20,
&hMetaBase );
if (FAILED(hr))
{
MemFree(pwsBuffer);
pIMeta->Release();
return hr;
}
//
// Remove the RpcProxy reference from the FilterLoadOrder value:
//
dwSize = dwBufferSize;
hr = GetMetaBaseString( pIMeta,
hMetaBase,
MD_KEY_FILTERS,
MD_FILTER_LOAD_ORDER,
pwsBuffer,
&dwSize );
if (!FAILED(hr))
{
if (pwsRpcProxy=wcsstr(pwsBuffer,RPCPROXY))
{
// "RpcProxy" is in FilterLoadOrder, so remove it:
// Check to see if RpcProxy is at the start of the list:
if (pwsRpcProxy != pwsBuffer)
{
pwsRpcProxy--; // Want to remove the comma before...
dwSize = sizeof(RPCPROXY);
}
else
{
dwSize = sizeof(RPCPROXY) - 1;
}
pws = pwsRpcProxy + dwSize;
memcpy(pwsRpcProxy,pws,sizeof(WCHAR)*(1+wcslen(pws)));
hr = SetMetaBaseString( pIMeta,
hMetaBase,
MD_KEY_FILTERS,
MD_FILTER_LOAD_ORDER,
pwsBuffer,
0,
IIS_MD_UT_SERVER );
}
}
//
// Delete: /W3Svc/Filters/RpcProxy
//
hr = pIMeta->DeleteKey( hMetaBase,
MD_KEY_FILTERS_RPCPROXY );
//
// Delete: /W3Svc/1/ROOT/Rpc
//
hr = pIMeta->DeleteKey( hMetaBase,
MD_KEY_FILTERS_RPCPROXY );
//
// Release the handle and buffer:
//
MemFree(pwsBuffer);
pIMeta->CloseKey(hMetaBase);
pIMeta->Release();
return S_OK;
}
//---------------------------------------------------------------------
// DllRegisterServer()
//
// Setup the Registry and MetaBase for the RPC proxy.
//---------------------------------------------------------------------
HRESULT DllRegisterServer()
{
HRESULT hr;
WORD wVersion = MAKEWORD(1,1);
WSADATA wsaData;
#ifdef DBG_REG
DbgPrint("RpcProxy: DllRegisterServer(): Start\n");
#endif
if (WSAStartup(wVersion,&wsaData))
{
return SELFREG_E_CLASS;
}
hr = CoInitializeEx(0,COINIT_MULTITHREADED);
if (FAILED(hr))
{
hr = CoInitializeEx(0,COINIT_APARTMENTTHREADED);
if (FAILED(hr))
{
#ifdef DBG_REG
DbgPrint("RpcProxy: CoInitialize(): Failed: 0x%x\n", hr );
#endif
return hr;
}
}
hr = SetupRegistry();
if (FAILED(hr))
{
#ifdef DBG_REG
DbgPrint("RpcProxy: SetupRegistry(): Failed: 0x%x (%d)\n",
hr, hr );
#endif
return hr;
}
hr = SetupMetaBase();
#ifdef DBG_REG
if (FAILED(hr))
{
DbgPrint("RpcProxy: SetupRegistry(): Failed: 0x%x (%d)\n",
hr, hr );
}
#endif
CoUninitialize();
#ifdef DBG_REG
DbgPrint("RpcProxy: DllRegisterServer(): End: hr: 0x%x\n",hr);
#endif
return hr;
}
//---------------------------------------------------------------------
// DllUnregisterServer()
//
// Uninstall Registry and MetaBase values used by the RPC proxy.
//
// Modified to mostly return S_Ok, even if a problem occurs. This is
// done so that the uninstall will complete even if there is a problem
// in the un-register.
//---------------------------------------------------------------------
HRESULT DllUnregisterServer()
{
HRESULT hr;
WORD wVersion = MAKEWORD(1,1);
WSADATA wsaData;
#ifdef DBG_REG
DbgPrint("RpcProxy: DllUnregisterServer(): Start\n");
#endif
if (WSAStartup(wVersion,&wsaData))
{
return SELFREG_E_CLASS;
}
hr = CoInitializeEx(0,COINIT_MULTITHREADED);
if (FAILED(hr))
{
hr = CoInitializeEx(0,COINIT_APARTMENTTHREADED);
if (FAILED(hr))
{
#ifdef DBG_REG
DbgPrint("RpcProxy: CoInitializeEx() Failed: 0x%x\n",hr);
#endif
return S_OK;
}
}
hr = CleanupRegistry();
if (FAILED(hr))
{
#ifdef DBG_REG
DbgPrint("RpcProxy: CleanupRegistry() Failed: 0x%x (%d)\n",hr,hr);
#endif
return S_OK;
}
hr = CleanupMetaBase();
#ifdef DBG_REG
if (FAILED(hr))
{
DbgPrint("RpcProxy: CleanupRegistry() Failed: 0x%x (%d)\n",hr,hr);
}
#endif
CoUninitialize();
#ifdef DBG_REG
DbgPrint("RpcProxy: DllUnregisterServer(): Start\n");
#endif
return S_OK;
}
#if FALSE
//--------------------------------------------------------------------
// DllMain()
//
//--------------------------------------------------------------------
BOOL WINAPI DllMain( HINSTANCE hInst,
ULONG ulReason,
LPVOID pvReserved )
{
BOOL fInitialized = TRUE;
switch (ulReason)
{
case DLL_PROCESS_ATTACH:
if (!DisableThreadLibraryCalls(hInst))
{
fInitialized = FALSE;
}
else
{
g_hInst = hInst;
}
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
// Not used. Disabled.
break;
case DLL_THREAD_DETACH:
// Not used. Disabled.
break;
}
return fInitialized;
}
#endif