windows-nt/Source/XPSP1/NT/sdktools/mtscript/exe/factory.cxx
2020-09-26 16:20:57 +08:00

266 lines
5.7 KiB
C++

#include "headers.hxx"
DeclareTag(tagFactory, "MTScript", "Monitor Class Factories");
HRESULT CreateConnectedMachine(CMTScript *pMT, IUnknown **ppUnk);
HRESULT CreateScriptedProcess(CMTScript *pMT, IUnknown **ppUnk);
REGCLASSDATA g_regData[] =
{
{
&CLSID_RemoteMTScript,
CreateConnectedMachine,
CLSCTX_SERVER,
0
},
{
&CLSID_LocalScriptedProcess,
CreateScriptedProcess,
CLSCTX_LOCAL_SERVER,
0
}
};
// ***************************************************************
//
//
HRESULT
RegisterClassObjects(CMTScript *pMT)
{
HRESULT hr = S_OK;
REGCLASSDATA *prcd;
int i;
CStdFactory *pFact;
TraceTag((tagFactory, "Registering Class Factories..."));
for (i = 0, prcd = g_regData;
i < ARRAY_SIZE(g_regData);
i++, prcd++)
{
pFact = new CStdFactory(pMT, prcd->pfnCreate);
if (!pFact)
{
hr = E_OUTOFMEMORY;
}
else
{
hr = CoRegisterClassObject(*prcd->pclsid,
pFact,
prcd->ctxCreate,
REGCLS_MULTIPLEUSE,
&prcd->dwCookie);
pFact->Release();
}
if (hr)
{
// BUGBUG -- how do we handle errors here?
WCHAR achBuf[100];
wsprintf(achBuf, L"CoRegisterClassObject failed with (%x)", hr);
MessageBox(NULL, achBuf, L"MTScript", MB_OK | MB_SETFOREGROUND);
break;
}
}
return hr;
}
void
UnregisterClassObjects()
{
REGCLASSDATA *prcd;
int i;
TraceTag((tagFactory, "Unregistering Class Factories..."));
for (i = 0, prcd = g_regData;
i < ARRAY_SIZE(g_regData);
i++, prcd++)
{
if (prcd->dwCookie != 0)
{
CoRevokeClassObject(prcd->dwCookie);
}
}
}
// ***************************************************************
CStdFactory::CStdFactory(CMTScript *pMT, FNCREATE *pfnCreate)
{
_ulRefs = 1;
_pMT = pMT;
_pfnCreate = pfnCreate;
}
STDMETHODIMP
CStdFactory::QueryInterface(REFIID iid, void ** ppvObject)
{
if (iid == IID_IClassFactory || iid == IID_IUnknown)
{
*ppvObject = (IClassFactory*)this;
}
else
{
*ppvObject = NULL;
return E_NOINTERFACE;
}
((IUnknown *)*ppvObject)->AddRef();
return S_OK;
}
STDMETHODIMP
CStdFactory::CreateInstance(IUnknown * pUnkOuter,
REFIID riid,
void ** ppvObject)
{
IUnknown *pUnk;
HRESULT hr = E_FAIL;
*ppvObject = NULL;
TraceTag((tagFactory, "%p: CreateInstance called...", this));
if (pUnkOuter != NULL)
{
hr = CLASS_E_NOAGGREGATION;
}
hr = (*_pfnCreate)(_pMT, &pUnk);
if (!hr)
{
hr = pUnk->QueryInterface(riid, ppvObject);
}
pUnk->Release();
if (hr)
{
// BUGBUG -- Fix this
WCHAR achBuf[100];
wsprintf(achBuf, L"CreateInstance failed with (%x)", hr);
MessageBox(NULL, achBuf, L"MTScript", MB_OK | MB_SETFOREGROUND);
}
return hr;
}
STDMETHODIMP
CStdFactory::LockServer(BOOL fLock)
{
// BUGBUG -- Increment a count on the CMTScript object and don't go
// away if it's not zero.
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Function: CreateConnectedMachine
//
// Synopsis: Creates the object which implements IConnectedMachine
//
// Arguments: [pMT] -- Pointer to CMTScript object
// [ppUnk] -- Created object is returned here
//
// Notes: This function creates only one object and returns it for
// all CreateInstance calls. There is no per-connection state
// so it is unnecessary to create a separate object for each
// connection.
//
//----------------------------------------------------------------------------
HRESULT
CreateConnectedMachine(CMTScript *pMT, IUnknown **ppUnk)
{
HRESULT hr = S_OK;
CMachine *pMach;
TraceTag((tagFactory, "Creating a CMachine object"));
pMT->PostToThread(pMT, MD_MACHINECONNECT);
LOCK_LOCALS(pMT);
if (!pMT->_pMachine)
{
TraceTag((tagFactory, "Creating a CMachine object"));
pMach = new CMachine(pMT, pMT->_pTIMachine);
if (!pMach)
{
return E_OUTOFMEMORY;
}
hr = pMach->StartThread(NULL);
if (FAILED(hr))
{
return hr;
}
pMT->_pMachine = pMach;
}
else
{
TraceTag((tagFactory, "Connecting to the existing CMachine object"));
pMach = pMT->_pMachine;
}
// We are in the free-threaded apartment so we don't have to marshal this.
return pMach->QueryInterface(IID_IUnknown, (LPVOID*)ppUnk);
}
//+---------------------------------------------------------------------------
//
// Function: CreateScriptedProcess
//
// Synopsis: Creates the object which implement IScriptedProcess
//
// Arguments: [pMT] -- Pointer to CMTScript object
// [ppUnk] -- Created object is returned here
//
// Notes: Creates a new object for each connection.
//
//----------------------------------------------------------------------------
HRESULT
CreateScriptedProcess(CMTScript *pMT, IUnknown **ppUnk)
{
HRESULT hr = S_OK;
CProcessComm *pPC;
TraceTag((tagFactory, "Creating a CProcessComm object"));
LOCK_LOCALS(pMT);
pPC = new CProcessComm(pMT);
if (!pPC)
{
return E_OUTOFMEMORY;
}
hr = pPC->QueryInterface(IID_IUnknown, (LPVOID*)ppUnk);
pPC->Release();
return hr;
}