Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

624 lines
13 KiB

/*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Copyright (c) 2000 Microsoft Corporation
Module Name:
factory.cpp
Abstract:
W3Spoof class factory implementation. Also implements component
registration and runtime registration for the local server.
Author:
Paul M Midgen (pmidge) 17-July-2000
Revision History:
17-July-2000 pmidge
Created
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
#include "common.h"
LPCWSTR g_wszRegistered = L"Registered";
LPCWSTR g_wszAdvPackDll = L"advpack.dll";
// advapi doesn't speak unicode
LPCSTR g_szRegSection = "reg";
LPCSTR g_szUnRegSection = "unreg";
/*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
CFactory::CFactory()
WHAT : W3Spoof class factory constructor. Writes the COM server entries
to the registry and registers itself with COM as the W3Spoof
class factory.
ARGS : fEmbedded - when the server starts and creates the class factory,
it passes this flag in, letting us know if the server
is running embedded or not. if we're embedded, we
don't want to pop ui, so we store this value and
use it when creating W3Spoof objects.
RETURNS : nothing.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
CFactory::CFactory()
{
DEBUG_ENTER((
DBG_FACTORY,
rt_void,
"CFactory::CFactory",
"this=%#x",
this
));
LPDWORD pdw = NULL;
BOOL bRet = FALSE;
DWORD dwRet = ERROR_SUCCESS;
m_pw3s = NULL;
m_dwCookie = 0L;
m_cRefs = 1;
m_cLocks = 0L;
//
// component registration check
//
// if the regkey exists but is 0 (someone wants to force us to reregister)
// or if the regkey doesn't exist (new install or someone nuked the regkey)
// then we register ourselves as a COM server.
//
bRet = GetRegValue(g_wszRegistered, REG_DWORD, (void**)&pdw);
if( (bRet && (*pdw == 0)) || !bRet )
{
_RegisterServer(TRUE);
}
delete pdw;
//
// create a single instance (singleton) of CW3Spoof to
// be used by all callers and grab an IUnknown* for the
// factory object so it controls the singleton's lifetime.
//
CW3Spoof::Create(&m_pw3s);
DEBUG_ASSERT((m_pw3s != NULL));
_RegisterClassFactory(TRUE);
DEBUG_LEAVE(0);
}
/*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
CFactory::~CFactory()
WHAT : W3Spoof class factory destructor. Cleans up.
ARGS : none.
RETURNS : nothing.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
CFactory::~CFactory()
{
DEBUG_ENTER((
DBG_FACTORY,
rt_void,
"CFactory::~CFactory",
"this=%#x",
this
));
DEBUG_TRACE(FACTORY, ("refcount=%d; locks=%d", m_cRefs, m_cLocks));
DEBUG_LEAVE(0);
}
/*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
CFactory::Create()
WHAT : Creates the class factory.
ARGS : none.
RETURNS : nothing.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
HRESULT
CFactory::Create(CFactory** ppCF)
{
DEBUG_ENTER((
DBG_FACTORY,
rt_hresult,
"CFactory::Create",
"ppCF=%#x",
ppCF
));
HRESULT hr = S_OK;
*ppCF = new CFactory;
if( !(*ppCF) )
{
hr = E_OUTOFMEMORY;
}
DEBUG_LEAVE(hr);
return hr;
}
/*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
CFactory::Terminate()
WHAT : Terminates the class factory.
ARGS : none.
RETURNS : nothing.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
HRESULT
CFactory::Terminate(void)
{
DEBUG_ENTER((
DBG_FACTORY,
rt_hresult,
"CFactory::Terminate",
"this=%#x",
this
));
HRESULT hr = S_OK;
_RegisterClassFactory(FALSE);
if( m_pw3s )
m_pw3s->Terminate();
SAFERELEASE(m_pw3s);
Release();
DEBUG_LEAVE(hr);
return hr;
}
/*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
CFactory::QueryInterface()
WHAT : IUnknown member implementation.
ARGS : riid - IID wanted by caller
ppv - pointer to return interface through
RETURNS : S_OK - the caller got the interface they wanted.
E_NOINTERFACE - they didn't.
E_INVALIDARG - the supplied a bogus return pointer.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
HRESULT
__stdcall
CFactory::QueryInterface(REFIID riid, void** ppv)
{
DEBUG_ENTER((
DBG_FACTORY,
rt_hresult,
"CFactory::QueryInterface",
"this=%#x; riid=%s; ppv=%#x",
this,
MapIIDToString(riid),
ppv
));
HRESULT hr = S_OK;
if( !ppv )
{
hr = E_INVALIDARG;
goto quit;
}
if( IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory) )
{
*ppv = static_cast<IClassFactory*>(this);
}
else
{
*ppv = NULL;
hr = E_NOINTERFACE;
}
if( SUCCEEDED(hr) )
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
quit:
DEBUG_LEAVE(hr);
return hr;
}
/*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
CFactory::AddRef()
WHAT : IUnknown member implementation.
ARGS : none.
RETURNS : nothing of consequence.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
ULONG
__stdcall
CFactory::AddRef(void)
{
InterlockedIncrement(&m_cRefs);
DEBUG_ADDREF("CFactory", m_cRefs);
return m_cRefs;
}
/*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
CFactory::Release()
WHAT : IUnknown member implementation.
ARGS : none.
RETURNS : nothing of consequence.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
ULONG
__stdcall
CFactory::Release(void)
{
InterlockedDecrement(&m_cRefs);
DEBUG_RELEASE("CFactory", m_cRefs);
if( m_cRefs == 0 )
{
DEBUG_FINALRELEASE("CFactory");
delete this;
return 0;
}
return m_cRefs;
}
/*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
CFactory::CreateInstance()
WHAT : IClassFactory member implementation.
ARGS : pContainer - an object attempting to aggregate this class
will supply its IUnknown pointer through this
parameter.
riid - interface caller wants.
ppv - pointer to return interface through.
RETURNS : S_OK - caller got what they wanted.
E_INVALIDARG - caller supplied bogus return pointer.
CLASS_E_NOAGGREGATION - caller tried to aggregate.
E_NOINTERFACE - caller asked for unsupported interface.
E_OUTOFMEMORY - couldn't allocate object.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
HRESULT
__stdcall
CFactory::CreateInstance(IUnknown* pContainer, REFIID riid, void** ppv)
{
DEBUG_ENTER((
DBG_FACTORY,
rt_hresult,
"CFactory::CreateInstance",
"this=%#x; pContainer=%#x; riid=%s; ppv=%#x",
this,
pContainer,
MapIIDToString(riid),
ppv
));
HRESULT hr = S_OK;
if( !ppv )
{
hr = E_INVALIDARG;
goto quit;
}
if( pContainer )
{
*ppv = NULL;
hr = CLASS_E_NOAGGREGATION;
goto quit;
}
if( m_pw3s )
{
hr = m_pw3s->QueryInterface(riid, ppv);
}
else
{
hr = E_OUTOFMEMORY;
goto quit;
}
quit:
DEBUG_LEAVE(hr);
return hr;
}
/*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
CFactory::LockServer()
WHAT : IClassFactory member implementation.
ARGS : fLock - apply or remove a lock.
RETURNS : S_OK - always.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
HRESULT
__stdcall
CFactory::LockServer(BOOL fLock)
{
DEBUG_ENTER((
DBG_FACTORY,
rt_hresult,
"CFactory::LockServer",
"this=%#x; fLock=%d",
this,
fLock
));
HRESULT hr = S_OK;
fLock ? InterlockedIncrement(&m_cLocks) : InterlockedDecrement(&m_cLocks);
DEBUG_TRACE(REFCOUNT, ("factory locks=%d", m_cLocks));
DEBUG_LEAVE(hr);
return hr;
}
/*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
CFactory::Activate()
WHAT : Allows COM to use the class factory, which is registered in
suspended mode.
ARGS : none.
RETURNS : S_OK - class factory was resumed..
other - error describes reason for failure.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
HRESULT
CFactory::Activate(void)
{
DEBUG_ENTER((
DBG_FACTORY,
rt_hresult,
"CFactory::Activate",
"this=%#x",
this
));
HRESULT hr = S_OK;
hr = CoResumeClassObjects();
DEBUG_LEAVE(hr);
return hr;
}
/*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
CFactory::_RegisterServer()
WHAT : Self-registration routine.
ARGS : fMode - if true, registers the component. if false...
RETURNS : S_OK - registration succeeded.
E_FAIL - registration failed.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
HRESULT
CFactory::_RegisterServer(BOOL fMode)
{
DEBUG_ENTER((
DBG_FACTORY,
rt_hresult,
"CFactory::_RegisterServer",
"this=%#x; fMode=%s",
this,
fMode ? "reg" : "unreg"
));
HRESULT hr = S_OK;
HINSTANCE advpack = NULL;
REGINSTALL pfnri = NULL;
advpack = LoadLibrary(g_wszAdvPackDll);
if( !advpack )
{
DEBUG_TRACE(
FACTORY,
("couldn't load advpack.dll: %s", MapErrorToString(GetLastError()))
);
hr = E_FAIL;
goto quit;
}
DEBUG_TRACE(FACTORY, ("loaded advpack.dll"));
pfnri = (REGINSTALL) GetProcAddress(advpack, achREGINSTALL);
if( !pfnri )
{
DEBUG_TRACE(
FACTORY,
("couldn't get RegInstall pointer: %s", MapErrorToString(GetLastError()))
);
hr = E_FAIL;
goto quit;
}
DEBUG_TRACE(FACTORY, ("calling reginstall to %s", (fMode ? "reg" : "unreg")));
hr = pfnri(
GetModuleHandle(NULL),
fMode ? g_szRegSection : g_szUnRegSection,
NULL
);
if( SUCCEEDED(hr) )
{
DWORD dw = 1;
SetRegValue(g_wszRegistered, REG_DWORD, (void*)&dw, sizeof(DWORD));
}
DEBUG_TRACE(FACTORY, ("unloading advpack.dll"));
FreeLibrary(advpack);
hr = _RegisterTypeLibrary(fMode);
quit:
DEBUG_LEAVE(hr);
return hr;
}
/*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
CFactory::_RegisterClassFactory()
WHAT : Class factory registration routine.
ARGS : fMode - if true, register, if false...
RETURNS : S_OK - success
E_FAIL - failure
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
HRESULT
CFactory::_RegisterClassFactory(BOOL fMode)
{
DEBUG_ENTER((
DBG_FACTORY,
rt_hresult,
"CFactory::_RegisterClassFactory",
"this=%#x; fMode=%s",
this,
fMode ? "reg" : "unreg"
));
HRESULT hr = S_OK;
if( fMode )
{
hr = CoRegisterClassObject(
CLSID_W3Spoof,
static_cast<IUnknown*>(this),
CLSCTX_LOCAL_SERVER,
REGCLS_MULTI_SEPARATE | REGCLS_SUSPENDED,
&m_dwCookie
);
}
else
{
hr = CoRevokeClassObject(m_dwCookie);
}
DEBUG_LEAVE(hr);
return hr;
}
/*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
CFactory::_RegisterTypeLibrary()
WHAT : TypeLib registration routine.
ARGS : fMode - if true, register, if false...
RETURNS : S_OK - success
E_FAIL - failure
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
HRESULT
CFactory::_RegisterTypeLibrary(BOOL fMode)
{
DEBUG_ENTER((
DBG_FACTORY,
rt_hresult,
"CFactory::_RegisterTypeLibrary",
"this=%#x; fMode=%s",
this,
fMode ? "reg" : "unreg"
));
ITypeLib* ptl = NULL;
TLIBATTR* pta = NULL;
WCHAR* pbuf = NULL;
HRESULT hr = S_OK;
if( (pbuf = new WCHAR[MAX_PATH]) )
{
GetModuleFileName(NULL, pbuf, MAX_PATH);
}
else
{
hr = E_OUTOFMEMORY;
goto quit;
}
hr = LoadTypeLib(pbuf, &ptl);
if( SUCCEEDED(hr) )
{
if( fMode )
{
hr = RegisterTypeLib(ptl, pbuf, NULL);
}
else
{
hr = ptl->GetLibAttr(&pta);
if( SUCCEEDED(hr) )
{
hr = UnRegisterTypeLib(
pta->guid,
pta->wMajorVerNum,
pta->wMinorVerNum,
pta->lcid,
pta->syskind
);
ptl->ReleaseTLibAttr(pta);
}
else
{
goto quit;
}
}
ptl->Release();
}
quit:
delete [] pbuf;
DEBUG_LEAVE(hr);
return hr;
}