// ************************************************************************** // // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved // // File: OLESRVR.CPP // // Description: // Event provider sample - COM server implementations // // History: // // ************************************************************************** #include #include #include #include #include #include #include "evprov.h" static HINSTANCE g_hInstance; //*************************************************************************** // // DllMain // //*************************************************************************** BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved ) { if (dwReason == DLL_PROCESS_ATTACH) { g_hInstance = hinstDLL; setlocale(LC_ALL, ""); } else if (dwReason == DLL_PROCESS_DETACH) { } return TRUE; } //*************************************************************************** // // class CFactory // //*************************************************************************** class CFactory : public IClassFactory { ULONG m_cRef; CLSID m_ClsId; public: CFactory(const CLSID & ClsId); ~CFactory(); // // IUnknown members // STDMETHODIMP QueryInterface(REFIID, LPVOID *); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); // // IClassFactory members // STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, LPVOID *); STDMETHODIMP LockServer(BOOL); }; //*************************************************************************** // // Count number of objects and number of locks on this DLL. // //*************************************************************************** static ULONG g_cObj = 0; static ULONG g_cLock = 0; //*************************************************************************** // // DllGetClassObject // //*************************************************************************** extern "C" HRESULT APIENTRY DllGetClassObject( REFCLSID rclsid, REFIID riid, LPVOID * ppv ) { HRESULT hr; CFactory *pFactory; // // Verify the caller is asking for our type of object. // if (CLSID_MyEventProvider != rclsid) return E_FAIL; // // Check that we can provide the interface. // if (IID_IUnknown != riid && IID_IClassFactory != riid) return E_NOINTERFACE; // // Get a new class factory. // pFactory = new CFactory(rclsid); if (!pFactory) return E_OUTOFMEMORY; // // Verify we can get an instance. // hr = pFactory->QueryInterface(riid, ppv); if (FAILED(hr)) delete pFactory; return hr; } //*************************************************************************** // // DllCanUnloadNow // //*************************************************************************** extern "C" HRESULT APIENTRY DllCanUnloadNow(void) { SCODE sc = TRUE; if (g_cObj || g_cLock) sc = S_FALSE; return sc; } //*************************************************************************** // //*************************************************************************** void ObjectCreated(DWORD dwType) { InterlockedIncrement((LONG *) &g_cObj); } void ObjectDestroyed(DWORD dwType) { InterlockedDecrement((LONG *) &g_cObj); } //*************************************************************************** // // CFactory::CFactory // //*************************************************************************** CFactory::CFactory(const CLSID & ClsId) { m_cRef = 0; m_ClsId = ClsId; ObjectCreated(0); } //*************************************************************************** // // CFactory::~CFactory // //*************************************************************************** CFactory::~CFactory() { // nothing ObjectDestroyed(0); } //*************************************************************************** // // CFactory::QueryInterface, AddRef and Release // //*************************************************************************** STDMETHODIMP CFactory::QueryInterface(REFIID riid, LPVOID * ppv) { *ppv = 0; if (IID_IUnknown==riid || IID_IClassFactory==riid) { *ppv = this; AddRef(); return NOERROR; } return E_NOINTERFACE; } ULONG CFactory::AddRef() { return ++m_cRef; } ULONG CFactory::Release() { if (0 != --m_cRef) return m_cRef; delete this; return 0; } //*************************************************************************** // // CFactory::CreateInstance // //*************************************************************************** STDMETHODIMP CFactory::CreateInstance( LPUNKNOWN pUnkOuter, REFIID riid, LPVOID * ppvObj) { 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_MyEventProvider) { pObj = (IWbemProviderInit *) new CMyEventProvider; } 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) { if (fLock) InterlockedIncrement((LONG *) &g_cLock); else InterlockedDecrement((LONG *) &g_cLock); return NOERROR; } //*************************************************************************** // // DllRegisterServer // // Standard OLE entry point for registering the server. // // RETURN VALUES: // // S_OK Registration was successful // E_FAIL Registration failed. // //*************************************************************************** extern "C" HRESULT APIENTRY DllRegisterServer(void) { wchar_t Path[1024]; wchar_t *pGuidStr = 0; wchar_t KeyPath[1024]; // Where are we? // ============= GetModuleFileNameW(g_hInstance, Path, 1024); // Convert CLSID to string. // ======================== StringFromCLSID(CLSID_MyEventProvider, &pGuidStr); swprintf(KeyPath, L"CLSID\\\\%s", pGuidStr); HKEY hKey; LONG lRes = RegCreateKeyW(HKEY_CLASSES_ROOT, KeyPath, &hKey); if (lRes) return E_FAIL; wchar_t *pName = L"WMI Sample Event Provider"; RegSetValueExW(hKey, 0, 0, REG_SZ, (const BYTE *) pName, (DWORD)(wcslen(pName) * 2 + 2)); HKEY hSubkey; lRes = RegCreateKey(hKey, "InprocServer32", &hSubkey); RegSetValueExW(hSubkey, 0, 0, REG_SZ, (const BYTE *) Path, (DWORD)(wcslen(Path) * 2 + 2)); RegSetValueExW(hSubkey, L"ThreadingModel", 0, REG_SZ, (const BYTE *) L"Both", (DWORD)(wcslen(L"Both") * 2 + 2)); RegCloseKey(hSubkey); RegCloseKey(hKey); CoTaskMemFree(pGuidStr); return S_OK; } //*************************************************************************** // // DllUnregisterServer // // Standard OLE entry point for unregistering the server. // // RETURN VALUES: // // S_OK Unregistration was successful // E_FAIL Unregistration failed. // //*************************************************************************** extern "C" HRESULT APIENTRY DllUnregisterServer(void) { wchar_t *pGuidStr = 0; HKEY hKey; wchar_t KeyPath[256]; StringFromCLSID(CLSID_MyEventProvider, &pGuidStr); swprintf(KeyPath, L"CLSID\\%s", pGuidStr); // Delete InProcServer32 subkey. // ============================= LONG lRes = RegOpenKeyW(HKEY_CLASSES_ROOT, KeyPath, &hKey); if (lRes) return E_FAIL; RegDeleteKeyW(hKey, L"InprocServer32"); RegCloseKey(hKey); // Delete CLSID GUID key. // ====================== lRes = RegOpenKeyW(HKEY_CLASSES_ROOT, L"CLSID", &hKey); if (lRes) return E_FAIL; RegDeleteKeyW(hKey, pGuidStr); RegCloseKey(hKey); CoTaskMemFree(pGuidStr); return S_OK; }