//+------------------------------------------------------------------------- // // 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) { CProcess* pProcess = CheckLocalSecurity(hRpc, phProcess); if (!pProcess) return E_ACCESSDENIED; if (!prpcstat || !pActToken) return E_INVALIDARG; *prpcstat = 0; HRESULT hr = S_OK; CServerTableEntry *pProcessEntry = NULL; CAppidData *pAppidData = NULL; ScmProcessReg *pScmProcessReg = NULL; DWORD RegistrationToken = 0; BOOL fCallerOK = FALSE; // Lookup appid info hr = LookupAppidData( pActToken->ProcessGUID, pProcess->GetToken(), &pAppidData ); if (FAILED(hr)) { goto exit; } ASSERT(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; pProcess->SetProcessReg(pScmProcessReg); hr = pProcessEntry->RegisterServer( pProcess, pActToken->ActivatorIPID, NULL, pAppidData, SERVERSTATE_SUSPENDED, &RegistrationToken ); pScmProcessReg->RegistrationToken = RegistrationToken; exit: if (pProcessEntry) pProcessEntry->Release(); if (pAppidData) delete pAppidData; return hr; } HRESULT ProcessActivatorInitializing( IN handle_t hRpc, IN PHPROCESS phProcess, OUT error_status_t *prpcstat) { CProcess* pProcess = CheckLocalSecurity(hRpc, phProcess); if (!pProcess) return E_ACCESSDENIED; if (!prpcstat) return E_INVALIDARG; *prpcstat = 0; ScmProcessReg *pScmProcessReg = pProcess->GetProcessReg(); ASSERT(pScmProcessReg); if ( ! pScmProcessReg ) return E_UNEXPECTED; pScmProcessReg->TimeOfLastPing = GetTickCount(); return S_OK; } HRESULT ProcessActivatorReady( IN handle_t hRpc, IN PHPROCESS phProcess, OUT error_status_t *prpcstat) { CProcess* pProcess = CheckLocalSecurity(hRpc, phProcess); if (!pProcess) return E_ACCESSDENIED; if (!prpcstat) return E_INVALIDARG; *prpcstat = 0; 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); } return hr; } HRESULT ProcessActivatorStopped( IN handle_t hRpc, IN PHPROCESS phProcess, OUT error_status_t *prpcstat) { CProcess* pProcess = CheckLocalSecurity(hRpc, phProcess); if (!pProcess) return E_ACCESSDENIED; if (!prpcstat) return E_INVALIDARG; *prpcstat = 0; ScmProcessReg *pScmProcessReg = pProcess->RemoveProcessReg(); ASSERT(pScmProcessReg); if (!pScmProcessReg ) 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(); 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) { CProcess* pProcess = CheckLocalSecurity(hRpc, phProcess); if (!pProcess) return E_ACCESSDENIED; if (!prpcstat) return E_INVALIDARG; *prpcstat = 0; pProcess->Pause(); 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) { CProcess* pProcess = CheckLocalSecurity(hRpc, phProcess); if (!pProcess) return E_ACCESSDENIED; if (!prpcstat) return E_INVALIDARG; *prpcstat = 0; pProcess->Resume(); 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) { CProcess* pProcess = CheckLocalSecurity(hRpc, phProcess); if (!pProcess) return E_ACCESSDENIED; if (!prpcstat) return E_INVALIDARG; *prpcstat = 0; // // Make this process active, but mark it as initializing so that // attempts to call into it will block... // pProcess->BeginInit(); HRESULT hr = MakeProcessActive(pProcess); return hr; } HRESULT MakeProcessActive( IN CProcess *pProcess ) { CServerTableEntry *pProcessEntry = NULL; CAppidData *pAppidData = NULL; CNamedObject* pRegisterEvent = 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(), &pAppidData); if (FAILED(hr)) goto exit; ASSERT(pAppidData && "LookupAppidData returned NULL AppidData"); pRegisterEvent = pAppidData->ServerRegisterEvent(); if (pRegisterEvent) { SetEvent( pRegisterEvent->Handle() ); pRegisterEvent->Release(); 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(), &pAppidData ); if (FAILED(hr)) goto exit; // Signal the initialized event. CNamedObject* pInitializedEvent = pAppidData->ServerInitializedEvent(); if (!pInitializedEvent) { hr = E_OUTOFMEMORY; goto exit; } // The order of the following is important: // // Clear the initializing flag... pProcess->EndInit(); // Set the initialized event... SetEvent(pInitializedEvent->Handle()); pInitializedEvent->Release(); hr = S_OK; exit: delete pAppidData; return hr; }