windows-nt/Source/XPSP1/NT/admin/wmi/wbem/adapters/oledb/dllmain.cpp
2020-09-26 16:20:57 +08:00

908 lines
31 KiB
C++

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Microsoft WMI OLE DB Provider
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
//
// The module contains the DLL Entry and Exit points
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define DECLARE_GLOBALS
//===============================================================================
// Don't include everything from windows.h, but always bring in OLE 2 support
//===============================================================================
//#define WIN32_LEAN_AND_MEAN
#define INC_OLE2
//===============================================================================
// Make sure constants get initialized
//===============================================================================
#define INITGUID
#define DBINITCONSTANTS
//===============================================================================
// Basic Windows and OLE everything
//===============================================================================
#include <windows.h>
//===============================================================================
// OLE DB headers
//===============================================================================
#include "oledb.h"
#include "oledberr.h"
//===============================================================================
// Data conversion library header
//===============================================================================
#include "msdadc.h"
//===============================================================================
// Guids for data conversion library
//===============================================================================
#include "msdaguid.h"
//===============================================================================
// GUIDs
//===============================================================================
#include "guids.h"
//===============================================================================
// OLEDB RootBinder
//===============================================================================
#include "msdasc.h"
//===============================================================================
// Common project stuff
//===============================================================================
#include "headers.h"
#include "classfac.h"
#include "binderclassfac.h"
#include "binder.h"
//===============================================================================
// Globals
//===============================================================================
LONG g_cObj; // # of outstanding objects
LONG g_cLock; // # of explicit locks set
DWORD g_cAttachedProcesses; // # of attached processes
DWORD g_dwPageSize; // System page size
long glGlobalErrorInit = 0;
BOOL CGlobals::m_bInitialized = FALSE;
STDAPI DllUnregisterServer( void );
//===============================================================================
// Static vars
//===============================================================================
/*
static const WCHAR * s_strDllName = L"WMIOLEDB";
static const struct{
PWSTR strRegKey;
PWSTR strValueName;
DWORD dwType;
PWSTR strValue;
} s_rgRegInfo[] =
{
{ L"WMIOLEDB", NULL, REG_SZ, L"Microsoft WMI OLE DB Provider" },
{ L"WMIOLEDB\\Clsid", NULL, REG_SZ, L"{FD8D9C02-265E-11d2-98D9-00A0C9B7CBFE}" },
{ L"CLSID\\{FD8D9C02-265E-11d2-98D9-00A0C9B7CBFE}", NULL, REG_SZ, L"WMIOLEDB" },
{ L"CLSID\\{FD8D9C02-265E-11d2-98D9-00A0C9B7CBFE}", L"OLEDB_SERVICES", REG_DWORD, L"-1" },
{ L"CLSID\\{FD8D9C02-265E-11d2-98D9-00A0C9B7CBFE}\\ProgID", NULL, REG_SZ, L"WMIOLEDB" },
{ L"CLSID\\{FD8D9C02-265E-11d2-98D9-00A0C9B7CBFE}\\VersionIndependentProgID", NULL, REG_SZ, L"WMIOLEDB" },
{ L"CLSID\\{FD8D9C02-265E-11d2-98D9-00A0C9B7CBFE}\\InprocServer32", NULL, REG_SZ, L"%s" },
{ L"CLSID\\{FD8D9C02-265E-11d2-98D9-00A0C9B7CBFE}\\InprocServer32", L"ThreadingModel", REG_SZ, L"Both" },
{ L"CLSID\\{FD8D9C02-265E-11d2-98D9-00A0C9B7CBFE}\\OLE DB Provider", NULL, REG_SZ, L"Microsoft WMI OLE DB Provider" },
{ L"CLSID\\{FD8D9C02-265E-11d2-98D9-00A0C9B7CBFE}\\ExtendedErrors", NULL, REG_SZ, L"Extended Error Service" },
{ L"CLSID\\{FD8D9C02-265E-11d2-98D9-00A0C9B7CBFE}\\ExtendedErrors\\{80C4A61D-CB78-46fd-BD8F-8BF45BE46A4C}", NULL, REG_SZ, L"WMIOLEDB Error Lookup" },
{ L"WMIOLEDB.ErrorLookup", NULL, REG_SZ, L"WMIOLEDB Error Lookup" },
{ L"WMIOLEDB.ErrorLookup\\Clsid", NULL, REG_SZ, L"{80C4A61D-CB78-46fd-BD8F-8BF45BE46A4C}" },
{ L"CLSID\\{80C4A61D-CB78-46fd-BD8F-8BF45BE46A4C}", NULL, REG_SZ, L"WMIOLEDB.ErrorLookup" },
{ L"CLSID\\{80C4A61D-CB78-46fd-BD8F-8BF45BE46A4C}\\ProgID", NULL, REG_SZ, L"WMIOLEDB.ErrorLookup" },
{ L"CLSID\\{80C4A61D-CB78-46fd-BD8F-8BF45BE46A4C}\\VersionIndependentProgID", NULL, REG_SZ, L"WMIOLEDB.ErrorLookup" },
{ L"CLSID\\{80C4A61D-CB78-46fd-BD8F-8BF45BE46A4C}\\InprocServer32", NULL, REG_SZ, L"%s" },
{ L"CLSID\\{80C4A61D-CB78-46fd-BD8F-8BF45BE46A4C}\\InprocServer32", L"ThreadingModel", REG_SZ, L"Both" },
{ L"WMIOLEDB.RootBinder", NULL, REG_SZ, L"Microsoft WMI OLE DB Root Binder" },
{ L"WMIOLEDB.RootBinder\\Clsid", NULL, REG_SZ, L"{CDCEDB81-5FEC-11d3-9D1C-00C04F5F1164}" },
{ L"CLSID\\{CDCEDB81-5FEC-11d3-9D1C-00C04F5F1164}", NULL, REG_SZ, L"WMIOLEDB.RootBinder" },
{ L"CLSID\\{CDCEDB81-5FEC-11d3-9D1C-00C04F5F1164}\\ProgID", NULL, REG_SZ, L"WMIOLEDB.RootBinder" },
{ L"CLSID\\{CDCEDB81-5FEC-11d3-9D1C-00C04F5F1164}\\VersionIndependentProgID", NULL, REG_SZ, L"WMIOLEDB.RootBinder" },
{ L"CLSID\\{CDCEDB81-5FEC-11d3-9D1C-00C04F5F1164}\\InprocServer32", NULL, REG_SZ, L"%s" },
{ L"CLSID\\{CDCEDB81-5FEC-11d3-9D1C-00C04F5F1164}\\InprocServer32", L"ThreadingModel", REG_SZ, L"Both" },
{ L"CLSID\\{CDCEDB81-5FEC-11d3-9D1C-00C04F5F1164}\\OLE DB Binder", NULL, REG_SZ, L"Microsoft WMI OLE DB Root Binder" },
{ L"WMIOLEDB.Enumerator", NULL, REG_SZ, L"Microsoft WMI OLE DB Enumerator" },
{ L"WMIOLEDB.Enumerator\\Clsid", NULL, REG_SZ, L"{E14321B2-67C0-11d3-B3B4-00104BCC48C4}" },
{ L"CLSID\\{E14321B2-67C0-11d3-B3B4-00104BCC48C4}", NULL, REG_SZ, L"WMIOLEDB.Enumerator" },
{ L"CLSID\\{E14321B2-67C0-11d3-B3B4-00104BCC48C4}\\ProgID", NULL, REG_SZ, L"WMIOLEDB.Enumerator" },
{ L"CLSID\\{E14321B2-67C0-11d3-B3B4-00104BCC48C4}\\VersionIndependentProgID", NULL, REG_SZ, L"WMIOLEDB.Enumerator" },
{ L"CLSID\\{E14321B2-67C0-11d3-B3B4-00104BCC48C4}\\InprocServer32", NULL, REG_SZ, L"%s" },
{ L"CLSID\\{E14321B2-67C0-11d3-B3B4-00104BCC48C4}\\InprocServer32", L"ThreadingModel", REG_SZ, L"Both" },
{ L"CLSID\\{E14321B2-67C0-11d3-B3B4-00104BCC48C4}\\OLE DB Enumerator", NULL, REG_SZ, L"Microsoft WMI OLE DB Enumerator" },
};
*/
static CTString s_strDllName;
static const struct{
UINT uRegKey;
UINT uValueName;
DWORD dwType;
UINT uValue;
} s_rgRegInfo[] =
{
{ IDS_PROGID, 0, REG_SZ, IDS_DESCRIPTION },
{ IDS_PROGCLSID, 0, REG_SZ, IDS_CLSID },
{ IDS_CLSIDKEY, 0, REG_SZ, IDS_PROGID},
{ IDS_CLSIDKEY, IDS_OLEDBSER, REG_DWORD, -1 },
{ IDS_PROGIDKEY, 0, REG_SZ, IDS_PROGID },
{ IDS_VIPROGIDKEY, 0, REG_SZ, IDS_PROGID },
{ IDS_INPROCSER, 0, REG_SZ, IDS_STRFORMAT },
{ IDS_INPROCSER, IDS_THREADMODEL,REG_SZ, IDS_BOTHTHREADMODEL },
{ IDS_OLEDBPROVKEY, 0, REG_SZ, IDS_DESCRIPTION},
{ IDS_EXTERROR, 0, REG_SZ, IDS_EXTERRDESC },
{ IDS_EXTERRORCLSIDKEY, 0, REG_SZ, IDS_ERRLOOKUPDESC },
{ IDS_EL_PROGID, 0, REG_SZ, IDS_ERRLOOKUPDESC },
{ IDS_EL_PROGCLSID, 0, REG_SZ, IDS_EL_CLSID },
{ IDS_EL_CLSIDKEY, 0, REG_SZ, IDS_EL_PROGID },
{ IDS_EL_CLSPROGID, 0, REG_SZ, IDS_EL_PROGID },
{ IDS_EL_CLSVIPROGID, 0, REG_SZ, IDS_EL_PROGID },
{ IDS_EL_INPROCSERKEY, 0, REG_SZ, IDS_STRFORMAT },
{ IDS_EL_INPROCSERKEY, IDS_THREADMODEL,REG_SZ, IDS_BOTHTHREADMODEL},
{ IDS_RB_PROGID, 0, REG_SZ, IDS_RB_DESC },
{ IDS_RB_PROGCLSID, 0, REG_SZ, IDS_RB_CLSID },
{ IDS_RB_CLSIDKEY, 0, REG_SZ, IDS_RB_PROGID },
{ IDS_RB_CLSPROGID, 0, REG_SZ, IDS_RB_PROGID },
{ IDS_RB_CLSVIPROGID, 0, REG_SZ, IDS_RB_PROGID },
{ IDS_RB_INPROCSERKEY, 0, REG_SZ, IDS_STRFORMAT},
{ IDS_RB_INPROCSERKEY, IDS_THREADMODEL,REG_SZ, IDS_BOTHTHREADMODEL },
{ IDS_RB_ROOTBINDER, 0, REG_SZ, IDS_RB_DESC},
{ IDS_EN_PROGID, 0, REG_SZ, IDS_EN_DESC },
{ IDS_EN_PROGCLSID, 0, REG_SZ, IDS_EN_CLSID },
{ IDS_EN_CLSIDKEY, 0, REG_SZ, IDS_EN_PROGID },
{ IDS_EN_CLSPROGID, 0, REG_SZ, IDS_EN_PROGID },
{ IDS_EN_CLSVIPROGID, 0, REG_SZ, IDS_EN_PROGID },
{ IDS_EN_INPROCSERKEY, 0, REG_SZ, IDS_STRFORMAT },
{ IDS_EN_INPROCSERKEY, IDS_THREADMODEL,REG_SZ, IDS_BOTHTHREADMODEL },
{ IDS_EN_ENUMERATOR, 0, REG_SZ, IDS_EN_DESC },
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Verify and create the objects if requiered
////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT VerifyGlobalErrorHandling()
{
HRESULT hr = S_OK;
if( InterlockedIncrement(&glGlobalErrorInit) == 1 ){
g_pCError = new CError;
if( g_pCError ){
hr = g_pCError->FInit();
if( hr == S_OK ){
hr = CoGetClassObject(CLSID_EXTENDEDERRORINFO, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory,(void **) & g_pErrClassFact);
}
}
else{
LogMessage("Could not instantiate internal error handling object\n");
hr = E_FAIL;
}
}
if( hr != S_OK ){
glGlobalErrorInit = 0;
}
else
{
g_pErrClassFact->LockServer(TRUE);
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Release the error releated interfaces and object
////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT ReleaseGlobalErrorHandling()
{
HRESULT hr = E_FAIL;
if( InterlockedDecrement(&glGlobalErrorInit) == 0 ){
if( g_pCError ){
if(g_pErrClassFact)
{
g_pErrClassFact->LockServer(FALSE);
}
SAFE_RELEASE_PTR(g_pErrClassFact);
SAFE_DELETE_PTR(g_pCError);
hr = S_OK;
}
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Registering the Root Binder object of the Provider
////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT RegisterRootBinder()
{
HRESULT hr = S_OK;
IRegisterProvider *pRegisterProvider = NULL;
if(SUCCEEDED(hr = CoCreateInstance(CLSID_RootBinder, NULL,CLSCTX_INPROC_SERVER, IID_IRegisterProvider ,(void **)&pRegisterProvider)))
{
hr = pRegisterProvider->SetURLMapping(UMIURLPREFIX,0,CLSID_WMIOLEDB_ROOTBINDER);
hr = pRegisterProvider->SetURLMapping(WMIURLPREFIX,0,CLSID_WMIOLEDB_ROOTBINDER);
pRegisterProvider->Release();
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Unregistering the Root Binder object of the Provider
////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT UnRegisterRootBinder()
{
HRESULT hr = S_OK;
IRegisterProvider *pRegisterProvider = NULL;
if(SUCCEEDED(hr = CoCreateInstance(CLSID_RootBinder, NULL, CLSCTX_INPROC_SERVER, IID_IRegisterProvider ,(void **)&pRegisterProvider)))
{
hr = pRegisterProvider->UnregisterProvider(UMIURLPREFIX,0,CLSID_WMIOLEDB_ROOTBINDER);
hr = pRegisterProvider->UnregisterProvider(WMIURLPREFIX,0,CLSID_WMIOLEDB_ROOTBINDER);
pRegisterProvider->Release();
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// DLL Entry point where Instance and Thread attach/detach notifications takes place.
// OLE is initialized and the IMalloc Interface pointer is obtained.
//
// Boolean Flag
// TRUE Successful initialization
// FALSE Failure to intialize
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL WINAPI DllMain( HINSTANCE hInstDLL, // IN Application Instance Handle
DWORD fdwReason, // IN Indicated Process or Thread activity
LPVOID lpvReserved // IN Reserved...
)
{
BOOL fRetVal = FALSE;
CSetStructuredExceptionHandler seh;
// TRY_BLOCK;
switch (fdwReason)
{
LogMessage("Inside DllMain");
case DLL_PROCESS_ATTACH:
{
//==================================================================
// Assume successfully initialized
//==================================================================
fRetVal = TRUE;
//==================================================================
// Do one-time initialization when first process attaches
//==================================================================
if (!g_cAttachedProcesses)
{
g_hInstance = hInstDLL;
// Initialize the global variables
g_cgGlobals.Init();
}
//==============================================================
// Do per-process initialization here...
// Remember that another process successfully attached
//==============================================================
g_cAttachedProcesses++;
break;
}
case DLL_PROCESS_DETACH:
{
//==============================================================
// Do per-process clean up here...
// Remember that a process has detached
//==============================================================
g_cAttachedProcesses--;
break;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
{
fRetVal = TRUE;
break;
}
} // switch
// CATCH_BLOCK_BOOL(fRetVal,L"DllMain");
return fRetVal;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// This function is exposed to OLE so that the classfactory can be obtained.
//
// HRESULT indicating status of routine
// S_OK The object was retrieved successfully.
// CLASS_E_CLASSNOTAVAILABLE DLL does not support class.
// E_OUTOFMEMORY Out of memory.
// E_INVALIDARG One or more arguments are invalid.
// E_UNEXPECTED An unexpected error occurred.
// OTHER Other HRESULTs returned by called functions
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CALLBACK DllGetClassObject( REFCLSID rclsid, // IN CLSID of the object class to be loaded
REFIID riid, // IN Interface on object to be instantiated
LPVOID * ppvObj // OUT Pointer to interface that was instantiated
)
{
// CClassFactory * pClassFactory;
IClassFactory * pClassFactory = NULL;
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
//=======================================================================
// Check for valid ppvObj pointer
//=======================================================================
if (!ppvObj){
hr = E_INVALIDARG;
LogMessage("DllGetClassObject failed with invalid argument");
}
else
{
//===================================================================
// In case we fail, we need to zero output arguments
//===================================================================
*ppvObj = NULL;
//===================================================================
// We only service CLSID_WMIOLEDB
//===================================================================
if (!(rclsid == CLSID_WMIOLEDB || rclsid == CLSID_WMIOLEDB_ROOTBINDER ||
rclsid == CLSID_WMIOLEDB_ENUMERATOR || rclsid == CLSID_WMIOLEDB_ERRORLOOOKUP))
{
hr = CLASS_E_CLASSNOTAVAILABLE;
LogMessage("DllGetClassObject failed with CLSID_WMIOLEDB not available - Not registered?");
}
else{
//===============================================================
// We only support the IUnknown and IClassFactory interfaces
//===============================================================
if (riid != IID_IUnknown && riid != IID_IClassFactory){
hr = E_NOINTERFACE;
LogMessage("DllGetClassObject failed with no interface");
}
else{
try
{
//===========================================================
// Create our ClassFactory object
//===========================================================
if( rclsid == CLSID_WMIOLEDB ){
pClassFactory = new CDataSourceClassFactory();
}
else if( rclsid == CLSID_WMIOLEDB_ENUMERATOR ){
pClassFactory = new CEnumeratorClassFactory();
}
else if( rclsid == CLSID_WMIOLEDB_ROOTBINDER ){
pClassFactory = new CBinderClassFactory();
}
else if( rclsid == CLSID_WMIOLEDB_ERRORLOOOKUP ){
pClassFactory = new CErrorLookupClassFactory();
}
}
catch(...)
{
SAFE_DELETE_PTR(pClassFactory);
throw;
}
if (pClassFactory == NULL){
hr = E_OUTOFMEMORY;
LogMessage("DllGetClassObject failed - out of memory");
}
else{
//=======================================================
// Get the desired interface on this object
//=======================================================
hr = pClassFactory->QueryInterface( riid, ppvObj );
if (!SUCCEEDED( hr )){
SAFE_DELETE_PTR( pClassFactory );
LogMessage("DllGetClassObject failed - return code:",hr);
}
}
}
}
}
CATCH_BLOCK_HRESULT(hr,L"DllGetClassObject");
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Indicates whether the DLL is no longer in use and can be unloaded.
//
// HRESULT indicating status of routine
// S_OK DLL can be unloaded now.
// S_FALSE DLL cannot be unloaded now.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
STDAPI DllCanUnloadNow( void )
{
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
// if(!(!g_cObj && !g_cLock))
if(g_cObj || g_cLock)
{
hr = S_FALSE;
}
CATCH_BLOCK_HRESULT(hr,L"DllCanUnloadNow");
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Adds necessary keys to the registry.
//
// Returns one of the following
// NOERROR Registration succeeded
// E_FAIL Something didn't work
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
STDAPI DllRegisterServer( void )
{
HKEY hk;
HMODULE hModule = 0;
DWORD dwDisposition;
LONG stat;
TCHAR strFileName[MAX_PATH+1];
TCHAR strOutBuff[300+1];
HRESULT hr = S_OK;
CTString strKey,strValueName,strValue;
DWORD dwValue;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
hModule = GetModuleHandle(s_strDllName );
//================================================================
// Get the full path name for this DLL.
//================================================================
if (hModule == NULL)
{
hr = E_FAIL;
LogMessage("DllRegisterServer: GetModuleHandle failed");
}
else
if (0 == GetModuleFileName( hModule, strFileName, sizeof( strFileName ) / sizeof(TCHAR)))
{
hr = E_FAIL;
LogMessage("DllRegisterServer: GetModuleFileName failed");
}
else
{
//============================================================
// Make a clean start
//============================================================
//============================================================
// Loop through s_rgRegInfo, and put everything in it.
// Every entry is based on HKEY_CLASSES_ROOT.
//============================================================
for (ULONG i=0; i < NUMELEM( s_rgRegInfo ); i++)
{
// NTRaid: 136432 , 136436
// 07/05/00
if(SUCCEEDED(hr =strValue.LoadStr(s_rgRegInfo[i].uValue)) &&
SUCCEEDED(hr =strKey.LoadStr(s_rgRegInfo[i].uRegKey)) &&
SUCCEEDED(hr =strValueName.LoadStr(s_rgRegInfo[i].uValueName)))
{
//========================================================
// Fill in any "%s" arguments with the name of this DLL.
//========================================================
if (s_rgRegInfo[i].dwType == REG_DWORD)
{
dwValue = (DWORD)s_rgRegInfo[i].uValue;
}
else
{
_stprintf( strOutBuff, strValue, strFileName );
}
//========================================================
// Create the Key. If it exists, we open it.
// Thus we can still change the value below.
//========================================================
stat = RegCreateKeyEx( HKEY_CLASSES_ROOT,
strKey,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hk,
&dwDisposition );
if (stat != ERROR_SUCCESS){
hr = E_FAIL ;
LogMessage("DllRegisterServer: failed to create key");
LogMessage(strKey);
}
else{
stat = RegSetValueEx( hk,
strValueName,
0,
s_rgRegInfo[i].dwType,
s_rgRegInfo[i].dwType == REG_DWORD ? (BYTE *) &dwValue :(BYTE *) strOutBuff,
s_rgRegInfo[i].dwType == REG_SZ ? (_tcslen( strOutBuff ) + 1) * sizeof(TCHAR) :sizeof(DWORD));
RegCloseKey( hk );
if (stat != ERROR_SUCCESS){
LogMessage("DllRegisterServer: failed to set value");
LogMessage(strValueName);
hr = E_FAIL;
}
}
}
else
{
// remove all the registry entries
DllUnregisterServer();
break;
}
}
}
if(SUCCEEDED(hr))
{
//=========================================================
// Register the root binder object of the provider
//=========================================================
hr = RegisterRootBinder();
}
CATCH_BLOCK_HRESULT(hr,L"DllUnregisterServer");
return hr;
}
STDAPI DllUnregisterServer( void )
{
int i;
int iNumErrors = 0;
LONG stat;
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
CTString strKey;
TRY_BLOCK;
//==========================================================
// UnRegister the root binder object of the provider
//==========================================================
UnRegisterRootBinder();
//=========================================================================
// Delete all table entries. Loop in reverse order, since they
// are entered in a basic-to-complex order.
// We cannot delete a key that has subkeys.
// Ignore errors.
//=========================================================================
for (i=NUMELEM( s_rgRegInfo ) - 1; i >= 0; i--)
{
// NTRaid: 136432 , 136436
// 07/05/00
if(SUCCEEDED(hr = strKey.LoadStr(s_rgRegInfo[i].uRegKey)))
{
stat = RegDeleteKey( HKEY_CLASSES_ROOT, strKey );
if ((stat != ERROR_SUCCESS) && (stat != ERROR_FILE_NOT_FOUND) ){
iNumErrors++;
hr = E_FAIL;
LogMessage("DllUnregisterServer failed");
}
}
else
{
break;
}
}
CATCH_BLOCK_HRESULT(hr,L"DllUnregisterServer");
return hr;
}
/*
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Removes keys to the registry.
//
// Returns NOERROR
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
STDAPI DllUnregisterServer( void )
{
int i;
int iNumErrors = 0;
LONG stat;
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
//==========================================================
// UnRegister the root binder object of the provider
//==========================================================
UnRegisterRootBinder();
//=========================================================================
// Delete all table entries. Loop in reverse order, since they
// are entered in a basic-to-complex order.
// We cannot delete a key that has subkeys.
// Ignore errors.
//=========================================================================
for (i=NUMELEM( s_rgRegInfo ) - 1; i >= 0; i--) {
stat = RegDeleteKeyW( HKEY_CLASSES_ROOT, s_rgRegInfo[i].strRegKey );
if ((stat != ERROR_SUCCESS) && (stat != ERROR_FILE_NOT_FOUND) ){
iNumErrors++;
hr = E_FAIL;
LogMessage("DllUnregisterServer failed");
}
}
CATCH_BLOCK_HRESULT(hr,L"DllUnregisterServer");
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Adds necessary keys to the registry.
//
// Returns one of the following
// NOERROR Registration succeeded
// E_FAIL Something didn't work
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
STDAPI DllRegisterServer( void )
{
HKEY hk;
HMODULE hModule;
DWORD dwDisposition;
LONG stat;
WCHAR strFileName[MAX_PATH+1];
WCHAR strOutBuff[300+1];
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
//================================================================
// Get the full path name for this DLL.
//================================================================
if (NULL == (hModule = GetModuleHandleW( s_strDllName ))){
hr = E_FAIL;
LogMessage("DllRegisterServer: GetModuleHandle failed");
}
else if (0 == GetModuleFileNameW( hModule, strFileName, sizeof( strFileName ) / sizeof( char ))){
hr = E_FAIL;
LogMessage("DllRegisterServer: GetModuleFileName failed");
}
else{
//============================================================
// Make a clean start
//============================================================
// DllUnregisterServer();
DWORD dwType = REG_DWORD;
//============================================================
// Loop through s_rgRegInfo, and put everything in it.
// Every entry is based on HKEY_CLASSES_ROOT.
//============================================================
for (ULONG i=0; i < NUMELEM( s_rgRegInfo ); i++){
//========================================================
// Fill in any "%s" arguments with the name of this DLL.
//========================================================
if (s_rgRegInfo[i].dwType == REG_DWORD)
{
*(DWORD*)strOutBuff = _wtol( s_rgRegInfo[i].strValue );
}
else
{
wsprintfW( strOutBuff, s_rgRegInfo[i].strValue, strFileName );
}
//========================================================
// Create the Key. If it exists, we open it.
// Thus we can still change the value below.
//========================================================
stat = RegCreateKeyExW( HKEY_CLASSES_ROOT, s_rgRegInfo[i].strRegKey,
0, // dwReserved
NULL, // lpszClass
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, // security access mask
NULL, // lpSecurityAttributes
&hk, // phkResult
&dwDisposition );
if (stat != ERROR_SUCCESS){
hr = E_FAIL ;
LogMessage("DllRegisterServer: failed to create key");
LogMessage(s_rgRegInfo[i].strRegKey);
}
else{
stat = RegSetValueExW(hk,s_rgRegInfo[i].strValueName, // lpszValueName
0, // dwReserved
s_rgRegInfo[i].dwType, // fdwType
(BYTE *) strOutBuff, // value
s_rgRegInfo[i].dwType == REG_SZ ?
(wcslen( strOutBuff ) + 1) * sizeof(WCHAR) : // cbData, including null terminator
sizeof(DWORD));
RegCloseKey( hk );
if (stat != ERROR_SUCCESS){
LogMessage("DllRegisterServer: failed to set value");
LogMessage(s_rgRegInfo[i].strValueName);
hr = E_FAIL;
}
}
}
}
//=========================================================
// Register the root binder object of the provider
//=========================================================
hr = RegisterRootBinder();
CATCH_BLOCK_HRESULT(hr,L"DllUnregisterServer");
return hr;
}
*/
/////////////////////////////////////////////////////////////////////////////
// Constructor
/////////////////////////////////////////////////////////////////////////////
CGlobals::CGlobals()
{
g_pIMalloc = NULL; // OLE2 task memory allocator
g_pIDataConvert = NULL; // IDataConvert pointer
g_pCError = NULL;
g_pErrClassFact = NULL;
g_bIsAnsiOS = FALSE;
g_pIWbemPathParser = FALSE; // class factory pointer for Parser object
g_pIWbemCtxClassFac = NULL;
}
/////////////////////////////////////////////////////////////////////////////
// Destructor
/////////////////////////////////////////////////////////////////////////////
CGlobals::~CGlobals()
{
//==================================================================
// Clean up the global error handling
//==================================================================
ReleaseGlobalErrorHandling();
//==============================================================
// Clean up when the last process is going away
//==============================================================
m_CsGlobalError.Delete();
//==============================================================
// Delete internal error handler
//==============================================================
SAFE_DELETE_PTR( g_pCError )
SAFE_RELEASE_PTR(g_pIDataConvert);
if(g_pIWbemPathParser)
{
g_pIWbemPathParser->LockServer(FALSE);
}
SAFE_RELEASE_PTR(g_pIWbemPathParser);
SAFE_RELEASE_PTR(g_pIWbemCtxClassFac);
//==========================================================
// Release the memory allocator object.
//==========================================================
SAFE_RELEASE_PTR(g_pIMalloc)
}
/////////////////////////////////////////////////////////////////////////////
// Initialize global variables
/////////////////////////////////////////////////////////////////////////////
HRESULT CGlobals::Init()
{
HRESULT hr = S_OK;
SYSTEM_INFO SystemInformation;
if(!m_bInitialized)
{
s_strDllName.LoadStr(IDS_WMIOLEDBDLLNAME);
//==================================================================
// Initialize the global error handling
//==================================================================
VerifyGlobalErrorHandling();
m_CsGlobalError.Init();
//==============================================================
// Get the OLE task memory allocator; we'll use it to allocate
// all memory that we return to the client
//==============================================================
hr = CoGetMalloc( MEMCTX_TASK, &g_pIMalloc );
if (!g_pIMalloc || !SUCCEEDED( hr )){
LogMessage("CoGetMalloc failed in CGlobals::Init");
}
else
{
//==============================================================
// Get the system page size
//==============================================================
if (!g_dwPageSize)
{
GetSystemInfo( &SystemInformation );
g_dwPageSize = SystemInformation.dwPageSize;
}
//========================================================
// Determine if we are a unicode or non-unicode OS
//========================================================
g_bIsAnsiOS = !OnUnicodeSystem();
m_bInitialized = TRUE;
}
}
return hr;
}