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.

353 lines
11 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. Process.hxx
  5. Abstract:
  6. Process objects represent local clients and servers. These
  7. objects live as context handles.
  8. There are relativly few of these objects in the universe.
  9. Author:
  10. Mario Goertzel [MarioGo]
  11. Revision History:
  12. MarioGo 02-11-95 Bits 'n pieces
  13. MarioGo 01-06-96 Based on CReferencedObject
  14. Ronans 01-20-97 Added custom protseq array entries to CProcess
  15. TarunA 10-30-98 Added PID of the client process to CProcess
  16. --*/
  17. #ifndef __PROCESS_HXX
  18. #define __PROCESS_HXX
  19. typedef struct tagScmProcessRegistration {
  20. GUID ProcessGUID;
  21. DWORD RegistrationToken;
  22. DWORD ReadinessStatus;
  23. CTime TimeOfLastPing;
  24. DWORD AppIDFlags;
  25. } ScmProcessReg;
  26. void
  27. SCMRemoveRegistration(
  28. CProcess * pProcess,
  29. GUID & Guid,
  30. DWORD Reg
  31. );
  32. void
  33. SCMRemoveRegistration(
  34. ScmProcessReg * pScmProcessReg
  35. );
  36. void
  37. SCMProcessCleanup(
  38. const CProcess *pProcess
  39. );
  40. // forward decls
  41. class CClassReg;
  42. class CSCMProcessControl;
  43. // bit flags for _dwFlags of CProcess
  44. typedef enum tagPROCESSFLAGS
  45. {
  46. PROCESS_SUSPENDED = 0x0000001, // process is suspended for all activations
  47. PROCESS_RETIRED = 0x0000002, // process is retired (til it dies) for all activations
  48. PROCESS_SPI_DIRTY = 0x0000004, // process state has changed since last SCMProcessInfo was cached
  49. PROCESS_RUNDOWN = 0x0000008, // process has been rundown
  50. PROCESS_PAUSED = 0x0000010, // process has been paused
  51. PROCESS_64BIT = 0x0000020, // process is 64 bit
  52. PROCESS_NEEDSBINDINGS = 0x0000040, // process needs current OR bindings at first opportunity
  53. PROCESS_INITIALIZING = 0x0000080 // process is currently running long-running init code
  54. } PROCESSFLAGS;
  55. // Note on above flags: PROCESS_SUSPENDED and PROCESS_PAUSED look suspiciously identical; why
  56. // keep both? The basic reason is that the a process may only be suspended by a custom activator
  57. // (or the SCM itself, if it so decides), and that a process may only be paused by the process
  58. // itself (which in current usage means in response to a user action). We keep both flags in
  59. // order to tell the difference; certain scenarios (com+ process pooling/recycling) need the
  60. // ability to discriminate between the two cases.
  61. class CProcess : public CReferencedObject
  62. /*++
  63. Class Description:
  64. An instance of this class is created for each process
  65. using the OR as either a client or server.
  66. The process object is referenced by server OXIDs and has
  67. one implicit reference by the actual process (which is
  68. dereferenced during the context rundown). Instances of
  69. these objects are managed by the RPC runtime as context
  70. handles.
  71. Members:
  72. _pToken - A pointer to the CToken instance of the process.
  73. _csCallbackLock - use to serialize callback to LazyUseProtseq
  74. _hProcess - An RPC binding handle back to the process.
  75. _pdsaLocalBindings - The string bindings of the process, including
  76. local only protseqs
  77. _pdsaRemoteBindings - A subset of _pdsaLocalBindings not containing
  78. any local-only protseqs
  79. _blistOxids - A CBList containing pointers to the CServerOxid's
  80. owned by this process, if any.
  81. _blistOids - A CBList of pointers to CClientOid's which this
  82. process is using and referencing, if any.
  83. _listClasses - A CBList of registration handles for classes that
  84. a server process has registered.
  85. _fReadCustomProtseqs - a flag to indicate if the server has been queried
  86. for custom protseq and endpoints (specific to the server)
  87. _pcpaCustomProtseqs - a pointer to a counted array of custom protseqs
  88. _dwFlags -- state bits for this process
  89. _pSCMProcessInfo -- pointer to the current SCMProcessInfo struct for ourself
  90. _ftCreated - the filetime that this object was created.
  91. --*/
  92. {
  93. friend CSCMProcessControl;
  94. private:
  95. DWORD _cClientReferences;
  96. CToken *_pToken;
  97. WCHAR *_pwszWinstaDesktop;
  98. RPC_BINDING_HANDLE _hProcess;
  99. BOOL _fCacheFree;
  100. DUALSTRINGARRAY *_pdsaLocalBindings;
  101. DUALSTRINGARRAY *_pdsaRemoteBindings;
  102. ULONG _ulClasses;
  103. ScmProcessReg *_pScmProcessReg;
  104. DUALSTRINGARRAY *_pdsaCustomProtseqs;
  105. void *_pvRunAsHandle;
  106. DWORD _procID;
  107. DWORD _dwFlags;
  108. void* _pSCMProcessInfo;
  109. GUID _guidProcessIdentifier;
  110. HANDLE _hProcHandle;
  111. FILETIME _ftCreated;
  112. DWORD64 _dwCurrentBindingsID;
  113. DWORD _dwAsyncUpdatesOutstanding; // for debug purposes?
  114. CRITICAL_SECTION _csCallbackLock;
  115. BOOL _fLockValid:1;
  116. BOOL _fReadCustomProtseqs : 1;
  117. CBList _blistOxids;
  118. CBList _blistOids;
  119. CList _listClasses;
  120. #if DBG
  121. // Debug members used to monitor and track rundown callbacks
  122. ULONG _cRundowns;
  123. CTime _timeFirstRundown;
  124. #endif
  125. void EnsureRealBinding();
  126. RPC_BINDING_HANDLE AllocateBinding();
  127. void FreeBinding(RPC_BINDING_HANDLE);
  128. static
  129. void RPC_ENTRY AsyncRpcNotification(RPC_ASYNC_STATE* pAsync,
  130. void* pContext,
  131. RPC_ASYNC_EVENT Event);
  132. void BindingsUpdateNotify(RPC_BINDING_HANDLE hBinding,
  133. DWORD64 dwBindingsID,
  134. DUALSTRINGARRAY* pdsaNewBindings,
  135. DUALSTRINGARRAY* pdsaSecBindings);
  136. static
  137. void RPC_ENTRY AsyncRundownReturnNotification(RPC_ASYNC_STATE* pAsync,
  138. void* pContext,
  139. RPC_ASYNC_EVENT Event);
  140. void RundownOidNotify(RPC_BINDING_HANDLE hBinding,
  141. CServerOxid* pOwningOxid,
  142. ULONG cOids,
  143. CServerOid* aOids[],
  144. BYTE aRundownStatus[],
  145. HRESULT hrReturn);
  146. public:
  147. CProcess(IN CToken*& pToken,
  148. IN WCHAR *pwszWinstaDesktop,
  149. IN DWORD procID,
  150. IN DWORD dwFlags,
  151. OUT ORSTATUS &status);
  152. ~CProcess();
  153. RPC_STATUS ProcessBindings(DUALSTRINGARRAY *,
  154. DUALSTRINGARRAY *);
  155. DUALSTRINGARRAY *GetLocalBindings(void);
  156. DUALSTRINGARRAY *GetRemoteBindings(void);
  157. RPC_BINDING_HANDLE GetBindingHandle(void);
  158. ORSTATUS AddOxid(CServerOxid *);
  159. BOOL RemoveOxid(CServerOxid *);
  160. ORSTATUS AddRemoteOxid(CClientOxid *);
  161. void RemoveRemoteOxid(CClientOxid *);
  162. BOOL IsOwner(CServerOxid *);
  163. ORSTATUS AddOid(CClientOid *);
  164. CClientOid *RemoveOid(CClientOid *);
  165. // These are methods to record per-class SCM registrations
  166. // in traditional local servers and services
  167. void AddClassReg(GUID & Guid, DWORD Reg);
  168. void RemoveClassReg(DWORD Reg);
  169. void RevokeClassRegs();
  170. // These are methods to record per-process SCM registration info
  171. // for the new COM+ unified surrogate for startup, shutdown and rundown
  172. void SetProcessReg(ScmProcessReg *pProcessReg);
  173. ScmProcessReg* GetProcessReg();
  174. ScmProcessReg* RemoveProcessReg();
  175. void RevokeProcessReg();
  176. void SetProcessReadyState(DWORD dwState);
  177. RPC_STATUS RundownOids(CServerOxid* pOwningOxid, ULONG cOids, CServerOid* aOids[]);
  178. ORSTATUS UseProtseqIfNeeded(USHORT cClientProtseqs, USHORT aProtseqs[]);
  179. ORSTATUS UpdateResolverBindings(DWORD64 dwBindingsID, DUALSTRINGARRAY* pdsaResolverBindings);
  180. void Rundown();
  181. CToken *GetToken() {
  182. return(_pToken);
  183. }
  184. WCHAR *WinstaDesktop() {
  185. return(_pwszWinstaDesktop);
  186. }
  187. void ClientReference() {
  188. InterlockedIncrement((PLONG)&_cClientReferences);
  189. }
  190. DWORD ClientRelease()
  191. {
  192. return InterlockedDecrement((PLONG)&_cClientReferences);
  193. }
  194. DWORD GetPID() { return _procID; }
  195. void SetRunAsHandle(void *pvRunAsHandle);
  196. HANDLE GetProcessHandle()
  197. {
  198. return _hProcHandle;
  199. }
  200. BOOL SetProcessHandle(HANDLE hProcHandle, DWORD dwLaunchedPID);
  201. GUID* GetGuidProcessIdentifier() { return &_guidProcessIdentifier; };
  202. void Cleanup();
  203. // Not sure yet if (un)suspending an already (un)suspended process
  204. // is a valid or possible thing to do. Assert on these two cases.
  205. void Suspend() { ASSERT(!IsSuspended()); _dwFlags |= (PROCESS_SUSPENDED | PROCESS_SPI_DIRTY); }
  206. void Unsuspend() { ASSERT(IsSuspended()); _dwFlags &= ~PROCESS_SUSPENDED; _dwFlags |= PROCESS_SPI_DIRTY; }
  207. BOOL IsSuspended() { return (_dwFlags & PROCESS_SUSPENDED); }
  208. // Note: no accessor method provided to "un-retire" a process.
  209. void Retire();
  210. BOOL IsRetired() { return (_dwFlags & PROCESS_RETIRED); }
  211. void Pause() { ASSERT(!IsPaused()); _dwFlags |= (PROCESS_PAUSED | PROCESS_SPI_DIRTY); }
  212. void Resume() { ASSERT(IsPaused()); _dwFlags &= ~PROCESS_PAUSED; _dwFlags |= PROCESS_SPI_DIRTY; }
  213. BOOL IsPaused() { return (_dwFlags & PROCESS_PAUSED); }
  214. void BeginInit() { _dwFlags |= (PROCESS_INITIALIZING | PROCESS_SPI_DIRTY); }
  215. void EndInit() { _dwFlags &= ~PROCESS_INITIALIZING; _dwFlags |= PROCESS_SPI_DIRTY; }
  216. BOOL IsInitializing() { return (_dwFlags & PROCESS_INITIALIZING); }
  217. // Although we track the paused bit for the benefit of any custom activators that might care about
  218. // it, it does not influence our choice of servers. So if two potential servers are running, and
  219. // one is paused, then to the scm both appear equally suitable. We have to do it this way to
  220. // support various com+ scenarios.
  221. BOOL AvailableForActivations() { return !(_dwFlags & (PROCESS_SUSPENDED | PROCESS_RETIRED)); }
  222. // Returns TRUE if this process needs updated bindings.
  223. BOOL NeedsORBindings() { return _dwFlags & PROCESS_NEEDSBINDINGS; };
  224. void BindingsUpdated() { _dwFlags &= ~PROCESS_NEEDSBINDINGS; };
  225. const FILETIME* GetFileTimeCreated() { return &_ftCreated; }
  226. BOOL SPIDirty() { return _dwFlags & PROCESS_SPI_DIRTY; }
  227. HRESULT SetSCMProcessInfo(void* pSPI);
  228. void* GetSCMProcessInfo()
  229. {
  230. //ASSERT(gpServerLock->HeldSharedOrExclusive();
  231. // should not be called unless we are not not dirty
  232. ASSERT(_pSCMProcessInfo && !(_dwFlags & (PROCESS_SPI_DIRTY | PROCESS_RUNDOWN)));
  233. return _pSCMProcessInfo;
  234. };
  235. BOOL Is64Bit() { return (_dwFlags & PROCESS_64BIT); };
  236. };
  237. class CClassReg : public CListElement
  238. {
  239. public :
  240. GUID _Guid;
  241. DWORD _Reg;
  242. CClassReg( GUID & Guid, DWORD reg ) : _Guid(Guid), _Reg(reg) {}
  243. };
  244. extern CRITICAL_SECTION gcsFastProcessLock;
  245. extern CBList *gpProcessList;
  246. extern CSharedLock* gpProcessListLock;
  247. CProcess *ReferenceProcess(PVOID key, BOOL fNotContext = FALSE);
  248. void ReleaseProcess(CProcess *pProcess);
  249. #endif // __PROCESS_HXX