|
|
#include "stdafx.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 "netplwiz"
#define SZ_MODULE "NETPLWIZ"
#define DECLARE_DEBUG
#include "debug.h"
// 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; g_hinst = hinstDLL; // For shell/lib files who extern him
g_bMirroredOS = IS_MIRRORING_ENABLED(); SHFusionInitializeFromModule(hinstDLL); } else if (dwReason == DLL_PROCESS_DETACH) { CleanUpIntroFont(); 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() { _CallRegInstall("UnregDll", TRUE);
HRESULT hres = _CallRegInstall("RegDll", FALSE); if ( SUCCEEDED(hres) ) { // if this is a workstation build then lets install the users and password cpl
NT_PRODUCT_TYPE NtProductType; RtlGetNtProductType(&NtProductType); // get the product type
if (NtProductType == NtProductWinNt) { hres = _CallRegInstall("RegDllWorkstation", FALSE); } } return S_OK; }
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_PublishingWizard, CPublishingWizard_CreateInstance, COCREATEONLY), CF_TABLE_ENTRY( &CLSID_PublishDropTarget, CPublishDropTarget_CreateInstance, COCREATEONLY), CF_TABLE_ENTRY( &CLSID_UserPropertyPages, CUserPropertyPages_CreateInstance, COCREATEONLY), CF_TABLE_ENTRY( &CLSID_InternetPrintOrdering, CPublishDropTarget_CreateInstance, COCREATEONLY), CF_TABLE_ENTRY( &CLSID_PassportWizard, CPassportWizard_CreateInstance, COCREATEONLY), CF_TABLE_ENTRY( &CLSID_PassportClientServices, CPassportClientServices_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; } }
}
#ifdef ATL_ENABLED
if (hr == CLASS_E_CLASSNOTAVAILABLE) hr = AtlGetClassObject(rclsid, riid, ppv); #endif
return hr; }
|