/*++ Copyright (C) 1996-2001 Microsoft Corporation Module Name: MainDll.cpp Abstract: History: --*/ #include "PreComp.h" #include #include #include #include #include #include #include "Globals.h" #include "ClassFac.h" #include "ProvResv.h" #include "ProvFact.h" #include "ProvSubS.h" #include "ProvAggr.h" #include "ProvLoad.h" #include "ProvSelf.h" #include "ProvHost.h" #include "StrobeThread.h" #include "ProvCache.h" #include "Guids.h" #include #include #include /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ HINSTANCE g_hInst=NULL; CriticalSection s_CriticalSection(NOTHROW_LOCK) ; /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ HRESULT DllStartup () { HRESULT t_Result = S_OK ; WmiStatusCode t_StatusCode = WmiDebugLog :: Initialize ( *ProviderSubSystem_Globals :: s_Allocator ) ; t_Result = ProviderSubSystem_Globals :: Initialize_SharedCounters () ; if ( FAILED ( t_Result ) ) { t_Result = S_OK ; } if ( SUCCEEDED ( t_Result ) ) { t_Result = ProviderSubSystem_Globals :: Initialize_Events () ; if ( SUCCEEDED ( t_Result ) ) { } else { t_Result = WBEM_E_INVALID_PARAMETER ; } } if ( SUCCEEDED ( t_Result ) ) { t_Result = ProviderSubSystem_Common_Globals :: CreateSystemAces () ; } if ( SUCCEEDED ( t_Result ) ) { t_Result = ProviderSubSystem_Common_Globals :: CreateMethodSecurityDescriptor () ; } if ( SUCCEEDED ( t_Result ) ) { ProviderSubSystem_Globals :: s_StrobeThread = new StrobeThread ( *ProviderSubSystem_Globals :: s_Allocator, ProviderSubSystem_Globals :: s_StrobeTimeout ) ; if ( ProviderSubSystem_Globals :: s_StrobeThread) { if (!Dispatcher::scheduleTimer(*ProviderSubSystem_Globals :: s_StrobeThread, ProviderSubSystem_Globals :: s_StrobeTimeout, 0 , WT_EXECUTELONGFUNCTION)) { ProviderSubSystem_Globals :: s_StrobeThread->Release(); ProviderSubSystem_Globals :: s_StrobeThread=0; t_Result = WBEM_E_OUT_OF_MEMORY; } else ProviderSubSystem_Globals :: s_StrobeThread->Release(); } else { t_Result = WBEM_E_OUT_OF_MEMORY; } } if ( SUCCEEDED ( t_Result ) ) { ProviderSubSystem_Globals :: s_CoFreeUnusedLibrariesEvent = OpenEvent ( EVENT_ALL_ACCESS, FALSE, L"WINMGMT_PROVIDER_CANSHUTDOWN" ) ; if ( ProviderSubSystem_Globals :: s_CoFreeUnusedLibrariesEvent == NULL ) { t_Result = WBEM_E_UNEXPECTED ; } } if ( SUCCEEDED ( t_Result ) ) { _IWmiCoreServices *t_CoreService = NULL ; t_Result = CoCreateInstance ( CLSID_IWmiCoreServices , NULL , CLSCTX_INPROC_SERVER , IID__IWmiCoreServices , ( void ** ) & t_CoreService ) ; if ( SUCCEEDED ( t_Result ) ) { IWbemServices *t_Service = NULL ; LONG t_Flags = WMICORE_FLAG_REPOSITORY | WMICORE_CLIENT_TYPE_PROVIDER ; t_Result = t_CoreService->GetServices ( L"root" , NULL, NULL, t_Flags , IID_IWbemServices , ( void ** ) & t_Service ) ; if ( SUCCEEDED ( t_Result ) ) { CServerObject_GlobalRegistration t_Registration ; t_Result = t_Registration.SetContext ( NULL , NULL , t_Service ) ; if ( SUCCEEDED ( t_Result ) ) { t_Result = t_Registration.Load ( e_All ) ; if ( SUCCEEDED ( t_Result ) ) { ProviderSubSystem_Globals :: s_StrobeTimeout = t_Registration.GetUnloadTimeoutMilliSeconds () >> 1 ; ProviderSubSystem_Globals :: s_InternalCacheTimeout = t_Registration.GetUnloadTimeoutMilliSeconds () ; ProviderSubSystem_Globals :: s_ObjectCacheTimeout = t_Registration.GetObjectUnloadTimeoutMilliSeconds () ; ProviderSubSystem_Globals :: s_EventCacheTimeout = t_Registration.GetEventUnloadTimeoutMilliSeconds () ; } } if ( SUCCEEDED ( t_Result ) ) { CServerObject_HostQuotaRegistration t_Registration ; t_Result = t_Registration.SetContext ( NULL , NULL , t_Service ) ; if ( SUCCEEDED ( t_Result ) ) { t_Result = t_Registration.Load ( e_All ) ; if ( SUCCEEDED ( t_Result ) ) { ProviderSubSystem_Globals ::s_Quota_ProcessLimitCount = t_Registration.GetProcessLimitAllHosts () ; ProviderSubSystem_Globals ::s_Quota_ProcessMemoryLimitCount = t_Registration.GetMemoryPerHost () ; ProviderSubSystem_Globals ::s_Quota_JobMemoryLimitCount = t_Registration.GetMemoryAllHosts () ; ProviderSubSystem_Globals ::s_Quota_HandleCount = t_Registration.GetHandlesPerHost () ; ProviderSubSystem_Globals ::s_Quota_NumberOfThreads = t_Registration.GetThreadsPerHost () ; ProviderSubSystem_Globals ::s_Quota_PrivatePageCount = t_Registration.GetMemoryPerHost () ; } } } t_Service->Release () ; } t_CoreService->Release () ; } } if ( SUCCEEDED ( t_Result ) ) { t_Result = ProviderSubSystem_Globals :: CreateJobObject () ; } if ( SUCCEEDED ( t_Result ) ) { ProviderSubSystem_Globals :: s_Initialized = 1 ; } return t_Result ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ HRESULT DllShutdown () { HRESULT t_Result = S_OK ; if (ProviderSubSystem_Globals :: s_StrobeThread) { Dispatcher::cancelTimer(*ProviderSubSystem_Globals :: s_StrobeThread); Dispatcher::close(); ProviderSubSystem_Globals :: s_StrobeThread = 0; } t_Result = ProviderSubSystem_Globals :: UnInitialize_Events () ; t_Result = ProviderSubSystem_Globals :: UnInitialize_SharedCounters () ; if ( ProviderSubSystem_Globals :: s_CoFreeUnusedLibrariesEvent ) { CloseHandle ( ProviderSubSystem_Globals :: s_CoFreeUnusedLibrariesEvent ) ; ProviderSubSystem_Globals :: s_CoFreeUnusedLibrariesEvent = NULL ; } t_Result = ProviderSubSystem_Common_Globals :: DeleteMethodSecurityDescriptor () ; t_Result = ProviderSubSystem_Common_Globals :: DeleteSystemAces () ; WmiStatusCode t_StatusCode = WmiDebugLog :: UnInitialize ( *ProviderSubSystem_Globals :: s_Allocator ) ; t_Result = ProviderSubSystem_Globals :: DeleteJobObject () ; ProviderSubSystem_Globals :: s_Initialized = 0 ; return t_Result ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ BOOL APIENTRY DllMain ( HINSTANCE hInstance, ULONG ulReason , LPVOID pvReserved ) { g_hInst=hInstance; BOOL t_Status = TRUE ; if ( DLL_PROCESS_DETACH == ulReason ) { HRESULT t_Result = ProviderSubSystem_Globals :: Global_Shutdown () ; if ( SUCCEEDED ( t_Result ) ) { t_Status = TRUE ; } else { t_Status = FALSE ; } WmiHelper :: DeleteCriticalSection ( & s_CriticalSection ) ; t_Status = TRUE ; } else if ( DLL_PROCESS_ATTACH == ulReason ) { DisableThreadLibraryCalls ( hInstance ) ; WmiStatusCode t_StatusCode = WmiHelper :: InitializeCriticalSection ( & s_CriticalSection ) ; if ( t_StatusCode == e_StatusCode_Success ) { HRESULT t_Result = ProviderSubSystem_Globals :: Global_Startup () ; if ( SUCCEEDED ( t_Result ) ) { t_Status = TRUE ; } else { t_Status = FALSE ; } } else { t_Status = FALSE ; } } else if ( DLL_THREAD_DETACH == ulReason ) { t_Status = TRUE ; } else if ( DLL_THREAD_ATTACH == ulReason ) { t_Status = TRUE ; } return t_Status ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ STDAPI DllGetClassObject ( REFCLSID rclsid , REFIID riid, void **ppv ) { HRESULT t_Result = S_OK ; WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection ( & s_CriticalSection , FALSE ) ; if ( t_StatusCode == e_StatusCode_Success ) { if ( ProviderSubSystem_Globals :: s_Initialized == 0 ) { DllStartup () ; } if ( rclsid == CLSID_WmiProvSS ) { CServerProvSubSysClassFactory *lpunk = new CServerProvSubSysClassFactory ; if ( lpunk == NULL ) { t_Result = E_OUTOFMEMORY ; } else { t_Result = lpunk->QueryInterface ( riid , ppv ) ; if ( FAILED ( t_Result ) ) { delete lpunk ; } else { } } } else if ( rclsid == CLSID_WmiProviderBindingFactory ) { CServerClassFactory *lpunk = new CServerClassFactory ; if ( lpunk == NULL ) { t_Result = E_OUTOFMEMORY ; } else { t_Result = lpunk->QueryInterface ( riid , ppv ) ; if ( FAILED ( t_Result ) ) { delete lpunk ; } else { } } } else if ( rclsid == CLSID_WmiProviderInProcFactory ) { CServerClassFactory *lpunk = new CServerClassFactory ; if ( lpunk == NULL ) { t_Result = E_OUTOFMEMORY ; } else { t_Result = lpunk->QueryInterface ( riid , ppv ) ; if ( FAILED ( t_Result ) ) { delete lpunk ; } else { } } } else if ( rclsid == CLSID_ProvSubSys_Provider ) { CServerClassFactory *lpunk = new CServerClassFactory ; if ( lpunk == NULL ) { t_Result = E_OUTOFMEMORY ; } else { t_Result = lpunk->QueryInterface ( riid , ppv ) ; if ( FAILED ( t_Result ) ) { delete lpunk ; } else { } } } else { t_Result = CLASS_E_CLASSNOTAVAILABLE ; } WmiHelper :: LeaveCriticalSection ( & s_CriticalSection ) ; } else { t_Result = E_OUTOFMEMORY ; } return t_Result ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ STDAPI DllCanUnloadNow () { /* * Place code in critical section */ WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection ( & s_CriticalSection , FALSE ) ; if ( t_StatusCode == e_StatusCode_Success ) { BOOL unload = ( ProviderSubSystem_Globals :: s_LocksInProgress || ProviderSubSystem_Globals :: s_ObjectsInProgress ) ; unload = ! unload ; if ( unload ) { DllShutdown () ; } WmiHelper :: LeaveCriticalSection ( & s_CriticalSection ) ; return unload ? ResultFromScode ( S_OK ) : ResultFromScode ( S_FALSE ) ; } else { return FALSE ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ HRESULT SetApplicationSecurity ( HKEY a_Key , LPCWSTR a_Name , DWORD a_Access ) { HRESULT t_Result = S_OK ; SID_IDENTIFIER_AUTHORITY t_NtAuthoritySid = SECURITY_NT_AUTHORITY ; PSID t_Administrator_Sid = NULL ; ACCESS_ALLOWED_ACE *t_Administrator_ACE = NULL ; WORD t_Administrator_ACESize = 0 ; BOOL t_BoolResult = AllocateAndInitializeSid ( & t_NtAuthoritySid , 2 , SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, & t_Administrator_Sid ); if ( t_BoolResult ) { DWORD t_SidLength = ::GetLengthSid ( t_Administrator_Sid ); t_Administrator_ACESize = sizeof(ACCESS_ALLOWED_ACE) + (WORD) ( t_SidLength - sizeof(DWORD) ) ; t_Administrator_ACE = (ACCESS_ALLOWED_ACE*) new BYTE [ t_Administrator_ACESize ] ; if ( t_Administrator_ACE ) { CopySid ( t_SidLength, (PSID) & t_Administrator_ACE->SidStart, t_Administrator_Sid ) ; t_Administrator_ACE->Mask = a_Access; t_Administrator_ACE->Header.AceType = 0 ; t_Administrator_ACE->Header.AceFlags = 3 ; t_Administrator_ACE->Header.AceSize = t_Administrator_ACESize ; } else { t_Result = E_OUTOFMEMORY ; } } else { DWORD t_LastError = ::GetLastError(); t_Result = E_OUTOFMEMORY ; } PSID t_Interactive_Sid = NULL ; ACCESS_ALLOWED_ACE *t_Interactive_ACE = NULL ; WORD t_Interactive_ACESize = 0 ; t_BoolResult = AllocateAndInitializeSid ( & t_NtAuthoritySid , 1 , SECURITY_INTERACTIVE_RID, 0, 0, 0, 0, 0, 0, 0, & t_Interactive_Sid ); if ( t_BoolResult ) { DWORD t_SidLength = ::GetLengthSid ( t_Interactive_Sid ); t_Interactive_ACESize = sizeof(ACCESS_ALLOWED_ACE) + (WORD) ( t_SidLength - sizeof(DWORD) ) ; t_Interactive_ACE = (ACCESS_ALLOWED_ACE*) new BYTE [ t_Interactive_ACESize ] ; if ( t_Interactive_ACE ) { CopySid ( t_SidLength, (PSID) & t_Interactive_ACE->SidStart, t_Interactive_Sid ) ; t_Interactive_ACE->Mask = a_Access; t_Interactive_ACE->Header.AceType = 0 ; t_Interactive_ACE->Header.AceFlags = 3 ; t_Interactive_ACE->Header.AceSize = t_Interactive_ACESize ; } else { t_Result = E_OUTOFMEMORY ; } } else { DWORD t_LastError = ::GetLastError(); t_Result = E_OUTOFMEMORY ; } PSID t_System_Sid = NULL ; ACCESS_ALLOWED_ACE *t_System_ACE = NULL ; WORD t_System_ACESize = 0 ; t_BoolResult = AllocateAndInitializeSid ( & t_NtAuthoritySid , 1 , SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, & t_System_Sid ); if ( t_BoolResult ) { DWORD t_SidLength = ::GetLengthSid ( t_System_Sid ); t_System_ACESize = sizeof(ACCESS_ALLOWED_ACE) + (WORD) ( t_SidLength - sizeof(DWORD) ) ; t_System_ACE = (ACCESS_ALLOWED_ACE*) new BYTE [ t_System_ACESize ] ; if ( t_System_ACE ) { CopySid ( t_SidLength, (PSID) & t_System_ACE->SidStart, t_System_Sid ) ; t_System_ACE->Mask = a_Access; t_System_ACE->Header.AceType = 0 ; t_System_ACE->Header.AceFlags = 3 ; t_System_ACE->Header.AceSize = t_System_ACESize ; } else { t_Result = E_OUTOFMEMORY ; } } else { DWORD t_LastError = ::GetLastError(); t_Result = E_OUTOFMEMORY ; } PSID t_LocalService_Sid = NULL ; ACCESS_ALLOWED_ACE *t_LocalService_ACE = NULL ; WORD t_LocalService_ACESize = 0 ; t_BoolResult = AllocateAndInitializeSid ( & t_NtAuthoritySid , 1 , SECURITY_LOCAL_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0, & t_LocalService_Sid ); if ( t_BoolResult ) { DWORD t_SidLength = ::GetLengthSid ( t_LocalService_Sid ); t_LocalService_ACESize = sizeof(ACCESS_ALLOWED_ACE) + (WORD) ( t_SidLength - sizeof(DWORD) ) ; t_LocalService_ACE = (ACCESS_ALLOWED_ACE*) new BYTE [ t_LocalService_ACESize ] ; if ( t_LocalService_ACE ) { CopySid ( t_SidLength, (PSID) & t_LocalService_ACE->SidStart, t_LocalService_Sid ) ; t_LocalService_ACE->Mask = a_Access; t_LocalService_ACE->Header.AceType = 0 ; t_LocalService_ACE->Header.AceFlags = 3 ; t_LocalService_ACE->Header.AceSize = t_LocalService_ACESize ; } else { t_Result = E_OUTOFMEMORY ; } } else { DWORD t_LastError = ::GetLastError(); t_Result = E_OUTOFMEMORY ; } PSID t_NetworkService_Sid = NULL ; ACCESS_ALLOWED_ACE *t_NetworkService_ACE = NULL ; WORD t_NetworkService_ACESize = 0 ; t_BoolResult = AllocateAndInitializeSid ( & t_NtAuthoritySid , 1 , SECURITY_NETWORK_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0, & t_NetworkService_Sid ); if ( t_BoolResult ) { DWORD t_SidLength = ::GetLengthSid ( t_NetworkService_Sid ); t_NetworkService_ACESize = sizeof(ACCESS_ALLOWED_ACE) + (WORD) ( t_SidLength - sizeof(DWORD) ) ; t_NetworkService_ACE = (ACCESS_ALLOWED_ACE*) new BYTE [ t_NetworkService_ACESize ] ; if ( t_NetworkService_ACE ) { CopySid ( t_SidLength, (PSID) & t_NetworkService_ACE->SidStart, t_NetworkService_Sid ) ; t_NetworkService_ACE->Mask = a_Access; t_NetworkService_ACE->Header.AceType = 0 ; t_NetworkService_ACE->Header.AceFlags = 3 ; t_NetworkService_ACE->Header.AceSize = t_NetworkService_ACESize ; } else { t_Result = E_OUTOFMEMORY ; } } else { DWORD t_LastError = ::GetLastError(); t_Result = E_OUTOFMEMORY ; } // Now we need to set permissions on the registry: Everyone read; Admins full. // We have the sid for admins from the above code. Now get the sid for "Everyone" DWORD t_TotalAclSize = sizeof(ACL) + t_Administrator_ACESize + t_Interactive_ACESize + t_LocalService_ACESize + t_NetworkService_ACESize + t_System_ACESize ; PACL t_Dacl = (PACL) new BYTE [ t_TotalAclSize ] ; if ( t_Dacl ) { if ( :: InitializeAcl ( t_Dacl, t_TotalAclSize, ACL_REVISION ) ) { DWORD t_AceIndex = 0 ; if ( t_Interactive_ACESize && :: AddAce ( t_Dacl , ACL_REVISION , t_AceIndex , t_Interactive_ACE , t_Interactive_ACESize ) ) { t_AceIndex ++ ; } if ( t_System_ACESize && :: AddAce ( t_Dacl , ACL_REVISION , t_AceIndex , t_System_ACE , t_System_ACESize ) ) { t_AceIndex ++ ; } if ( t_LocalService_ACESize && :: AddAce ( t_Dacl , ACL_REVISION , t_AceIndex , t_LocalService_ACE , t_LocalService_ACESize ) ) { t_AceIndex ++ ; } if ( t_NetworkService_ACESize && :: AddAce ( t_Dacl , ACL_REVISION , t_AceIndex , t_NetworkService_ACE , t_NetworkService_ACESize ) ) { t_AceIndex ++ ; } if ( t_Administrator_ACESize && :: AddAce ( t_Dacl , ACL_REVISION , t_AceIndex , t_Administrator_ACE , t_Administrator_ACESize ) ) { t_AceIndex ++ ; } SECURITY_INFORMATION t_SecurityInfo = 0L; t_SecurityInfo |= DACL_SECURITY_INFORMATION; t_SecurityInfo |= PROTECTED_DACL_SECURITY_INFORMATION; SECURITY_DESCRIPTOR t_SecurityDescriptor ; t_BoolResult = InitializeSecurityDescriptor ( & t_SecurityDescriptor , SECURITY_DESCRIPTOR_REVISION ) ; if ( t_BoolResult ) { t_BoolResult = SetSecurityDescriptorDacl ( & t_SecurityDescriptor , TRUE , t_Dacl , FALSE ) ; if ( t_BoolResult ) { t_BoolResult = SetSecurityDescriptorOwner ( & t_SecurityDescriptor , t_System_Sid, FALSE ) ; } if ( t_BoolResult ) { t_BoolResult = SetSecurityDescriptorGroup ( & t_SecurityDescriptor , t_Administrator_Sid, FALSE ) ; } if ( t_BoolResult ) { DWORD t_Length = GetSecurityDescriptorLength ( & t_SecurityDescriptor ) ; SECURITY_DESCRIPTOR *t_RelativeSecurityDescriptor = ( SECURITY_DESCRIPTOR * ) new BYTE [ t_Length ]; ; if ( t_RelativeSecurityDescriptor ) { t_BoolResult = MakeSelfRelativeSD ( & t_SecurityDescriptor , t_RelativeSecurityDescriptor , & t_Length ); if ( t_BoolResult ) { DWORD t_ValueType = REG_BINARY ; DWORD t_DataSize = t_Length ; LONG t_RegResult = RegSetValueEx ( a_Key , a_Name , 0 , t_ValueType , LPBYTE ( t_RelativeSecurityDescriptor ) , t_DataSize ) ; if ( t_RegResult != ERROR_SUCCESS ) { t_Result = E_FAIL ; } } delete [] t_RelativeSecurityDescriptor ; } else { t_Result = E_OUTOFMEMORY ; } } else { t_Result = E_FAIL ; } } else { t_Result = E_FAIL ; } } delete [] ( ( BYTE * ) t_Dacl ) ; } else { t_Result = E_OUTOFMEMORY ; } if ( t_Administrator_ACE ) { delete [] ( ( BYTE * ) t_Administrator_ACE ) ; } if ( t_Interactive_ACE ) { delete [] ( ( BYTE * ) t_Interactive_ACE ) ; } if ( t_System_ACE ) { delete [] ( ( BYTE * ) t_System_ACE ) ; } if ( t_LocalService_ACE ) { delete [] ( ( BYTE * ) t_LocalService_ACE ) ; } if ( t_NetworkService_ACE ) { delete [] ( ( BYTE * ) t_NetworkService_ACE ) ; } if ( t_Interactive_Sid ) { FreeSid ( t_Interactive_Sid ) ; } if ( t_System_Sid ) { FreeSid ( t_System_Sid ) ; } if ( t_LocalService_Sid ) { FreeSid ( t_LocalService_Sid ) ; } if ( t_NetworkService_Sid ) { FreeSid ( t_NetworkService_Sid ) ; } if ( t_Administrator_Sid ) { FreeSid ( t_Administrator_Sid ) ; } return t_Result ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ //Strings used during self registeration #define REG_FORMAT_STR L"%s\\%s" #define NOT_INSERT_STR L"NotInsertable" #define INPROC32_STR L"InprocServer32" #define LOCALSERVER32_STR L"LocalServer32" #define THREADING_MODULE_STR L"ThreadingModel" #define APARTMENT_STR L"Both" #define APPID_VALUE_STR L"AppId" #define APPID_STR L"APPID\\" #define CLSID_STR L"CLSID\\" #define WMI_PROVIDER_SUBSYSTEM __TEXT("Microsoft WMI Provider Subsystem") #define WMI_PROVIDER_HOST __TEXT("Microsoft WMI Provider Subsystem Host") #define WMI_PROVIDER_BINDINGFACTORY __TEXT("Microsoft WMI Provider Subsystem Binding Factory") #define WMI_PROVIDER_INPROCFACTORY __TEXT("Microsoft WMI Provider Subsystem InProc Factory") #define WMI_PROVIDER_HOSTINPROCFACTORY __TEXT("Microsoft WMI Provider Subsystem Host InProc Factory") #define WMI_PROVIDER __TEXT("Microsoft WMI Provider Subsystem Self Instrumentation") #define WMI_REFRESHER_MANAGER __TEXT("Microsoft WMI Provider Subsystem Refresher Manager") /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ BOOL SetKeyAndValue ( wchar_t *pszKey , wchar_t *pszSubkey , wchar_t *pszValueName , wchar_t *pszValue ) { HKEY hKey; wchar_t szKey[256]; StringCchCopyW ( szKey , 256, pszKey ) ; if (NULL!=pszSubkey) { StringCchCatW ( szKey , 256, L"\\" ) ; StringCchCatW ( szKey , 256, pszSubkey ) ; } if ( ERROR_SUCCESS != RegCreateKeyEx ( HKEY_CLASSES_ROOT , 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) ) ) { return FALSE; } } RegCloseKey ( hKey ) ; return TRUE; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ class OnScopeClose_DeleteString { private: wchar_t *m_Executable ; protected: public: OnScopeClose_DeleteString ( wchar_t *a_Executable ) : m_Executable ( a_Executable ) { } ~OnScopeClose_DeleteString () { delete [] m_Executable ; } } ; STDAPI RegisterServer ( BOOL a_Local , BOOL a_InProc , GUID a_ProviderClassId , wchar_t *a_ProviderName , wchar_t *a_ExecutableArguments ) { wchar_t t_Executable [MAX_PATH + 1]; t_Executable [ 0 ] = 0 ; t_Executable [ MAX_PATH ] = 0 ; DWORD t_Length = GetModuleFileName ( g_hInst , ( wchar_t * ) t_Executable , sizeof ( t_Executable ) / sizeof ( wchar_t ) - 1 ) ; if ( t_Length ) { DWORD t_ExecutableAndArgsLength = wcslen ( t_Executable ) + 1 ; if (a_ExecutableArguments) { t_ExecutableAndArgsLength += sizeof ( L" " )/sizeof(wchar_t) + wcslen ( a_ExecutableArguments ) ; } wchar_t *t_ExecutableAndArgs = new wchar_t [ t_ExecutableAndArgsLength ] ; if ( t_ExecutableAndArgs ) { OnScopeClose_DeleteString t_GarbageCollect ( t_ExecutableAndArgs ) ; StringCchCopyW ( t_ExecutableAndArgs ,t_ExecutableAndArgsLength, t_Executable ) ; if ( a_ExecutableArguments ) { StringCchCatW ( t_ExecutableAndArgs , t_ExecutableAndArgsLength, L" " ) ; StringCchCatW ( t_ExecutableAndArgs , t_ExecutableAndArgsLength, a_ExecutableArguments ) ; } wchar_t szProviderClassID[128]; wchar_t szProviderCLSIDClassID[128]; int iRet = StringFromGUID2(a_ProviderClassId,szProviderClassID, 128); if ( a_Local ) { wchar_t szProviderCLSIDAppID[128]; StringCchCopyW(szProviderCLSIDAppID,128, APPID_STR); StringCchCatW(szProviderCLSIDAppID,128, szProviderClassID); if (FALSE ==SetKeyAndValue(szProviderCLSIDAppID, NULL, NULL, a_ProviderName )) return SELFREG_E_CLASS; HKEY t_Key ; DWORD t_Disposition = 0 ; LONG t_RegResult = RegOpenKeyEx ( HKEY_CLASSES_ROOT , szProviderCLSIDAppID , NULL , KEY_READ | KEY_WRITE , & t_Key ) ; if ( t_RegResult == ERROR_SUCCESS ) { ON_BLOCK_EXIT(RegCloseKey, t_Key); HRESULT t_Result = SetApplicationSecurity ( t_Key , L"LaunchPermission" , COM_RIGHTS_EXECUTE ) ; if ( FAILED ( t_Result ) ) { return SELFREG_E_CLASS; } } else { return SELFREG_E_CLASS; } } StringCchCopyW(szProviderCLSIDClassID,128, CLSID_STR); StringCchCatW(szProviderCLSIDClassID,128, szProviderClassID); if ( a_Local ) { if (FALSE ==SetKeyAndValue(szProviderCLSIDClassID, NULL , APPID_VALUE_STR, szProviderClassID )) return SELFREG_E_CLASS; } //Create entries under CLSID if (FALSE ==SetKeyAndValue(szProviderCLSIDClassID, NULL, NULL, a_ProviderName )) return SELFREG_E_CLASS; if (FALSE ==SetKeyAndValue(szProviderCLSIDClassID, NOT_INSERT_STR, NULL, NULL)) return SELFREG_E_CLASS; if ( a_Local ) { if (FALSE ==SetKeyAndValue(szProviderCLSIDClassID, LOCALSERVER32_STR, NULL,t_ExecutableAndArgs)) return SELFREG_E_CLASS; if (FALSE ==SetKeyAndValue(szProviderCLSIDClassID, LOCALSERVER32_STR,THREADING_MODULE_STR, APARTMENT_STR)) return SELFREG_E_CLASS; } if ( a_InProc ) { if (FALSE ==SetKeyAndValue(szProviderCLSIDClassID, INPROC32_STR, NULL,t_ExecutableAndArgs)) return SELFREG_E_CLASS; if (FALSE ==SetKeyAndValue(szProviderCLSIDClassID, INPROC32_STR,THREADING_MODULE_STR, APARTMENT_STR)) return SELFREG_E_CLASS; } return S_OK; } else { return E_FAIL ; } } else { return E_FAIL ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ STDAPI UnregisterServer( BOOL a_Local , BOOL a_InProc , GUID a_ProviderClassId ) { wchar_t szTemp[128]; wchar_t szProviderClassID[128]; wchar_t szProviderCLSIDClassID[128]; int iRet = StringFromGUID2(a_ProviderClassId ,szProviderClassID, 128); StringCchCopyW(szProviderCLSIDClassID,128, CLSID_STR); StringCchCatW(szProviderCLSIDClassID,128, szProviderClassID); //Delete entries under CLSID StringCchPrintfW(szTemp, 128, REG_FORMAT_STR, szProviderCLSIDClassID, NOT_INSERT_STR); RegDeleteKey(HKEY_CLASSES_ROOT, szTemp); if ( a_Local ) { wchar_t szProviderCLSIDAppID[128]; StringCchCopyW(szProviderCLSIDAppID,128, APPID_STR); StringCchCatW(szProviderCLSIDAppID,128, szProviderClassID); //Delete entries under APPID DWORD t_Status = RegDeleteKey(HKEY_CLASSES_ROOT, szProviderCLSIDAppID); StringCchPrintfW(szTemp, 128, REG_FORMAT_STR,szProviderCLSIDClassID, LOCALSERVER32_STR); t_Status = RegDeleteKey(HKEY_CLASSES_ROOT, szTemp); } if ( a_InProc ) { StringCchPrintfW(szTemp, 128, REG_FORMAT_STR,szProviderCLSIDClassID, INPROC32_STR); RegDeleteKey(HKEY_CLASSES_ROOT, szTemp); } RegDeleteKey(HKEY_CLASSES_ROOT, szProviderCLSIDClassID); return S_OK; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ STDAPI DllRegisterServer () { HRESULT t_Result ; #ifdef WMIASLOCAL t_Result = RegisterServer ( TRUE , FALSE , CLSID_WmiProviderHost , WMI_PROVIDER_HOST , NULL ) ; #else t_Result = RegisterServer ( FALSE , TRUE , CLSID_WmiProvSS , WMI_PROVIDER_SUBSYSTEM , NULL ) ; t_Result = RegisterServer ( FALSE , TRUE , CLSID_WmiProviderBindingFactory , WMI_PROVIDER_BINDINGFACTORY , NULL ) ; t_Result = RegisterServer ( FALSE , TRUE , CLSID_WmiProviderInProcFactory , WMI_PROVIDER_INPROCFACTORY , NULL ) ; t_Result = RegisterServer ( FALSE , TRUE , CLSID_ProvSubSys_Provider , WMI_PROVIDER , NULL ) ; #endif return t_Result ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ STDAPI DllUnregisterServer () { HRESULT t_Result ; #ifdef WMIASLOCAL t_Result = UnregisterServer ( TRUE , FALSE , CLSID_WmiProviderHost ) ; #else t_Result = UnregisterServer ( FALSE , TRUE , CLSID_WmiProvSS ) ; t_Result = UnregisterServer ( FALSE , TRUE , CLSID_WmiProviderBindingFactory ) ; t_Result = UnregisterServer ( FALSE , TRUE , CLSID_WmiProviderInProcFactory ) ; t_Result = UnregisterServer ( FALSE , TRUE , CLSID_ProvSubSys_Provider ) ; #endif return t_Result ; }