///////////////////////////////////////////////////////////////////// // // CopyRight (c) 1999-2002 Microsoft Corporation // // Module Name: // ClusterWMIProvider.cpp // // Description: // Implementation of the provider registration and entry point. // // Author: // Henry Wang (HenryWa) 24-AUG-1999 // ////////////////////////////////////////////////////////////////////// #include "Pch.h" #include #include "ProvFactory.h" #include "InstanceProv.h" #include "EventProv.h" #include "ClusterWMIProvider.tmh" ////////////////////////////////////////////////////////////////////////////// // Global Data ////////////////////////////////////////////////////////////////////////////// // {598065EA-EDC9-4b2c-913B-5104D04D098A} DEFINE_GUID( CLSID_CLUSTER_WMI_PROVIDER, 0x598065ea, 0xedc9, 0x4b2c, 0x91, 0x3b, 0x51, 0x4, 0xd0, 0x4d, 0x9, 0x8a ); // {6A52C339-DCB0-4682-8B1B-02DE2C436A6D} DEFINE_GUID( CLSID_CLUSTER_WMI_CLASS_PROVIDER, 0x6a52c339, 0xdcb0, 0x4682, 0x8b, 0x1b, 0x2, 0xde, 0x2c, 0x43, 0x6a, 0x6d ); // {92863246-4EDE-4eff-B606-79C1971DB230} DEFINE_GUID( CLSID_CLUSTER_WMI_EVENT_PROVIDER, 0x92863246, 0x4ede, 0x4eff, 0xb6, 0x6, 0x79, 0xc1, 0x97, 0x1d, 0xb2, 0x30 ); // Count number of objects and number of locks. long g_cObj = 0; long g_cLock = 0; HMODULE g_hModule; FactoryData g_FactoryDataArray[] = { { &CLSID_CLUSTER_WMI_PROVIDER, CInstanceProv::S_HrCreateThis, L"Cluster service WMI instance provider" }, { &CLSID_CLUSTER_WMI_CLASS_PROVIDER, CClassProv::S_HrCreateThis, L"Cluster service WMI class provider" }, { &CLSID_CLUSTER_WMI_EVENT_PROVIDER, CEventProv::S_HrCreateThis, L"Cluster service WMI event provider" }, }; ////////////////////////////////////////////////////////////////////////////// //++ // // BOOL // WINAPI // DllMain( // HANDLE hModule, // DWORD ul_reason_for_call, // LPVOID lpReserved // ) // // Description: // Main DLL entry point. // // Arguments: // hModule -- DLL module handle. // ul_reason_for_call -- // lpReserved -- // // Return Values: // TRUE // //-- ////////////////////////////////////////////////////////////////////////////// BOOL WINAPI DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { // begin_wpp config // CUSTOM_TYPE(dllreason, ItemListLong(DLL_PROCESS_DETACH, DLL_PROCESS_ATTACH, DLL_THREAD_ATTACH, DLL_THREAD_DETACH) ); // // CUSTOM_TYPE(EventIdx, ItemSetLong(NODE_STATE, NODE_DELETED, NODE_ADDED, NODE_PROPERTY, REGISTRY_NAME,REGISTRY_ATTRIBUTES, REGISTRY_VALUE, REGISTRY_SUBTREE, RESOURCE_STATE, RESOURCE_DELETED, RESOURCE_ADDED, RESOURCE_PROPERTY, GROUP_STATE, GROUP_DELETED, GROUP_ADDED, GROUP_PROPERTY, RESOURCE_TYPE_DELETED, RESOURCE_TYPE_ADDED, RESOURCE_TYPE_PROPERTY, CLUSTER_RECONNECT, NETWORK_STATE, NETWORK_DELETED, NETWORK_ADDED, NETWORK_PROPERTY, NETINTERFACE_STATE, NETINTERFACE_DELETED, NETINTERFACE_ADDED, NETINTERFACE_PROPERTY, QUORUM_STATE, CLUSTER_STATE, CLUSTER_PROPERTY, HANDLE_CLOSE)); // // CUSTOM_TYPE(GroupState, ItemListLong(Online, Offline, Failed, PartialOnline, Pending) ); // CUSTOM_TYPE(ResourceState, ItemListLong(Initing, Initializing, Online, Offline, Failed) ); // end_wpp // // Cluster event filter flags. // /* NODE_STATE = 0x00000001, NODE_DELETED = 0x00000002, NODE_ADDED = 0x00000004, NODE_PROPERTY = 0x00000008, REGISTRY_NAME = 0x00000010, REGISTRY_ATTRIBUTES = 0x00000020, REGISTRY_VALUE = 0x00000040, REGISTRY_SUBTREE = 0x00000080, RESOURCE_STATE = 0x00000100, RESOURCE_DELETED = 0x00000200, RESOURCE_ADDED = 0x00000400, RESOURCE_PROPERTY = 0x00000800, GROUP_STATE = 0x00001000, GROUP_DELETED = 0x00002000, GROUP_ADDED = 0x00004000, GROUP_PROPERTY = 0x00008000, RESOURCE_TYPE_DELETED = 0x00010000, RESOURCE_TYPE_ADDED = 0x00020000, RESOURCE_TYPE_PROPERTY = 0x00040000, CLUSTER_RECONNECT = 0x00080000, NETWORK_STATE = 0x00100000, NETWORK_DELETED = 0x00200000, NETWORK_ADDED = 0x00400000, NETWORK_PROPERTY = 0x00800000, NETINTERFACE_STATE = 0x01000000, NETINTERFACE_DELETED = 0x02000000, NETINTERFACE_ADDED = 0x04000000, NETINTERFACE_PROPERTY = 0x08000000, QUORUM_STATE = 0x10000000, CLUSTER_STATE = 0x20000000, CLUSTER_PROPERTY = 0x40000000, HANDLE_CLOSE = 0x80000000, */ //#ifdef _DEBUG // _CrtSetBreakAlloc( 228 ); //#endif TracePrint(("ClusWMI: DllMain entry, reason = %!dllreason!", ul_reason_for_call)); g_hModule = static_cast< HMODULE >( hModule ); switch ( ul_reason_for_call ) { case DLL_PROCESS_ATTACH: WPP_INIT_TRACING( NULL ); break; case DLL_PROCESS_DETACH: WPP_CLEANUP(); break; default: break; } return TRUE; } //*** DllMain() ////////////////////////////////////////////////////////////////////////////// //++ // // STDAPI // DllCanUnloadNow( void ) // // Description: // Called periodically by Ole in order to determine if the // DLL can be freed. // // Arguments: // None. // // Return Values: // S_OK if there are no objects in use and the class factory // isn't locked. // //-- ////////////////////////////////////////////////////////////////////////////// STDAPI DllCanUnloadNow( void ) { SCODE sc; //It is OK to unload if there are no objects or locks on the // class factory. sc = ( (0L == g_cObj) && (0L == g_cLock) ) ? S_OK : S_FALSE; TracePrint(("ClusWMI: DllCanUnloadNow is returning %d", sc)); return sc; } //*** DllCanUnloadNow() ////////////////////////////////////////////////////////////////////////////// //++ // // STDAPI // DllRegisterServer( void ) // // Description: // Called during setup or by regsvr32. // // Arguments: // None. // // Return Values: // NOERROR if registration successful, error otherwise. // SELFREG_E_CLASS // //-- ////////////////////////////////////////////////////////////////////////////// STDAPI DllRegisterServer( void ) { WCHAR wszID[ 128 ]; WCHAR wszCLSID[ 128 ]; WCHAR wszModule[ MAX_PATH ]; INT idx; WCHAR * pwszModel = L"Both"; HKEY hKey1 = NULL; HKEY hKey2 = NULL; DWORD dwRt = ERROR_SUCCESS; INT cArray = sizeof ( g_FactoryDataArray ) / sizeof ( FactoryData ); TracePrint(("ClusWMI: DllRegisterServer entry")); // Create the path. try { DWORD cbModuleNameSize = 0; if ( GetModuleFileNameW( g_hModule, wszModule, MAX_PATH ) == 0 ) { dwRt = GetLastError(); throw( dwRt ); } wszModule[ MAX_PATH - 1 ] = L'\0'; cbModuleNameSize = (DWORD) ( wcslen( wszModule ) + 1 ) * sizeof( wszModule[ 0 ] ); for ( idx = 0 ; idx < cArray && dwRt == ERROR_SUCCESS ; idx++ ) { LPCWSTR pwszName = g_FactoryDataArray[ idx ].m_pwszRegistryName; StringFromGUID2( *g_FactoryDataArray[ idx ].m_pCLSID, wszID, 128 ); HRESULT hr = StringCchPrintfW( wszCLSID, RTL_NUMBER_OF( wszCLSID ), L"Software\\Classes\\CLSID\\%ws", wszID ); dwRt = (DWORD) hr; if ( dwRt != ERROR_SUCCESS ) { throw( dwRt ); } // Create entries under CLSID dwRt = RegCreateKeyExW( HKEY_LOCAL_MACHINE, wszCLSID, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY | KEY_WRITE, NULL, &hKey1, NULL ); if ( dwRt != ERROR_SUCCESS ) { throw( dwRt ); } dwRt = RegSetValueExW( hKey1, NULL, 0, REG_SZ, (BYTE *) pwszName, (DWORD) ( sizeof( WCHAR ) * ( wcslen( pwszName ) + 1 ) ) ); if ( dwRt != ERROR_SUCCESS ) { throw( dwRt ); } dwRt = RegCreateKeyExW( hKey1, L"InprocServer32", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY | KEY_WRITE, NULL, &hKey2, NULL ); if ( dwRt != ERROR_SUCCESS ) { throw( dwRt ); } dwRt = RegSetValueExW( hKey2, NULL, 0, REG_SZ, (BYTE *) wszModule, cbModuleNameSize ); if ( dwRt != ERROR_SUCCESS ) { throw( dwRt ); } dwRt = RegSetValueExW( hKey2, L"ThreadingModel", 0, REG_SZ, (BYTE *) pwszModel, (DWORD) ( sizeof( WCHAR ) * ( wcslen( pwszModel ) + 1 ) ) ); if ( dwRt != ERROR_SUCCESS ) { throw( dwRt ); } } // for: each entry in factory entry array if ( dwRt != ERROR_SUCCESS ) { throw( dwRt ); } } catch ( DWORD sc ) { dwRt = sc; } catch ( ... ) { dwRt = (DWORD) SELFREG_E_CLASS; } TracePrint(("ClusWMI: RegisterServer returned %d", dwRt)); if ( hKey1 != NULL ) { RegCloseKey( hKey1 ); } if ( hKey2 != NULL ) { RegCloseKey( hKey2 ); } return dwRt; } //*** DllRegisterServer() ////////////////////////////////////////////////////////////////////////////// //++ // // STDAPI // DllUnregisterServer( void ) // // Description: // Called when it is time to remove the registry entries. // // Arguments: // None. // // Return Values: // NOERROR if registration successful, error otherwise. // SELFREG_E_CLASS // //-- ////////////////////////////////////////////////////////////////////////////// STDAPI DllUnregisterServer( void ) { WCHAR wszID[ 128 ]; WCHAR wszCLSID[ 128 ]; HKEY hKey; INT idx; DWORD dwRet = ERROR_SUCCESS; for ( idx = 0 ; idx < 2 && dwRet == ERROR_SUCCESS ; idx++ ) { StringFromGUID2( *g_FactoryDataArray[ idx ].m_pCLSID, wszID, 128 ); HRESULT hr = StringCchPrintfW( wszCLSID, RTL_NUMBER_OF( wszCLSID ), L"Software\\Classes\\CLSID\\%ws", wszID ); dwRet = (DWORD) hr; if ( dwRet != ERROR_SUCCESS ) { break; } // First delete the InProcServer subkey. dwRet = RegOpenKeyExW( HKEY_LOCAL_MACHINE, wszCLSID, 0, KEY_ALL_ACCESS, &hKey ); if ( dwRet != ERROR_SUCCESS ) { break; } dwRet = RegDeleteKeyW( hKey, L"InProcServer32" ); RegCloseKey( hKey ); if ( dwRet != ERROR_SUCCESS ) { break; } dwRet = RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID", 0, KEY_ALL_ACCESS, &hKey ); if ( dwRet != ERROR_SUCCESS ) { break; } dwRet = RegDeleteKeyW( hKey,wszID ); RegCloseKey( hKey ); if ( dwRet != ERROR_SUCCESS ) { break; } } // for: each object if ( dwRet != ERROR_SUCCESS ) { dwRet = (DWORD) SELFREG_E_CLASS; } return dwRet; } //*** DllUnregisterServer() ////////////////////////////////////////////////////////////////////////////// //++ // // STDAPI // DllGetClassObject( // REFCLSID rclsidIn, // REFIID riidIn, // PPVOID ppvOut // ) // // Description: // Called by Ole when some client wants a class factory. Return // one only if it is the sort of class this DLL supports. // // Arguments: // rclsidIn -- // riidIn -- // ppvOut -- // // Return Values: // NOERROR if registration successful, error otherwise. // E_OUTOFMEMORY // E_FAIL // //-- ////////////////////////////////////////////////////////////////////////////// STDAPI DllGetClassObject( REFCLSID rclsidIn, REFIID riidIn, PPVOID ppvOut ) { HRESULT hr; CProvFactory * pObj = NULL; UINT idx; UINT cDataArray = sizeof ( g_FactoryDataArray ) / sizeof ( FactoryData ); for ( idx = 0 ; idx < cDataArray ; idx++ ) { if ( rclsidIn == *g_FactoryDataArray[ idx ].m_pCLSID ) { pObj= new CProvFactory( &g_FactoryDataArray[ idx ] ); if ( NULL == pObj ) { return E_OUTOFMEMORY; } hr = pObj->QueryInterface( riidIn, ppvOut ); if ( FAILED( hr ) ) { delete pObj; } return hr; } } return E_FAIL; } //*** DllGetClassObject()