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.

488 lines
9.9 KiB

  1. #ifndef _RAWCONNECTION_HXX_
  2. #define _RAWCONNECTION_HXX_
  3. #include <streamfilt.h>
  4. #include "w3filter.hxx"
  5. #define RAW_CONNECTION_SIGNATURE (DWORD)'NOCR'
  6. #define RAW_CONNECTION_SIGNATURE_FREE (DWORD)'nocr'
  7. class RAW_CONNECTION_HASH;
  8. class W3_CONNECTION;
  9. class RAW_CONNECTION
  10. {
  11. public:
  12. RAW_CONNECTION(
  13. CONNECTION_INFO * pConnectionInfo
  14. );
  15. virtual ~RAW_CONNECTION();
  16. static
  17. HRESULT
  18. Initialize(
  19. VOID
  20. );
  21. static
  22. VOID
  23. Terminate(
  24. VOID
  25. );
  26. static
  27. HRESULT
  28. StartListening(
  29. VOID
  30. );
  31. static
  32. HRESULT
  33. StopListening(
  34. VOID
  35. );
  36. static
  37. HRESULT
  38. GetConnection(
  39. CONNECTION_INFO * pConnectionInfo,
  40. RAW_CONNECTION ** ppRawConnection
  41. );
  42. static
  43. HRESULT
  44. FindConnection(
  45. HTTP_RAW_CONNECTION_ID ConnectionId,
  46. RAW_CONNECTION ** ppRawConnection
  47. );
  48. static
  49. BOOL
  50. WINAPI
  51. RawFilterServerSupportFunction(
  52. HTTP_FILTER_CONTEXT * pfc,
  53. enum SF_REQ_TYPE SupportFunction,
  54. void * pData,
  55. ULONG_PTR ul,
  56. ULONG_PTR ul2
  57. );
  58. static
  59. BOOL
  60. WINAPI
  61. RawFilterGetServerVariable(
  62. HTTP_FILTER_CONTEXT * pfc,
  63. LPSTR lpszVariableName,
  64. LPVOID lpvBuffer,
  65. LPDWORD lpdwSize
  66. );
  67. static
  68. BOOL
  69. WINAPI
  70. RawFilterWriteClient(
  71. HTTP_FILTER_CONTEXT * pfc,
  72. LPVOID Buffer,
  73. LPDWORD lpdwBytes,
  74. DWORD dwReserved
  75. );
  76. static
  77. VOID *
  78. WINAPI
  79. RawFilterAllocateMemory(
  80. HTTP_FILTER_CONTEXT * pfc,
  81. DWORD cbSize,
  82. DWORD dwReserved
  83. );
  84. static
  85. BOOL
  86. WINAPI
  87. RawFilterAddResponseHeaders(
  88. HTTP_FILTER_CONTEXT * pfc,
  89. LPSTR lpszHeaders,
  90. DWORD dwReserved
  91. );
  92. static
  93. HRESULT
  94. ProcessRawRead(
  95. RAW_STREAM_INFO * pRawStreamInfo,
  96. PVOID pvContext,
  97. BOOL * pfReadMore,
  98. BOOL * pfComplete,
  99. DWORD * pcbNextReadSize
  100. );
  101. static
  102. HRESULT
  103. ProcessRawWrite(
  104. RAW_STREAM_INFO * pRawStreamInfo,
  105. PVOID pvContext,
  106. BOOL * pfComplete
  107. );
  108. static
  109. HRESULT
  110. ProcessNewConnection(
  111. CONNECTION_INFO * pConnectionInfo,
  112. PVOID * ppvContext
  113. );
  114. static
  115. VOID
  116. ProcessConnectionClose(
  117. VOID * pvContext
  118. );
  119. HRESULT
  120. NotifyRawReadFilters(
  121. RAW_STREAM_INFO * pRawStreamInfo,
  122. BOOL * pfReadMore,
  123. BOOL * pfComplete
  124. );
  125. HRESULT
  126. NotifyRawWriteFilters(
  127. RAW_STREAM_INFO * pRawStreamInfo,
  128. BOOL * pfComplete,
  129. DWORD dwStartFilter
  130. );
  131. HRESULT
  132. SendResponseHeader(
  133. CHAR * pszStatus,
  134. CHAR * pszAdditionalHeaders,
  135. HTTP_FILTER_CONTEXT * pfc
  136. );
  137. HRESULT
  138. NotifyEndOfNetSessionFilters(
  139. VOID
  140. );
  141. VOID
  142. CopyAllocatedFilterMemory(
  143. W3_FILTER_CONTEXT * pFilterContext
  144. );
  145. PVOID
  146. AllocateFilterMemory(
  147. DWORD cbSize
  148. )
  149. {
  150. FILTER_POOL_ITEM * pPoolItem;
  151. pPoolItem = FILTER_POOL_ITEM::CreateMemPoolItem( cbSize );
  152. if ( pPoolItem != NULL )
  153. {
  154. InsertHeadList( &_PoolHead, &(pPoolItem->_ListEntry) );
  155. return pPoolItem->_pvData;
  156. }
  157. return NULL;
  158. }
  159. BOOL
  160. CheckSignature(
  161. VOID
  162. ) const
  163. {
  164. return _dwSignature == RAW_CONNECTION_SIGNATURE;
  165. }
  166. HTTP_RAW_CONNECTION_ID
  167. QueryRawConnectionId(
  168. VOID
  169. ) const
  170. {
  171. return _RawConnectionId;
  172. }
  173. W3_MAIN_CONTEXT *
  174. QueryMainContext(
  175. VOID
  176. )
  177. {
  178. return _pMainContext;
  179. }
  180. VOID
  181. SetMainContext(
  182. W3_MAIN_CONTEXT * pNewContext
  183. )
  184. {
  185. if ( _pMainContext != NULL )
  186. {
  187. _pMainContext->DereferenceMainContext();
  188. }
  189. if ( pNewContext != NULL )
  190. {
  191. pNewContext->ReferenceMainContext();
  192. }
  193. _pMainContext = pNewContext;
  194. }
  195. HRESULT
  196. AddResponseHeaders(
  197. LPSTR pszAddResponseHeaders
  198. )
  199. {
  200. return _strAddResponseHeaders.Append( pszAddResponseHeaders );
  201. }
  202. HRESULT
  203. AddDenialHeaders(
  204. LPSTR pszAddDenialHeaders
  205. )
  206. {
  207. return _strAddDenialHeaders.Append( pszAddDenialHeaders );
  208. }
  209. VOID
  210. ReferenceRawConnection(
  211. VOID
  212. )
  213. {
  214. InterlockedIncrement( &_cRefs );
  215. }
  216. VOID
  217. DereferenceRawConnection(
  218. VOID
  219. )
  220. {
  221. if ( !InterlockedDecrement( &_cRefs ) )
  222. {
  223. delete this;
  224. }
  225. }
  226. DWORD
  227. QueryNextReadSize(
  228. VOID
  229. ) const
  230. {
  231. return _cbNextReadSize;
  232. }
  233. VOID
  234. SetNextReadSize(
  235. DWORD cbNextReadSize
  236. )
  237. {
  238. _cbNextReadSize = cbNextReadSize;
  239. }
  240. //
  241. // A bunch of functions which need to gate their execution on whether
  242. // or not we have an associated W3_CONNECTION with the this raw connection
  243. //
  244. FILTER_LIST *
  245. QueryFilterList(
  246. VOID
  247. );
  248. BOOL
  249. QueryNotificationChanged(
  250. VOID
  251. );
  252. BOOL
  253. IsDisableNotificationNeeded(
  254. DWORD dwFilter,
  255. DWORD dwNotification
  256. );
  257. PVOID
  258. QueryClientContext(
  259. DWORD dwFilter
  260. );
  261. VOID
  262. SetClientContext(
  263. DWORD dwFilter,
  264. PVOID pvContext
  265. );
  266. VOID
  267. CopyContextPointers(
  268. W3_FILTER_CONTEXT * pFilterContext
  269. );
  270. HRESULT
  271. CopyHeaders(
  272. W3_FILTER_CONTEXT * pFilterContext
  273. );
  274. HRESULT
  275. GetLimitedServerVariables(
  276. LPSTR pszVariableName,
  277. PVOID pvBuffer,
  278. PDWORD pdwSize
  279. );
  280. static
  281. HRESULT
  282. AssociateW3Connection(
  283. HTTP_RAW_CONNECTION_ID rawConnectionId,
  284. W3_CONNECTION * pW3Connection
  285. );
  286. private:
  287. DWORD _dwSignature;
  288. LONG _cRefs;
  289. //
  290. // Filter opaque contexts
  291. //
  292. PVOID _rgContexts[ MAX_FILTERS ];
  293. //
  294. // List of pool items allocated by client. These pool items will be
  295. // migrated to the W3_FILTER_CONNECTION_CONTEXT when possible
  296. //
  297. LIST_ENTRY _PoolHead;
  298. //
  299. // The filter descriptor passed to filters
  300. //
  301. HTTP_FILTER_CONTEXT _hfc;
  302. //
  303. // Current filter. This is used to handle WriteClient()s from
  304. // read/write raw data filters
  305. //
  306. DWORD _dwCurrentFilter;
  307. //
  308. // A function/context to call back into stream filter
  309. //
  310. PFN_SEND_DATA_BACK _pfnSendDataBack;
  311. PVOID _pvStreamContext;
  312. //
  313. // Local/remote port info
  314. //
  315. USHORT _LocalPort;
  316. DWORD _LocalAddress;
  317. USHORT _RemotePort;
  318. DWORD _RemoteAddress;
  319. //
  320. // Raw connection id
  321. //
  322. HTTP_RAW_CONNECTION_ID _RawConnectionId;
  323. //
  324. // A response object which is needed if a raw read notification sends
  325. // a response and then expects a send-response notification.
  326. // (triple AAARRRRGGGGHH)
  327. //
  328. W3_RESPONSE _response;
  329. //
  330. // Main context which applies to this connection. There may be several
  331. // during the life of this connection
  332. //
  333. W3_MAIN_CONTEXT * _pMainContext;
  334. //
  335. // While we haven't associated with a WP request, we need to keep track
  336. // of our own additional response/denial headers
  337. //
  338. STRA _strAddDenialHeaders;
  339. STRA _strAddResponseHeaders;
  340. //
  341. // Next read size (0 means use default size)
  342. //
  343. DWORD _cbNextReadSize;
  344. static RAW_CONNECTION_HASH * sm_pRawConnectionHash;
  345. };
  346. //
  347. // RAW_CONNECTION_HASH
  348. //
  349. class RAW_CONNECTION_HASH
  350. : public CTypedHashTable<
  351. RAW_CONNECTION_HASH,
  352. RAW_CONNECTION,
  353. ULONGLONG
  354. >
  355. {
  356. public:
  357. RAW_CONNECTION_HASH()
  358. : CTypedHashTable< RAW_CONNECTION_HASH,
  359. RAW_CONNECTION,
  360. ULONGLONG > ( "RAW_CONNECTION_HASH" )
  361. {
  362. }
  363. static
  364. ULONGLONG
  365. ExtractKey(
  366. const RAW_CONNECTION * pRawConnection
  367. )
  368. {
  369. return pRawConnection->QueryRawConnectionId();
  370. }
  371. static
  372. DWORD
  373. CalcKeyHash(
  374. ULONGLONG ullKey
  375. )
  376. {
  377. return Hash( (DWORD) ullKey );
  378. }
  379. static
  380. bool
  381. EqualKeys(
  382. ULONGLONG ullKey1,
  383. ULONGLONG ullKey2
  384. )
  385. {
  386. return ullKey1 == ullKey2;
  387. }
  388. static
  389. void
  390. AddRefRecord(
  391. RAW_CONNECTION * pEntry,
  392. int nIncr
  393. )
  394. {
  395. if ( nIncr == +1 )
  396. {
  397. pEntry->ReferenceRawConnection();
  398. }
  399. else if ( nIncr == -1 )
  400. {
  401. pEntry->DereferenceRawConnection();
  402. }
  403. }
  404. };
  405. #endif