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.

837 lines
16 KiB

  1. #ifndef _W3CONTEXT_HXX_
  2. #define _W3CONTEXT_HXX_
  3. #define W3_PARAMETERS_KEY \
  4. L"System\\CurrentControlSet\\Services\\w3svc\\Parameters"
  5. #define W3_FLAG_ASYNC 0x00000001
  6. #define W3_FLAG_SYNC 0x00000002
  7. #define W3_FLAG_NO_CUSTOM_ERROR 0x00000004
  8. #define W3_FLAG_MORE_DATA 0x00000008
  9. #define W3_FLAG_PAST_END_OF_REQ 0x00000010
  10. #define W3_FLAG_NO_HEADERS 0x00000020
  11. #define W3_FLAG_GENERATE_CONTENT_LENGTH 0x00000040
  12. #define W3_FLAG_NO_ERROR_BODY 0x00000080
  13. #define W3_FLAG_VALID ( W3_FLAG_ASYNC | \
  14. W3_FLAG_SYNC | \
  15. W3_FLAG_NO_CUSTOM_ERROR | \
  16. W3_FLAG_MORE_DATA | \
  17. W3_FLAG_PAST_END_OF_REQ | \
  18. W3_FLAG_NO_HEADERS | \
  19. W3_FLAG_NO_ERROR_BODY | \
  20. W3_FLAG_GENERATE_CONTENT_LENGTH )
  21. #define VALID_W3_FLAGS(x) ( (x) == ((x) & (W3_FLAG_VALID)) )
  22. class URL_CONTEXT;
  23. class W3_HANDLER;
  24. class COMPRESSION_CONTEXT;
  25. //
  26. // Access check state
  27. //
  28. // We potentially do two asynchronous operations in determining whether
  29. // a given request is valid
  30. // 1) Do an RDNS lookup if restrictions are configured in metabase
  31. // 2) Request a client certificate if configured in metabase
  32. //
  33. enum W3_CONTEXT_ACCESS_STATE
  34. {
  35. ACCESS_STATE_START,
  36. ACCESS_STATE_RDNS,
  37. ACCESS_STATE_CLIENT_CERT,
  38. ACCESS_STATE_AUTHENTICATION,
  39. ACCESS_STATE_SENDING_ERROR,
  40. ACCESS_STATE_DONE
  41. };
  42. //
  43. // W3_CONTEXT - Object representing an execution of the state machine to
  44. // handle a given request from UL
  45. //
  46. #define W3_CONTEXT_LIST_SPINS 200
  47. #define W3_CONTEXT_SIGNATURE ((DWORD) 'XC3W')
  48. #define W3_CONTEXT_SIGNATURE_FREE ((DWORD) 'xc3w')
  49. class W3_CONTEXT
  50. {
  51. private:
  52. DWORD _dwSignature;
  53. //
  54. // Handler for this context
  55. //
  56. W3_HANDLER * _pHandler;
  57. //
  58. // Error Status for request
  59. //
  60. HRESULT _errorStatus;
  61. //
  62. // Completion indication (for synchronous execution of handlers)
  63. //
  64. HANDLE _hCompletion;
  65. //
  66. // Custom error file to cleanup
  67. //
  68. W3_FILE_INFO * _pCustomErrorFile;
  69. //
  70. // Maintain list of contexts
  71. //
  72. LIST_ENTRY _listEntry;
  73. //
  74. // Where are we with checking access rights for this request
  75. //
  76. W3_CONTEXT_ACCESS_STATE _accessState;
  77. BOOL _fDNSRequiredForAccess; // argh
  78. //
  79. // The status of last child request executed by this context
  80. //
  81. USHORT _childStatusCode;
  82. USHORT _childSubErrorCode;
  83. HRESULT _childError;
  84. //
  85. // Is authentication access check required or not
  86. //
  87. BOOL _fAuthAccessCheckRequired;
  88. CONTEXT_STATUS
  89. ExecuteCurrentHandler(
  90. VOID
  91. );
  92. protected:
  93. //
  94. // The flags determining how to execute this request
  95. // (we let child contexts alter these flags if needed)
  96. //
  97. DWORD _dwExecFlags;
  98. public:
  99. static CHAR sm_achRedirectMessage[ 512 ];
  100. static DWORD sm_cbRedirectMessage;
  101. static CHAR * sm_pszAccessDeniedMessage;
  102. W3_CONTEXT(
  103. DWORD dwExecFlags
  104. );
  105. virtual ~W3_CONTEXT();
  106. virtual
  107. BOOL
  108. QueryResponseSent(
  109. VOID
  110. ) = 0;
  111. virtual
  112. BOOL
  113. QuerySendLocation(
  114. VOID
  115. )
  116. {
  117. return FALSE;
  118. }
  119. virtual
  120. BOOL
  121. QueryNeedFinalDone(
  122. VOID
  123. ) = 0;
  124. virtual
  125. VOID
  126. SetNeedFinalDone(
  127. VOID
  128. ) = 0;
  129. virtual
  130. W3_REQUEST *
  131. QueryRequest(
  132. VOID
  133. ) = 0;
  134. virtual
  135. W3_RESPONSE *
  136. QueryResponse(
  137. VOID
  138. ) = 0;
  139. virtual
  140. W3_SITE *
  141. QuerySite(
  142. VOID
  143. ) = 0;
  144. virtual
  145. W3_CONTEXT *
  146. QueryParentContext(
  147. VOID
  148. ) = 0;
  149. virtual
  150. W3_MAIN_CONTEXT *
  151. QueryMainContext(
  152. VOID
  153. ) = 0;
  154. virtual
  155. URL_CONTEXT *
  156. QueryUrlContext(
  157. VOID
  158. ) = 0;
  159. virtual
  160. W3_USER_CONTEXT *
  161. QueryUserContext(
  162. VOID
  163. ) = 0;
  164. virtual
  165. W3_FILTER_CONTEXT *
  166. QueryFilterContext(
  167. BOOL fCreateIfNotFound = TRUE
  168. ) = 0;
  169. virtual
  170. ULATQ_CONTEXT
  171. QueryUlatqContext(
  172. VOID
  173. ) = 0;
  174. virtual
  175. BOOL
  176. QueryProviderHandled(
  177. VOID
  178. ) = 0;
  179. virtual
  180. BOOL
  181. NotifyFilters(
  182. DWORD dwNotification,
  183. VOID * pvFilterInfo,
  184. BOOL * pfFinished
  185. ) = 0;
  186. virtual
  187. BOOL
  188. IsNotificationNeeded(
  189. DWORD dwNotification
  190. ) = 0;
  191. virtual
  192. VOID
  193. SetDisconnect(
  194. BOOL fDisconnect
  195. ) = 0;
  196. virtual
  197. BOOL
  198. QueryDisconnect(
  199. VOID
  200. ) = 0;
  201. virtual
  202. VOID
  203. SetDoneWithCompression(
  204. VOID
  205. ) = 0;
  206. virtual
  207. BOOL
  208. QueryDoneWithCompression(
  209. VOID
  210. ) = 0;
  211. virtual
  212. VOID
  213. SetCompressionContext(
  214. COMPRESSION_CONTEXT * pCompressionContext
  215. ) = 0;
  216. virtual
  217. COMPRESSION_CONTEXT *
  218. QueryCompressionContext(
  219. VOID
  220. ) = 0;
  221. virtual
  222. HTTP_LOG_FIELDS_DATA *
  223. QueryUlLogData(
  224. VOID
  225. ) = 0;
  226. virtual
  227. VOID
  228. SetLastIOPending(
  229. LAST_IO_PENDING ioPending
  230. ) = 0;
  231. virtual
  232. VOID
  233. IncrementBytesRecvd(
  234. DWORD dwRead
  235. ) = 0;
  236. virtual
  237. VOID
  238. IncrementBytesSent(
  239. DWORD dwSent
  240. ) = 0;
  241. virtual
  242. BOOL
  243. QueryIsUlCacheable(
  244. VOID
  245. ) = 0;
  246. virtual
  247. VOID
  248. DisableUlCache(
  249. VOID
  250. ) = 0;
  251. //
  252. // Other fixed W3_CONTEXT methods
  253. //
  254. W3_HANDLER *
  255. QueryHandler(
  256. VOID
  257. ) const
  258. {
  259. return _pHandler;
  260. }
  261. VOID
  262. SetChildStatusAndError(
  263. USHORT ChildStatusCode,
  264. USHORT ChildSubError,
  265. HRESULT ChildError
  266. )
  267. {
  268. _childStatusCode = ChildStatusCode;
  269. _childSubErrorCode = ChildSubError;
  270. _childError = ChildError;
  271. }
  272. VOID
  273. QueryChildStatusAndError(
  274. USHORT * pChildStatusCode,
  275. USHORT * pChildSubError,
  276. DWORD * pChildError
  277. ) const
  278. {
  279. DBG_ASSERT( pChildStatusCode != NULL );
  280. DBG_ASSERT( pChildSubError != NULL );
  281. DBG_ASSERT( pChildError != NULL );
  282. *pChildStatusCode = _childStatusCode;
  283. *pChildSubError = _childSubErrorCode;
  284. if ( FAILED( _childError ) )
  285. {
  286. *pChildError = WIN32_FROM_HRESULT( _childError );
  287. }
  288. else
  289. {
  290. *pChildError = ERROR_SUCCESS;
  291. }
  292. }
  293. BOOL
  294. QuerySendCustomError(
  295. VOID
  296. ) const
  297. {
  298. if ( _dwExecFlags & W3_FLAG_NO_CUSTOM_ERROR )
  299. {
  300. return FALSE;
  301. }
  302. else
  303. {
  304. return TRUE;
  305. }
  306. }
  307. BOOL
  308. QuerySendErrorBody(
  309. VOID
  310. ) const
  311. {
  312. if ( _dwExecFlags & W3_FLAG_NO_ERROR_BODY )
  313. {
  314. return FALSE;
  315. }
  316. else
  317. {
  318. return TRUE;
  319. }
  320. }
  321. BOOL
  322. QuerySendHeaders(
  323. VOID
  324. ) const
  325. {
  326. if ( _dwExecFlags & W3_FLAG_NO_HEADERS )
  327. {
  328. return FALSE;
  329. }
  330. else
  331. {
  332. return TRUE;
  333. }
  334. }
  335. VOID
  336. SetAuthAccessCheckRequired(
  337. BOOL fAuthAccessCheckRequired
  338. )
  339. {
  340. _fAuthAccessCheckRequired = fAuthAccessCheckRequired;
  341. }
  342. BOOL
  343. QueryAuthAccessCheckRequired(
  344. VOID
  345. ) const
  346. {
  347. return _fAuthAccessCheckRequired;
  348. }
  349. VOID
  350. SetSSICommandHandler(
  351. W3_HANDLER * pHandler
  352. );
  353. BOOL
  354. QueryDoUlLogging(
  355. VOID
  356. );
  357. BOOL
  358. QueryDoCustomLogging(
  359. VOID
  360. );
  361. HRESULT
  362. SetupCustomErrorFileResponse(
  363. STRU & strErrorFile
  364. );
  365. HRESULT
  366. SendResponse(
  367. DWORD dwFlags
  368. );
  369. HRESULT
  370. GetCertificateInfoEx(
  371. IN DWORD cbAllocated,
  372. OUT DWORD * pdwCertEncodingType,
  373. OUT unsigned char * pbCertEncoded,
  374. OUT DWORD * pcbCertEncoded,
  375. OUT DWORD * pdwCertificateFlags
  376. );
  377. HANDLE
  378. QueryImpersonationToken(
  379. BOOL * pfIsVrToken = NULL
  380. );
  381. HANDLE
  382. QueryPrimaryToken(
  383. VOID
  384. );
  385. VOID
  386. QueryFileCacheUser(
  387. FILE_CACHE_USER * pFileUser
  388. );
  389. CONTEXT_STATUS
  390. CheckAccess(
  391. BOOL fCompletion,
  392. DWORD dwCompletionStatus,
  393. BOOL * pfAccessAllowed
  394. );
  395. CERTIFICATE_CONTEXT *
  396. QueryCertificateContext(
  397. VOID
  398. );
  399. CHUNK_BUFFER *
  400. QueryHeaderBuffer(
  401. VOID
  402. );
  403. BOOL
  404. CheckClientCertificateAccess(
  405. VOID
  406. );
  407. HRESULT
  408. SendEntity(
  409. DWORD dwFlags
  410. );
  411. HRESULT
  412. ReceiveEntity(
  413. DWORD dwFlags,
  414. VOID * pBuffer,
  415. DWORD cbBuffer,
  416. DWORD * pBytesReceived
  417. );
  418. DWORD
  419. QueryRemainingEntityFromUl(
  420. VOID
  421. );
  422. VOID SetRemainingEntityFromUl(
  423. DWORD cbRemaining
  424. );
  425. VOID
  426. QueryAlreadyAvailableEntity(
  427. VOID ** ppvBuffer,
  428. DWORD * pcbBuffer
  429. );
  430. HRESULT
  431. QueryErrorStatus(
  432. VOID
  433. ) const
  434. {
  435. return _errorStatus;
  436. }
  437. VOID
  438. SetErrorStatus(
  439. HRESULT errorStatus
  440. )
  441. {
  442. _errorStatus = errorStatus;
  443. }
  444. HRESULT
  445. DoUrlRedirection(
  446. BOOL *pfRedirected
  447. );
  448. HRESULT
  449. SetupHttpRedirect(
  450. STRA & strPath,
  451. BOOL fIncludeParameters,
  452. HTTP_STATUS & httpStatus
  453. );
  454. HRESULT
  455. SetupHttpRedirect(
  456. STRU & strPath,
  457. BOOL fIncludeParameters,
  458. HTTP_STATUS & httpStatus
  459. );
  460. HRESULT
  461. SetupAllowHeader(
  462. VOID
  463. );
  464. BOOL
  465. CheckSignature(
  466. VOID
  467. ) const
  468. {
  469. return _dwSignature == W3_CONTEXT_SIGNATURE;
  470. }
  471. BOOL
  472. QueryAccessChecked(
  473. VOID
  474. ) const
  475. {
  476. return _accessState == ACCESS_STATE_DONE;
  477. }
  478. VOID
  479. ResetAccessCheck(
  480. VOID
  481. )
  482. {
  483. _accessState = ACCESS_STATE_START;
  484. }
  485. HRESULT
  486. SetupCompletionEvent(
  487. VOID
  488. )
  489. {
  490. _hCompletion = IIS_CREATE_EVENT( "W3_CONTEXT::_hCompletion",
  491. this,
  492. FALSE,
  493. FALSE );
  494. if ( _hCompletion == NULL )
  495. {
  496. return HRESULT_FROM_WIN32( GetLastError() );
  497. }
  498. else
  499. {
  500. return NO_ERROR;
  501. }
  502. }
  503. VOID
  504. WaitForCompletion(
  505. VOID
  506. )
  507. {
  508. if ( _hCompletion )
  509. {
  510. WaitForSingleObject( _hCompletion, INFINITE );
  511. }
  512. }
  513. VOID
  514. IndicateCompletion(
  515. VOID
  516. )
  517. {
  518. if ( _hCompletion )
  519. {
  520. SetEvent( _hCompletion );
  521. }
  522. }
  523. BOOL
  524. QueryIsSynchronous(
  525. VOID
  526. ) const
  527. {
  528. return _hCompletion != NULL;
  529. }
  530. HRESULT
  531. IsapiExecuteUrl(
  532. HSE_EXEC_URL_INFO * pExecUrlInfo
  533. );
  534. HRESULT
  535. CleanIsapiExecuteUrl(
  536. HSE_EXEC_URL_INFO * pExecUrlInfo
  537. );
  538. HRESULT
  539. IsapiSendCustomError(
  540. HSE_CUSTOM_ERROR_INFO * pCustomErrorInfo
  541. );
  542. HRESULT
  543. CleanIsapiSendCustomError(
  544. HSE_CUSTOM_ERROR_INFO * pCustomErrorInfo
  545. );
  546. HRESULT
  547. ExecuteChildRequest(
  548. W3_REQUEST * pNewRequest,
  549. BOOL fOwnRequest,
  550. DWORD dwFlags
  551. );
  552. HRESULT
  553. ExecuteHandler(
  554. DWORD dwFlags,
  555. BOOL * pfDidImmediateFinish = NULL
  556. );
  557. CONTEXT_STATUS
  558. ExecuteHandlerCompletion(
  559. DWORD cbCompletion,
  560. DWORD dwCompletionStatus
  561. );
  562. HRESULT
  563. CheckPathInfoExists(
  564. W3_HANDLER ** ppHandler
  565. );
  566. HRESULT
  567. DetermineHandler(
  568. BOOL fAllowWildcardMapping
  569. );
  570. static HRESULT
  571. Initialize(
  572. VOID
  573. );
  574. static VOID
  575. Terminate(
  576. VOID
  577. );
  578. static
  579. VOID
  580. OnCleanIsapiExecuteUrl(
  581. DWORD dwCompletionStatus,
  582. DWORD cbWritten,
  583. LPOVERLAPPED lpo
  584. );
  585. static
  586. VOID
  587. OnCleanIsapiSendCustomError(
  588. DWORD dwCompletionStatus,
  589. DWORD cbWritten,
  590. LPOVERLAPPED lpo
  591. );
  592. };
  593. //
  594. // EXECUTE_CONTEXT Used to marshall an IsapiExecuteUrl() or
  595. // IsapiSendCustomError() on a clean (non-coinited) thread
  596. //
  597. #define EXECUTE_CONTEXT_SIGNATURE ((DWORD) 'TCXE')
  598. #define EXECUTE_CONTEXT_SIGNATURE_FREE ((DWORD) 'xcxe')
  599. class EXECUTE_CONTEXT
  600. {
  601. public:
  602. EXECUTE_CONTEXT( W3_CONTEXT * pW3Context )
  603. {
  604. DBG_ASSERT( pW3Context != NULL );
  605. _hEvent = NULL;
  606. _pW3Context = pW3Context;
  607. ZeroMemory( &_ExecUrlInfo, sizeof( _ExecUrlInfo ) );
  608. ZeroMemory( &_UserInfo, sizeof( _UserInfo ) );
  609. ZeroMemory( &_EntityInfo, sizeof( _EntityInfo ) );
  610. _dwSignature = EXECUTE_CONTEXT_SIGNATURE;
  611. }
  612. virtual ~EXECUTE_CONTEXT()
  613. {
  614. _dwSignature = EXECUTE_CONTEXT_SIGNATURE_FREE;
  615. if ( _hEvent != NULL )
  616. {
  617. SetEvent( _hEvent );
  618. }
  619. }
  620. HRESULT
  621. InitializeFromExecUrlInfo(
  622. HSE_EXEC_URL_INFO * pExecUrlInfo
  623. );
  624. HSE_EXEC_URL_INFO *
  625. QueryExecUrlInfo(
  626. VOID
  627. )
  628. {
  629. return &_ExecUrlInfo;
  630. }
  631. VOID
  632. SetCompleteEvent(
  633. HANDLE hEvent
  634. )
  635. {
  636. _hEvent = hEvent;
  637. }
  638. BOOL
  639. CheckSignature(
  640. VOID
  641. ) const
  642. {
  643. return _dwSignature == EXECUTE_CONTEXT_SIGNATURE;
  644. }
  645. HANDLE
  646. QueryCompleteEvent(
  647. VOID
  648. ) const
  649. {
  650. return _hEvent;
  651. }
  652. W3_CONTEXT *
  653. QueryW3Context(
  654. VOID
  655. ) const
  656. {
  657. return _pW3Context;
  658. }
  659. VOID *
  660. operator new(
  661. size_t size
  662. )
  663. {
  664. DBG_ASSERT( size == sizeof( EXECUTE_CONTEXT ) );
  665. DBG_ASSERT( sm_pachExecuteContexts != NULL );
  666. return sm_pachExecuteContexts->Alloc();
  667. }
  668. VOID
  669. operator delete(
  670. VOID * pExecuteContext
  671. )
  672. {
  673. DBG_ASSERT( pExecuteContext != NULL );
  674. DBG_ASSERT( sm_pachExecuteContexts != NULL );
  675. DBG_REQUIRE( sm_pachExecuteContexts->Free( pExecuteContext ) );
  676. }
  677. static
  678. HRESULT
  679. Initialize(
  680. VOID
  681. );
  682. static
  683. VOID
  684. Terminate(
  685. VOID
  686. );
  687. private:
  688. DWORD _dwSignature;
  689. W3_CONTEXT * _pW3Context;
  690. HSE_EXEC_URL_INFO _ExecUrlInfo;
  691. HSE_EXEC_URL_USER_INFO _UserInfo;
  692. HSE_EXEC_URL_ENTITY_INFO _EntityInfo;
  693. CHUNK_BUFFER _HeaderBuffer;
  694. HANDLE _hEvent;
  695. static ALLOC_CACHE_HANDLER * sm_pachExecuteContexts;
  696. };
  697. #endif