2025-04-27 07:49:33 -04:00

402 lines
8.8 KiB
C++

// **************************************************************************
//
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
//
// File: OLESRVR.CPP
//
// Description:
// Event provider sample - COM server implementations
//
// History:
//
// **************************************************************************
#include <windows.h>
#include <stdio.h>
#include <time.h>
#include <locale.h>
#include <wbemidl.h>
#include <initguid.h>
#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;
}