266 lines
5.7 KiB
C++
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;
|
||
|
}
|