485 lines
14 KiB
C++
485 lines
14 KiB
C++
|
//
|
||
|
|
||
|
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
|
||
|
//
|
||
|
// ***************************************************************************
|
||
|
//
|
||
|
// Original Author: Rajesh Rao
|
||
|
//
|
||
|
// $Author: rajeshr $
|
||
|
// $Date: 6/11/98 4:43p $
|
||
|
// $Workfile: maindll.cpp $
|
||
|
//
|
||
|
// $Modtime: 6/11/98 11:21a $
|
||
|
// $Revision: 1 $
|
||
|
// $Nokeywords: $
|
||
|
//
|
||
|
//
|
||
|
// Description: Contains DLL entry points. Also has code that controls
|
||
|
// when the DLL can be unloaded by tracking the number of objects and locks.
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
#include "precomp.h"
|
||
|
#include <initguid.h>
|
||
|
#include "dscpguid.h"
|
||
|
#include "dsipguid.h"
|
||
|
|
||
|
// HANDLE of the DLL
|
||
|
HINSTANCE g_hInst = NULL;
|
||
|
|
||
|
// Count of locks
|
||
|
long g_lComponents = 0;
|
||
|
// Count of active locks
|
||
|
long g_lServerLocks = 0;
|
||
|
|
||
|
// A critical section to create/delete statics
|
||
|
CRITICAL_SECTION g_StaticsCreationDeletion;
|
||
|
|
||
|
ProvDebugLog *g_pLogObject = NULL;
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// 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
|
||
|
)
|
||
|
{
|
||
|
g_hInst = hInstance;
|
||
|
BOOL status = TRUE ;
|
||
|
|
||
|
if ( DLL_PROCESS_ATTACH == ulReason )
|
||
|
{
|
||
|
// Initialize the critical section to access the static initializer objects
|
||
|
InitializeCriticalSection(&g_StaticsCreationDeletion);
|
||
|
|
||
|
// Initialize the static Initializer objects. These are destroyed in DllCanUnloadNow
|
||
|
CDSClassProviderClassFactory :: s_pDSClassProviderInitializer = NULL;
|
||
|
CDSClassProviderClassFactory ::s_pLDAPClassProviderInitializer = NULL;
|
||
|
CDSInstanceProviderClassFactory :: s_pDSInstanceProviderInitializer = NULL;
|
||
|
DisableThreadLibraryCalls(g_hInst); // 158024
|
||
|
|
||
|
status = TRUE ;
|
||
|
}
|
||
|
else if ( DLL_PROCESS_DETACH == ulReason )
|
||
|
{
|
||
|
DeleteCriticalSection(&g_StaticsCreationDeletion);
|
||
|
status = TRUE ;
|
||
|
}
|
||
|
else if ( DLL_THREAD_DETACH == ulReason )
|
||
|
{
|
||
|
status = TRUE ;
|
||
|
}
|
||
|
else if ( DLL_THREAD_ATTACH == ulReason )
|
||
|
{
|
||
|
status = TRUE ;
|
||
|
}
|
||
|
|
||
|
return status ;
|
||
|
}
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// 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 ;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
if ( rclsid == CLSID_DSProvider )
|
||
|
{
|
||
|
CDSClassProviderClassFactory *lpunk = NULL;
|
||
|
lpunk = new CDSClassProviderClassFactory ;
|
||
|
|
||
|
status = lpunk->QueryInterface ( riid , ppv ) ;
|
||
|
if ( FAILED ( status ) )
|
||
|
{
|
||
|
delete lpunk ;
|
||
|
}
|
||
|
}
|
||
|
else if ( rclsid == CLSID_DSClassAssocProvider )
|
||
|
{
|
||
|
CDSClassAssociationsProviderClassFactory *lpunk = new CDSClassAssociationsProviderClassFactory ;
|
||
|
status = lpunk->QueryInterface ( riid , ppv ) ;
|
||
|
if ( FAILED ( status ) )
|
||
|
{
|
||
|
delete lpunk ;
|
||
|
}
|
||
|
}
|
||
|
else if ( rclsid == CLSID_DSInstanceProvider )
|
||
|
{
|
||
|
CDSInstanceProviderClassFactory *lpunk = new CDSInstanceProviderClassFactory ;
|
||
|
status = lpunk->QueryInterface ( riid , ppv ) ;
|
||
|
if ( FAILED ( status ) )
|
||
|
{
|
||
|
delete lpunk ;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
status = CLASS_E_CLASSNOTAVAILABLE ;
|
||
|
}
|
||
|
}
|
||
|
catch(Heap_Exception e_HE)
|
||
|
{
|
||
|
status = E_OUTOFMEMORY ;
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
{
|
||
|
// Delete the Initializer objects
|
||
|
EnterCriticalSection(&g_StaticsCreationDeletion);
|
||
|
|
||
|
if ( g_pLogObject )
|
||
|
{
|
||
|
g_pLogObject->WriteW(L"DllCanUnloadNow called\r\n");
|
||
|
}
|
||
|
|
||
|
if ( CDSClassProviderClassFactory::s_pDSClassProviderInitializer )
|
||
|
{
|
||
|
delete CDSClassProviderClassFactory::s_pDSClassProviderInitializer;
|
||
|
CDSClassProviderClassFactory::s_pDSClassProviderInitializer = NULL;
|
||
|
}
|
||
|
|
||
|
if ( CDSClassProviderClassFactory::s_pLDAPClassProviderInitializer )
|
||
|
{
|
||
|
delete CDSClassProviderClassFactory::s_pLDAPClassProviderInitializer;
|
||
|
CDSClassProviderClassFactory::s_pLDAPClassProviderInitializer = NULL;
|
||
|
}
|
||
|
|
||
|
if ( CDSInstanceProviderClassFactory::s_pDSInstanceProviderInitializer )
|
||
|
{
|
||
|
delete CDSInstanceProviderClassFactory::s_pDSInstanceProviderInitializer;
|
||
|
CDSInstanceProviderClassFactory::s_pDSInstanceProviderInitializer = NULL;
|
||
|
}
|
||
|
|
||
|
if ( g_pLogObject )
|
||
|
{
|
||
|
delete g_pLogObject;
|
||
|
g_pLogObject = NULL;
|
||
|
}
|
||
|
|
||
|
LeaveCriticalSection(&g_StaticsCreationDeletion);
|
||
|
|
||
|
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 DSPROVIDER_NAME_STR = __TEXT("Microsoft NT DS Class Provider for WBEM");
|
||
|
|
||
|
// DS Class Associations provider
|
||
|
LPCTSTR DS_ASSOC_PROVIDER_NAME_STR = __TEXT("Microsoft NT DS Class Associations Provider for WBEM");
|
||
|
|
||
|
// DS Instance provider
|
||
|
LPCTSTR DS_INSTANCE_PROVIDER_NAME_STR = __TEXT("Microsoft NT DS Instance Provider for WBEM");
|
||
|
|
||
|
STDAPI DllRegisterServer()
|
||
|
{
|
||
|
TCHAR szModule[512];
|
||
|
GetModuleFileName(g_hInst, szModule, sizeof(szModule)/sizeof(TCHAR));
|
||
|
|
||
|
TCHAR szDSProviderClassID[128];
|
||
|
TCHAR szDSProviderCLSIDClassID[128];
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
if(StringFromGUID2(CLSID_DSProvider, szDSProviderClassID, 128) == 0)
|
||
|
return SELFREG_E_CLASS;
|
||
|
#else
|
||
|
WCHAR wszDSProviderClassID[128];
|
||
|
if(StringFromGUID2(CLSID_DSProvider, wszDSProviderClassID, 128) == 0)
|
||
|
return SELFREG_E_CLASS;
|
||
|
WideCharToMultiByte(CP_ACP, 0, wszDSProviderClassID, -1, szDSProviderClassID, 128, NULL, NULL);
|
||
|
|
||
|
#endif
|
||
|
|
||
|
_tcscpy(szDSProviderCLSIDClassID, CLSID_STR);
|
||
|
_tcscat(szDSProviderCLSIDClassID, szDSProviderClassID);
|
||
|
|
||
|
//
|
||
|
// Create entries under CLSID for DS Class Provider
|
||
|
//
|
||
|
if (FALSE == SetKeyAndValue(szDSProviderCLSIDClassID, NULL, NULL, DSPROVIDER_NAME_STR))
|
||
|
return SELFREG_E_CLASS;
|
||
|
if (FALSE == SetKeyAndValue(szDSProviderCLSIDClassID, INPROC32_STR, NULL, szModule))
|
||
|
return SELFREG_E_CLASS;
|
||
|
if (FALSE == SetKeyAndValue(szDSProviderCLSIDClassID, INPROC32_STR, THREADING_MODEL_STR, APARTMENT_STR))
|
||
|
return SELFREG_E_CLASS;
|
||
|
|
||
|
|
||
|
TCHAR szDSClassAssocProviderClassID[128];
|
||
|
TCHAR szDSClassAssocProviderCLSIDClassID[128];
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
if(StringFromGUID2(CLSID_DSClassAssocProvider, szDSClassAssocProviderClassID, 128) == 0)
|
||
|
return SELFREG_E_CLASS;
|
||
|
#else
|
||
|
WCHAR wszDSClassAssocProviderClassID[128];
|
||
|
if(StringFromGUID2(CLSID_DSClassAssocProvider, wszDSClassAssocProviderClassID, 128) == 0)
|
||
|
return SELFREG_E_CLASS;
|
||
|
WideCharToMultiByte(CP_ACP, 0, wszDSClassAssocProviderClassID, -1, szDSClassAssocProviderClassID, 128, NULL, NULL);
|
||
|
|
||
|
#endif
|
||
|
|
||
|
_tcscpy(szDSClassAssocProviderCLSIDClassID, CLSID_STR);
|
||
|
_tcscat(szDSClassAssocProviderCLSIDClassID, szDSClassAssocProviderClassID);
|
||
|
|
||
|
//
|
||
|
// Create entries under CLSID for DS Class Associations Provider
|
||
|
//
|
||
|
if (FALSE == SetKeyAndValue(szDSClassAssocProviderCLSIDClassID, NULL, NULL, DS_ASSOC_PROVIDER_NAME_STR))
|
||
|
return SELFREG_E_CLASS;
|
||
|
if (FALSE == SetKeyAndValue(szDSClassAssocProviderCLSIDClassID, INPROC32_STR, NULL, szModule))
|
||
|
return SELFREG_E_CLASS;
|
||
|
if (FALSE == SetKeyAndValue(szDSClassAssocProviderCLSIDClassID, INPROC32_STR, THREADING_MODEL_STR, APARTMENT_STR))
|
||
|
return SELFREG_E_CLASS;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
TCHAR szDSInstanceProviderClassID[128];
|
||
|
TCHAR szDSInstanceProviderCLSIDClassID[128];
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
if(StringFromGUID2(CLSID_DSInstanceProvider, szDSInstanceProviderClassID, 128) == 0)
|
||
|
return SELFREG_E_CLASS;
|
||
|
#else
|
||
|
WCHAR wszDSInstanceProviderClassID[128];
|
||
|
if(StringFromGUID2(CLSID_DSInstanceProvider, wszDSInstanceProviderClassID, 128) == 0)
|
||
|
return SELFREG_E_CLASS;
|
||
|
WideCharToMultiByte(CP_ACP, 0, wszDSInstanceProviderClassID, -1, szDSInstanceProviderClassID, 128, NULL, NULL);
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
_tcscpy(szDSInstanceProviderCLSIDClassID, CLSID_STR);
|
||
|
_tcscat(szDSInstanceProviderCLSIDClassID, szDSInstanceProviderClassID);
|
||
|
|
||
|
//
|
||
|
// Create entries under CLSID for DS Instance Provider
|
||
|
//
|
||
|
if (FALSE == SetKeyAndValue(szDSInstanceProviderCLSIDClassID, NULL, NULL, DS_INSTANCE_PROVIDER_NAME_STR))
|
||
|
return SELFREG_E_CLASS;
|
||
|
|
||
|
if (FALSE == SetKeyAndValue(szDSInstanceProviderCLSIDClassID, INPROC32_STR, NULL, szModule))
|
||
|
return SELFREG_E_CLASS;
|
||
|
if (FALSE == SetKeyAndValue(szDSInstanceProviderCLSIDClassID, 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 szDSProviderClassID[128];
|
||
|
TCHAR szDSProviderCLSIDClassID[128];
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
if(StringFromGUID2(CLSID_DSProvider, szDSProviderClassID, 128) == 0)
|
||
|
return SELFREG_E_CLASS;
|
||
|
#else
|
||
|
WCHAR wszDSProviderClassID[128];
|
||
|
if(StringFromGUID2(CLSID_DSProvider, wszDSProviderClassID, 128) == 0)
|
||
|
return SELFREG_E_CLASS;
|
||
|
WideCharToMultiByte(CP_ACP, 0, wszDSProviderClassID, -1, szDSProviderClassID, 128, NULL, NULL);
|
||
|
|
||
|
#endif
|
||
|
|
||
|
_tcscpy(szDSProviderCLSIDClassID, CLSID_STR);
|
||
|
_tcscat(szDSProviderCLSIDClassID, szDSProviderClassID);
|
||
|
|
||
|
//
|
||
|
// Delete the keys for DS Class Provider in the reverse order of creation in DllRegisterServer()
|
||
|
//
|
||
|
if(FALSE == DeleteKey(szDSProviderCLSIDClassID, INPROC32_STR))
|
||
|
return SELFREG_E_CLASS;
|
||
|
if(FALSE == DeleteKey(CLSID_STR, szDSProviderClassID))
|
||
|
return SELFREG_E_CLASS;
|
||
|
|
||
|
TCHAR szDSClassAssocProviderClassID[128];
|
||
|
TCHAR szDSClassAssocProviderCLSIDClassID[128];
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
if(StringFromGUID2(CLSID_DSClassAssocProvider, szDSClassAssocProviderClassID, 128) == 0)
|
||
|
return SELFREG_E_CLASS;
|
||
|
#else
|
||
|
WCHAR wszDSClassAssocProviderClassID[128];
|
||
|
if(StringFromGUID2(CLSID_DSClassAssocProvider, wszDSClassAssocProviderClassID, 128) == 0)
|
||
|
return SELFREG_E_CLASS;
|
||
|
WideCharToMultiByte(CP_ACP, 0, wszDSClassAssocProviderClassID, -1, szDSClassAssocProviderClassID, 128, NULL, NULL);
|
||
|
|
||
|
#endif
|
||
|
|
||
|
_tcscpy(szDSClassAssocProviderCLSIDClassID, CLSID_STR);
|
||
|
_tcscat(szDSClassAssocProviderCLSIDClassID, szDSClassAssocProviderClassID);
|
||
|
|
||
|
//
|
||
|
// Delete the keys for DS Class Provider in the reverse order of creation in DllRegisterServer()
|
||
|
//
|
||
|
if(FALSE == DeleteKey(szDSClassAssocProviderCLSIDClassID, INPROC32_STR))
|
||
|
return SELFREG_E_CLASS;
|
||
|
if(FALSE == DeleteKey(CLSID_STR, szDSClassAssocProviderClassID))
|
||
|
return SELFREG_E_CLASS;
|
||
|
|
||
|
TCHAR szDSInstanceProviderClassID[128];
|
||
|
TCHAR szDSInstanceProviderCLSIDClassID[128];
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
if(StringFromGUID2(CLSID_DSInstanceProvider, szDSInstanceProviderClassID, 128) == 0)
|
||
|
return SELFREG_E_CLASS;
|
||
|
#else
|
||
|
WCHAR wszDSInstanceProviderClassID[128];
|
||
|
if(StringFromGUID2(CLSID_DSInstanceProvider, wszDSInstanceProviderClassID, 128) == 0)
|
||
|
return SELFREG_E_CLASS;
|
||
|
WideCharToMultiByte(CP_ACP, 0, wszDSInstanceProviderClassID, -1, szDSInstanceProviderClassID, 128, NULL, NULL);
|
||
|
|
||
|
#endif
|
||
|
|
||
|
_tcscpy(szDSInstanceProviderCLSIDClassID, CLSID_STR);
|
||
|
_tcscat(szDSInstanceProviderCLSIDClassID, szDSInstanceProviderClassID);
|
||
|
|
||
|
//
|
||
|
// Delete the keys in the reverse order of creation in DllRegisterServer()
|
||
|
//
|
||
|
if(FALSE == DeleteKey(szDSInstanceProviderCLSIDClassID, INPROC32_STR))
|
||
|
return SELFREG_E_CLASS;
|
||
|
if(FALSE == DeleteKey(CLSID_STR, szDSInstanceProviderClassID))
|
||
|
return SELFREG_E_CLASS;
|
||
|
return S_OK;
|
||
|
}
|