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.

539 lines
11 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. wam_process.hxx
  5. Abstract:
  6. WAM process management for ISAPI
  7. Author:
  8. Wade Hilmo (wadeh) 10-Oct-2000
  9. Revision History:
  10. --*/
  11. #ifndef _WAM_PROCESS_HXX_
  12. #define _WAM_PROCESS_HXX_
  13. #include "precomp.hxx"
  14. #include <w3isapi.h>
  15. #include "isapi_request.hxx"
  16. #include "iwam.h"
  17. #include <comadmin.h>
  18. #define POOL_WAM_CLSID L"{99169CB1-A707-11d0-989D-00C04FD919C1}"
  19. #define DEFAULT_RECOVER_LIMIT 5
  20. #define MAX_MESSAGE_TEXT 2048
  21. class ISAPI_REQUEST;
  22. class WAM_PROCESS_MANAGER;
  23. class WAM_CRASH_RECORD
  24. {
  25. public:
  26. WCHAR szClsid[SIZE_CLSID_STRING];
  27. DWORD dwNumCrashes;
  28. LIST_ENTRY leCrashHistory;
  29. WAM_CRASH_RECORD()
  30. : dwNumCrashes( 0 )
  31. {
  32. InitializeListHead( &leCrashHistory );
  33. }
  34. };
  35. class WAM_PROCESS
  36. {
  37. public:
  38. WAM_PROCESS(
  39. LPCWSTR szWamClsid,
  40. WAM_PROCESS_MANAGER * pWamProcessManager,
  41. LPCSTR szIsapiHandlerInstance
  42. );
  43. HRESULT WAM_PROCESS::Create(
  44. LPCWSTR szApplMdPathW
  45. );
  46. LONG AddRef()
  47. {
  48. return InterlockedIncrement( &_cRefs );
  49. }
  50. LONG Release()
  51. {
  52. LONG lRet;
  53. lRet = InterlockedDecrement( &_cRefs );
  54. if ( lRet == 0 )
  55. {
  56. delete this;
  57. }
  58. return lRet;
  59. }
  60. HRESULT ProcessRequest(
  61. ISAPI_REQUEST * pIsapiRequest,
  62. ISAPI_CORE_DATA * pIsapiCoreData,
  63. DWORD * pdwHseResult
  64. );
  65. HRESULT ProcessCompletion(
  66. ISAPI_REQUEST * pIsapiRequest,
  67. DWORD64 IsapiContext,
  68. DWORD cbCompletion,
  69. DWORD dwCompletionStatus
  70. );
  71. VOID DecrementRequestCount(
  72. VOID
  73. );
  74. VOID HandleCrash(
  75. VOID
  76. );
  77. HRESULT Disable(
  78. BOOL fRemoveFromProcessHash = TRUE
  79. );
  80. HRESULT CleanupRequests(
  81. DWORD dwDrainTime
  82. );
  83. HRESULT Shutdown(
  84. VOID
  85. );
  86. HRESULT Unload(
  87. DWORD dwDrainTime
  88. );
  89. LPCWSTR QueryClsid(
  90. VOID
  91. ) const
  92. {
  93. return _szWamClsid;
  94. }
  95. HANDLE QueryProcess(
  96. VOID
  97. )
  98. {
  99. return _hProcess;
  100. }
  101. BOOL QueryCrashed(
  102. VOID
  103. )
  104. {
  105. return _fCrashed;
  106. }
  107. HRESULT
  108. MarshalAsyncReadBuffer(
  109. DWORD64 pWamExecInfo,
  110. LPBYTE pBuffer,
  111. DWORD cbBuffer
  112. )
  113. {
  114. return _pIWam->WamMarshalAsyncReadBuffer( pWamExecInfo, pBuffer,
  115. cbBuffer );
  116. }
  117. VOID
  118. AddIsapiRequestToList(
  119. ISAPI_REQUEST * pIsapiRequest
  120. );
  121. VOID
  122. RemoveIsapiRequestFromList(
  123. ISAPI_REQUEST * pIsapiRequest
  124. );
  125. LIST_ENTRY _leProcess;
  126. private:
  127. VOID
  128. LockRequestList()
  129. {
  130. EnterCriticalSection( &_csRequestList );
  131. }
  132. VOID
  133. UnlockRequestList()
  134. {
  135. LeaveCriticalSection( &_csRequestList );
  136. }
  137. VOID
  138. DisconnectIsapiRequests(
  139. VOID
  140. );
  141. ~WAM_PROCESS();
  142. WCHAR _szWamClsid[SIZE_CLSID_STRING];
  143. CHAR _szIsapiHandlerInstance[SIZE_CLSID_STRING];
  144. LONG _cRefs;
  145. LONG _cCurrentRequests;
  146. LONG _cTotalRequests;
  147. LONG _cMaxRequests;
  148. IWam * _pIWam;
  149. LIST_ENTRY _RequestListHead;
  150. CRITICAL_SECTION _csRequestList;
  151. WAM_PROCESS_MANAGER * _pWamProcessManager;
  152. DWORD _dwProcessId;
  153. BSTR _bstrInstanceId;
  154. HANDLE _hProcess;
  155. LONG _fGoingAway;
  156. STRU _strApplMdPathW;
  157. BOOL _fCrashed;
  158. };
  159. class WAM_PROCESS_HASH
  160. : public CTypedHashTable<
  161. WAM_PROCESS_HASH,
  162. WAM_PROCESS,
  163. LPCWSTR >
  164. {
  165. public:
  166. WAM_PROCESS_HASH()
  167. : CTypedHashTable< WAM_PROCESS_HASH,
  168. WAM_PROCESS,
  169. LPCWSTR > ( "WAM_PROCESS_HASH" )
  170. {
  171. }
  172. static
  173. LPCWSTR
  174. ExtractKey(
  175. const WAM_PROCESS * pWamProcess
  176. )
  177. {
  178. return pWamProcess->QueryClsid();
  179. }
  180. static
  181. DWORD
  182. CalcKeyHash(
  183. LPCWSTR szKey
  184. )
  185. {
  186. int cchKey = (int)wcslen( szKey );
  187. return HashStringNoCase( szKey, cchKey );
  188. }
  189. static
  190. bool
  191. EqualKeys(
  192. LPCWSTR szKey1,
  193. LPCWSTR szKey2
  194. )
  195. {
  196. return _wcsicmp( szKey1, szKey2 ) == 0;
  197. }
  198. static
  199. void
  200. AddRefRecord(
  201. WAM_PROCESS * pEntry,
  202. int nIncr
  203. )
  204. {
  205. if ( nIncr == +1 )
  206. {
  207. pEntry->AddRef();
  208. }
  209. else if ( nIncr == -1 )
  210. {
  211. pEntry->Release();
  212. }
  213. }
  214. private:
  215. //
  216. // Avoid c++ errors
  217. //
  218. WAM_PROCESS_HASH( const WAM_PROCESS_HASH & )
  219. : CTypedHashTable< WAM_PROCESS_HASH,
  220. WAM_PROCESS,
  221. LPCWSTR > ( "WAM_PROCESS_HASH" )
  222. {
  223. }
  224. WAM_PROCESS_HASH & operator = ( const WAM_PROCESS_HASH & ) { return *this; }
  225. };
  226. class WAM_APP_INFO
  227. {
  228. public:
  229. WAM_APP_INFO(
  230. LPWSTR szAppPath,
  231. LPWSTR szClsid,
  232. DWORD dwAppIsolated
  233. )
  234. : _cRefs( 1 ),
  235. _dwAppIsolated( dwAppIsolated )
  236. {
  237. wcsncpy( _szAppPath, szAppPath, MAX_PATH );
  238. wcsncpy( _szClsid, szClsid, SIZE_CLSID_STRING );
  239. }
  240. VOID
  241. AddRef(
  242. VOID
  243. )
  244. {
  245. InterlockedIncrement( &_cRefs );
  246. }
  247. VOID
  248. Release(
  249. VOID
  250. )
  251. {
  252. LONG cRefs;
  253. cRefs = InterlockedDecrement( &_cRefs );
  254. if ( cRefs == 0 )
  255. {
  256. delete this;
  257. }
  258. }
  259. DWORD _dwAppIsolated;
  260. WCHAR _szClsid[SIZE_CLSID_STRING];
  261. WCHAR _szAppPath[MAX_PATH];
  262. DWORD _dwAppOopRecoverLimit;
  263. private:
  264. LONG _cRefs;
  265. };
  266. class WAM_PROCESS_MANAGER
  267. {
  268. public:
  269. WAM_PROCESS_MANAGER( LPWSTR szIsapiModule )
  270. : _cRefs( 1 ),
  271. _pCatalog( NULL )
  272. {
  273. DBG_ASSERT( szIsapiModule );
  274. INITIALIZE_CRITICAL_SECTION( &_csWamHashLock );
  275. INITIALIZE_CRITICAL_SECTION( &_csCrashHistoryLock );
  276. InitializeListHead( &_CrashHistoryList );
  277. wcsncpy( _szIsapiModule, szIsapiModule, MAX_PATH );
  278. }
  279. HRESULT
  280. WAM_PROCESS_MANAGER::Create(
  281. VOID
  282. );
  283. HRESULT
  284. GetWamProcess(
  285. LPCWSTR szWamClsid,
  286. LPCWSTR szApplMdPathW,
  287. DWORD * pdwWamSubError,
  288. WAM_PROCESS ** ppWamProcess,
  289. LPCSTR szIsapiHandlerInstance
  290. );
  291. HRESULT
  292. GetWamProcessInfo(
  293. LPCWSTR szAppPath,
  294. WAM_APP_INFO ** ppWamAppInfo,
  295. BOOL * pfIsLoaded
  296. );
  297. HRESULT
  298. RemoveWamProcessFromHash(
  299. WAM_PROCESS * pWamProcess
  300. );
  301. static
  302. LK_PREDICATE
  303. UnloadWamProcess(
  304. WAM_PROCESS * pWamProcess,
  305. void * pvState
  306. );
  307. HRESULT
  308. Shutdown(
  309. VOID
  310. );
  311. ICOMAdminCatalog2 *
  312. QueryCatalog(
  313. VOID
  314. )
  315. {
  316. return _pCatalog;
  317. }
  318. VOID
  319. LockWamProcessHash()
  320. {
  321. EnterCriticalSection( &_csWamHashLock );
  322. }
  323. VOID
  324. UnlockWamProcessHash()
  325. {
  326. LeaveCriticalSection( &_csWamHashLock );
  327. }
  328. LONG AddRef()
  329. {
  330. return InterlockedIncrement( &_cRefs );
  331. }
  332. LONG Release()
  333. {
  334. LONG cRefs = InterlockedDecrement( &_cRefs );
  335. if ( cRefs == 0 )
  336. {
  337. delete this;
  338. return 0;
  339. }
  340. return cRefs;
  341. }
  342. LPWSTR
  343. QueryIsapiModule(
  344. VOID
  345. )
  346. {
  347. DBG_ASSERT( _szIsapiModule[0] != L'\0' );
  348. return _szIsapiModule;
  349. }
  350. VOID
  351. RegisterCrash(
  352. LPCWSTR szWamClsid
  353. );
  354. HRESULT
  355. QueryCrashHistory(
  356. LPCWSTR szWamClsid,
  357. DWORD * pdwNumCrashes
  358. );
  359. private:
  360. //
  361. // Avoid c++ errors
  362. //
  363. WAM_PROCESS_MANAGER( const WAM_PROCESS_MANAGER & ) {}
  364. WAM_PROCESS_MANAGER & operator = ( const WAM_PROCESS_MANAGER & ) { return *this; }
  365. ~WAM_PROCESS_MANAGER()
  366. {
  367. LIST_ENTRY * pleTemp;
  368. WAM_CRASH_RECORD * pWamCrashRecord;
  369. //
  370. // Delete the WAM crash history. It's not necessary
  371. // to lock the list because if WAM_PROCESS_MANAGER is
  372. // getting destroyed, then there had better not be
  373. // any requests alive that are holding references
  374. // to the entries.
  375. //
  376. while ( !IsListEmpty( &_CrashHistoryList ) )
  377. {
  378. pleTemp = RemoveHeadList( &_CrashHistoryList );
  379. pWamCrashRecord = CONTAINING_RECORD(
  380. pleTemp,
  381. WAM_CRASH_RECORD,
  382. leCrashHistory
  383. );
  384. DBG_ASSERT( pWamCrashRecord );
  385. delete pWamCrashRecord;
  386. pWamCrashRecord = NULL;
  387. }
  388. //
  389. // Release the COM catalog
  390. //
  391. if ( _pCatalog )
  392. {
  393. _pCatalog->Release();
  394. }
  395. //
  396. // Cleanup the hash lock (the hash itself will
  397. // get cleaned up automatically).
  398. //
  399. DeleteCriticalSection( &_csWamHashLock );
  400. DeleteCriticalSection( &_csCrashHistoryLock );
  401. IF_DEBUG( ISAPI )
  402. {
  403. DBGPRINTF((
  404. DBG_CONTEXT,
  405. "WAM_PROCESS_MANAGER %p has been destroyed.\r\n",
  406. this
  407. ));
  408. }
  409. }
  410. VOID
  411. LockCrashHistoryList(
  412. VOID
  413. )
  414. {
  415. EnterCriticalSection( &_csCrashHistoryLock );
  416. }
  417. VOID
  418. UnlockCrashHistoryList(
  419. VOID
  420. )
  421. {
  422. LeaveCriticalSection( &_csCrashHistoryLock );
  423. }
  424. WAM_PROCESS_HASH _WamProcessHash;
  425. CRITICAL_SECTION _csWamHashLock;
  426. CRITICAL_SECTION _csCrashHistoryLock;
  427. ICOMAdminCatalog2 * _pCatalog;
  428. LONG _cRefs;
  429. WCHAR _szIsapiModule[MAX_PATH];
  430. LIST_ENTRY _CrashHistoryList;
  431. };
  432. #endif // _WAM_PROCESS_HXX