You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
4.5 KiB
226 lines
4.5 KiB
/* cat_dll.cpp */
|
|
|
|
#include <windows.h>
|
|
#include <comdef.h>
|
|
|
|
|
|
const GUID CLSID_COMCatalog = { 0x00000346, 0, 0, 0xC0,0,0,0,0,0,0,0x46 };
|
|
|
|
HRESULT __stdcall GetCatalogObject
|
|
(
|
|
/* [in] */ REFIID riid,
|
|
/* [out, iis_is(riid)] */ void ** ppv
|
|
)
|
|
{
|
|
return CoCreateInstance (CLSID_COMCatalog, NULL, CLSCTX_INPROC, riid, ppv);
|
|
}
|
|
|
|
|
|
#define CLSID_CATALOG "{1A26EFEF-9F04-11D1-8F36-00C04FD8FF5E}"
|
|
|
|
const CLSID g_clsid_catalog =
|
|
{0x1A26EFEF,0x9F04,0x11D1,{0x8F,0x36,0x00,0xC0,0x4F,0xD8,0xFF,0x5E}};
|
|
|
|
class CClassFactory : public IClassFactory
|
|
{
|
|
public:
|
|
CClassFactory(void);
|
|
STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
|
|
STDMETHODIMP_(ULONG) AddRef(void);
|
|
STDMETHODIMP_(ULONG) Release(void);
|
|
STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID FAR* ppvObject);
|
|
STDMETHODIMP LockServer(BOOL fLock);
|
|
|
|
private:
|
|
long m_cRef;
|
|
};
|
|
|
|
CClassFactory::CClassFactory(void) : m_cRef(0) { }
|
|
|
|
STDMETHODIMP CClassFactory::QueryInterface(
|
|
REFIID riid,
|
|
LPVOID FAR* ppvObj)
|
|
{
|
|
*ppvObj = NULL;
|
|
|
|
if ((riid == IID_IClassFactory) || (riid == IID_IUnknown))
|
|
{
|
|
*ppvObj = (LPVOID) (IClassFactory *) this;
|
|
}
|
|
|
|
if (*ppvObj != NULL)
|
|
{
|
|
((LPUNKNOWN)*ppvObj)->AddRef();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
|
|
STDMETHODIMP_(ULONG) CClassFactory::AddRef(void)
|
|
{
|
|
long cRef;
|
|
|
|
cRef = InterlockedIncrement(&m_cRef);
|
|
|
|
return(cRef);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CClassFactory::Release(void)
|
|
{
|
|
long cRef;
|
|
|
|
cRef = InterlockedDecrement(&m_cRef);
|
|
if (cRef == 0)
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
return(cRef);
|
|
}
|
|
|
|
|
|
STDMETHODIMP CClassFactory::CreateInstance(
|
|
LPUNKNOWN pUnkOuter,
|
|
REFIID riid,
|
|
LPVOID FAR* ppvObj)
|
|
{
|
|
HRESULT hr;
|
|
|
|
*ppvObj = NULL;
|
|
|
|
if (pUnkOuter)
|
|
{
|
|
return(CLASS_E_NOAGGREGATION);
|
|
}
|
|
|
|
hr = CoCreateInstance (CLSID_COMCatalog, NULL, CLSCTX_INPROC, riid, ppvObj);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
|
|
{
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
static HINSTANCE g_hInst = NULL;
|
|
|
|
STDAPI_(BOOL) APIENTRY DllMain
|
|
(
|
|
HINSTANCE hInst,
|
|
DWORD dwReason,
|
|
LPVOID lpReserved
|
|
)
|
|
{
|
|
g_hInst = hInst;
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
STDAPI DllCanUnloadNow(void)
|
|
{
|
|
return( S_FALSE );
|
|
}
|
|
|
|
|
|
STDAPI DllGetClassObject
|
|
(
|
|
REFCLSID rclsid,
|
|
REFIID riid,
|
|
LPVOID FAR* ppvObj
|
|
)
|
|
{
|
|
if (rclsid != g_clsid_catalog)
|
|
{
|
|
return(E_FAIL);
|
|
}
|
|
|
|
if (ppvObj == NULL)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
*ppvObj = NULL;
|
|
|
|
CClassFactory *pcf = new CClassFactory;
|
|
if (pcf == NULL)
|
|
{
|
|
return(E_OUTOFMEMORY);
|
|
}
|
|
|
|
pcf->AddRef();
|
|
HRESULT hRes = pcf->QueryInterface(riid, ppvObj);
|
|
pcf->Release();
|
|
|
|
return(hRes);
|
|
}
|
|
|
|
|
|
typedef struct
|
|
{
|
|
char *KeyName;
|
|
char *ValueName;
|
|
char *Value;
|
|
} REGISTRATION_ENTRY;
|
|
|
|
REGISTRATION_ENTRY registration[] =
|
|
{
|
|
{ "CLSID\\" CLSID_CATALOG, NULL, "COM+ Catalog Queries" },
|
|
{ "CLSID\\" CLSID_CATALOG "\\InprocServer32", NULL, /* dynamic */ },
|
|
{ "CLSID\\" CLSID_CATALOG "\\InprocServer32", "ThreadingModel", "Both" }
|
|
};
|
|
|
|
#define NUM_REGISTRATION_VALUES (sizeof(registration) / sizeof(registration[0]))
|
|
#define REGISTRATION_SERVER (1)
|
|
|
|
|
|
STDAPI DllRegisterServer(void)
|
|
{
|
|
HRESULT hr;
|
|
char szModuleName[MAX_PATH+1];
|
|
|
|
GetModuleFileNameA(g_hInst, szModuleName, sizeof(szModuleName)/sizeof(szModuleName[0]));
|
|
szModuleName[sizeof(szModuleName)/sizeof(szModuleName[0])-1]= '\0';
|
|
registration[REGISTRATION_SERVER].Value = szModuleName;
|
|
|
|
for (int i = 0; i < NUM_REGISTRATION_VALUES; i++)
|
|
{
|
|
HKEY hKey;
|
|
hr = RegCreateKeyA(HKEY_CLASSES_ROOT, registration[i].KeyName, &hKey);
|
|
if (hr == ERROR_SUCCESS)
|
|
{
|
|
hr = RegSetValueExA(hKey,
|
|
registration[i].ValueName,
|
|
0,
|
|
REG_SZ,
|
|
(BYTE *) registration[i].Value,
|
|
strlen(registration[i].Value) + 1);
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
if (hr != ERROR_SUCCESS)
|
|
{
|
|
DllUnregisterServer();
|
|
|
|
return(SELFREG_E_CLASS);
|
|
}
|
|
}
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
STDAPI DllUnregisterServer(void)
|
|
{
|
|
for (int i = NUM_REGISTRATION_VALUES - 1; i >= 0; i--)
|
|
{
|
|
RegDeleteKeyA(HKEY_CLASSES_ROOT, registration[i].KeyName);
|
|
}
|
|
|
|
return(S_OK);
|
|
}
|