Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

493 lines
12 KiB

//***************************************************************************
//
// File:
//
// Module: MS SNMP Provider
//
// Purpose:
//
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
//
//***************************************************************************
#ifndef INITGUID
#define INITGUID
#endif
#include <precomp.h>
#include <initguid.h>
#include "smir.h"
#include "csmir.h"
#include "handles.h"
#include "classfac.h"
#include "textdef.h"
#include "thread.h"
#include "helper.h"
#include <scopeguard.h>
BOOL SetKeyAndValue(wchar_t* pszKey, wchar_t* pszSubkey, wchar_t* pszValueName, wchar_t* pszValue);
//Globals Bah!
BOOL g_initialised = FALSE ;
//OK we need this one
HINSTANCE g_hInst;
//and this is a thread safe speed up
SmirClassFactoryHelper *g_pClassFactoryHelper=NULL;
CSmirConnObject* CSmir::sm_ConnectionObjects = NULL;
CRITICAL_SECTION g_CriticalSection ;
//***************************************************************************
//
// LibMain32
//
// Purpose: Entry point for DLL. Good place for initialization.
// Return: TRUE if OK.
//***************************************************************************
static bool g_csInitialized = false;
BOOL APIENTRY DllMain (HINSTANCE hInstance, ULONG ulReason , LPVOID pvReserved)
{
BOOL status = TRUE;
/*remember the instance handle to the dll so that we can use it in
*register dll
*/
g_hInst=hInstance;
SetStructuredExceptionHandler seh;
try
{
switch (ulReason)
{
case DLL_PROCESS_ATTACH:
{
g_csInitialized = InitializeCriticalSectionAndSpinCount ( & g_CriticalSection, 4000 ) != 0 ;
DisableThreadLibraryCalls(hInstance);
status = g_csInitialized == true;
}
break;
case DLL_PROCESS_DETACH:
{
CThread :: ProcessDetach();
if (g_csInitialized)
{
DeleteCriticalSection ( & g_CriticalSection ) ;
}
//release the helper
}
break;
//if DisableThreadLibraryCalls() worked these will never be called
case DLL_THREAD_DETACH:
case DLL_THREAD_ATTACH:
{
}
break;
default:
{
status = FALSE;
}
break;
}
}
catch(Structured_Exception e_SE)
{
status = FALSE;
}
catch(Heap_Exception e_HE)
{
status = FALSE;
}
catch(...)
{
status = FALSE;
}
return status ;
}
//***************************************************************************
//
// DllGetClassObject
//
// Purpose: Called by Ole when some client wants a class factory. Return
// one only if it is the sort of class this DLL supports.
//
//***************************************************************************
STDAPI DllGetClassObject (REFCLSID rclsid , REFIID riid, void **ppv)
{
HRESULT status = S_OK ;
SetStructuredExceptionHandler seh;
try
{
EnterCriticalSection ( & g_CriticalSection ) ;
ON_BLOCK_EXIT(LeaveCriticalSection, &g_CriticalSection);
if ( !g_initialised )
{
/*I don't do anything in thread attach and
*detach so do give them to me
*/
//BOOL bCallsDisabled;
//bCallsDisabled=DisableThreadLibraryCalls(hInstance);
//initialise the helper
if (S_OK != CSmirAccess :: Init())
{
status = FALSE;
}
else
{
//allocate the cached class factory
if(NULL == g_pClassFactoryHelper)
g_pClassFactoryHelper= new SmirClassFactoryHelper;
status = TRUE ;
}
g_initialised = TRUE ;
}
CSMIRGenericClassFactory *lpClassFac = NULL;
if((CLSID_SMIR_Database==rclsid)||
(IID_IConnectionPointContainer ==rclsid))
{
lpClassFac = new CSMIRClassFactory(rclsid) ;
}
else if(CLSID_SMIR_ModHandle==rclsid)
{
lpClassFac = new CModHandleClassFactory(rclsid) ;
}
else if(CLSID_SMIR_GroupHandle==rclsid)
{
lpClassFac = new CGroupHandleClassFactory(rclsid) ;
}
else if(CLSID_SMIR_ClassHandle==rclsid)
{
lpClassFac = new CClassHandleClassFactory(rclsid) ;
}
else if(CLSID_SMIR_NotificationClassHandle==rclsid)
{
lpClassFac = new CNotificationClassHandleClassFactory(rclsid) ;
}
else if(CLSID_SMIR_ExtNotificationClassHandle==rclsid)
{
lpClassFac = new CExtNotificationClassHandleClassFactory(rclsid) ;
}
else
{
//the caller has asked for an interface I don't support
return(CLASS_E_CLASSNOTAVAILABLE);
}
if (NULL==lpClassFac)
{
return(E_OUTOFMEMORY);
}
status = lpClassFac->QueryInterface (riid , ppv) ;
if (FAILED(status))
{
delete lpClassFac;
}
}
catch(Structured_Exception e_SE)
{
return E_UNEXPECTED;
}
catch(Heap_Exception e_HE)
{
return E_OUTOFMEMORY;
}
catch(...)
{
return E_UNEXPECTED;
}
return status ;
}
//***************************************************************************
//
// DllCanUnloadNow
//
// Purpose: Called periodically by Ole in order to determine if the
// DLL can be unloaded.
// Return: TRUE if there are no objects in use and the class factory
// isn't locked.
//***************************************************************************
STDAPI DllCanUnloadNow ()
{
SetStructuredExceptionHandler seh;
try
{
EnterCriticalSection ( & g_CriticalSection ) ;
ON_BLOCK_EXIT(LeaveCriticalSection, &g_CriticalSection);
BOOL unload = (0 == CSMIRClassFactory :: locksInProgress) &&
(0 == CSMIRClassFactory :: objectsInProgress) &&
(0 == CModHandleClassFactory :: locksInProgress) &&
(0 == CModHandleClassFactory :: objectsInProgress) &&
(0 == CGroupHandleClassFactory :: locksInProgress) &&
(0 == CGroupHandleClassFactory :: objectsInProgress) &&
(0 == CClassHandleClassFactory :: locksInProgress) &&
(0 == CClassHandleClassFactory :: objectsInProgress) &&
(0 == CNotificationClassHandleClassFactory :: locksInProgress) &&
(0 == CNotificationClassHandleClassFactory :: objectsInProgress) &&
(0 == CExtNotificationClassHandleClassFactory :: locksInProgress) &&
(0 == CExtNotificationClassHandleClassFactory :: objectsInProgress);
if ( unload )
CSmirAccess :: ShutDown();
return ResultFromScode(unload?S_OK:S_FALSE);
}
catch(Structured_Exception e_SE)
{
return S_FALSE;
}
catch(Heap_Exception e_HE)
{
return S_FALSE;
}
catch(...)
{
return S_FALSE;
}
}
/***************************************************************************
* DllRegisterServer
*
* Purpose:
* Instructs the server to create its own registry entries
*
* Parameters:
* None
*
* Return Value:
* HRESULT NOERROR if registration successful, error
* otherwise.
***************************************************************************/
STDAPI DllRegisterServer()
{
SetStructuredExceptionHandler seh;
try
{
wchar_t szID[NUMBER_OF_SMIR_INTERFACES][128];
LPTSTR szModule[512];
/*life would be easier if I could create a pointer to a reference
*but I can't so I have to hand create each root string before creating
*the registry entries.
*/
//Create some base key strings.
//one for the interrogative interface
int iRet = StringFromGUID2(CLSID_SMIR_Database,(wchar_t*)&szID[0], 128);
//one for the module handle interface
iRet = StringFromGUID2(CLSID_SMIR_ModHandle, (wchar_t*)&szID[1], 128);
//one for the group handle interface
iRet = StringFromGUID2(CLSID_SMIR_GroupHandle, (wchar_t*)&szID[2], 128);
//one for the class handle interface
iRet = StringFromGUID2(CLSID_SMIR_ClassHandle, (wchar_t*)&szID[3], 128);
//one for the notificationclass handle interface
iRet = StringFromGUID2(CLSID_SMIR_NotificationClassHandle, (wchar_t*)&szID[4], 128);
//one for the extnotificationclass handle interface
iRet = StringFromGUID2(CLSID_SMIR_ExtNotificationClassHandle, (wchar_t*)&szID[5], 128);
for (int i=0;i<NUMBER_OF_SMIR_INTERFACES;i++)
{
wchar_t szCLSID[128];
wcscpy((wchar_t*)szCLSID, CLSID_STR);
wcscat((wchar_t*)szCLSID,(wchar_t*)&szID[i]);
//Create entries under CLSID
if (FALSE ==SetKeyAndValue((wchar_t*)szCLSID, NULL, NULL, SMIR_NAME_STR))
return SELFREG_E_CLASS;
if (FALSE ==SetKeyAndValue((wchar_t*)szCLSID, NOT_INTERT_STR, NULL, NULL))
return SELFREG_E_CLASS;
GetModuleFileName(g_hInst, (wchar_t*)szModule
, sizeof(szModule)/sizeof(wchar_t));
if (FALSE ==SetKeyAndValue((wchar_t*)szCLSID, INPROC32_STR, NULL,(wchar_t*) szModule))
return SELFREG_E_CLASS;
if (FALSE ==SetKeyAndValue((wchar_t*)szCLSID, INPROC32_STR,
THREADING_MODULE_STR, APARTMENT_STR))
return SELFREG_E_CLASS;
}
}
catch(Structured_Exception e_SE)
{
return E_UNEXPECTED;
}
catch(Heap_Exception e_HE)
{
return E_OUTOFMEMORY;
}
catch(...)
{
return E_UNEXPECTED;
}
return S_OK;
}
/***************************************************************************
* DllUnregisterServer
*
* Purpose:
* Instructs the server to remove its own registry entries
*
* Parameters:
* None
*
* Return Value:
* HRESULT NOERROR if registration successful, error
* otherwise.
***************************************************************************/
STDAPI DllUnregisterServer(void)
{
SetStructuredExceptionHandler seh;
try
{
wchar_t szID[128];
wchar_t szCLSID[NUMBER_OF_SMIR_INTERFACES][128];
wchar_t szTemp[256];
//one for the smir interface
int iRet = StringFromGUID2(CLSID_SMIR_Database, szID, 128);
wcscpy((wchar_t*)szCLSID[0], CLSID_STR);
wcscat((wchar_t*)szCLSID[0], szID);
//one for the module handle interface
iRet = StringFromGUID2(CLSID_SMIR_ModHandle, szID, 128);
wcscpy((wchar_t*)szCLSID[1], CLSID_STR);
wcscat((wchar_t*)szCLSID[1], szID);
//one for the group handle interface
iRet = StringFromGUID2(CLSID_SMIR_GroupHandle, szID, 128);
wcscpy((wchar_t*)szCLSID[2], CLSID_STR);
wcscat((wchar_t*)szCLSID[2], szID);
//one for the class handle interface
iRet = StringFromGUID2(CLSID_SMIR_ClassHandle, szID, 128);
wcscpy((wchar_t*)szCLSID[3], CLSID_STR);
wcscat((wchar_t*)szCLSID[3],szID);
//one for the notificationclass handle interface
iRet = StringFromGUID2(CLSID_SMIR_NotificationClassHandle, szID, 128);
wcscpy((wchar_t*)szCLSID[4], CLSID_STR);
wcscat((wchar_t*)szCLSID[4], szID);
//one for the extnotificationclass handle interface
iRet = StringFromGUID2(CLSID_SMIR_ExtNotificationClassHandle, szID, 128);
wcscpy((wchar_t*)szCLSID[5], CLSID_STR);
wcscat((wchar_t*)szCLSID[5], szID);
for (int i=0;i<NUMBER_OF_SMIR_INTERFACES;i++)
{
wsprintf(szTemp, REG_FORMAT_STR, (wchar_t*)&szCLSID[i], NOT_INTERT_STR);
RegDeleteKey(HKEY_LOCAL_MACHINE, szTemp);
wsprintf(szTemp, REG_FORMAT_STR, (wchar_t*)&szCLSID[i], INPROC32_STR);
RegDeleteKey(HKEY_LOCAL_MACHINE, szTemp);
RegDeleteKey(HKEY_LOCAL_MACHINE, (wchar_t*)&szCLSID[i]);
}
}
catch(Structured_Exception e_SE)
{
return E_UNEXPECTED;
}
catch(Heap_Exception e_HE)
{
return E_OUTOFMEMORY;
}
catch(...)
{
return E_UNEXPECTED;
}
return S_OK;
}
/***************************************************************************
* SetKeyAndValue
*
* Purpose:
* Private helper function for DllRegisterServer that creates
* a key, sets a value, and closes that key.
*
* Parameters:
* pszKey LPTSTR to the ame of the key
* pszSubkey LPTSTR ro the name of a subkey
* pszValue LPTSTR to the value to store
*
* Return Value:
* BOOL TRUE if successful, FALSE otherwise.
***************************************************************************/
BOOL SetKeyAndValue(wchar_t* pszKey, wchar_t* pszSubkey, wchar_t* pszValueName, wchar_t* pszValue)
{
HKEY hKey;
wchar_t szKey[256] = { L'\0' };
wcscpy(szKey, pszKey);
if (NULL!=pszSubkey)
{
wcscat(szKey, L"\\");
wcscat(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
, (lstrlen(pszValue)+1)*sizeof(wchar_t))){
RegCloseKey(hKey);
return FALSE;
}
}
RegCloseKey(hKey);
return TRUE;
}