Leaked source code of windows server 2003
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.

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