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