204 lines
4.3 KiB
C++
204 lines
4.3 KiB
C++
|
//
|
||
|
// standard inprocserver DLL code, you should not need to mess with this
|
||
|
//
|
||
|
|
||
|
#include "project.h"
|
||
|
|
||
|
|
||
|
HANDLE g_hInst = NULL;
|
||
|
LONG g_cRefDll = 0; // Number of locks on this DLL
|
||
|
|
||
|
|
||
|
|
||
|
STDAPI_(void) DllAddRef()
|
||
|
{
|
||
|
InterlockedIncrement(&g_cRefDll);
|
||
|
}
|
||
|
|
||
|
STDAPI_(void) DllRelease()
|
||
|
{
|
||
|
InterlockedDecrement(&g_cRefDll);
|
||
|
}
|
||
|
|
||
|
|
||
|
STDAPI_(BOOL) DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID reserved)
|
||
|
{
|
||
|
if (fdwReason == DLL_PROCESS_ATTACH)
|
||
|
{
|
||
|
g_hInst = hInstDll;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CSampleClassFactory::QueryInterface(REFIID riid, void **ppvObject)
|
||
|
{
|
||
|
if (IsEqualIID(riid, IID_IUnknown) ||
|
||
|
IsEqualIID(riid, IID_IClassFactory)) {
|
||
|
*ppvObject = (void *)this;
|
||
|
AddRef();
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|
||
|
*ppvObject = NULL;
|
||
|
return E_NOINTERFACE;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CSampleClassFactory::AddRef(void)
|
||
|
{
|
||
|
DllAddRef();
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CSampleClassFactory::Release(void)
|
||
|
{
|
||
|
DllRelease();
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CSampleClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
|
||
|
{
|
||
|
*ppvObject = NULL;
|
||
|
|
||
|
if (NULL != pUnkOuter)
|
||
|
return CLASS_E_NOAGGREGATION;
|
||
|
|
||
|
CSampleObtainRating *pObj = new CSampleObtainRating; /* doing this does implicit AddRef() */
|
||
|
|
||
|
if (NULL == pObj)
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
HRESULT hr = pObj->QueryInterface(riid, ppvObject);
|
||
|
pObj->Release();
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CSampleClassFactory::LockServer(BOOL fLock)
|
||
|
{
|
||
|
if (fLock)
|
||
|
DllAddRef();
|
||
|
else
|
||
|
DllRelease();
|
||
|
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// standard COM DLL self registering entry point
|
||
|
//
|
||
|
|
||
|
STDAPI DllRegisterServer(void)
|
||
|
{
|
||
|
HKEY hkeyCLSID;
|
||
|
LONG err;
|
||
|
TCHAR szPath[MAX_PATH];
|
||
|
|
||
|
// get path to this DLL
|
||
|
|
||
|
GetModuleFileName(g_hInst, szPath, MAX_PATH);
|
||
|
|
||
|
/* First register our CLSID under HKEY_CLASSES_ROOT. */
|
||
|
err = ::RegOpenKey(HKEY_CLASSES_ROOT, "CLSID", &hkeyCLSID);
|
||
|
if (err == ERROR_SUCCESS) {
|
||
|
HKEY hkeyOurs;
|
||
|
err = ::RegCreateKey(hkeyCLSID, ::szOurGUID, &hkeyOurs);
|
||
|
if (err == ERROR_SUCCESS) {
|
||
|
HKEY hkeyInproc;
|
||
|
err = ::RegCreateKey(hkeyOurs, "InProcServer32", &hkeyInproc);
|
||
|
if (err == ERROR_SUCCESS) {
|
||
|
err = ::RegSetValueEx(hkeyInproc, NULL, 0, REG_SZ,
|
||
|
(LPBYTE)szPath, lstrlen(szPath) + 1);
|
||
|
if (err == ERROR_SUCCESS) {
|
||
|
err = ::RegSetValueEx(hkeyInproc, "ThreadingModel", 0,
|
||
|
REG_SZ, (LPBYTE)"Apartment", 10);
|
||
|
}
|
||
|
::RegCloseKey(hkeyInproc);
|
||
|
}
|
||
|
|
||
|
::RegCloseKey(hkeyOurs);
|
||
|
}
|
||
|
|
||
|
::RegCloseKey(hkeyCLSID);
|
||
|
|
||
|
/* Now install ourselves as a ratings helper. */
|
||
|
if (err == ERROR_SUCCESS) {
|
||
|
err = ::RegCreateKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Rating Helpers", &hkeyCLSID);
|
||
|
if (err == ERROR_SUCCESS) {
|
||
|
err = ::RegSetValueEx(hkeyCLSID, ::szOurGUID, 0, REG_SZ, (LPBYTE)"", 2);
|
||
|
::RegCloseKey(hkeyCLSID);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (err == ERROR_SUCCESS)
|
||
|
return S_OK;
|
||
|
else
|
||
|
return HRESULT_FROM_WIN32(err);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// standard COM DLL self registering entry point
|
||
|
//
|
||
|
|
||
|
STDAPI DllUnregisterServer(void)
|
||
|
{
|
||
|
HKEY hkeyCLSID;
|
||
|
LONG err;
|
||
|
|
||
|
err = ::RegOpenKey(HKEY_CLASSES_ROOT, "CLSID", &hkeyCLSID);
|
||
|
if (err == ERROR_SUCCESS) {
|
||
|
HKEY hkeyOurs;
|
||
|
err = ::RegOpenKey(hkeyCLSID, ::szOurGUID, &hkeyOurs);
|
||
|
if (err == ERROR_SUCCESS) {
|
||
|
err = ::RegDeleteKey(hkeyOurs, "InProcServer32");
|
||
|
|
||
|
::RegCloseKey(hkeyOurs);
|
||
|
|
||
|
if (err == ERROR_SUCCESS)
|
||
|
err = ::RegDeleteKey(hkeyCLSID, ::szOurGUID);
|
||
|
}
|
||
|
|
||
|
::RegCloseKey(hkeyCLSID);
|
||
|
|
||
|
if (err == ERROR_SUCCESS) {
|
||
|
err = ::RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Rating Helpers", &hkeyCLSID);
|
||
|
if (err == ERROR_SUCCESS) {
|
||
|
err = ::RegDeleteValue(hkeyCLSID, ::szOurGUID);
|
||
|
::RegCloseKey(hkeyCLSID);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (err == ERROR_SUCCESS)
|
||
|
return S_OK;
|
||
|
else
|
||
|
return HRESULT_FROM_WIN32(err);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// standard COM DLL entry point
|
||
|
//
|
||
|
|
||
|
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
|
||
|
{
|
||
|
if (IsEqualCLSID(rclsid, CLSID_Sample))
|
||
|
{
|
||
|
static CSampleClassFactory cf; /* note, declaring this doesn't constitute a reference */
|
||
|
|
||
|
return cf.QueryInterface(riid, ppv); /* will AddRef() if successful */
|
||
|
}
|
||
|
// to make this support more com objects add them here
|
||
|
|
||
|
*ppv = NULL;
|
||
|
return CLASS_E_CLASSNOTAVAILABLE;;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// standard COM DLL entry point
|
||
|
//
|
||
|
|
||
|
STDAPI DllCanUnloadNow(void)
|
||
|
{
|
||
|
return g_cRefDll == 0 ? S_OK : S_FALSE;
|
||
|
}
|