#include "precomp.h" #include "advpub.h" // For REGINSTALL #pragma hdrstop #define DECL_CRTFREE #include // 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; }