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.

495 lines
11 KiB

  1. /*++
  2. Copyright (c) 1998-2001 Microsoft Corporation
  3. Module Name:
  4. apool.h
  5. Abstract:
  6. The public definition of app pool interfaces.
  7. Author:
  8. Paul McDaniel (paulmcd) 28-Jan-1999
  9. Revision History:
  10. --*/
  11. #ifndef _APOOL_H_
  12. #define _APOOL_H_
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif
  16. //
  17. // Kernel mode mappings to the user mode set defined in ulapi.h
  18. //
  19. //
  20. // Forwarders.
  21. //
  22. typedef struct _UL_INTERNAL_REQUEST *PUL_INTERNAL_REQUEST;
  23. typedef struct _UL_HTTP_CONNECTION *PUL_HTTP_CONNECTION;
  24. typedef struct _UL_CONFIG_GROUP_OBJECT *PUL_CONFIG_GROUP_OBJECT;
  25. //
  26. // this structure contains a queue of HTTP_REQUEST objects
  27. // CODEWORK: investigate using an NBQUEUE instead
  28. //
  29. typedef struct _UL_REQUEST_QUEUE
  30. {
  31. LONG RequestCount;
  32. LONG MaxRequests;
  33. LIST_ENTRY RequestHead;
  34. } UL_REQUEST_QUEUE, *PUL_REQUEST_QUEUE;
  35. //
  36. // This structure represents an internal app pool object
  37. //
  38. #define IS_VALID_AP_OBJECT(pObject) \
  39. (((pObject) != NULL) && ((pObject)->Signature == UL_APP_POOL_OBJECT_POOL_TAG) && ((pObject)->RefCount > 0))
  40. typedef struct _UL_APP_POOL_OBJECT
  41. {
  42. //
  43. // NonPagedPool
  44. //
  45. //
  46. // lock that protects NewRequestQueue, PendingRequestQueue
  47. // for each attached process and queue state of the request
  48. //
  49. // ensure it on cache-line and use InStackQueuedSpinLock for
  50. // better performance
  51. //
  52. UL_SPIN_LOCK QueueSpinLock;
  53. //
  54. // UL_APP_POOL_OBJECT_POOL_TAG
  55. //
  56. ULONG Signature;
  57. //
  58. // Ref count for this app pool
  59. //
  60. LONG RefCount;
  61. //
  62. // links all apool objects, anchored by g_AppPoolListHead
  63. //
  64. LIST_ENTRY ListEntry;
  65. //
  66. // Locks lists on the app pool & process objects, is refcounted and
  67. // given to the HTTP_REQUEST object to synchronize access to process
  68. // objects when connections drop and the request(s) need to be released
  69. //
  70. PUL_NONPAGED_RESOURCE pResource;
  71. //
  72. // A apool wide new request list (when no irps are available)
  73. //
  74. UL_REQUEST_QUEUE NewRequestQueue;
  75. //
  76. // the demand start irp (OPTIONAL)
  77. //
  78. PIRP pDemandStartIrp;
  79. PEPROCESS pDemandStartProcess;
  80. //
  81. // the list of processes bound to this app pool
  82. //
  83. LIST_ENTRY ProcessListHead;
  84. PSECURITY_DESCRIPTOR pSecurityDescriptor;
  85. //
  86. // List of transient config groups
  87. //
  88. UL_NOTIFY_HEAD TransientHead;
  89. //
  90. // the length of pName
  91. //
  92. ULONG NameLength;
  93. //
  94. // number of active processes in the AppPool, used to decide if binding
  95. // is necessary
  96. //
  97. ULONG NumberActiveProcesses;
  98. //
  99. // Only route requests to this AppPool if it's marked active
  100. //
  101. HTTP_ENABLED_STATE Enabled;
  102. //
  103. // the apool's name
  104. //
  105. WCHAR pName[0];
  106. } UL_APP_POOL_OBJECT, *PUL_APP_POOL_OBJECT;
  107. //
  108. // The structure representing a process bound to an app pool.
  109. //
  110. #define IS_VALID_AP_PROCESS(pObject) \
  111. (((pObject) != NULL) && ((pObject)->Signature == UL_APP_POOL_PROCESS_POOL_TAG))
  112. typedef struct _UL_APP_POOL_PROCESS
  113. {
  114. //
  115. // NonPagedPool
  116. //
  117. //
  118. // UL_APP_POOL_PROCESS_POOL_TAG
  119. //
  120. ULONG Signature;
  121. //
  122. // set if we are in cleanup. You must check this flag before attaching
  123. // any IRPs to the process.
  124. //
  125. ULONG InCleanup : 1;
  126. //
  127. // set if process is attached with the HTTP_OPTION_CONTROLLER option
  128. //
  129. ULONG Controller : 1;
  130. //
  131. // used to link into the apool object
  132. //
  133. LIST_ENTRY ListEntry;
  134. //
  135. // points to the app pool this process belongs
  136. //
  137. PUL_APP_POOL_OBJECT pAppPool;
  138. //
  139. // a list of pending IRP(s) waiting to receive new requests
  140. //
  141. LIST_ENTRY NewIrpHead;
  142. //
  143. // lock that protects the above list
  144. //
  145. UL_SPIN_LOCK NewIrpSpinLock;
  146. //
  147. // links requests that would not fit in a irp buffer and need to wait for
  148. // the larger buffer
  149. //
  150. // and
  151. //
  152. // requests that this process is working on and need
  153. // i/o cancellation if the process detaches from the apool
  154. //
  155. UL_REQUEST_QUEUE PendingRequestQueue;
  156. //
  157. // Pointer to the actual process (for debugging)
  158. //
  159. PEPROCESS pProcess;
  160. //
  161. // List of pending "wait for disconnect" IRPs.
  162. //
  163. UL_NOTIFY_HEAD WaitForDisconnectHead;
  164. } UL_APP_POOL_PROCESS, *PUL_APP_POOL_PROCESS;
  165. // IRQL == PASSIVE_LEVEL
  166. //
  167. NTSTATUS
  168. UlAttachProcessToAppPool(
  169. IN PWCHAR pName OPTIONAL,
  170. IN ULONG NameLength,
  171. IN BOOLEAN Create,
  172. IN PACCESS_STATE pAccessState,
  173. IN ACCESS_MASK DesiredAccess,
  174. IN KPROCESSOR_MODE RequestorMode,
  175. OUT PUL_APP_POOL_PROCESS * ppProcess
  176. );
  177. // IRQL == PASSIVE_LEVEL
  178. //
  179. NTSTATUS
  180. UlDetachProcessFromAppPool(
  181. IN PUL_APP_POOL_PROCESS pProcess
  182. );
  183. // IRQL == PASSIVE_LEVEL
  184. //
  185. #if REFERENCE_DEBUG
  186. VOID
  187. UlReferenceAppPool(
  188. IN PUL_APP_POOL_OBJECT pAppPool
  189. REFERENCE_DEBUG_FORMAL_PARAMS
  190. );
  191. #else
  192. __inline
  193. VOID
  194. FASTCALL
  195. UlReferenceAppPool(
  196. IN PUL_APP_POOL_OBJECT pAppPool
  197. )
  198. {
  199. InterlockedIncrement(&pAppPool->RefCount);
  200. }
  201. #endif
  202. #define REFERENCE_APP_POOL( papp ) \
  203. UlReferenceAppPool( \
  204. (papp) \
  205. REFERENCE_DEBUG_ACTUAL_PARAMS \
  206. )
  207. // IRQL == PASSIVE_LEVEL
  208. //
  209. VOID
  210. UlDeleteAppPool(
  211. IN PUL_APP_POOL_OBJECT pAppPool
  212. REFERENCE_DEBUG_FORMAL_PARAMS
  213. );
  214. #define DELETE_APP_POOL( papp ) \
  215. UlDeleteAppPool( \
  216. (papp) \
  217. REFERENCE_DEBUG_ACTUAL_PARAMS \
  218. )
  219. #if REFERENCE_DEBUG
  220. VOID
  221. UlDereferenceAppPool(
  222. IN PUL_APP_POOL_OBJECT pAppPool
  223. REFERENCE_DEBUG_FORMAL_PARAMS
  224. );
  225. #else
  226. __inline
  227. VOID
  228. FASTCALL
  229. UlDereferenceAppPool(
  230. IN PUL_APP_POOL_OBJECT pAppPool
  231. )
  232. {
  233. if (InterlockedDecrement(&pAppPool->RefCount) == 0)
  234. {
  235. UlDeleteAppPool(pAppPool);
  236. }
  237. }
  238. #endif
  239. #define DEREFERENCE_APP_POOL( papp ) \
  240. UlDereferenceAppPool( \
  241. (papp) \
  242. REFERENCE_DEBUG_ACTUAL_PARAMS \
  243. )
  244. // IRQL == PASSIVE_LEVEL
  245. //
  246. NTSTATUS
  247. UlQueryAppPoolInformation(
  248. IN PUL_APP_POOL_PROCESS pProcess,
  249. IN HTTP_APP_POOL_INFORMATION_CLASS InformationClass,
  250. OUT PVOID pAppPoolInformation,
  251. IN ULONG Length,
  252. OUT PULONG pReturnLength OPTIONAL
  253. );
  254. // IRQL == PASSIVE_LEVEL
  255. //
  256. NTSTATUS
  257. UlSetAppPoolInformation(
  258. IN PUL_APP_POOL_PROCESS pProcess,
  259. IN HTTP_APP_POOL_INFORMATION_CLASS InformationClass,
  260. IN PVOID pAppPoolInformation,
  261. IN ULONG Length
  262. );
  263. // IRQL == PASSIVE_LEVEL
  264. //
  265. NTSTATUS
  266. UlWaitForDemandStart(
  267. IN PUL_APP_POOL_PROCESS pProcess,
  268. IN PIRP pIrp
  269. );
  270. // IRQL == PASSIVE_LEVEL
  271. //
  272. NTSTATUS
  273. UlReceiveHttpRequest(
  274. IN HTTP_REQUEST_ID RequestId,
  275. IN ULONG Flags,
  276. IN PUL_APP_POOL_PROCESS pProcess,
  277. IN PIRP pIrp
  278. );
  279. // IRQL == PASSIVE_LEVEL
  280. //
  281. NTSTATUS
  282. UlDeliverRequestToProcess(
  283. IN PUL_APP_POOL_OBJECT pAppPool,
  284. IN PUL_INTERNAL_REQUEST pRequest
  285. );
  286. VOID
  287. UlUnlinkRequestFromProcess(
  288. IN PUL_APP_POOL_OBJECT pAppPool,
  289. IN PUL_INTERNAL_REQUEST pRequest
  290. );
  291. // IRQL == PASSIVE_LEVEL
  292. //
  293. NTSTATUS
  294. UlGetPoolFromHandle(
  295. IN HANDLE hAppPool,
  296. OUT PUL_APP_POOL_OBJECT * ppAppPool
  297. );
  298. NTSTATUS
  299. UlInitializeAP(
  300. VOID
  301. );
  302. VOID
  303. UlTerminateAP(
  304. VOID
  305. );
  306. PUL_APP_POOL_PROCESS
  307. UlCreateAppPoolProcess(
  308. PUL_APP_POOL_OBJECT pObject
  309. );
  310. VOID
  311. UlFreeAppPoolProcess(
  312. PUL_APP_POOL_PROCESS pProcess
  313. );
  314. PUL_APP_POOL_OBJECT
  315. UlAppPoolObjectFromProcess(
  316. PUL_APP_POOL_PROCESS pProcess
  317. );
  318. VOID
  319. UlLinkConfigGroupToAppPool(
  320. IN PUL_CONFIG_GROUP_OBJECT pConfigGroup,
  321. IN PUL_APP_POOL_OBJECT pAppPool
  322. );
  323. NTSTATUS
  324. UlWaitForDisconnect(
  325. IN PUL_APP_POOL_PROCESS pProcess,
  326. IN PUL_HTTP_CONNECTION pHttpConn,
  327. IN PIRP pIrp
  328. );
  329. VOID
  330. UlCompleteAllWaitForDisconnect(
  331. IN PUL_HTTP_CONNECTION pHttpConnection
  332. );
  333. NTSTATUS
  334. UlpCopyRequestToBuffer(
  335. IN PUL_INTERNAL_REQUEST pRequest,
  336. IN PUCHAR pKernelBuffer,
  337. IN PVOID pUserBuffer,
  338. IN ULONG BufferLength,
  339. IN PUCHAR pEntityBody,
  340. IN ULONG EntityBodyLength
  341. );
  342. PUL_INTERNAL_REQUEST
  343. UlpDequeueNewRequest(
  344. IN PUL_APP_POOL_PROCESS pProcess
  345. );
  346. __inline
  347. NTSTATUS
  348. FASTCALL
  349. UlpComputeRequestBytesNeeded(
  350. IN PUL_INTERNAL_REQUEST pRequest,
  351. IN PULONG pBytesNeeded
  352. )
  353. {
  354. NTSTATUS Status;
  355. ULONG SslInfoSize;
  356. //
  357. // Calculate the size needed for the request, we'll need it below.
  358. //
  359. *pBytesNeeded =
  360. sizeof(HTTP_REQUEST) +
  361. pRequest->TotalRequestSize +
  362. (pRequest->UnknownHeaderCount * sizeof(HTTP_UNKNOWN_HEADER));
  363. //
  364. // Include additional space for the local and remote addresses.
  365. //
  366. // CODEWORK: Make this transport independent.
  367. //
  368. *pBytesNeeded += sizeof(HTTP_NETWORK_ADDRESS_IPV4) * 2;
  369. //
  370. // Include space for any SSL information.
  371. //
  372. if (pRequest->pHttpConn->SecureConnection)
  373. {
  374. Status = UlGetSslInfo(
  375. &pRequest->pHttpConn->pConnection->FilterInfo,
  376. 0, // BufferSize
  377. NULL, // pUserBuffer
  378. NULL, // pBuffer
  379. &SslInfoSize // pBytesNeeded
  380. );
  381. if (NT_SUCCESS(Status))
  382. {
  383. //
  384. // Struct must be aligned; add some slop space
  385. //
  386. *pBytesNeeded = ALIGN_UP(*pBytesNeeded, PVOID);
  387. *pBytesNeeded += SslInfoSize;
  388. }
  389. else
  390. {
  391. return Status;
  392. }
  393. }
  394. return STATUS_SUCCESS;
  395. }
  396. #ifdef __cplusplus
  397. }; // extern "C"
  398. #endif
  399. #endif // _APOOL_H_