2025-04-27 07:49:33 -04:00

321 lines
8.4 KiB
C++

// XMLProx.cpp : Defines the entry point for the DLL application.
//
#include "XMLProx.h"
#include "Utils.h"
#include "WbemClientTransportFactory.h"
// HANDLE of the DLL
HINSTANCE g_hInst = NULL;
//used to initialize/uninitialize Global DLL resources
CRITICAL_SECTION g_csGlobalsInitialized;
static bool g_bStaticLibraryInitialized = false; // The static library requires that we call Initialize() only once
// Count of locks
long g_lComponents = 0;
// Count of active locks
long g_lServerLocks = 0;
// The Globals in the DLL
//==========================
// This is a global packet factory used to create XML client packets
CXMLClientPacketFactory g_oXMLClientPacketFactory;
// 2 Functions to initialize and uninitialize the globals in the DLL
static HRESULT InitializeDLLResources();
static void UninitializeDLLResources();
//***************************************************************************
//
// DllMain
//
// Description: Entry point for DLL. Good place for initialization.
// Parameters: The standard DllMain() parameters
// Return: TRUE if OK.
//***************************************************************************
BOOL APIENTRY DllMain (
HINSTANCE hInstance,
ULONG ulReason ,
LPVOID pvReserved
)
{
switch(ulReason)
{
case DLL_PROCESS_ATTACH:
InitializeCriticalSection(&g_csGlobalsInitialized);
break;
case DLL_PROCESS_DETACH:
DeleteCriticalSection(&g_csGlobalsInitialized);
break;
}
g_hInst = hInstance;
return TRUE;
}
//***************************************************************************
//
// DllGetClassObject
//
// Description: Called by COM when some client wants a a class factory.
//
// Parameters: Ths standard DllGetClassObject() parameters
//
// Return Value: S_OK only if it is the sort of class this DLL supports.
//
//***************************************************************************
STDAPI DllGetClassObject (
REFCLSID rclsid ,
REFIID riid,
void **ppv
)
{
HRESULT status = S_OK;
// Initialize Global DLL Resources - The corresponsing compelementary call is in DllCanUnloadNow()
status = InitializeDLLResources();
if(FAILED(status))
return status;
IClassFactory *lpunk = NULL;
//this is the CLSID we enter in the registry under transports.
if ( rclsid == CLSID_WbemClientTransport )
{
if((riid == IID_IWbemClientTransport)||(riid == IID_IClassFactory))
{
if(!(lpunk = new CWbemClientTransportFactory))
return E_OUTOFMEMORY;
status = lpunk->QueryInterface ( riid , ppv ) ;
lpunk->Release();
}
}
else
return CLASS_E_CLASSNOTAVAILABLE;
return status ;
}
//***************************************************************************
//
// DllCanUnloadNow
//
// Description: Called periodically by COM in order to determine if the
// DLL can be unloaded.
//
// Return Value: S_OK if there are no objects in use and the class factory
// isn't locked.
//***************************************************************************
STDAPI DllCanUnloadNow ()
{
if(g_lServerLocks == 0 && g_lComponents == 0)
{
InitializeDLLResources();
return S_OK;
}
else
return S_FALSE;
}
/***************************************************************************
*
* SetKeyAndValue
*
* Description: Helper function for DllRegisterServer that creates
* a key, sets a value, and closes that key. If pszSubkey is NULL, then
* the value is created for the pszKey key.
*
* Parameters:
* pszKey LPTSTR to the name of the key
* pszSubkey LPTSTR to the name of a subkey
* pszValueName LPTSTR to the value name to use
* pszValue LPTSTR to the value to store
*
* Return Value:
* BOOL TRUE if successful, FALSE otherwise.
***************************************************************************/
BOOL SetKeyAndValue(LPCTSTR pszKey, LPCTSTR pszSubkey, LPCTSTR pszValueName, LPCTSTR pszValue)
{
HKEY hKey;
TCHAR szKey[256];
_tcscpy(szKey, pszKey);
// If a sub key is mentioned, use it.
if (NULL != pszSubkey)
{
_tcscat(szKey, __TEXT("\\"));
_tcscat(szKey, pszSubkey);
}
if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_LOCAL_MACHINE,
szKey, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hKey, NULL))
return FALSE;
if (NULL != pszValue)
{
if (ERROR_SUCCESS != RegSetValueEx(hKey, pszValueName, 0, REG_SZ, (BYTE *)pszValue,
(_tcslen(pszValue)+1)*sizeof(TCHAR)))
return FALSE;
}
RegCloseKey(hKey);
return TRUE;
}
/***************************************************************************
*
* DeleteKey
*
* Description: Helper function for DllUnRegisterServer that deletes the subkey
* of a key.
*
* Parameters:
* pszKey LPTSTR to the name of the key
* pszSubkey LPTSTR ro the name of a subkey
*
* Return Value:
* BOOL TRUE if successful, FALSE otherwise.
***************************************************************************/
BOOL DeleteKey(LPCTSTR pszKey, LPCTSTR pszSubkey)
{
HKEY hKey;
if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_LOCAL_MACHINE,
pszKey, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hKey, NULL))
return FALSE;
if(ERROR_SUCCESS != RegDeleteKey(hKey, pszSubkey))
return FALSE;
RegCloseKey(hKey);
return TRUE;
}
////////////////////////////////////////////////////////////////////
// Strings used during self registration
////////////////////////////////////////////////////////////////////
LPCTSTR INPROC32_STR = __TEXT("InprocServer32");
LPCTSTR INPROC_STR = __TEXT("InprocServer");
LPCTSTR THREADING_MODEL_STR = __TEXT("ThreadingModel");
LPCTSTR APARTMENT_STR = __TEXT("Both");
LPCTSTR CLSID_STR = __TEXT("SOFTWARE\\CLASSES\\CLSID\\");
// DS Class Provider
LPCTSTR FRIENDLY_NAME_STR = __TEXT("Microsoft XMLHTTP Transport Client");
STDAPI DllRegisterServer()
{
TCHAR szModule[512];
GetModuleFileName(g_hInst, szModule, sizeof(szModule)/sizeof(TCHAR));
TCHAR szClassID[128];
TCHAR szCLSIDClassID[128];
#ifdef UNICODE
if(StringFromGUID2(CLSID_WbemClientTransport, szClassID, 128) == 0)
return SELFREG_E_CLASS;
#else
WCHAR wszClassID[128];
if(StringFromGUID2(CLSID_WbemClientTransport, wszClassID, 128) == 0)
return SELFREG_E_CLASS;
WideCharToMultiByte(CP_ACP, 0, wszClassID, -1, szClassID, 128, NULL, NULL);
#endif
wcscpy(szCLSIDClassID, CLSID_STR);
wcscat(szCLSIDClassID, szClassID);
//
// Create entries under CLSID
//
if (FALSE == SetKeyAndValue(szCLSIDClassID, NULL, NULL, FRIENDLY_NAME_STR))
return SELFREG_E_CLASS;
if (FALSE == SetKeyAndValue(szCLSIDClassID, INPROC32_STR, NULL, szModule))
return SELFREG_E_CLASS;
if (FALSE == SetKeyAndValue(szCLSIDClassID, INPROC32_STR, THREADING_MODEL_STR, APARTMENT_STR))
return SELFREG_E_CLASS;
return S_OK;
}
STDAPI DllUnregisterServer(void)
{
TCHAR szModule[512];
GetModuleFileName(g_hInst,szModule, sizeof(szModule)/sizeof(TCHAR));
TCHAR szClassID[128];
TCHAR szCLSIDClassID[128];
#ifdef UNICODE
if(StringFromGUID2(CLSID_WbemClientTransport, szClassID, 128) == 0)
return SELFREG_E_CLASS;
#else
WCHAR wszClassID[128];
if(StringFromGUID2(CLSID_WbemClientTransport, wszClassID, 128) == 0)
return SELFREG_E_CLASS;
WideCharToMultiByte(CP_ACP, 0, wszClassID, -1, szClassID, 128, NULL, NULL);
#endif
wcscpy(szCLSIDClassID, CLSID_STR);
wcscat(szCLSIDClassID, szClassID);
//
// Delete the keys for DS Class Provider in the reverse order of creation in DllRegisterServer()
//
if(FALSE == DeleteKey(szCLSIDClassID, INPROC32_STR))
return SELFREG_E_CLASS;
if(FALSE == DeleteKey(CLSID_STR, szClassID))
return SELFREG_E_CLASS;
return S_OK;
}
static void UninitializeDLLResources()
{
// Unnitialize Global DLL Resources that were done in DllGetClassObject()
EnterCriticalSection(&g_csGlobalsInitialized);
if(g_bStaticLibraryInitialized)
{
UninitWMIXMLClientLibrary();
g_bStaticLibraryInitialized = false;
}
LeaveCriticalSection(&g_csGlobalsInitialized);
}
static HRESULT InitializeDLLResources()
{
HRESULT hr = S_OK;
EnterCriticalSection(&g_csGlobalsInitialized);
if(!g_bStaticLibraryInitialized)
{
if(SUCCEEDED(hr = InitWMIXMLClientLibrary()))
g_bStaticLibraryInitialized = true;
}
if(FAILED(hr))
UninitializeDLLResources();
LeaveCriticalSection(&g_csGlobalsInitialized);
return hr;
}