windows-nt/Source/XPSP1/NT/com/rpc/ndr20/registry.cxx
2020-09-26 16:20:57 +08:00

1232 lines
34 KiB
C++

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1994-2000 Microsoft Corporation. All rights reserved.
Module Name:
registry.cxx
Abstract:
Registers the interfaces contained in the proxy DLL.
Public Functions:
DllRegisterServer
NdrDllRegisterProxy
NdrDllUnregisterProxy
Private Functions:
NdrpGetClassID
NdrpRegisterClass
NdrpRegisterInterface
NdrpUnregisterClass
NdrpUnregisterInterface
Author:
ShannonC 12-Oct-1994
Environment:
Windows NT and Windows 95.
Revision History:
RyszardK Nov 1997 Changes for async registration.
--------------------------------------------------------------------*/
#define USE_STUBLESS_PROXY
#define CINTERFACE
#include <ndrp.h>
#include <ndrole.h>
#include <rpcproxy.h>
#include <stdlib.h>
EXTERN_C HINSTANCE g_hRpcrt4 = 0;
HRESULT NdrpGetClassID(
OUT LPSTR pszClassID,
IN const CLSID * pclsid,
IN const ProxyFileInfo ** pProxyFileList);
HRESULT NdrpRegisterClass(
IN LPCSTR pszClassID,
IN LPCTSTR pszClassName,
IN LPCTSTR pszDllFileName,
IN LPCTSTR pszThreadingModel);
HRESULT NdrpRegisterInterface(
IN HKEY hKeyInterface,
IN REFIID riid,
IN LPCSTR pszInterfaceName,
IN LPCSTR pszClassID,
IN long NumMethods,
IN const IID * riidAsync
);
HRESULT NdrpRegisterAsyncInterface(
IN HKEY hKeyInterface,
IN REFIID riid,
IN LPCSTR pszSyncInterfaceName,
IN long SyncNumMethods,
IN REFIID riidAsync
);
HRESULT NdrpUnregisterClass(
IN LPCSTR pszClassID,
IN LPCTSTR pszDllFileName);
HRESULT NdrpUnregisterInterface(
IN HKEY hKeyInterface,
IN REFIID riid,
IN LPCSTR pszClassID,
IN const IID * riidAsync );
HRESULT RPC_ENTRY NdrDllRegisterProxy (
IN HMODULE hDll,
IN const ProxyFileInfo ** pProxyFileList,
IN const CLSID * pclsid OPTIONAL)
/*++
Routine Description:
Creates registry entries for the interfaces contained in the proxy DLL.
Arguments:
hDll - Supplies a handle to the proxy DLL.
pProxyFileList - Supplies a list of proxy files to be registered.
pclsid - Supplies the classid for the proxy DLL. May be zero.
Return Value:
S_OK
See Also:
DllRegisterServer
NdrDllUnregisterProxy
--*/
{
HRESULT hr;
long i, j;
HKEY hKeyInterface;
DWORD dwDisposition;
TCHAR szDllFileName[MAX_PATH];
long error;
ULONG length;
char szClassID[39];
if(hDll != 0)
{
//Get the proxy dll name.
length = GetModuleFileName(hDll,
szDllFileName,
sizeof(szDllFileName));
if(length > 0)
{
hr = S_OK;
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
else
{
//The proxy DLL's DLL_PROCESS_ATTACH did not initialize hProxyDll.
hr = E_HANDLE;
}
if(SUCCEEDED(hr))
{
//Convert the class ID to to a registry key name.
hr = NdrpGetClassID(szClassID, pclsid, pProxyFileList);
}
if(SUCCEEDED(hr))
{
//Register the class
hr = NdrpRegisterClass(szClassID,
TEXT("PSFactoryBuffer"),
szDllFileName,
TEXT("Both"));
}
if(SUCCEEDED(hr))
{
//Create the Interface key.
error = RegCreateKeyEx(HKEY_CLASSES_ROOT,
TEXT("Interface"),
0,
TEXT("REG_SZ"),
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
0,
&hKeyInterface,
&dwDisposition);
if(!error)
{
HRESULT hr2;
//iterate over the list of proxy files in the proxy DLL.
for(i = 0;
pProxyFileList[i] != 0;
i++)
{
if ( pProxyFileList[i]->TableVersion & NDR_PROXY_FILE_ASYNC_UUID)
{
// Iterate through sync and async interfaces.
for(j = 0;
pProxyFileList[i]->pProxyVtblList[j] != 0;
j++)
{
if ( pProxyFileList[i]->pAsyncIIDLookup[j] == 0)
{
// just a sync interface, no async counterpart.
hr2 = NdrpRegisterInterface(hKeyInterface,
*pProxyFileList[i]->pStubVtblList[j]->header.piid,
pProxyFileList[i]->pNamesArray[j],
szClassID,
pProxyFileList[i]->pStubVtblList[j]->header.DispatchTableCount,
0 /* no async */);
if(FAILED(hr2) && SUCCEEDED(hr))
hr = hr2;
}
else if ( (ULONG_PTR) pProxyFileList[i]->pAsyncIIDLookup[j] != -1 )
{
// Register an sync-async pair of interfaces.
hr2 = NdrpRegisterInterface(hKeyInterface,
*pProxyFileList[i]->pStubVtblList[j]->header.piid,
pProxyFileList[i]->pNamesArray[j],
szClassID,
pProxyFileList[i]->pStubVtblList[j]->header.DispatchTableCount,
pProxyFileList[i]->pAsyncIIDLookup[j]);
if(FAILED(hr2) && SUCCEEDED(hr))
hr = hr2;
hr2 = NdrpRegisterAsyncInterface(hKeyInterface,
*pProxyFileList[i]->pStubVtblList[j]->header.piid,
pProxyFileList[i]->pNamesArray[j],
pProxyFileList[i]->pStubVtblList[j]->header.DispatchTableCount,
*pProxyFileList[i]->pAsyncIIDLookup[j] );
if(FAILED(hr2) && SUCCEEDED(hr))
hr = hr2;
}
}
}
else
{
// Plain old style sync interfaces only.
// iterate over the list of interfaces in the proxy file.
for(j = 0;
pProxyFileList[i]->pProxyVtblList[j] != 0;
j++)
{
hr2 = NdrpRegisterInterface(hKeyInterface,
*pProxyFileList[i]->pStubVtblList[j]->header.piid,
pProxyFileList[i]->pNamesArray[j],
szClassID,
pProxyFileList[i]->pStubVtblList[j]->header.DispatchTableCount,
0 /* no async */);
if(FAILED(hr2) && SUCCEEDED(hr))
hr = hr2;
}
}
}
RegCloseKey(hKeyInterface);
}
else
{
hr = HRESULT_FROM_WIN32(error);
}
}
return hr;
}
HRESULT CheckInprocServer32(
IN HKEY hKeyIID,
IN LPCTSTR pszDllFileName)
{
HRESULT hr;
HKEY hKey;
TCHAR szDll[MAX_PATH];
long cbData = sizeof(szDll);
long error;
DWORD dwType;
//Open the InprocServer32 key.
error = RegOpenKeyEx(hKeyIID,
TEXT("InprocServer32"),
0,
KEY_READ,
&hKey);
if(!error)
{
error = RegQueryValueEx(hKey,
TEXT(""),
0,
&dwType,
(BYTE*)szDll,
(ulong*)&cbData);
if(!error)
{
if(0 == lstrcmpi(pszDllFileName,
szDll))
hr = S_OK;
else
hr = REGDB_E_INVALIDVALUE;
}
else
{
hr = HRESULT_FROM_WIN32(error);
}
RegCloseKey(hKey);
}
else
{
hr = HRESULT_FROM_WIN32(error);
}
return hr;
}
HRESULT NdrpCheckClass(
IN LPCSTR pszClassID,
IN LPCTSTR pszDllFileName)
{
HRESULT hr;
long error;
HKEY hKeyCLSID;
//open the CLSID key
error = RegOpenKeyEx(HKEY_CLASSES_ROOT,
TEXT("CLSID"),
0,
KEY_WRITE,
&hKeyCLSID);
if(!error)
{
HKEY hKeyClassID;
//open registry key for class ID string
error = RegOpenKeyExA(hKeyCLSID,
pszClassID,
0,
KEY_WRITE,
&hKeyClassID);
if(!error)
{
hr = CheckInprocServer32(hKeyClassID,
pszDllFileName);
RegCloseKey(hKeyClassID);
}
else
{
hr = HRESULT_FROM_WIN32(error);
}
RegCloseKey(hKeyCLSID);
}
else
{
hr = HRESULT_FROM_WIN32(error);
}
return hr;
}
HRESULT RPC_ENTRY NdrDllUnregisterProxy (
IN HMODULE hDll,
IN const ProxyFileInfo ** pProxyFileList,
IN const CLSID * pclsid OPTIONAL)
/*++
Routine Description:
Removes registry entries for the interfaces contained in the proxy DLL.
Arguments:
hDll - Supplies a handle to the proxy DLL.
pProxyFileList - Supplies a list of proxy files to be unregistered.
pclsid - Supplies the classid for the proxy DLL. May be zero.
Return Value:
S_OK
See Also:
DllUnregisterServer
NdrDllRegisterProxy
--*/
{
HRESULT hr;
HKEY hKeyInterface;
long i, j;
long error;
TCHAR szDllFileName[MAX_PATH];
ULONG length;
char szClassID[39];
if(hDll != 0)
{
//Get the proxy dll name.
length = GetModuleFileName(hDll, szDllFileName, sizeof(szDllFileName));
if(length > 0)
{
hr = S_OK;
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
else
{
//The DLL_PROCESS_ATTACH in the proxy DLL failed to initialize hProxyDll.
hr = E_HANDLE;
}
if(SUCCEEDED(hr))
{
//Convert the class ID to a registry key name.
hr = NdrpGetClassID(szClassID, pclsid, pProxyFileList);
}
if(SUCCEEDED(hr))
{
//Check the class
hr = NdrpCheckClass(szClassID, szDllFileName);
}
if(SUCCEEDED(hr))
{
HRESULT hr2;
//Open the Interface key.
error = RegOpenKeyEx(HKEY_CLASSES_ROOT,
TEXT("Interface"),
0,
KEY_WRITE,
&hKeyInterface);
if (!error)
{
//iterate over the list of proxy files in the proxy DLL.
for(i = 0;
pProxyFileList[i] != 0;
i++)
{
if ( pProxyFileList[i]->TableVersion & NDR_PROXY_FILE_ASYNC_UUID)
{
// Iterate through sync and async interfaces.
for(j = 0;
pProxyFileList[i]->pProxyVtblList[j] != 0;
j++)
{
if ( (ULONG_PTR) pProxyFileList[i]->pAsyncIIDLookup[j] != -1 )
{
// Unegister a single sync only interface or an sync-async
// pair of interfaces. Skip async interfaces.
NdrpUnregisterInterface( hKeyInterface,
*pProxyFileList[i]->pStubVtblList[j]->header.piid,
szClassID,
pProxyFileList[i]->pAsyncIIDLookup[j]);
}
}
}
else
{
//iterate over the list of interfaces in the proxy file.
for(j = 0;
pProxyFileList[i]->pProxyVtblList[j] != 0;
j++)
{
NdrpUnregisterInterface(hKeyInterface,
*pProxyFileList[i]->pStubVtblList[j]->header.piid,
szClassID,
0 /* no async */);
}
}
}
RegCloseKey(hKeyInterface);
}
else
{
hr = HRESULT_FROM_WIN32(error);
}
//Unregister the class
hr2 = NdrpUnregisterClass(szClassID, szDllFileName);
if(FAILED(hr2) && SUCCEEDED(hr))
hr = hr2;
}
return hr;
}
HRESULT NdrpGetClassID(
OUT LPSTR pszClassID,
IN const CLSID * pclsid,
IN const ProxyFileInfo ** pProxyFileList)
/*++
Routine Description:
Gets a string specifying the Class ID for the PSFactoryBuffer.
If pclsid is NULL, then this function will use the IID of the
first interface as the class ID.
Arguments:
pszClassID - The Class ID string is returned in this buffer.
pclsid - Specifies the class ID. May be zero.
pProxyFileList - Points to a list of ProxyFiles.
Return Value:
S_OK
E_NOINTERFACE
--*/
{
HRESULT hr;
long i, j;
//If necessary, use the IID of the first interface as the CLSID.
for(i = 0;
(pProxyFileList[i] != 0) && (!pclsid);
i++)
{
for(j = 0;
(pProxyFileList[i]->pProxyVtblList[j] != 0) && (!pclsid);
j++)
{
pclsid = pProxyFileList[i]->pStubVtblList[j]->header.piid;
}
}
if(pclsid != 0)
{
hr = NdrStringFromIID( *pclsid, pszClassID );
}
else
{
hr = E_NOINTERFACE;
}
return hr;
}
HRESULT NdrpRegisterClass(
IN LPCSTR pszClassID,
IN LPCTSTR pszClassName OPTIONAL,
IN LPCTSTR pszDllFileName,
IN LPCTSTR pszThreadingModel OPTIONAL)
/*++
Routine Description:
Creates a registry entry for an in-process server class.
Arguments:
pszClassID - Supplies the class ID.
pszClassName - Supplies the class name. May be NULL.
pszDllFileName - Supplies the DLL file name.
pszThreadingModel - Supplies the threading model. May be NULL.
The threading model should be one of the following:
"Apartment", "Both", "Free".
Return Value:
S_OK
See Also:
NdrDllRegisterProxy
NdrpUnregisterClass
--*/
{
HRESULT hr;
long error;
HKEY hKeyCLSID;
HKEY hKeyClassID;
HKEY hKey;
DWORD dwDisposition;
//create the CLSID key
error = RegCreateKeyEx(HKEY_CLASSES_ROOT,
TEXT("CLSID"),
0,
TEXT("REG_SZ"),
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
0,
&hKeyCLSID,
&dwDisposition);
if(!error)
{
//Create registry key for class ID
error = RegCreateKeyExA(hKeyCLSID,
pszClassID,
0,
"REG_SZ",
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
0,
&hKeyClassID,
&dwDisposition);
if(!error)
{
//Create InProcServer32 key for the proxy dll
error = RegCreateKeyEx(hKeyClassID,
TEXT("InProcServer32"),
0,
TEXT("REG_SZ"),
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
0,
&hKey,
&dwDisposition);
if(!error)
{
//register the proxy DLL filename
error = RegSetValueEx(hKey,
TEXT(""),
0,
REG_SZ,
(BYTE*)pszDllFileName,
strlen(pszDllFileName) + 1);
if((!error) && (pszThreadingModel != 0))
{
//register the threading model for the proxy DLL.
error = RegSetValueEx(hKey,
TEXT("ThreadingModel"),
0,
REG_SZ,
(BYTE*)pszThreadingModel,
strlen(pszThreadingModel) + 1);
}
RegCloseKey(hKey);
}
if((!error) && (pszClassName != 0))
{
// put the class name in an unnamed value
error = RegSetValueEx(hKeyClassID,
TEXT(""),
0,
REG_SZ,
(BYTE*)pszClassName,
strlen(pszClassName) + 1);
}
RegCloseKey(hKeyClassID);
}
RegCloseKey(hKeyCLSID);
}
if(!error)
hr = S_OK;
else
hr = HRESULT_FROM_WIN32(error);
return hr;
}
HRESULT NdrpRegisterInterface(
IN HKEY hKeyInterface,
IN REFIID riid,
IN LPCSTR pszInterfaceName,
IN LPCSTR pszClassID,
IN long NumMethods,
IN const IID * riidAsync )
/*++
Routine Description:
Creates a registry entry for an interface proxy.
Arguments:
hKeyInterface
riid
pszInterfaceName
pszClassID
NumMethods
riidAsync - async iid, may be null.
Return Value:
S_OK
See Also:
NdrDllRegisterProxy
NdrpUnregisterInterface
--*/
{
HRESULT hr;
long error;
char szIID[39];
char szNumMethods[6];
DWORD dwDisposition;
HKEY hKey;
HKEY hKeyIID;
//convert the IID to a registry key name.
NdrStringFromIID( riid, szIID );
//create registry key for the interface
error = RegCreateKeyExA(hKeyInterface,
szIID,
0,
"REG_SZ",
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
0,
&hKeyIID,
&dwDisposition);
if (!error)
{
//create ProxyStubClsid32 key.
error = RegCreateKeyEx(hKeyIID,
TEXT("ProxyStubClsid32"),
0,
TEXT("REG_SZ"),
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
0,
&hKey,
&dwDisposition);
if (!error)
{
//Set the class id for the PSFactoryBuffer.
error = RegSetValueExA(hKey,
"",
0,
REG_SZ,
(BYTE*)pszClassID,
strlen(pszClassID) + 1);
RegCloseKey(hKey);
}
// put the interface name in the unnamed value
if(!error)
{
error = RegSetValueExA(hKeyIID,
"",
0,
REG_SZ,
(BYTE*)pszInterfaceName,
strlen(pszInterfaceName) + 1);
}
//create NumMethods key.
if(!error)
{
error = RegCreateKeyEx(hKeyIID,
TEXT("NumMethods"),
0,
TEXT("REG_SZ"),
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
0,
&hKey,
&dwDisposition);
if(!error)
{
//Set the number of methods
RpcItoa( NumMethods, szNumMethods, 10 );
error = RegSetValueExA(hKey,
"",
0,
REG_SZ,
(UCHAR *) szNumMethods,
strlen(szNumMethods) + 1);
RegCloseKey(hKey);
}
}
if ( riidAsync )
{
//create AsynchronousInterface key under the interface.
if(!error)
{
error = RegCreateKeyEx( hKeyIID,
TEXT("AsynchronousInterface"),
0,
TEXT("REG_SZ"),
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
0,
&hKey,
&dwDisposition);
if(!error)
{
// Set the iid as value for the string.
NdrStringFromIID( *riidAsync, szIID );
error = RegSetValueExA( hKey,
"",
0,
REG_SZ,
(UCHAR *) szIID,
strlen(szIID) + 1);
RegCloseKey(hKey);
}
}
}
RegCloseKey(hKeyIID);
}
if(!error)
hr = S_OK;
else
hr = HRESULT_FROM_WIN32(error);
return hr;
}
HRESULT NdrpRegisterAsyncInterface(
IN HKEY hKeyInterface,
IN REFIID riid,
IN LPCSTR pszSyncInterfaceName,
IN long SyncNumMethods,
IN REFIID riidAsync )
/*++
Routine Description:
Creates a registry entry for an async interface proxy.
Arguments:
hKeyInterface
riid
pszInterfaceName
pszClassID
NumMethods
riidAsync
Return Value:
S_OK
See Also:
NdrDllRegisterProxy
NdrpUnregisterInterface
--*/
{
HRESULT hr;
long error;
char szIID[39];
char szNumMethods[6];
DWORD dwDisposition;
HKEY hKey;
HKEY hKeyIID;
//convert the IID to a registry key name.
NdrStringFromIID( riidAsync, szIID );
//create registry key for the interface
error = RegCreateKeyExA(hKeyInterface,
szIID,
0,
"REG_SZ",
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
0,
&hKeyIID,
&dwDisposition);
// By definition, for async interfaces do not create Clsid32 key.
// put the interface name in the unnamed value
if(!error)
{
char * pszAsyncInterfaceName;
int len;
len = 5 + strlen(pszSyncInterfaceName) + 1; /* 5 is strlen("Async") */
pszAsyncInterfaceName = (char*)alloca(len);
RpcpMemoryCopy( pszAsyncInterfaceName, "Async", 5 );
RpcpMemoryCopy( pszAsyncInterfaceName + 5, pszSyncInterfaceName, len - 5 );
error = RegSetValueExA(hKeyIID,
"",
0,
REG_SZ,
(BYTE*)pszAsyncInterfaceName,
len);
//create NumMethods key.
if(!error)
{
long AsyncNumMethods = 2 * SyncNumMethods - 3;
error = RegCreateKeyEx(hKeyIID,
TEXT("NumMethods"),
0,
TEXT("REG_SZ"),
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
0,
&hKey,
&dwDisposition);
if(!error)
{
//Set the number of methods
RpcItoa( AsyncNumMethods, szNumMethods, 10 );
error = RegSetValueExA(hKey,
"",
0,
REG_SZ,
(UCHAR *) szNumMethods,
strlen(szNumMethods) + 1);
RegCloseKey(hKey);
}
}
//create SynchronousInterface key under the interface.
if(!error)
{
error = RegCreateKeyEx( hKeyIID,
TEXT("SynchronousInterface"),
0,
TEXT("REG_SZ"),
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
0,
&hKey,
&dwDisposition);
if(!error)
{
// Set the iid as value for the string.
NdrStringFromIID( riid, szIID );
error = RegSetValueExA( hKey,
"",
0,
REG_SZ,
(UCHAR *) szIID,
strlen(szIID) + 1);
RegCloseKey(hKey);
}
}
RegCloseKey(hKeyIID);
}
if(!error)
hr = S_OK;
else
hr = HRESULT_FROM_WIN32(error);
return hr;
}
HRESULT NdrpUnregisterClass(
IN LPCSTR pszClassID,
IN LPCTSTR pszDllFileName)
/*++
Routine Description:
Removes an in-process server class from the registry.
Arguments:
pszClassID - Supplies the class ID.
Return Value:
S_OK
See Also:
NdrDllUnregisterProxy
NdrpRegisterClass
--*/
{
HRESULT hr;
HKEY hKeyCLSID;
HKEY hKeyClassID;
long error;
//open the CLSID key
error = RegOpenKeyEx(HKEY_CLASSES_ROOT,
TEXT("CLSID"),
0,
KEY_WRITE,
&hKeyCLSID);
if(!error)
{
//open registry key for class ID string
error = RegOpenKeyExA(hKeyCLSID,
pszClassID,
0,
KEY_WRITE,
&hKeyClassID);
if(!error)
{
hr = CheckInprocServer32(hKeyClassID,
pszDllFileName);
if(SUCCEEDED(hr))
{
//delete InProcServer32 key.
error = RegDeleteKey(hKeyClassID,
TEXT("InProcServer32"));
if(error != 0)
{
hr = HRESULT_FROM_WIN32(error);
}
}
RegCloseKey(hKeyClassID);
}
else
{
hr = HRESULT_FROM_WIN32(error);
}
if(SUCCEEDED(hr))
{
error = RegDeleteKeyA(hKeyCLSID, pszClassID);
if(error != 0)
{
hr = HRESULT_FROM_WIN32(error);
}
}
RegCloseKey(hKeyCLSID);
}
else
{
hr = HRESULT_FROM_WIN32(error);
}
return hr;
}
HRESULT CheckProxyStubClsid32(
IN HKEY hKeyIID,
IN LPCSTR pszClassID)
{
HRESULT hr;
HKEY hKey;
char szClassID[39];
long cbData = sizeof(szClassID);
long error;
DWORD dwType;
//Open the ProxyStubClsid32 key.
error = RegOpenKeyEx(hKeyIID,
TEXT("ProxyStubClsid32"),
0,
KEY_READ,
&hKey);
if(!error)
{
error = RegQueryValueExA(hKey,
"",
0,
&dwType,
(BYTE*)szClassID,
(ulong*)&cbData);
if(!error)
{
if(0 == memcmp(szClassID, pszClassID, cbData))
hr = S_OK;
else
hr = REGDB_E_INVALIDVALUE;
}
else
{
hr = HRESULT_FROM_WIN32(error);
}
RegCloseKey(hKey);
}
else
{
hr = HRESULT_FROM_WIN32(error);
}
return hr;
}
HRESULT NdrpUnregisterInterface(
IN HKEY hKeyInterface,
IN REFIID riid,
IN LPCSTR pszClassID,
IN const IID * riidAsync )
/*++
Routine Description:
Unregisters an interface proxy.
Arguments:
hKeyInterface
riid
Return Value:
S_OK
See Also:
NdrDllUnregisterProxy
NdrpRegisterInterface
--*/
{
HRESULT hr = S_OK;
long error;
char szIID[39];
HKEY hKeyIID;
//convert the IID to a registry key name.
NdrStringFromIID( riid, szIID );
//Open the IID key.
error = RegOpenKeyExA(hKeyInterface,
szIID,
0,
KEY_WRITE,
&hKeyIID);
if (!error)
{
// As we call for sync singles or sync pairs (sync-async),
// we always have the class id.
hr = CheckProxyStubClsid32(hKeyIID, pszClassID);
if(SUCCEEDED(hr))
{
// Once the class id matches, just attempt to delete
// every possible key that may happen under the sync entry.
// Note that additional key may be present due to oleauto
// registering a TLB.
RegDeleteKey(hKeyIID, TEXT("NumMethods"));
RegDeleteKey(hKeyIID, TEXT("ProxyStubClsid32"));
RegDeleteKey(hKeyIID, TEXT("AsynchronousInterface"));
// Now remove the matching async interface entry, if there is one.
if ( riidAsync )
{
char szAsyncIID[39];
HKEY hKeyAsyncIID;
//convert the IID to a registry key name.
NdrStringFromIID( *riidAsync, szAsyncIID );
//Open the IID key.
error = RegOpenKeyExA(hKeyInterface,
szAsyncIID,
0,
KEY_WRITE,
&hKeyAsyncIID);
if ( !error )
{
RegDeleteKey( hKeyAsyncIID, TEXT("NumMethods"));
RegDeleteKey( hKeyAsyncIID, TEXT("SynchronousInterface"));
RegCloseKey(hKeyAsyncIID);
RegDeleteKeyA(hKeyInterface, szAsyncIID);
}
}
}
else
hr = S_FALSE;
//Close the IID key.
RegCloseKey(hKeyIID);
RegDeleteKeyA(hKeyInterface, szIID);
}
return hr;
}
STDAPI DllRegisterServer(void)
/*++
Routine Description:
Creates registry entries for the classes contained in rpcrt4.dll.
Return Value:
S_OK
--*/
{
HRESULT hr;
TCHAR szDllFileName[MAX_PATH];
ULONG length;
if(!g_hRpcrt4)
return E_HANDLE;
//Get the proxy dll name.
length = GetModuleFileName(g_hRpcrt4,
szDllFileName,
sizeof(szDllFileName));
if(length > 0)
{
//Register the class
hr = NdrpRegisterClass(TEXT("{b5866878-bd99-11d0-b04b-00c04fd91550}"),
TEXT("TypeFactory"),
szDllFileName,
TEXT("Both"));
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
return hr;
}