|
|
#include "precomp.h"
#include "advpub.h" // For REGINSTALL
#pragma hdrstop
#define DECL_CRTFREE
#include <crtfree.h>
// Fix the debug builds
#define SZ_DEBUGINI "ccshell.ini"
#define SZ_DEBUGSECTION "resize"
#define SZ_MODULE "resize"
#define DECLARE_DEBUG
#include "debug.h"
// interface stuff
// CLSID_ResizePhotos {1530f7ee-5128-43bd-9977-84a4b0fad7df}
const CLSID CLSID_ResizePhotos = {0x1530f7ee,0x5128,0x43bd,{0x99, 0x77, 0x84, 0xa4, 0xb0, 0xfa, 0xd7, 0xdf}}; // CLSID_SlideshowExtension {efb97cb8-a4a4-4357-a261-002ffaed0267}
const CLSID CLSID_SlideshowExtension = {0xefb97cb8,0xa4a4,0x4357,{0xa2, 0x61, 0x00, 0x2f, 0xfa, 0xed, 0x02, 0x67}};
STDAPI CResizePhotos_CreateInstance(IUnknown* pUnkOuter, IUnknown** ppunk, LPCOBJECTINFO poi); STDAPI CSlideshowExtension_CreateInstance(IUnknown* pUnkOuter, IUnknown** ppunk, LPCOBJECTINFO poi);
// shell/lib files look for this instance variable
EXTERN_C HINSTANCE g_hinst = 0; LONG g_cLocks = 0; BOOL g_bMirroredOS = FALSE;
// DLL lifetime stuff
STDAPI_(BOOL) DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved) { if (dwReason == DLL_PROCESS_ATTACH) { g_hinst = hinstDLL; // For shell/lib files who extern him
g_bMirroredOS = IS_MIRRORING_ENABLED(); SHFusionInitializeFromModule(hinstDLL); } else if (dwReason == DLL_PROCESS_DETACH) { SHFusionUninitialize(); } return TRUE; // Successful DLL_PROCESS_ATTACH.
}
STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine) { return S_OK; }
STDAPI DllCanUnloadNow() { return (g_cLocks == 0) ? S_OK:S_FALSE; } STDAPI_(void) DllAddRef(void) { InterlockedIncrement(&g_cLocks); }
STDAPI_(void) DllRelease(void) { InterlockedDecrement(&g_cLocks); }
// helper to handle the SELFREG.INF parsing
HRESULT _CallRegInstall(LPCSTR szSection, BOOL bUninstall) { HRESULT hr = E_FAIL; HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
if (hinstAdvPack) { REGINSTALL pfnri = (REGINSTALL)GetProcAddress(hinstAdvPack, "RegInstall");
if (pfnri) { STRENTRY seReg[] = { { "25", "%SystemRoot%" }, { "11", "%SystemRoot%\\system32" }, }; STRTABLE stReg = { ARRAYSIZE(seReg), seReg };
hr = pfnri(g_hinst, szSection, &stReg); if (bUninstall) { // ADVPACK will return E_UNEXPECTED if you try to uninstall
// (which does a registry restore) on an INF section that was
// never installed. We uninstall sections that may never have
// been installed, so ignore this error
hr = ((E_UNEXPECTED == hr) ? S_OK : hr); } } FreeLibrary(hinstAdvPack); } return hr; }
STDAPI DllRegisterServer() { return _CallRegInstall("RegDll", FALSE); }
STDAPI DllUnregisterServer() { return S_OK; }
//
// This array holds information needed for ClassFacory.
// OLEMISC_ flags are used by shembed and shocx.
//
// PERF: this table should be ordered in most-to-least used order
//
#define OIF_ALLOWAGGREGATION 0x0001
CF_TABLE_BEGIN(g_ObjectInfo)
CF_TABLE_ENTRY( &CLSID_ResizePhotos, CResizePhotos_CreateInstance, COCREATEONLY), CF_TABLE_ENTRY( &CLSID_SlideshowExtension, CSlideshowExtension_CreateInstance, COCREATEONLY),
CF_TABLE_END(g_ObjectInfo)
// constructor for CObjectInfo.
CObjectInfo::CObjectInfo(CLSID const* pclsidin, LPFNCREATEOBJINSTANCE pfnCreatein, IID const* piidIn, IID const* piidEventsIn, long lVersionIn, DWORD dwOleMiscFlagsIn, DWORD dwClassFactFlagsIn) { pclsid = pclsidin; pfnCreateInstance = pfnCreatein; piid = piidIn; piidEvents = piidEventsIn; lVersion = lVersionIn; dwOleMiscFlags = dwOleMiscFlagsIn; dwClassFactFlags = dwClassFactFlagsIn; }
// static class factory (no allocs!)
STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, void **ppvObj) { if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown)) { *ppvObj = (void *)GET_ICLASSFACTORY(this); DllAddRef(); return NOERROR; }
*ppvObj = NULL; return E_NOINTERFACE; }
STDMETHODIMP_(ULONG) CClassFactory::AddRef() { DllAddRef(); return 2; }
STDMETHODIMP_(ULONG) CClassFactory::Release() { DllRelease(); return 1; }
STDMETHODIMP CClassFactory::CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv) { *ppv = NULL;
if (punkOuter && !IsEqualIID(riid, IID_IUnknown)) { // It is technically illegal to aggregate an object and request
// any interface other than IUnknown. Enforce this.
//
return CLASS_E_NOAGGREGATION; } else { LPOBJECTINFO pthisobj = (LPOBJECTINFO)this;
if (punkOuter && !(pthisobj->dwClassFactFlags & OIF_ALLOWAGGREGATION)) return CLASS_E_NOAGGREGATION;
IUnknown *punk; HRESULT hres = pthisobj->pfnCreateInstance(punkOuter, &punk, pthisobj); if (SUCCEEDED(hres)) { hres = punk->QueryInterface(riid, ppv); punk->Release(); }
_ASSERT(FAILED(hres) ? *ppv == NULL : TRUE); return hres; } }
STDMETHODIMP CClassFactory::LockServer(BOOL fLock) { if (fLock) DllAddRef(); else DllRelease();
return S_OK; }
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) { HRESULT hr = CLASS_E_CLASSNOTAVAILABLE; *ppv = NULL; if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown)) { for (LPCOBJECTINFO pcls = g_ObjectInfo; pcls->pclsid; pcls++) { if (IsEqualGUID(rclsid, *(pcls->pclsid))) { *ppv = (void*)pcls; DllAddRef(); // class factory holds DLL ref count
hr = S_OK; } }
} return hr; }
|