windows-nt/Source/XPSP1/NT/shell/ext/powertoy/dll.cpp
2020-09-26 16:20:57 +08:00

239 lines
6 KiB
C++

#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;
}