/*++ Copyright (c) 1997-1999 Microsoft Corporation Module Name: server.cpp Abstract: This is the implementation of the class factory for the NTFRS WMI provider. This file contains the implementation of the CFactory class and other global initialization functions relating to the provider. Author: Sudarshan Chitre (sudarc) , Mathew George (t-mattg) - 3-Aug-2000 Environment User mode winnt --*/ #include ///////////////////////////////////////////////////////////////////////////// // // BEGIN CLSID SPECIFIC SECTION // // //DEFINE_GUID(CLSID_Provider, // 0x39143F73,0xFDB1,0x4CF5,0x8C,0xB7,0xC8,0x43,0x9E,0x3F,0x5C,0x20); const CLSID CLSID_Provider = {0x39143F73,0xFDB1,0x4CF5,0x8C,0xB7,0xC8,0x43,0x9E,0x3F,0x5C,0x20}; // // END CLSID SPECIFIC SECTION // ///////////////////////////////////////////////////////////////////////////// static DWORD dwRegId; static IClassFactory *pClassFactory = NULL; static ULONG g_cLock = 0; // // Routines to update registry when installing/uninstalling our server. // void RegisterServer() { return; } void UnregisterServer() { return; } // // Implementation of the IClassFactory interface. // CFactory::CFactory(const CLSID & ClsId) /*++ Routine Description: Constructor for the class factory. Arguments: ClsId : [in] CLSID of the server object which it creates when the CreateInstance method is called. Return Value: None --*/ { m_cRef = 0; g_cLock++; m_ClsId = ClsId; } CFactory::~CFactory() /*++ Routine Description: Destructor for the class factory. Arguments: None. Return Value: None --*/ { g_cLock--; } // Implementation of the IUnknown interface ULONG CFactory::AddRef() /*++ Routine Description: Increments the reference count of the object. Arguments: None Return Value: Current reference count. (> 0) --*/ { return ++m_cRef; } ULONG CFactory::Release() /*++ Routine Description: Decrements the reference count of the object. Frees the object resource when the reference count becomes zero. Arguments: None Return Value: New reference count. --*/ { if (0 != --m_cRef) return m_cRef; delete this; return 0; } STDMETHODIMP CFactory::QueryInterface(REFIID riid, LPVOID * ppv) /*++ Routine Description: This method is called by COM to obtain pointers to the IUnknown or the IClassFactory interface. Arguments: riid : GUID of the required interface. ppv : Pointer where the "interface pointer" is returned. Return Value: Status of operation. Pointer to the requested interface is returned in *ppv. --*/ { *ppv = 0; if (IID_IUnknown == riid || IID_IClassFactory == riid) { *ppv = this; AddRef(); return NOERROR; } return E_NOINTERFACE; } STDMETHODIMP CFactory::CreateInstance( LPUNKNOWN pUnkOuter, REFIID riid, LPVOID * ppvObj) /*++ Routine Description: Constructs an instance of the CProvider object and returns a pointer to the IUnknown interface. Arguments: pUnkOuter : [in] IUnknown of the aggregrator. We do not support aggregration, and so this parameter should be null. riid : [in] GUID of the object to be instantiated. ppv : Destination for the IUnknown interface pointer. Return Value: Status of operation. Pointer to the IUnknown interface of the requested object is returned in *ppv. S_OK Success CLASS_E_NOAGGREGATION pUnkOuter must be NULL E_NOINTERFACE No such interface supported. --*/ { IUnknown* pObj; HRESULT hr; // // Defaults // *ppvObj=NULL; hr = E_OUTOFMEMORY; // // We aren't supporting aggregation. // if (pUnkOuter) return CLASS_E_NOAGGREGATION; if (m_ClsId == CLSID_Provider) { pObj = (IWbemProviderInit *) new CProvider; } if (!pObj) return hr; // // Initialize the object and verify that it can return the // interface in question. // hr = pObj->QueryInterface(riid, ppvObj); // // Kill the object if initial creation or Init failed. // if (FAILED(hr)) delete pObj; return hr; } STDMETHODIMP CFactory::LockServer(BOOL fLock) /*++ Routine Description: Increments.Decrements the reference count of the server, so that resource can be deallocated when all instances of all objects provided by ther server are destroyed. Arguments: fLock : [in] Boolean indicating whether the refcount is to be incremented or decremented. Return Value: Status of the operation. --*/ { if (fLock) InterlockedIncrement((LONG *) &g_cLock); else InterlockedDecrement((LONG *) &g_cLock); return NOERROR; } DWORD FrsWmiInitialize() /*++ Routine Description: Main entry point to the WMI subsystem of NTFRS. This function initializes the COM libraries, initializes security and registers our class factory with COM. NOTE : The thread which calls this function should not terminate until the FrsWmiShutdown() function is called. Arguments: None. Return Value: Status of the operation. --*/ { HRESULT hRes; // Initialize the COM library. hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED); if(FAILED(hRes)) return hRes; // Initialize COM security. hRes = CoInitializeSecurity ( NULL, //Points to security descriptor -1, //Count of entries in asAuthSvc NULL, //Array of names to register NULL, //Reserved for future use RPC_C_AUTHN_LEVEL_CONNECT, //The default authentication level for proxies RPC_C_IMP_LEVEL_IMPERSONATE, //The default impersonation level for proxies NULL, //Authentication information for //each authentication service EOAC_DYNAMIC_CLOAKING, //Additional client and/or // server-side capabilities 0 //Reserved for future use ); if(FAILED(hRes)) { CoUninitialize() ; return hRes; } // Get a pointer to our class factory. pClassFactory = new CFactory(CLSID_Provider); pClassFactory->AddRef(); // Register our server with COM. CoRegisterClassObject(CLSID_Provider, pClassFactory, CLSCTX_LOCAL_SERVER, REGCLS_MULTI_SEPARATE, &dwRegId); return ERROR_SUCCESS; } DWORD FrsWmiShutdown() /*++ Routine Description: Shuts down the WMI subsystem within FRS, releases & and deregisters the class factory, unloads the COM libraries and free any other allocated resource. Arguments: None. Return Value: Status of the operation. --*/ { // // Shutdown the server // pClassFactory->Release(); CoRevokeClassObject(dwRegId); CoUninitialize(); return ERROR_SUCCESS; }