461 lines
12 KiB
C++
461 lines
12 KiB
C++
/*++
|
|
|
|
Copyright (C) 1997-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
MAINDLL.CPP
|
|
|
|
Abstract:
|
|
|
|
Contains DLL entry points. Also has code that controls
|
|
when the DLL can be unloaded by tracking the number of
|
|
objects and locks.
|
|
|
|
History:
|
|
|
|
a-davj 04-Mar-97 Created.
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#include <initguid.h>
|
|
|
|
DWORD LOG = LOG_WBEMSTUB;
|
|
|
|
bool bServer = true;
|
|
|
|
#ifdef TCPIP_MARSHALER
|
|
// {0877AE70-9523-11d1-9367-00AA00A4086C}
|
|
DEFINE_GUID(CLSID_WbemTcpip,
|
|
0x877ae70, 0x9523, 0x11d1, 0x93, 0x67, 0x0, 0xaa, 0x0, 0xa4, 0x8, 0x6c);
|
|
#endif
|
|
|
|
//{A4845882-333F-11d0-B724-00AA0062CBB7}
|
|
DEFINE_GUID(CLSID_WbemPipe, 0xa4845882, 0x333f, 0x11d0, 0xb7, 0x24, 0x0, 0xaa, 0x00, 0x62, 0xcb, 0xb7);
|
|
|
|
//Count number of objects and number of locks.
|
|
|
|
long g_cPipeObj = 0 ;
|
|
long g_cPipeLock = 0 ;
|
|
|
|
#ifdef TCPIP_MARSHALER
|
|
long g_cTcpipObj = 0 ;
|
|
long g_cTcpipLock = 0 ;
|
|
#endif
|
|
|
|
HMODULE ghModule = NULL ;
|
|
|
|
MaintObj gMaintObj ( FALSE ) ;
|
|
CThrdPool gThrdPool ;
|
|
|
|
LONG ObjectTypeTable [ MAX_DEFTRANS_OBJECT_TYPES ] = { 0 } ;
|
|
|
|
void ShowObjectCounts () ;
|
|
|
|
void DestroySharedMemory ();
|
|
|
|
//***************************************************************************
|
|
//
|
|
// BOOL WINAPI DllMain
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Entry point for DLL. Good place for initialization.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// hInstance instance handle
|
|
// ulReason why we are being called
|
|
// pvReserved reserved
|
|
//
|
|
// RETURN VALUE:
|
|
//
|
|
// TRUE
|
|
//
|
|
//***************************************************************************
|
|
|
|
BOOL WINAPI DllMain (
|
|
|
|
IN HINSTANCE hInstance,
|
|
IN ULONG ulReason,
|
|
LPVOID pvReserved
|
|
)
|
|
{
|
|
if (DLL_PROCESS_DETACH==ulReason)
|
|
{
|
|
DeleteCriticalSection ( & g_GlobalCriticalSection ) ;
|
|
DestroySharedMemory () ;
|
|
|
|
DEBUG_DumpAllocations("C:\\WBEMSTUB.LOG");
|
|
ShowObjectCounts();
|
|
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (DLL_PROCESS_ATTACH!=ulReason)
|
|
{
|
|
return TRUE;
|
|
}
|
|
else if (DLL_PROCESS_ATTACH ==ulReason)
|
|
{
|
|
InitializeCriticalSection ( & g_GlobalCriticalSection ) ;
|
|
ghModule = hInstance;
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// STDAPI DllGetClassObject
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Called when Ole wants a class factory. Return one only if it is the sort
|
|
// of class this DLL supports.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// rclsid CLSID of the object that is desired.
|
|
// riid ID of the desired interface.
|
|
// ppv Set to the class factory.
|
|
//
|
|
// RETURN VALUE:
|
|
//
|
|
// S_OK all is well
|
|
// E_FAILED not something we support
|
|
//
|
|
//***************************************************************************
|
|
|
|
STDAPI DllGetClassObject (
|
|
|
|
IN REFCLSID rclsid,
|
|
IN REFIID riid,
|
|
OUT PPVOID ppv
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
IUnknown *pObj = NULL ;
|
|
|
|
if ( CLSID_WbemPipe == rclsid )
|
|
{
|
|
pObj = new CPipeMarshalerClassFactory ;
|
|
}
|
|
#ifdef TCPIP_MARSHALER
|
|
else if ( CLSID_WbemTcpip == rclsid )
|
|
{
|
|
pObj = new CTcpipMarshalerClassFactory ;
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
return E_FAIL ;
|
|
}
|
|
|
|
if ( NULL == pObj )
|
|
{
|
|
return ResultFromScode ( E_OUTOFMEMORY ) ;
|
|
}
|
|
|
|
hr = pObj->QueryInterface ( riid , ppv ) ;
|
|
|
|
if ( FAILED ( hr ) )
|
|
{
|
|
delete pObj ;
|
|
}
|
|
|
|
return hr ;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// STDAPI DllCanUnloadNow
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Answers if the DLL can be freed, that is, if there are no
|
|
// references to anything this DLL provides.
|
|
//
|
|
// RETURN VALUE:
|
|
//
|
|
// S_OK if it is OK to unload
|
|
// S_FALSE if still in use
|
|
//
|
|
//***************************************************************************
|
|
|
|
extern BOOL g_InitialisationComplete ;
|
|
extern BOOL g_PipeInitialisationComplete ;
|
|
#ifdef TCPIP_MARSHALER
|
|
extern BOOL g_TcpipInitialisationComplete ;
|
|
#endif
|
|
|
|
STDAPI DllCanUnloadNow ()
|
|
{
|
|
SCODE sc;
|
|
|
|
//It is OK to unload if there are no objects or locks on the
|
|
// class factory.
|
|
|
|
#ifdef TCPIP_MARSHALER
|
|
sc = ( 0L == g_cPipeObj && 0L == g_cPipeLock && 0L == g_cTcpipObj && 0L == g_cTcpipLock ) ? S_OK : S_FALSE ;
|
|
#else
|
|
sc = ( 0L == g_cPipeObj && 0L == g_cPipeLock && 0L ) ? S_OK : S_FALSE ;
|
|
#endif
|
|
if ( sc == S_OK )
|
|
{
|
|
gThrdPool.Free () ;
|
|
|
|
SetEvent ( g_Terminate ) ;
|
|
CloseHandle ( g_Terminate ) ;
|
|
|
|
g_InitialisationComplete = FALSE ;
|
|
g_PipeInitialisationComplete = FALSE ;
|
|
|
|
#ifdef TCPIP_MARSHALER
|
|
g_TcpipInitialisationComplete = FALSE ;
|
|
#endif
|
|
}
|
|
|
|
return ResultFromScode ( sc ) ;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// ObjectCreated
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Keeps track of object creation.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// dwType type of object created.
|
|
//
|
|
//***************************************************************************
|
|
|
|
void ObjectCreated( IN DWORD dwType )
|
|
{
|
|
if(dwType < MAX_DEFTRANS_OBJECT_TYPES)
|
|
InterlockedIncrement(&ObjectTypeTable[dwType]);
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// void ObjectDestroyed
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Keeps track of object deletion.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// dwType type of object created.
|
|
//
|
|
//***************************************************************************
|
|
|
|
void ObjectDestroyed( IN DWORD dwType )
|
|
{
|
|
if(dwType < MAX_DEFTRANS_OBJECT_TYPES)
|
|
InterlockedDecrement(&ObjectTypeTable[dwType]);
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// void ShowObjectCounts
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Dumps out the object count. Used during shutdown to detect leaks.
|
|
//
|
|
//***************************************************************************
|
|
|
|
void ShowObjectCounts ()
|
|
{
|
|
DEBUGTRACE((LOG,"\n---COM Object Ref Count Info for marshalling client---\n"));
|
|
DEBUGTRACE((LOG,"Active Pipe Objects = %d\n", g_cPipeObj));
|
|
DEBUGTRACE((LOG,"Server Pipe locks = %d\n", g_cPipeLock));
|
|
|
|
#ifdef TCPIP_MARSHALER
|
|
DEBUGTRACE((LOG,"Active Tcpip Objects = %d\n", g_cTcpipObj));
|
|
DEBUGTRACE((LOG,"Server Tcpip locks = %d\n", g_cTcpipLock));
|
|
#endif
|
|
|
|
DEBUGTRACE((LOG,"Object counts by type:\n"));
|
|
|
|
DEBUGTRACE((LOG,"IWbemLocator counts = %d\n",
|
|
ObjectTypeTable[OBJECT_TYPE_LOCATOR]));
|
|
DEBUGTRACE((LOG,"IWbemClassObject counts = %d\n",
|
|
ObjectTypeTable[OBJECT_TYPE_CLSOBJ]));
|
|
DEBUGTRACE((LOG,"IWbemService counts = %d\n",
|
|
ObjectTypeTable[OBJECT_TYPE_PROVIDER]));
|
|
DEBUGTRACE((LOG,"IWbemQualifier counts = %d\n",
|
|
ObjectTypeTable[OBJECT_TYPE_QUALIFIER]));
|
|
DEBUGTRACE((LOG,"IEnumWbemClassObject counts = %d\n",
|
|
ObjectTypeTable[OBJECT_TYPE_OBJENUM]));
|
|
DEBUGTRACE((LOG,"IClassFactory counts = %d\n",
|
|
ObjectTypeTable[OBJECT_TYPE_FACTORY]));
|
|
|
|
DEBUGTRACE((LOG,"OBJECT_TYPE_OBJSINKPROXY counts = %d\n",
|
|
ObjectTypeTable[OBJECT_TYPE_OBJSINKPROXY]));
|
|
DEBUGTRACE((LOG,"OBJECT_TYPE_COMLINK counts = %d\n",
|
|
ObjectTypeTable[OBJECT_TYPE_COMLINK]));
|
|
DEBUGTRACE((LOG,"OBJECT_TYPE_CSTUB counts = %d\n",
|
|
ObjectTypeTable[OBJECT_TYPE_CSTUB]));
|
|
DEBUGTRACE((LOG,"OBJECT_TYPE_RQUEUE counts = %d\n",
|
|
ObjectTypeTable[OBJECT_TYPE_RQUEUE]));
|
|
DEBUGTRACE((LOG,"OBJECT_TYPE_PACKET_HEADER counts = %d\n",
|
|
ObjectTypeTable[OBJECT_TYPE_PACKET_HEADER]));
|
|
|
|
DEBUGTRACE((LOG,"---End of ref count dump---\n"));
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// AddTransportEntry
|
|
//
|
|
// Purpose: Adds transport section entries in the registry
|
|
//
|
|
// Return: NOERROR if registration successful, error otherwise.
|
|
//***************************************************************************
|
|
|
|
SCODE AddTransportEntry(CLSID clsid, TCHAR * pShortName, TCHAR * pDesc, TCHAR * pVersion)
|
|
{
|
|
|
|
HKEY h1 = NULL, h2 = NULL, h3 = NULL, h4 = NULL, h5 = NULL;
|
|
DWORD dwDisp;
|
|
DWORD dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, __TEXT("SOFTWARE\\MICROSOFT"),
|
|
0, KEY_ALL_ACCESS, &h1);
|
|
|
|
dwStatus = RegCreateKeyEx(h1, __TEXT("WBEM"), 0, 0, 0, KEY_ALL_ACCESS,
|
|
0, &h2, &dwDisp);
|
|
|
|
if(dwStatus == 0)
|
|
dwStatus = RegCreateKeyEx(h2, __TEXT("Cimom"), 0, 0, 0, KEY_ALL_ACCESS,
|
|
0, &h3, &dwDisp);
|
|
|
|
if(dwStatus == 0)
|
|
dwStatus = RegCreateKeyEx(h3, __TEXT("Transports"), 0, 0, 0, KEY_ALL_ACCESS,
|
|
0, &h4, &dwDisp);
|
|
|
|
if(dwStatus == 0)
|
|
dwStatus = RegCreateKeyEx(h4, pShortName, 0, 0, 0, KEY_ALL_ACCESS,
|
|
0, &h5, &dwDisp);
|
|
|
|
if(dwStatus == 0)
|
|
{
|
|
dwStatus = RegSetValueEx(h5, __TEXT("Enabled"), 0, REG_SZ, (BYTE *)"1", 2);
|
|
dwStatus = RegSetValueEx(h5, __TEXT("Name"), 0, REG_SZ, (BYTE *)pShortName, lstrlen(pShortName) + 1);
|
|
dwStatus = RegSetValueEx(h5, __TEXT("Version"), 0, REG_SZ, (BYTE *)pVersion, lstrlen(pVersion)+1);
|
|
|
|
char szID[50];
|
|
WCHAR wcID[50];
|
|
// Create the guid.
|
|
|
|
if(StringFromGUID2(clsid, wcID, 50))
|
|
{
|
|
wcstombs(szID, wcID, 50);
|
|
dwStatus = RegSetValueEx(h5, __TEXT("CLSID"), 0, REG_SZ, (BYTE *)szID, strlen(szID)+1);
|
|
}
|
|
|
|
}
|
|
|
|
if(h5)
|
|
RegCloseKey(h5);
|
|
if(h4)
|
|
RegCloseKey(h4);
|
|
if(h3)
|
|
RegCloseKey(h3);
|
|
if(h2)
|
|
RegCloseKey(h2);
|
|
if(h1)
|
|
RegCloseKey(h1);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// RemoveTransportEntry
|
|
//
|
|
// Purpose: Removes transport section entries in the registry
|
|
//
|
|
// Return: NOERROR if registration successful, error otherwise.
|
|
//***************************************************************************
|
|
|
|
SCODE RemoveTransportEntry(TCHAR * pShortName)
|
|
{
|
|
DWORD dwRet;
|
|
HKEY hKey;
|
|
TCHAR cKey[MAX_PATH];
|
|
lstrcpy(cKey, WBEM_REG_WINMGMT __TEXT("\\transports"));
|
|
|
|
dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, cKey, &hKey);
|
|
if(dwRet == NO_ERROR)
|
|
{
|
|
RegDeleteKey(hKey,pShortName);
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
lstrcpy(cKey, WBEM_REG_WINMGMT);
|
|
|
|
dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, cKey, &hKey);
|
|
if(dwRet == NO_ERROR)
|
|
{
|
|
RegDeleteKey(hKey,__TEXT("transports"));
|
|
RegCloseKey(hKey);
|
|
}
|
|
return S_OK;
|
|
}
|
|
//***************************************************************************
|
|
//
|
|
// DllRegisterServer
|
|
//
|
|
// Purpose: Called during setup or by regsvr32.
|
|
//
|
|
// Return: NOERROR if registration successful, error otherwise.
|
|
//***************************************************************************
|
|
|
|
STDAPI DllRegisterServer(void)
|
|
{
|
|
RegisterDLL(ghModule, CLSID_WbemPipe, __TEXT("WBEM Anon Pipe Transport"), __TEXT("Both"), NULL);
|
|
#ifdef TCPIP_MARSHALER
|
|
RegisterDLL(ghModule, CLSID_WbemTcpip, __TEXT("WBEM Tcpip Transport"), __TEXT("Both"), NULL);
|
|
#endif
|
|
AddTransportEntry(CLSID_WbemPipe, __TEXT("AnonPipes"),__TEXT("WBEM Anon Pipe Transport"), __TEXT("1.0"));
|
|
#ifdef TCPIP_MARSHALER
|
|
AddTransportEntry(CLSID_WbemTcpip, __TEXT("Tcpip"),__TEXT("WBEM Tcpip Transport"), __TEXT("1.0"));
|
|
#endif
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DllUnregisterServer
|
|
//
|
|
// Purpose: Called when it is time to remove the registry entries.
|
|
//
|
|
// Return: NOERROR if registration successful, error otherwise.
|
|
//***************************************************************************
|
|
|
|
STDAPI DllUnregisterServer(void)
|
|
{
|
|
UnRegisterDLL(CLSID_WbemPipe, NULL);
|
|
#ifdef TCPIP_MARSHALER
|
|
UnRegisterDLL(CLSID_WbemTcpip, NULL);
|
|
#endif
|
|
RemoveTransportEntry(__TEXT("AnonPipes"));
|
|
#ifdef TCPIP_MARSHALER
|
|
RemoveTransportEntry(__TEXT("Tcpip"));
|
|
#endif
|
|
|
|
return NOERROR;
|
|
}
|
|
|