Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

396 lines
9.6 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // activate.cxx
  7. //
  8. // Main dcom activation service routines.
  9. //
  10. //--------------------------------------------------------------------------
  11. #include "act.hxx"
  12. HRESULT MakeProcessActive(CProcess *pProcess);
  13. HRESULT ProcessInitializationFinished(CProcess *pProcess);
  14. HRESULT ProcessActivatorStarted(
  15. IN handle_t hRpc,
  16. IN PHPROCESS phProcess,
  17. IN ProcessActivatorToken *pActToken,
  18. OUT error_status_t *prpcstat)
  19. {
  20. CheckLocalCall( hRpc ); // raises exception if not
  21. *prpcstat = 0; // we got here so we are OK
  22. CProcess *pProcess = ReferenceProcess( phProcess, TRUE );
  23. if ( ! pProcess )
  24. return E_ACCESSDENIED;
  25. HRESULT hr = S_OK;
  26. CServerTableEntry *pProcessEntry = NULL;
  27. CAppidData *pAppidData = NULL;
  28. ScmProcessReg *pScmProcessReg = NULL;
  29. DWORD RegistrationToken = 0;
  30. BOOL fCallerOK = FALSE;
  31. DWORD AppIDFlags = 0;
  32. // Lookup appid info from appropriate registry side
  33. #if defined(_WIN64)
  34. AppIDFlags = pProcess->Is64Bit() ? CAT_REG64_ONLY : CAT_REG32_ONLY;
  35. #endif
  36. hr = LookupAppidData(
  37. pActToken->ProcessGUID,
  38. pProcess->GetToken(),
  39. AppIDFlags,
  40. &pAppidData );
  41. if (FAILED(hr))
  42. {
  43. goto exit;
  44. }
  45. Win4Assert(pAppidData && "LookupAppidData returned NULL AppidData");
  46. //
  47. // Check that the caller is allowed to register this CLSID.
  48. //
  49. fCallerOK = pAppidData->CertifyServer(pProcess);
  50. if (!fCallerOK)
  51. {
  52. hr = CO_E_WRONG_SERVER_IDENTITY;
  53. goto exit;
  54. }
  55. pProcessEntry = gpProcessTable->GetOrCreate( pActToken->ProcessGUID );
  56. if ( ! pProcessEntry )
  57. {
  58. hr = E_UNEXPECTED;
  59. goto exit;
  60. }
  61. pScmProcessReg = new ScmProcessReg;
  62. if (!pScmProcessReg)
  63. {
  64. hr = E_OUTOFMEMORY;
  65. goto exit;
  66. }
  67. pScmProcessReg->TimeOfLastPing = GetTickCount();
  68. pScmProcessReg->ProcessGUID = pActToken->ProcessGUID;
  69. pScmProcessReg->ReadinessStatus = SERVERSTATE_SUSPENDED;
  70. pScmProcessReg->AppIDFlags = AppIDFlags;
  71. pProcess->SetProcessReg(pScmProcessReg);
  72. hr = pProcessEntry->RegisterServer(
  73. pProcess,
  74. pActToken->ActivatorIPID,
  75. NULL,
  76. pAppidData,
  77. SERVERSTATE_SUSPENDED,
  78. &RegistrationToken );
  79. pScmProcessReg->RegistrationToken = RegistrationToken;
  80. exit:
  81. if (pProcessEntry) pProcessEntry->Release();
  82. if (pProcess) ReleaseProcess( pProcess );
  83. if (pAppidData) delete pAppidData;
  84. return hr;
  85. }
  86. HRESULT ProcessActivatorInitializing(
  87. IN handle_t hRpc,
  88. IN PHPROCESS phProcess,
  89. OUT error_status_t *prpcstat)
  90. {
  91. CheckLocalCall( hRpc ); // raises exception if not
  92. *prpcstat = 0; // we got here so we are OK
  93. CProcess *pProcess = ReferenceProcess( phProcess, TRUE );
  94. if ( ! pProcess )
  95. return E_ACCESSDENIED;
  96. ScmProcessReg *pScmProcessReg = pProcess->GetProcessReg();
  97. ASSERT(pScmProcessReg);
  98. if ( ! pScmProcessReg )
  99. {
  100. ReleaseProcess( pProcess );
  101. return E_UNEXPECTED;
  102. }
  103. pScmProcessReg->TimeOfLastPing = GetTickCount();
  104. ReleaseProcess( pProcess );
  105. return S_OK;
  106. }
  107. HRESULT ProcessActivatorReady(
  108. IN handle_t hRpc,
  109. IN PHPROCESS phProcess,
  110. OUT error_status_t *prpcstat)
  111. {
  112. CheckLocalCall( hRpc ); // raises exception if not
  113. *prpcstat = 0; // we got here so we are OK
  114. CProcess *pProcess = ReferenceProcess( phProcess, TRUE );
  115. if ( ! pProcess )
  116. return E_ACCESSDENIED;
  117. HRESULT hr;
  118. if (pProcess->IsInitializing())
  119. {
  120. // Process was running user initializaiton code,
  121. // so signal that we've finished with that.
  122. hr = ProcessInitializationFinished(pProcess);
  123. }
  124. else
  125. {
  126. // Normal case-- simply mark the process as
  127. // ready-to-go.
  128. hr = MakeProcessActive(pProcess);
  129. }
  130. if (pProcess) ReleaseProcess( pProcess );
  131. return hr;
  132. }
  133. HRESULT ProcessActivatorStopped(
  134. IN handle_t hRpc,
  135. IN PHPROCESS phProcess,
  136. OUT error_status_t *prpcstat)
  137. {
  138. CheckLocalCall( hRpc ); // raises exception if not
  139. *prpcstat = 0; // we got here so we are OK
  140. CProcess *pProcess = ReferenceProcess( phProcess, TRUE );
  141. if ( ! pProcess )
  142. return E_ACCESSDENIED;
  143. ScmProcessReg *pScmProcessReg = pProcess->RemoveProcessReg();
  144. ASSERT(pScmProcessReg);
  145. if ( ! pScmProcessReg )
  146. {
  147. ReleaseProcess( pProcess );
  148. return E_UNEXPECTED;
  149. }
  150. HRESULT hr = S_OK;
  151. CServerTableEntry *pProcessEntry
  152. = gpProcessTable->Lookup( pScmProcessReg->ProcessGUID );
  153. if ( !pProcessEntry )
  154. {
  155. hr = E_UNEXPECTED;
  156. goto exit;
  157. }
  158. pProcessEntry->RevokeServer( pScmProcessReg );
  159. exit:
  160. if (pScmProcessReg) delete pScmProcessReg;
  161. if (pProcessEntry) pProcessEntry->Release();
  162. if (pProcess) ReleaseProcess( pProcess );
  163. return hr;
  164. }
  165. //
  166. // ProcessActivatorPaused
  167. //
  168. // A process activator is telling us to turn on the "paused" bit
  169. // for its process.
  170. //
  171. HRESULT ProcessActivatorPaused(
  172. IN handle_t hRpc,
  173. IN PHPROCESS phProcess,
  174. OUT error_status_t * prpcstat)
  175. {
  176. CheckLocalCall( hRpc ); // raises exception if not
  177. *prpcstat = 0; // we got here so we are OK
  178. CProcess *pProcess = ReferenceProcess( phProcess, TRUE );
  179. if ( ! pProcess )
  180. return E_ACCESSDENIED;
  181. pProcess->Pause();
  182. ReleaseProcess(pProcess);
  183. return S_OK;
  184. }
  185. //
  186. // ProcessActivatorResumed
  187. //
  188. // A process activator is telling us to turn off the "paused" bit
  189. // for its process.
  190. //
  191. HRESULT ProcessActivatorResumed(
  192. IN handle_t hRpc,
  193. IN PHPROCESS phProcess,
  194. OUT error_status_t * prpcstat)
  195. {
  196. CheckLocalCall( hRpc ); // raises exception if not
  197. *prpcstat = 0; // we got here so we are OK
  198. CProcess *pProcess = ReferenceProcess( phProcess, TRUE );
  199. if ( ! pProcess )
  200. return E_ACCESSDENIED;
  201. pProcess->Resume();
  202. ReleaseProcess(pProcess);
  203. return S_OK;
  204. }
  205. //
  206. // ProcessActivatorUserInitializing
  207. //
  208. // A process activator is telling us that it's running long-running
  209. // code and that we might have to wait for a long time on it.
  210. //
  211. HRESULT ProcessActivatorUserInitializing(
  212. IN handle_t hRpc,
  213. IN PHPROCESS phProcess,
  214. OUT error_status_t * prpcstat)
  215. {
  216. CheckLocalCall( hRpc ); // raises exception if not
  217. *prpcstat = 0; // we got here so we are OK
  218. CProcess *pProcess = ReferenceProcess( phProcess, TRUE );
  219. if ( ! pProcess )
  220. return E_ACCESSDENIED;
  221. //
  222. // Make this process active, but mark it as initializing so that
  223. // attempts to call into it will block...
  224. //
  225. pProcess->BeginInit();
  226. HRESULT hr = MakeProcessActive(pProcess);
  227. ReleaseProcess( pProcess );
  228. return hr;
  229. }
  230. HRESULT MakeProcessActive(
  231. IN CProcess *pProcess
  232. )
  233. {
  234. CServerTableEntry *pProcessEntry = NULL;
  235. CAppidData *pAppidData = NULL;
  236. HANDLE hRegisterEvent = NULL;
  237. HRESULT hr = S_OK;
  238. ScmProcessReg *pScmProcessReg = pProcess->GetProcessReg();
  239. ASSERT(pScmProcessReg);
  240. if ( !pScmProcessReg )
  241. return E_UNEXPECTED;
  242. pProcessEntry = gpProcessTable->Lookup( pScmProcessReg->ProcessGUID );
  243. if ( !pProcessEntry )
  244. {
  245. hr = E_UNEXPECTED;
  246. goto exit;
  247. }
  248. pProcessEntry->UnsuspendServer( pScmProcessReg->RegistrationToken );
  249. // Lookup an appiddata, from which we will get the register event
  250. hr = LookupAppidData(pScmProcessReg->ProcessGUID,
  251. pProcess->GetToken(),
  252. pScmProcessReg->AppIDFlags,
  253. &pAppidData);
  254. if (FAILED(hr))
  255. goto exit;
  256. Win4Assert(pAppidData && "LookupAppidData returned NULL AppidData");
  257. hRegisterEvent = pAppidData->ServerRegisterEvent();
  258. if ( hRegisterEvent )
  259. {
  260. SetEvent( hRegisterEvent );
  261. CloseHandle( hRegisterEvent );
  262. pProcess->SetProcessReadyState(SERVERSTATE_READY);
  263. }
  264. else
  265. {
  266. hr = E_OUTOFMEMORY;
  267. goto exit;
  268. }
  269. exit:
  270. if ( FAILED(hr) && pProcess && pProcessEntry )
  271. pProcessEntry->RevokeServer( pScmProcessReg );
  272. if (pProcessEntry) pProcessEntry->Release();
  273. if (pAppidData) delete pAppidData;
  274. return hr;
  275. }
  276. HRESULT ProcessInitializationFinished(
  277. IN CProcess *pProcess
  278. )
  279. {
  280. CAppidData *pAppidData = NULL;
  281. ScmProcessReg *pScmProcessReg = pProcess->GetProcessReg();
  282. ASSERT(pScmProcessReg);
  283. if ( !pScmProcessReg )
  284. return E_UNEXPECTED;
  285. // Initialization is finished... set the initialization event...
  286. HRESULT hr = LookupAppidData(pScmProcessReg->ProcessGUID,
  287. pProcess->GetToken(),
  288. pScmProcessReg->AppIDFlags,
  289. &pAppidData );
  290. if (FAILED(hr))
  291. goto exit;
  292. // Signal the initialized event.
  293. HANDLE hInitializedEvent = pAppidData->ServerInitializedEvent();
  294. if (!hInitializedEvent)
  295. {
  296. hr = E_OUTOFMEMORY;
  297. goto exit;
  298. }
  299. // The order of the following is important:
  300. //
  301. // Clear the initializing flag...
  302. pProcess->EndInit();
  303. // Set the initialized event...
  304. SetEvent(hInitializedEvent);
  305. CloseHandle(hInitializedEvent);
  306. hr = S_OK;
  307. exit:
  308. delete pAppidData;
  309. return hr;
  310. }