|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997.
//
// activate.cxx
//
// Main dcom activation service routines.
//
//--------------------------------------------------------------------------
#include "act.hxx"
HRESULT MakeProcessActive(CProcess *pProcess); HRESULT ProcessInitializationFinished(CProcess *pProcess);
HRESULT ProcessActivatorStarted( IN handle_t hRpc, IN PHPROCESS phProcess, IN ProcessActivatorToken *pActToken, OUT error_status_t *prpcstat) { CheckLocalCall( hRpc ); // raises exception if not
*prpcstat = 0; // we got here so we are OK
CProcess *pProcess = ReferenceProcess( phProcess, TRUE ); if ( ! pProcess ) return E_ACCESSDENIED;
HRESULT hr = S_OK; CServerTableEntry *pProcessEntry = NULL; CAppidData *pAppidData = NULL; ScmProcessReg *pScmProcessReg = NULL; DWORD RegistrationToken = 0; BOOL fCallerOK = FALSE;
DWORD AppIDFlags = 0;
// Lookup appid info from appropriate registry side
#if defined(_WIN64)
AppIDFlags = pProcess->Is64Bit() ? CAT_REG64_ONLY : CAT_REG32_ONLY; #endif
hr = LookupAppidData( pActToken->ProcessGUID, pProcess->GetToken(), AppIDFlags, &pAppidData ); if (FAILED(hr)) { goto exit; }
Win4Assert(pAppidData && "LookupAppidData returned NULL AppidData"); //
// Check that the caller is allowed to register this CLSID.
//
fCallerOK = pAppidData->CertifyServer(pProcess);
if (!fCallerOK) { hr = CO_E_WRONG_SERVER_IDENTITY; goto exit; }
pProcessEntry = gpProcessTable->GetOrCreate( pActToken->ProcessGUID );
if ( ! pProcessEntry ) { hr = E_UNEXPECTED; goto exit; }
pScmProcessReg = new ScmProcessReg; if (!pScmProcessReg) { hr = E_OUTOFMEMORY; goto exit; } pScmProcessReg->TimeOfLastPing = GetTickCount(); pScmProcessReg->ProcessGUID = pActToken->ProcessGUID; pScmProcessReg->ReadinessStatus = SERVERSTATE_SUSPENDED; pScmProcessReg->AppIDFlags = AppIDFlags; pProcess->SetProcessReg(pScmProcessReg);
hr = pProcessEntry->RegisterServer( pProcess, pActToken->ActivatorIPID, NULL, pAppidData, SERVERSTATE_SUSPENDED, &RegistrationToken );
pScmProcessReg->RegistrationToken = RegistrationToken;
exit:
if (pProcessEntry) pProcessEntry->Release(); if (pProcess) ReleaseProcess( pProcess ); if (pAppidData) delete pAppidData;
return hr; }
HRESULT ProcessActivatorInitializing( IN handle_t hRpc, IN PHPROCESS phProcess, OUT error_status_t *prpcstat) { CheckLocalCall( hRpc ); // raises exception if not
*prpcstat = 0; // we got here so we are OK
CProcess *pProcess = ReferenceProcess( phProcess, TRUE );
if ( ! pProcess ) return E_ACCESSDENIED;
ScmProcessReg *pScmProcessReg = pProcess->GetProcessReg(); ASSERT(pScmProcessReg); if ( ! pScmProcessReg ) { ReleaseProcess( pProcess ); return E_UNEXPECTED; }
pScmProcessReg->TimeOfLastPing = GetTickCount();
ReleaseProcess( pProcess ); return S_OK; }
HRESULT ProcessActivatorReady( IN handle_t hRpc, IN PHPROCESS phProcess, OUT error_status_t *prpcstat) { CheckLocalCall( hRpc ); // raises exception if not
*prpcstat = 0; // we got here so we are OK
CProcess *pProcess = ReferenceProcess( phProcess, TRUE ); if ( ! pProcess ) return E_ACCESSDENIED;
HRESULT hr; if (pProcess->IsInitializing()) { // Process was running user initializaiton code,
// so signal that we've finished with that.
hr = ProcessInitializationFinished(pProcess); } else { // Normal case-- simply mark the process as
// ready-to-go.
hr = MakeProcessActive(pProcess); }
if (pProcess) ReleaseProcess( pProcess );
return hr; }
HRESULT ProcessActivatorStopped( IN handle_t hRpc, IN PHPROCESS phProcess, OUT error_status_t *prpcstat) { CheckLocalCall( hRpc ); // raises exception if not
*prpcstat = 0; // we got here so we are OK
CProcess *pProcess = ReferenceProcess( phProcess, TRUE );
if ( ! pProcess ) return E_ACCESSDENIED;
ScmProcessReg *pScmProcessReg = pProcess->RemoveProcessReg(); ASSERT(pScmProcessReg); if ( ! pScmProcessReg ) { ReleaseProcess( pProcess ); return E_UNEXPECTED; }
HRESULT hr = S_OK;
CServerTableEntry *pProcessEntry = gpProcessTable->Lookup( pScmProcessReg->ProcessGUID );
if ( !pProcessEntry ) { hr = E_UNEXPECTED; goto exit; }
pProcessEntry->RevokeServer( pScmProcessReg );
exit:
if (pScmProcessReg) delete pScmProcessReg; if (pProcessEntry) pProcessEntry->Release(); if (pProcess) ReleaseProcess( pProcess );
return hr; }
//
// ProcessActivatorPaused
//
// A process activator is telling us to turn on the "paused" bit
// for its process.
//
HRESULT ProcessActivatorPaused( IN handle_t hRpc, IN PHPROCESS phProcess, OUT error_status_t * prpcstat) { CheckLocalCall( hRpc ); // raises exception if not
*prpcstat = 0; // we got here so we are OK
CProcess *pProcess = ReferenceProcess( phProcess, TRUE ); if ( ! pProcess ) return E_ACCESSDENIED;
pProcess->Pause();
ReleaseProcess(pProcess);
return S_OK; }
//
// ProcessActivatorResumed
//
// A process activator is telling us to turn off the "paused" bit
// for its process.
//
HRESULT ProcessActivatorResumed( IN handle_t hRpc, IN PHPROCESS phProcess, OUT error_status_t * prpcstat) { CheckLocalCall( hRpc ); // raises exception if not
*prpcstat = 0; // we got here so we are OK
CProcess *pProcess = ReferenceProcess( phProcess, TRUE ); if ( ! pProcess ) return E_ACCESSDENIED;
pProcess->Resume();
ReleaseProcess(pProcess);
return S_OK; }
//
// ProcessActivatorUserInitializing
//
// A process activator is telling us that it's running long-running
// code and that we might have to wait for a long time on it.
//
HRESULT ProcessActivatorUserInitializing( IN handle_t hRpc, IN PHPROCESS phProcess, OUT error_status_t * prpcstat) { CheckLocalCall( hRpc ); // raises exception if not
*prpcstat = 0; // we got here so we are OK
CProcess *pProcess = ReferenceProcess( phProcess, TRUE ); if ( ! pProcess ) return E_ACCESSDENIED; //
// Make this process active, but mark it as initializing so that
// attempts to call into it will block...
//
pProcess->BeginInit(); HRESULT hr = MakeProcessActive(pProcess);
ReleaseProcess( pProcess ); return hr; }
HRESULT MakeProcessActive( IN CProcess *pProcess ) { CServerTableEntry *pProcessEntry = NULL; CAppidData *pAppidData = NULL; HANDLE hRegisterEvent = NULL; HRESULT hr = S_OK;
ScmProcessReg *pScmProcessReg = pProcess->GetProcessReg(); ASSERT(pScmProcessReg); if ( !pScmProcessReg ) return E_UNEXPECTED; pProcessEntry = gpProcessTable->Lookup( pScmProcessReg->ProcessGUID ); if ( !pProcessEntry ) { hr = E_UNEXPECTED; goto exit; }
pProcessEntry->UnsuspendServer( pScmProcessReg->RegistrationToken );
// Lookup an appiddata, from which we will get the register event
hr = LookupAppidData(pScmProcessReg->ProcessGUID, pProcess->GetToken(), pScmProcessReg->AppIDFlags, &pAppidData); if (FAILED(hr)) goto exit;
Win4Assert(pAppidData && "LookupAppidData returned NULL AppidData");
hRegisterEvent = pAppidData->ServerRegisterEvent(); if ( hRegisterEvent ) { SetEvent( hRegisterEvent ); CloseHandle( hRegisterEvent ); pProcess->SetProcessReadyState(SERVERSTATE_READY); } else { hr = E_OUTOFMEMORY; goto exit; }
exit: if ( FAILED(hr) && pProcess && pProcessEntry ) pProcessEntry->RevokeServer( pScmProcessReg );
if (pProcessEntry) pProcessEntry->Release(); if (pAppidData) delete pAppidData;
return hr; }
HRESULT ProcessInitializationFinished( IN CProcess *pProcess ) { CAppidData *pAppidData = NULL;
ScmProcessReg *pScmProcessReg = pProcess->GetProcessReg(); ASSERT(pScmProcessReg); if ( !pScmProcessReg ) return E_UNEXPECTED;
// Initialization is finished... set the initialization event...
HRESULT hr = LookupAppidData(pScmProcessReg->ProcessGUID, pProcess->GetToken(), pScmProcessReg->AppIDFlags, &pAppidData ); if (FAILED(hr)) goto exit; // Signal the initialized event.
HANDLE hInitializedEvent = pAppidData->ServerInitializedEvent(); if (!hInitializedEvent) { hr = E_OUTOFMEMORY; goto exit; }
// The order of the following is important:
//
// Clear the initializing flag...
pProcess->EndInit(); // Set the initialized event...
SetEvent(hInitializedEvent); CloseHandle(hInitializedEvent); hr = S_OK; exit: delete pAppidData;
return hr; }
|