// // 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 #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 g_pLogObject = ProvDebugLog::GetProvDebugLog(LOG_DSPROV); 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 () { HRESULT hResult = S_FALSE; EnterCriticalSection(&g_StaticsCreationDeletion); try { if(g_lServerLocks == 0 && g_lComponents == 0) { // Delete the Initializer objects 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; } hResult = S_OK; } } catch ( ... ) { } LeaveCriticalSection(&g_StaticsCreationDeletion); return hResult; } /*************************************************************************** * * 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; }