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.

2018 lines
57 KiB

  1. // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. //
  3. // REQUEST.CPP
  4. //
  5. // HTTP 1.1/DAV 1.0 request handling via ISAPI
  6. //
  7. //
  8. // Copyright 1986-1997 Microsoft Corporation, All Rights Reserved
  9. //
  10. #include <_davprs.h>
  11. #include "ecb.h"
  12. #include "body.h"
  13. #include "header.h"
  14. // ========================================================================
  15. //
  16. // CLASS IRequest
  17. //
  18. // ------------------------------------------------------------------------
  19. //
  20. // IRequest::~IRequest()
  21. //
  22. // Out of line virtual destructor for request interface class
  23. // necessary for proper destruction of derived request classes
  24. // via a pointer to an IRequest
  25. //
  26. IRequest::~IRequest() {}
  27. // ========================================================================
  28. //
  29. // CLASS ISubPart
  30. //
  31. // Interface class for the request body part (CEcbRequestBodyPart)
  32. // "sub parts". CEcbRequestBodyPart has two "modes" of operation
  33. // through which execution flows:
  34. //
  35. // 1. Accessing the first 48K of data which IIS caches in the ECB.
  36. // 2. Accessing remaining unread data from the ECB in the form of an
  37. // asynchronous read-once stream.
  38. //
  39. // An ISubPart is a stripped-down IBodyPart (..\inc\body.h) -- it does
  40. // not provide any Rewind() semantics because there's nothing that
  41. // needs to (or can be) rewound. It does, however, provide a function
  42. // to proceed from one mode to the next.
  43. //
  44. class CEcbRequestBodyPart;
  45. class ISubPart
  46. {
  47. // NOT IMPLEMENTED
  48. //
  49. ISubPart& operator=( const ISubPart& );
  50. ISubPart( const ISubPart& );
  51. protected:
  52. ISubPart() {}
  53. public:
  54. // CREATORS
  55. //
  56. virtual ~ISubPart() = 0;
  57. // ACCESSORS
  58. //
  59. virtual ULONG CbSize() const = 0;
  60. virtual ISubPart * NextPart( CEcbRequestBodyPart& part ) const = 0;
  61. // MANIPULATORS
  62. //
  63. virtual VOID Accept( IBodyPartVisitor& v,
  64. UINT ibPos,
  65. IAcceptObserver& obsAccept ) = 0;
  66. };
  67. // ------------------------------------------------------------------------
  68. //
  69. // ISubPart::~ISubPart()
  70. //
  71. // Out of line virtual destructor necessary for proper deletion
  72. // of objects of derived classes via this class
  73. //
  74. ISubPart::~ISubPart()
  75. {
  76. }
  77. // ========================================================================
  78. //
  79. // CLASS CEcbCache
  80. //
  81. //
  82. //
  83. class CEcbCache : public ISubPart
  84. {
  85. //
  86. // Our IEcb. Note that this is a C++ reference and not
  87. // a auto_ref_ptr. This is simply an optimization since
  88. // lifetime of CEcbCache is entirely scoped by the lifetime
  89. // of the request body which in turn is scoped by the
  90. // lifetime of the request which holds an auto_ref_ptr
  91. // to the IEcb.
  92. //
  93. IEcb& m_ecb;
  94. // NOT IMPLEMENTED
  95. //
  96. CEcbCache& operator=( const CEcbCache& );
  97. CEcbCache( const CEcbCache& );
  98. public:
  99. // CREATORS
  100. //
  101. CEcbCache( IEcb& ecb ) : m_ecb(ecb) {}
  102. // ACCESSORS
  103. //
  104. ULONG CbSize() const { return m_ecb.CbAvailable(); }
  105. ISubPart * NextPart( CEcbRequestBodyPart& ecbRequestBodyPart ) const;
  106. // MANIPULATORS
  107. //
  108. VOID Accept( IBodyPartVisitor& v,
  109. UINT ibPos,
  110. IAcceptObserver& obsAccept );
  111. };
  112. // ========================================================================
  113. //
  114. // CLASS CEcbStream
  115. //
  116. // Accesses remaining unread data from the ECB in the form of an
  117. // asynchronous read-once stream.
  118. //
  119. class CEcbStream :
  120. public ISubPart,
  121. private IAsyncStream,
  122. private IAsyncWriteObserver,
  123. private IIISAsyncIOCompleteObserver
  124. {
  125. //
  126. // Size of the static buffer that we read into. This buffer
  127. // improves performance by reducing the number of times we
  128. // have to call into IIS to read data from the ECB when we
  129. // are being called to read only a few bytes at a time.
  130. //
  131. enum
  132. {
  133. CB_BUF = 32 * 1024 //$??? Is 32K reasonable?
  134. };
  135. //
  136. // Ref back to our request object. This need not be a counted
  137. // ref because its lifetime scopes ours AS LONG AS we add a ref
  138. // when starting any async operation which could extend our
  139. // lifetime -- i.e. an async read from the ECB.
  140. //
  141. IRequest& m_request;
  142. //
  143. // Ref to the IEcb. This need not be a counted ref because its
  144. // lifetime, like ours, is scoped by the lifetime of the request
  145. // object.
  146. //
  147. IEcb& m_ecb;
  148. //
  149. // Last error HRESULT. Used in state processing to determine
  150. // when to quit because of an error
  151. //
  152. HRESULT m_hr;
  153. //
  154. // Size of the ECB stream and the amount of data that has
  155. // been consumed (read into the buffer below).
  156. //
  157. DWORD m_dwcbStreamSize;
  158. DWORD m_dwcbStreamConsumed;
  159. //
  160. // The three states of the buffer:
  161. //
  162. // IDLE
  163. // Data is present in the buffer or the buffer is empty
  164. // because we've reached the end of the stream. The
  165. // buffer is not being filled.
  166. //
  167. // FILLING
  168. // The buffer is in the process of being filled from the stream.
  169. // Data may or may not already be present. Nobody is waiting
  170. // on the data.
  171. //
  172. // FAULTING
  173. // The buffer is in the process of being filled from the stream.
  174. // There is no data present. A caller pended and needs to be
  175. // notified when data becomes available.
  176. //
  177. // WRITE_ERROR
  178. // This state is only enterable if the stream is in a CopyTo()
  179. // operation. See CEcbStream::WriteComplete() and
  180. // CEcbStream::FillComplete() for the conditions under which
  181. // the buffer is in this state.
  182. //
  183. enum
  184. {
  185. STATUS_IDLE,
  186. STATUS_FILLING,
  187. STATUS_FAULTING,
  188. STATUS_WRITE_ERROR
  189. };
  190. mutable LONG m_lBufStatus;
  191. //
  192. // AsyncRead()/AsyncCopyTo() observer to notify as soon as the
  193. // stream is ready after FAULTING in data.
  194. //
  195. union
  196. {
  197. IAsyncReadObserver * m_pobsAsyncRead;
  198. IAsyncCopyToObserver * m_pobsAsyncCopyTo;
  199. };
  200. //
  201. // Wakeup functions and function pointer used to get processing
  202. // started again after an AsyncRead() or AsyncCopyTo() request
  203. // returns because data has to be faulted into the buffer.
  204. // All these functions do is notify their associated observer
  205. // (m_pobsAsyncRead or m_pobsAsyncCopyTo).
  206. //
  207. VOID WakeupAsyncRead();
  208. VOID WakeupAsyncCopyTo();
  209. typedef VOID (CEcbStream::*PFNWAKEUP)();
  210. PFNWAKEUP m_pfnWakeup;
  211. //
  212. // Hint as to the amount of data that we can expect to
  213. // be returned from a single async read from the
  214. // read-once ECB stream. Used to help fully utilize
  215. // the available space in the buffer. The hint is the
  216. // historical maximum over all of the previous reads.
  217. //
  218. UINT m_cbBufFillHint;
  219. //
  220. // Indices into the buffer that implement the 'ring' property.
  221. //
  222. // The Fill index (m_ibBufFill) is where data is read into the
  223. // buffer from the async stream.
  224. //
  225. // The Drain index (m_ibBufDrain) is where data is read from or
  226. // copied out of the buffer.
  227. //
  228. // The Wrap index (m_ibBufWrap) is used by the drainer to tell
  229. // it where the data in the buffer ends. This is needed because
  230. // we may not have filled all the way to the end of the buffer.
  231. // m_ibBufWrap has no meaning until m_ibBufDrain > m_ibBufFill,
  232. // so we explicitly leave it unitialized at construction time.
  233. //
  234. // The ring property of the buffer holds if and only if the
  235. // following condition is met:
  236. //
  237. // m_ibBufDrain <= m_ibBufFill
  238. // Data exists in the half-open interval [m_ibBufDrain,m_ibBufFill).
  239. //
  240. // m_ibBufDrain > m_ibBufFill
  241. // Data exists in the half-open interval [m_ibBufDrain,m_ibBufWrap)
  242. // and the half-open interval [0,m_ibBufFill).
  243. //
  244. UINT m_ibBufFill;
  245. mutable UINT m_ibBufDrain;
  246. mutable UINT m_ibBufWrap;
  247. //
  248. // Static buffer for requests of less than CB_BUF bytes.
  249. // Note that this variable is located at the END of the class
  250. // definition to make debugging in CDB easier -- all of the
  251. // other member variables are visible up front.
  252. //
  253. BYTE m_rgbBuf[CB_BUF];
  254. //
  255. // Debugging variables for easy (yeah, right) detection
  256. // of async buffering problems and interactions with
  257. // external streams.
  258. //
  259. #ifdef DBG
  260. UINT dbgm_cbBufDrained;
  261. UINT dbgm_cbBufAvail;
  262. UINT dbgm_cbToCopy;
  263. LONG dbgm_cRefAsyncWrite;
  264. #endif
  265. //
  266. // IAsyncWriteObserver
  267. //
  268. void AddRef();
  269. void Release();
  270. VOID WriteComplete( UINT cbWritten,
  271. HRESULT hr );
  272. //
  273. // IAsyncStream
  274. //
  275. UINT CbReady() const;
  276. VOID AsyncRead( BYTE * pbBuf,
  277. UINT cbBuf,
  278. IAsyncReadObserver& obsAsyncRead );
  279. VOID AsyncCopyTo( IAsyncStream& stmDst,
  280. UINT cbToCopy,
  281. IAsyncCopyToObserver& obsAsyncCopyTo );
  282. //
  283. // IIISAsyncIOCompleteObserver
  284. //
  285. VOID IISIOComplete( DWORD dwcbRead,
  286. DWORD dwLastError );
  287. //
  288. // Buffer functions
  289. //
  290. VOID AsyncFillBuf();
  291. VOID FillComplete();
  292. HRESULT HrBufReady( UINT * pcbBufReady,
  293. const BYTE ** ppbBufReady ) const;
  294. UINT CbBufReady() const;
  295. const BYTE * PbBufReady() const;
  296. VOID DrainComplete( UINT cbDrained );
  297. // NOT IMPLEMENTED
  298. //
  299. CEcbStream& operator=( const CEcbStream& );
  300. CEcbStream( const CEcbStream& );
  301. public:
  302. // CREATORS
  303. //
  304. CEcbStream( IEcb& ecb,
  305. IRequest& request ) :
  306. m_ecb(ecb),
  307. m_request(request),
  308. m_hr(S_OK),
  309. m_dwcbStreamSize(ecb.CbTotalBytes() - ecb.CbAvailable()),
  310. m_dwcbStreamConsumed(0),
  311. m_lBufStatus(STATUS_IDLE),
  312. m_cbBufFillHint(0),
  313. m_ibBufFill(0),
  314. #ifdef DBG
  315. dbgm_cbBufDrained(0),
  316. dbgm_cbBufAvail(0),
  317. dbgm_cRefAsyncWrite(0),
  318. #endif
  319. m_ibBufDrain(0),
  320. m_ibBufWrap(static_cast<UINT>(-1))
  321. {
  322. }
  323. // ACCESSORS
  324. //
  325. ULONG CbSize() const
  326. {
  327. //
  328. // Return the size of the stream. Normally this is just
  329. // the value we initialized above. But for chunked requests
  330. // this value changes as soon as we know the real
  331. // size of the request.
  332. //
  333. return m_dwcbStreamSize;
  334. }
  335. ISubPart * NextPart( CEcbRequestBodyPart& part ) const
  336. {
  337. //
  338. // The stated size of the CEcbRequestBodyPart should keep
  339. // us from ever getting here.
  340. //
  341. TrapSz( "CEcbStream is the last sub-part. There is NO next part!" );
  342. return NULL;
  343. }
  344. // MANIPULATORS
  345. //
  346. VOID Accept( IBodyPartVisitor& v,
  347. UINT ibPos,
  348. IAcceptObserver& obsAccept );
  349. };
  350. // ========================================================================
  351. //
  352. // CLASS CEcbRequestBodyPart
  353. //
  354. class CEcbRequestBodyPart : public IBodyPart
  355. {
  356. //
  357. // Position in the entire body part at the time of the most recent
  358. // call to Accept(). This value is used to compute the number of
  359. // bytes accepted by the previous call so that the sub-parts can
  360. // be properly positioned for the next call.
  361. //
  362. ULONG m_ibPosLast;
  363. //
  364. // The sub-parts
  365. //
  366. //$NYI If we ever need caching of data from the ECB stream again,
  367. //$NYI it should be implemented as a third sub-part comprised of
  368. //$NYI or derived from a CTextBodyPart.
  369. //
  370. CEcbCache m_partEcbCache;
  371. CEcbStream m_partEcbStream;
  372. //
  373. // Pointer to the current sub-part
  374. //
  375. ISubPart * m_pPart;
  376. //
  377. // Position in the current sub-part
  378. //
  379. ULONG m_ibPart;
  380. // NOT IMPLEMENTED
  381. //
  382. CEcbRequestBodyPart& operator=( const CEcbRequestBodyPart& );
  383. CEcbRequestBodyPart( const CEcbRequestBodyPart& );
  384. public:
  385. CEcbRequestBodyPart( IEcb& ecb,
  386. IRequest& request ) :
  387. m_partEcbCache(ecb),
  388. m_partEcbStream(ecb, request)
  389. {
  390. Rewind();
  391. }
  392. // ACCESSORS
  393. //
  394. UINT64 CbSize64() const
  395. {
  396. //
  397. // The size of the whole really is the sum of its parts.
  398. // But -- and this is a big but -- the reported size of
  399. // the stream may change, so we must not cache its value.
  400. // The reason is that chunked requests may not have a
  401. // Content-Length so the final size is not known until
  402. // we have read the entire stream.
  403. //
  404. return m_partEcbCache.CbSize() + m_partEcbStream.CbSize();
  405. }
  406. // MANIPULATORS
  407. //
  408. ISubPart& EcbCachePart() { return m_partEcbCache; }
  409. ISubPart& EcbStreamPart() { return m_partEcbStream; }
  410. VOID Rewind();
  411. VOID Accept( IBodyPartVisitor& v,
  412. UINT64 ibPos64,
  413. IAcceptObserver& obsAccept );
  414. };
  415. // ------------------------------------------------------------------------
  416. //
  417. // CEcbRequestBodyPart::Rewind()
  418. //
  419. VOID
  420. CEcbRequestBodyPart::Rewind()
  421. {
  422. m_ibPosLast = 0;
  423. m_pPart = &m_partEcbCache;
  424. m_ibPart = 0;
  425. }
  426. // ------------------------------------------------------------------------
  427. //
  428. // CEcbRequestBodyPart::Accept()
  429. //
  430. VOID
  431. CEcbRequestBodyPart::Accept( IBodyPartVisitor& v,
  432. UINT64 ibPos64,
  433. IAcceptObserver& obsAccept )
  434. {
  435. UINT ibPos;
  436. // NOTE: To be compatable with IBodyPart the position is passed
  437. // in as 64 bit value (this is necessary to support file body parts
  438. // that are bigger than 4GB). However we do not want anyone to create
  439. // text body parts that are bigger than 4GB. So assert that it is not
  440. // the case here and truncate the passed in 64 bit value to 32 bits.
  441. //
  442. Assert(0 == (0xFFFFFFFF00000000 & ibPos64));
  443. ibPos = static_cast<UINT>(ibPos64);
  444. //
  445. // Check our assumption that the position has increased since the
  446. // last call by not more than what was left of the current sub-part.
  447. //
  448. Assert( ibPos >= m_ibPosLast );
  449. Assert( ibPos - m_ibPosLast <= m_pPart->CbSize() - m_ibPart );
  450. //
  451. // Adjust the position of the current sub-part by the
  452. // previously accepted amount.
  453. //
  454. m_ibPart += ibPos - m_ibPosLast;
  455. //
  456. // Remember the current position so that we can do the above
  457. // computations again the next time through.
  458. //
  459. m_ibPosLast = ibPos;
  460. //
  461. // If we're at the end of the current sub-part, go on to the next one.
  462. //
  463. while ( m_ibPart == m_pPart->CbSize() )
  464. {
  465. m_pPart = m_pPart->NextPart(*this);
  466. m_ibPart = 0;
  467. }
  468. //
  469. // Forward the accept call to the current sub-part
  470. //
  471. m_pPart->Accept( v, m_ibPart, obsAccept );
  472. }
  473. // ========================================================================
  474. //
  475. // CLASS CEcbCache
  476. //
  477. // Accessing the first 48K of data which IIS caches in the ECB.
  478. //
  479. // ------------------------------------------------------------------------
  480. //
  481. // CEcbCache::Accept()
  482. //
  483. VOID
  484. CEcbCache::Accept( IBodyPartVisitor& v,
  485. UINT ibPos,
  486. IAcceptObserver& obsAccept )
  487. {
  488. //
  489. // Limit the request to just the amount of data cached in the ECB.
  490. //
  491. v.VisitBytes( m_ecb.LpbData() + ibPos,
  492. m_ecb.CbAvailable() - ibPos,
  493. obsAccept );
  494. }
  495. // ------------------------------------------------------------------------
  496. //
  497. // CEcbCache::NextPart()
  498. //
  499. ISubPart *
  500. CEcbCache::NextPart( CEcbRequestBodyPart& ecbRequestBodyPart ) const
  501. {
  502. return &ecbRequestBodyPart.EcbStreamPart();
  503. }
  504. // ========================================================================
  505. //
  506. // CLASS CEcbStream
  507. //
  508. // ------------------------------------------------------------------------
  509. //
  510. // CEcbStream::AddRef()
  511. //
  512. void
  513. CEcbStream::AddRef()
  514. {
  515. m_request.AddRef();
  516. }
  517. // ------------------------------------------------------------------------
  518. //
  519. // CEcbStream::Accept()
  520. //
  521. void
  522. CEcbStream::Release()
  523. {
  524. m_request.Release();
  525. }
  526. // ------------------------------------------------------------------------
  527. //
  528. // CEcbStream::Accept()
  529. //
  530. VOID
  531. CEcbStream::Accept( IBodyPartVisitor& v,
  532. UINT ibPos,
  533. IAcceptObserver& obsAccept )
  534. {
  535. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::Accept() ibPos = %u\n", GetCurrentThreadId(), this, ibPos );
  536. v.VisitStream( *this,
  537. m_dwcbStreamSize - ibPos,
  538. obsAccept );
  539. }
  540. // ------------------------------------------------------------------------
  541. //
  542. // CEcbStream::CbReady()
  543. //
  544. // Returns the number of bytes that are instantly available to be read.
  545. //
  546. UINT
  547. CEcbStream::CbReady() const
  548. {
  549. return CbBufReady();
  550. }
  551. // ------------------------------------------------------------------------
  552. //
  553. // CEcbStream::AsyncRead()
  554. //
  555. VOID
  556. CEcbStream::AsyncRead( BYTE * pbBufCaller,
  557. UINT cbToRead,
  558. IAsyncReadObserver& obsAsyncRead )
  559. {
  560. //
  561. // Don't assert that cbToRead > 0. It is a valid request to read 0
  562. // bytes from the stream. The net effect of such a call is to just
  563. // start/resume asynchronously filling the buffer.
  564. //
  565. // Assert( cbToRead > 0 );
  566. //
  567. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::AsyncRead() cbToRead = %u\n", GetCurrentThreadId(), this, cbToRead );
  568. //
  569. // Stash away the observer and wakeup method so that if
  570. // the call to HrBufReady() returns E_PENDING then then
  571. // wakeup function will be called when the data becomes
  572. // available.
  573. //
  574. m_pobsAsyncRead = &obsAsyncRead;
  575. m_pfnWakeup = WakeupAsyncRead;
  576. //
  577. // Start/Continue asynchronously filling the buffer
  578. //
  579. AsyncFillBuf();
  580. //
  581. // Check whether the buffer has data available to be read. If so, then
  582. // read it into the caller's buffer. If not, then it will wake us up
  583. // when data becomes available.
  584. //
  585. UINT cbBufReady;
  586. const BYTE * pbBufReady;
  587. HRESULT hr = HrBufReady( &cbBufReady, &pbBufReady );
  588. if ( FAILED(hr) )
  589. {
  590. //
  591. // If HrBufReady() returns a "real" error, then report it.
  592. //
  593. if ( E_PENDING != hr )
  594. obsAsyncRead.ReadComplete(0, hr);
  595. //
  596. // HrBufReady() returns E_PENDING if there is no data immediately
  597. // available. If it does then it will wake us up when data
  598. // becomes available.
  599. //
  600. return;
  601. }
  602. //
  603. // Limit what we read to the minimum of what's available in the
  604. // buffer or what was asked for. Keep in mind that cbBufReady or
  605. // cbToRead may be 0.
  606. //
  607. cbToRead = min(cbToRead, cbBufReady);
  608. //
  609. // Copy whatever is to be read from the I/O buffer into
  610. // the caller's buffer.
  611. //
  612. if ( cbToRead )
  613. {
  614. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::AsyncRead() %lu bytes to read\n", GetCurrentThreadId(), this, cbToRead );
  615. Assert( !IsBadWritePtr(pbBufCaller, cbToRead) );
  616. //
  617. // Copy data from our buffer into the caller's
  618. //
  619. memcpy( pbBufCaller, pbBufReady, cbToRead );
  620. //
  621. // Tell our buffer how much we've consumed so it can
  622. // continue to fill and replace what we consumed.
  623. //
  624. DrainComplete( cbToRead );
  625. }
  626. //
  627. // Tell our observer that we're done.
  628. //
  629. obsAsyncRead.ReadComplete(cbToRead, S_OK);
  630. }
  631. // ------------------------------------------------------------------------
  632. //
  633. // CEcbStream::WakeupAsyncRead()
  634. //
  635. // Called by FillComplete() when the buffer returns to IDLE after
  636. // FAULTING because an observer pended trying to access an empty buffer
  637. // while the buffer was FILLING.
  638. //
  639. VOID
  640. CEcbStream::WakeupAsyncRead()
  641. {
  642. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::WakeupAsyncRead()\n", GetCurrentThreadId(), this );
  643. //
  644. // Now that that the buffer is ready, tell the observer to try again.
  645. //
  646. m_pobsAsyncRead->ReadComplete(0, S_OK);
  647. }
  648. // ------------------------------------------------------------------------
  649. //
  650. // CEcbStream::AsyncCopyTo
  651. //
  652. // Called by FillComplete() when the buffer returns to IDLE after
  653. // FAULTING because an observer pended trying to access an empty buffer
  654. // while the buffer was FILLING.
  655. //
  656. VOID
  657. CEcbStream::AsyncCopyTo( IAsyncStream& stmDst,
  658. UINT cbToCopy,
  659. IAsyncCopyToObserver& obsAsyncCopyTo )
  660. {
  661. Assert( cbToCopy > 0 );
  662. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::AsyncCopyTo() cbToCopy = %u\n", GetCurrentThreadId(), this, cbToCopy );
  663. //
  664. // Stash away the observer and wakeup method so that if
  665. // the call to HrBufReady() returns E_PENDING then the
  666. // wakeup function will be called when the data becomes
  667. // available.
  668. //
  669. m_pobsAsyncCopyTo = &obsAsyncCopyTo;
  670. m_pfnWakeup = WakeupAsyncCopyTo;
  671. //
  672. // Start/Continue asynchronously filling the buffer
  673. //
  674. AsyncFillBuf();
  675. //
  676. // Check whether the buffer has data available to be read. If so, then
  677. // copy it to the caller's stream. If not, then it will wake us up
  678. // when data becomes available.
  679. //
  680. UINT cbBufReady;
  681. const BYTE * pbBufReady;
  682. HRESULT hr = HrBufReady( &cbBufReady, &pbBufReady );
  683. if ( FAILED(hr) )
  684. {
  685. //
  686. // If HrBufReady() returns a "real" error, then report it.
  687. //
  688. if ( E_PENDING != hr )
  689. obsAsyncCopyTo.CopyToComplete(0, hr);
  690. //
  691. // HrBufReady() returns E_PENDING if there is no data immediately
  692. // available. If it does then it will wake us up when data
  693. // becomes available.
  694. //
  695. return;
  696. }
  697. //
  698. // Limit what we copy to the minimum of what's available in the
  699. // buffer or what was asked for. Keep in mind cbBufReady may
  700. // be 0.
  701. //
  702. cbToCopy = min(cbToCopy, cbBufReady);
  703. //
  704. // Write whatever there is to write, if anything. If there is
  705. // nothing to write then notify the observer immediately that
  706. // we're done -- i.e. do not ask the destination stream to
  707. // write 0 bytes.
  708. //
  709. if ( cbToCopy )
  710. {
  711. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::AsyncCopyTo() %lu bytes to copy\n", GetCurrentThreadId(), this, cbToCopy );
  712. #ifdef DBG
  713. //
  714. // In DBG builds, remember how much we're writing so that
  715. // we can quickly catch streams that do something stupid
  716. // like tell our WriteComplete() that it wrote more than
  717. // we asked it to.
  718. //
  719. dbgm_cbToCopy = cbToCopy;
  720. #endif
  721. //
  722. // We should only ever be doing one AsyncWrite() at a time.
  723. //
  724. Assert( InterlockedIncrement(&dbgm_cRefAsyncWrite) == 1 );
  725. stmDst.AsyncWrite( pbBufReady, cbToCopy, *this );
  726. }
  727. else
  728. {
  729. obsAsyncCopyTo.CopyToComplete(0, S_OK);
  730. }
  731. }
  732. // ------------------------------------------------------------------------
  733. //
  734. // CEcbStream::WakeupAsyncCopyTo()
  735. //
  736. VOID
  737. CEcbStream::WakeupAsyncCopyTo()
  738. {
  739. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::WakeupAsyncCopyTo()\n", GetCurrentThreadId(), this );
  740. //
  741. // Now that that the buffer is ready, tell the observer to try again.
  742. //
  743. m_pobsAsyncCopyTo->CopyToComplete(0, S_OK);
  744. }
  745. // ------------------------------------------------------------------------
  746. //
  747. // CEcbStream::WriteComplete
  748. //
  749. VOID
  750. CEcbStream::WriteComplete(
  751. UINT cbWritten,
  752. HRESULT hr )
  753. {
  754. //
  755. // Make sure the stream isn't telling us it wrote more than we asked for!
  756. //
  757. Assert( dbgm_cbToCopy >= cbWritten );
  758. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::WriteComplete() %u "
  759. "bytes written (0x%08lX)\n", GetCurrentThreadId(),
  760. this, cbWritten, hr );
  761. //
  762. // If no error has occurred, we want to call DrainComplete as soon as
  763. // possible, as it will begin another AsyncFillBuf to fill in the part of
  764. // the buffer that was drained.
  765. //
  766. // However, in the case of error, we do not want to call DrainComplete
  767. // before the error gets set into m_hr and the state of the stream gets
  768. // set to STATUS_WRITE_ERROR. We don't want to call AsyncFillBuf without
  769. // the error latched in, or it will start another async. operation, which
  770. // is not good since we've already errored!
  771. //
  772. if (SUCCEEDED(hr))
  773. DrainComplete( cbWritten );
  774. //
  775. // We should only ever do one AsyncWrite() at a time. Assert that.
  776. //
  777. Assert( InterlockedDecrement(&dbgm_cRefAsyncWrite) == 0 );
  778. //
  779. // If the async write completed successfully just notify the CopyTo observer.
  780. //
  781. if ( SUCCEEDED(hr) )
  782. {
  783. m_pobsAsyncCopyTo->CopyToComplete( cbWritten, hr );
  784. }
  785. //
  786. // Otherwise things get a little tricky....
  787. //
  788. else
  789. {
  790. //
  791. // Normally we would just notify the CopyTo observer of the error.
  792. // But if we are FILLING that could be a bad idea. When we notify
  793. // the observer it will most likely send back an error to the client
  794. // via async I/O. If we are still FILLING at that point then we would
  795. // have multiple async I/Os outstanding which is a Bad Thing(tm) --
  796. // ECB leaks making the web service impossible to shut down, etc.
  797. //
  798. // So instead of notifying the observer unconditionally we latch
  799. // in the error and transition to a WRITE_ERROR state. If the
  800. // previous state was FILLING then don't notify the observer.
  801. // CEcbStream::FillComplete() will notify the observer when
  802. // FILLING completes (i.e. when it is safe to do another async I/O).
  803. // If the previous state was IDLE (and it must have been either IDLE
  804. // or FILLING) then it is safe to notify the observer because
  805. // the transition to WRITE_ERROR prevents any new filling operations
  806. // from starting.
  807. //
  808. //
  809. // Latch in the error now. FillComplete() can potentially send
  810. // the error response immediately after we change state below.
  811. //
  812. m_hr = hr;
  813. //
  814. // Change state. If the previous state was IDLE then it is safe
  815. // to notify the observer from this thread. No other thread can
  816. // start FILLING once the state changes.
  817. //
  818. LONG lBufStatusPrev = InterlockedExchange( &m_lBufStatus, STATUS_WRITE_ERROR );
  819. //
  820. // Now that we've latched in the errors, we can safely call
  821. // DrainComplete. AsyncFillBuf checks that the state of the
  822. // stream is NOT STATUS_WRITE_ERROR before beginning an
  823. // asynchronous read.
  824. //
  825. DrainComplete( cbWritten );
  826. if ( STATUS_IDLE == lBufStatusPrev )
  827. {
  828. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::WriteComplete() - Error writing. Notifying CopyTo observer.\n", GetCurrentThreadId(), this );
  829. m_pobsAsyncCopyTo->CopyToComplete( cbWritten, hr );
  830. }
  831. else
  832. {
  833. //
  834. // The previous state was not IDLE, so it must have
  835. // been FILLING. In no other state could we have been
  836. // writing.
  837. //
  838. Assert( STATUS_FILLING == lBufStatusPrev );
  839. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::WriteComplete() - Error writing while filling. FillComplete() will notify CopyTo observer\n", GetCurrentThreadId(), this );
  840. }
  841. }
  842. }
  843. // ------------------------------------------------------------------------
  844. //
  845. // CEcbStream::DrainComplete()
  846. //
  847. // Called by AsyncRead() and WriteComplete() when draining (consuming)
  848. // data from the buffer. This function updates the drain position of
  849. // the buffer and allows the buffer to continue filling the space
  850. // just drained.
  851. //
  852. VOID
  853. CEcbStream::DrainComplete( UINT cbDrained )
  854. {
  855. #ifdef DBG
  856. dbgm_cbBufDrained += cbDrained;
  857. UINT cbBufAvail = InterlockedExchangeAdd( reinterpret_cast<LONG *>(&dbgm_cbBufAvail),
  858. -static_cast<LONG>(cbDrained) );
  859. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: !!!CEcbStream::DrainComplete() %lu left to write (%u in buffer)\n", GetCurrentThreadId(), this, m_dwcbStreamSize - dbgm_cbBufDrained, cbBufAvail );
  860. Assert( dbgm_cbBufDrained <= m_dwcbStreamConsumed );
  861. #endif
  862. //
  863. // Update the drain position of the buffer. Don't wrap here.
  864. // We wrap only in CbBufReady().
  865. //
  866. m_ibBufDrain += cbDrained;
  867. //
  868. // Resume/Continue filling the buffer
  869. //
  870. AsyncFillBuf();
  871. }
  872. // ------------------------------------------------------------------------
  873. //
  874. // CEcbStream::CbBufReady()
  875. //
  876. UINT
  877. CEcbStream::CbBufReady() const
  878. {
  879. //
  880. // Poll the filling position now so that it doesn't change
  881. // between the time we do the comparison below and the time
  882. // we use its value.
  883. //
  884. UINT ibBufFill = m_ibBufFill;
  885. //
  886. // If the fill position is still ahead of the drain position
  887. // then the amount of data available is simply the difference
  888. // between the two.
  889. //
  890. if ( ibBufFill >= m_ibBufDrain )
  891. {
  892. return ibBufFill - m_ibBufDrain;
  893. }
  894. //
  895. // If the fill position is behind the drain then the fillling
  896. // side must have wrapped. If the drain position has not yet
  897. // reached the wrap position then the amount of data available
  898. // is the difference between the two.
  899. //
  900. else if ( m_ibBufDrain < m_ibBufWrap )
  901. {
  902. Assert( ibBufFill < m_ibBufDrain );
  903. Assert( m_ibBufWrap != static_cast<UINT>(-1) );
  904. return m_ibBufWrap - m_ibBufDrain;
  905. }
  906. //
  907. // Otherwise the fill position has wrapped and the drain
  908. // position has reached the wrap position so wrap the
  909. // drain position back to the beginning. At that point
  910. // the amount of data available will be the difference
  911. // between the fill and the drain positions.
  912. //
  913. else
  914. {
  915. Assert( ibBufFill < m_ibBufDrain );
  916. Assert( m_ibBufDrain == m_ibBufWrap );
  917. Assert( m_ibBufWrap != static_cast<UINT>(-1) );
  918. m_ibBufWrap = static_cast<UINT>(-1);
  919. m_ibBufDrain = 0;
  920. return m_ibBufFill;
  921. }
  922. }
  923. // ------------------------------------------------------------------------
  924. //
  925. // CEcbStream::PbBufReady()
  926. //
  927. const BYTE *
  928. CEcbStream::PbBufReady() const
  929. {
  930. return m_rgbBuf + m_ibBufDrain;
  931. }
  932. // ------------------------------------------------------------------------
  933. //
  934. // CEcbStream::AsyncFillBuf()
  935. //
  936. // Starts asynchronously filling the buffer. The buffer may not (and
  937. // usually won't) fill up with just one call. Called by:
  938. //
  939. // AsyncRead()/AsyncCopyTo()
  940. // to start filling the buffer for the read/copy request.
  941. //
  942. // DrainComplete()
  943. // to resume filling the buffer after draining some amount
  944. // from a previously full buffer.
  945. //
  946. // IISIOComplete()
  947. // to continue filling the buffer after the initial call.
  948. //
  949. VOID
  950. CEcbStream::AsyncFillBuf()
  951. {
  952. //
  953. // Don't do anything if the buffer is already FILLING (or FAULTING).
  954. // We can have only one outstanding async I/O at once. If the buffer
  955. // is IDLE, then start filling.
  956. //
  957. if ( STATUS_IDLE != InterlockedCompareExchange(
  958. &m_lBufStatus,
  959. STATUS_FILLING,
  960. STATUS_IDLE ) )
  961. return;
  962. //
  963. // Important!!! The following checks CANNOT be moved outside
  964. // the 'if' clause above without introducing the possibility
  965. // of having multiple outstanding async I/O operations.
  966. // So don't even consider that "optimization".
  967. //
  968. //
  969. // First, check whether we are in an error state. If we are
  970. // then don't try to read any more data. The stream is ready
  971. // with whatever data (if any) is already there when it goes
  972. // idle.
  973. //
  974. if ( FAILED(m_hr) )
  975. {
  976. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::FReadyBuf() m_hr = 0x%08lX\n", GetCurrentThreadId(), this, m_hr );
  977. FillComplete();
  978. return;
  979. }
  980. //
  981. // If we've read everything there is to read, then the buffer
  982. // is ready (though it may be empty) once we return to idle.
  983. // The only time we would not be idle in this case is if the
  984. // thread completing the final read is in IISIOComplete() and
  985. // has updated m_dwcbStreamConsumed, but has not yet returned
  986. // the status to idle.
  987. //
  988. if ( m_dwcbStreamConsumed == m_dwcbStreamSize )
  989. {
  990. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::FReadyBuf() End Of Stream\n", GetCurrentThreadId(), this );
  991. FillComplete();
  992. return;
  993. }
  994. //
  995. // Poll the current drain position and use the polled value
  996. // for all of the calculations below to keep them self-consistent.
  997. // We would have serious problems if the drain position were to
  998. // change (specifically, if it were to wrap) while we were in
  999. // the middle of things.
  1000. //
  1001. UINT ibBufDrain = m_ibBufDrain;
  1002. Assert( m_ibBufFill < CB_BUF );
  1003. Assert( ibBufDrain <= CB_BUF );
  1004. //
  1005. // If there's no space to fill, then we can't do anything more.
  1006. // The buffer is already full of data. Note that the situation
  1007. // can change the instant after we do the comparison below.
  1008. // In particular, if another thread is draining the buffer at
  1009. // the same time, it is possible that there may be no data
  1010. // available by the time we return TRUE. Callers which
  1011. // allow data to be drained asynchronously must be prepared
  1012. // to deal with this.
  1013. //
  1014. if ( (m_ibBufFill + 1) % CB_BUF == ibBufDrain % CB_BUF )
  1015. {
  1016. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::FReadyBuf() buffer full\n", GetCurrentThreadId(), this );
  1017. FillComplete();
  1018. return;
  1019. }
  1020. // Ideally, we could read up to as much data as is left in the stream.
  1021. //
  1022. UINT cbFill = m_dwcbStreamSize - m_dwcbStreamConsumed;
  1023. //
  1024. // But that amount is limited by the amount of buffer available
  1025. // for filling. If the current fill position in the buffer is
  1026. // ahead of (greater than) the drain position, that amount is
  1027. // the greater of the distance from the current fill position
  1028. // to the end of the buffer or the distance from the beginning
  1029. // of the buffer to the current drain position. If the fill
  1030. // position is behind (less than) the drain position, the amount
  1031. // is simply the distance from the fill position to the drain
  1032. // position.
  1033. //
  1034. if ( m_ibBufFill == ibBufDrain )
  1035. {
  1036. // Case 1.
  1037. //
  1038. // The buffer is empty so wrap both the fill and drain
  1039. // positions back to the beginning of the buffer to get
  1040. // maximum usage of the buffer. Note that it is safe for
  1041. // us (the filling code) to move m_ibBufDrain here because
  1042. // there can be nobody draining the buffer at this point -- it's empty!
  1043. //
  1044. // Note that above comment is NOT correct (but leave it here to that it's
  1045. // easy to understand why the following code is necessary). We can't assume
  1046. // nobody is draing the buffer at the same time, because the draining
  1047. // side may be in the middle of checking buffer status, say it's calling
  1048. // CbBufReady() to check the number of bytes availble, if this happens
  1049. // right after we set m_ibBufFill to 0 and before set m_ibBufDrain to 0,
  1050. // then CbBufReady() will report the buffer as not empty and we end up
  1051. // reading garbage data or crash.
  1052. //
  1053. if (STATUS_FAULTING == m_lBufStatus)
  1054. {
  1055. // Case 1.1
  1056. // This is what the original code looks like. this code is safe only
  1057. // when the status if in FAULING state, which means the draining side
  1058. // is in waiting state already.
  1059. // We have:
  1060. //
  1061. // [_________________________________________________]
  1062. // ^
  1063. // m_ibBufFill == ibBufDrain
  1064. // (i.e. empty buffer)
  1065. //
  1066. // After filling, we will have:
  1067. //
  1068. // [DATADATADATADATADATADATADATADATADATADATADAT______]
  1069. // ^ ^
  1070. // ibBufDrain m_ibBufFill
  1071. //
  1072. m_ibBufFill = 0;
  1073. m_ibBufDrain = 0;
  1074. cbFill = min(cbFill, CB_BUF - 1);
  1075. }
  1076. // If the status is not FAULTING (which means the draining side is not in
  1077. // waiting state yet), one alternative is to wait for the status
  1078. // to turn to FAULTING, but that will drag the performance, because the whole
  1079. // design of this async draining/filling mechanism is to avoid any expensive
  1080. // synchronization.
  1081. else
  1082. {
  1083. // Though we can't move both pointers, we still want to fill as much
  1084. // as we can. so depends on whether the fill pointer in the lower half
  1085. // or higher half of the buffer, different approach is used.
  1086. //
  1087. if (m_ibBufFill < (CB_BUF - 1) / 2)
  1088. {
  1089. // Case 1.2 - similar logic to case 3
  1090. // We have:
  1091. //
  1092. // [_________________________________________________]
  1093. // ^
  1094. // m_ibBufFill == ibBufDrain
  1095. // (i.e. empty buffer)
  1096. //
  1097. // After filling, we will have:
  1098. //
  1099. // [___________DATADATADATADATADATADATADATADAT______]
  1100. // ^ ^
  1101. // ibBufDrain m_ibBufFill
  1102. //
  1103. cbFill = min(cbFill, CB_BUF - m_ibBufFill - !ibBufDrain);
  1104. }
  1105. else
  1106. {
  1107. // Case 1.3 - similiar logic to case 4.
  1108. // We have:
  1109. //
  1110. // [_________________________________________________]
  1111. // ^
  1112. // m_ibBufFill == ibBufDrain
  1113. // (i.e. empty buffer)
  1114. //
  1115. // After filling, we will have:
  1116. //
  1117. // [DATADATADATADATADAT______________________________]
  1118. // ^ ^
  1119. // m_ibBufFill m_ibBufWrap == ibBufDrain
  1120. // Yes, we touch both m_ibBufWrap and m_ibBufFill. However, as
  1121. // in case 4, we are safe here, because, CbBufReady() get ibBufFill
  1122. // first, and then access m_ibBufWrap etc.
  1123. // Here we are setting these two members in reverse order, so that,
  1124. // if CbBufReady() doesn't see the new m_ibBufFill, then it simply
  1125. // returns 0 as usual, If it does see the new m_ibBufFill, the m_ibBufWrap
  1126. // is already set and thus CbBufReady will reset both m_ibBufWrap and
  1127. // m_ibBufDRain.
  1128. //
  1129. // If this thread is here when CbBufReady is called, CbBufReady will
  1130. // return 0, which means buffer empty and will put draining side to wait
  1131. // Set the wrap position so that a draining thread will
  1132. // know when to wrap the drain position.
  1133. //
  1134. m_ibBufWrap = m_ibBufFill;
  1135. // If this thread is here when CbBufReady is called, Again, CbBufRead will
  1136. // return 0, which means buffer empty and will put draining side to wait
  1137. // Set the fill position back at the beginning of the buffer
  1138. //
  1139. m_ibBufFill = 0;
  1140. // If this thread is here when CbBufReady is called, CbBufReady will
  1141. // reset m_ibBufWrap to -1, and m_ibBufDrain to 0, which is exactly
  1142. // what we want.
  1143. cbFill = min(cbFill, ibBufDrain - 1);
  1144. }
  1145. }
  1146. Assert( cbFill > 0 );
  1147. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::FReadyBuf() m_ibBufFill == ibBufDrain (empty buffer). New values: m_cbBufFillHint = %u, m_ibBufFill = %u, ibBufDrain = %u, m_ibBufWrap = %u\n", GetCurrentThreadId(), this, m_cbBufFillHint, m_ibBufFill, ibBufDrain, m_ibBufWrap );
  1148. }
  1149. else if ( m_ibBufFill < ibBufDrain )
  1150. {
  1151. // Case 2
  1152. //
  1153. // We have:
  1154. //
  1155. // [DATADATA_______________DATADATADATADA***UNUSED***]
  1156. // ^ ^ ^
  1157. // m_ibBufFill ibBufDrain m_ibBufWrap
  1158. //
  1159. // After filling, we will have:
  1160. //
  1161. // [DATADATADATADATADATADA_DATADATADATADA***UNUSED***]
  1162. // ^^ ^
  1163. // |ibBufDrain m_ibBufWrap
  1164. // m_ibBufFill
  1165. //
  1166. cbFill = min(cbFill, ibBufDrain - m_ibBufFill - 1);
  1167. Assert( cbFill > 0 );
  1168. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::FReadyBuf() m_ibBufFill < ibBufDrain. New values: m_cbBufFillHint = %u, m_ibBufFill = %u, ibBufDrain = %u, m_ibBufWrap = %u\n", GetCurrentThreadId(), this, m_cbBufFillHint, m_ibBufFill, ibBufDrain, m_ibBufWrap );
  1169. }
  1170. else if ( ibBufDrain <= CB_BUF - m_ibBufFill ||
  1171. m_cbBufFillHint <= CB_BUF - m_ibBufFill )
  1172. {
  1173. // Case 3
  1174. Assert( m_ibBufFill > ibBufDrain );
  1175. //
  1176. // If ibBufDrain is 0 then we can't fill all the way to
  1177. // the end of the buffer (since the end of the buffer is
  1178. // synonymous with the beginning). To account for this
  1179. // we need to subtract 1 from cbFill if ibBufDrain is 0.
  1180. // We can do that without the ?: operator as long as the
  1181. // following holds true:
  1182. //
  1183. Assert( 0 == !ibBufDrain || 1 == !ibBufDrain );
  1184. //
  1185. // We have: v------v m_cbBufFillHint
  1186. //
  1187. // [________________DATADATADATADATADATADAT__________]
  1188. // ^ ^
  1189. // ibBufDrain m_ibBufFill
  1190. // -OR-
  1191. //
  1192. // We have: v------------v m_cbBufFillHint
  1193. //
  1194. // [DATADATADATADATADATADATADATADATADATADAT__________]
  1195. // ^ ^
  1196. // ibBufDrain m_ibBufFill
  1197. //
  1198. //
  1199. // After filling, we will have:
  1200. //
  1201. // [________________DATADATADATADATADATADATADATADATAD]
  1202. // ^ ^ ^
  1203. // m_ibBufFill ibBufDrain m_ibBufWrap
  1204. //
  1205. // -OR-
  1206. //
  1207. // [DATADATADATADATADATADATADATADATADATADATADATADATA_]
  1208. // ^ ^
  1209. // ibBufDrain m_ibBufFill
  1210. //
  1211. cbFill = min(cbFill, CB_BUF - m_ibBufFill - !ibBufDrain);
  1212. Assert( cbFill > 0 );
  1213. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::FReadyBuf() m_ibBufFill > ibBufDrain (enough room at end of buffer). New values: m_cbBufFillHint = %u, m_ibBufFill = %u, ibBufDrain = %u, m_ibBufWrap = %u\n", GetCurrentThreadId(), this, m_cbBufFillHint, m_ibBufFill, ibBufDrain, m_ibBufWrap );
  1214. }
  1215. else
  1216. {
  1217. // Case 4
  1218. Assert( m_ibBufFill > ibBufDrain );
  1219. Assert( m_cbBufFillHint > CB_BUF - m_ibBufFill );
  1220. Assert( ibBufDrain > CB_BUF - m_ibBufFill );
  1221. //
  1222. // We have: v------------v m_cbBufFillHint
  1223. //
  1224. // [________________DATADATADATADATADATADAT__________]
  1225. // ^ ^
  1226. // ibBufDrain m_ibBufFill
  1227. //
  1228. //
  1229. // After filling, we will have:
  1230. //
  1231. // [DATADATADATADAT_DATADATADATADATADATADAT***UNUSED*]
  1232. // ^^ ^
  1233. // |ibBufDrain m_ibBufWrap
  1234. // m_ibBufFill
  1235. //
  1236. //
  1237. // Set the wrap position so that a draining thread will
  1238. // know when to wrap the drain position.
  1239. //
  1240. m_ibBufWrap = m_ibBufFill;
  1241. //
  1242. // Set the fill position back at the beginning of the buffer
  1243. //
  1244. m_ibBufFill = 0;
  1245. //
  1246. // And fill up to the drain position - 1
  1247. //
  1248. Assert( ibBufDrain > 0 );
  1249. cbFill = min(cbFill, ibBufDrain - 1);
  1250. Assert( cbFill > 0 );
  1251. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::FReadyBuf() m_ibBufFill > ibBufDrain (not enough room at end of buffer). New values: m_cbBufFillHint = %u, m_ibBufFill = %u, ibBufDrain = %u, m_ibBufWrap = %u\n", GetCurrentThreadId(), this, m_cbBufFillHint, m_ibBufFill, ibBufDrain, m_ibBufWrap );
  1252. }
  1253. //
  1254. // Start async I/O to read from the ECB.
  1255. //
  1256. {
  1257. SCODE sc = S_OK;
  1258. //
  1259. // Add a reference to our parent request to keep us alive
  1260. // for the duration of the async call.
  1261. //
  1262. // Use auto_ref_ptr so that we release the ref if the
  1263. // async call throws an exception.
  1264. //
  1265. auto_ref_ptr<IRequest> pRef(&m_request);
  1266. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::FReadyBuf() reading %u bytes\n", GetCurrentThreadId(), this, cbFill );
  1267. // Assert that we are actually going to fill something and that
  1268. // we aren't going to fill past the end of our buffer.
  1269. //
  1270. Assert( m_ibBufFill + cbFill <= CB_BUF );
  1271. sc = m_ecb.ScAsyncRead( m_rgbBuf + m_ibBufFill,
  1272. &cbFill,
  1273. *this );
  1274. if (SUCCEEDED(sc))
  1275. {
  1276. pRef.relinquish();
  1277. }
  1278. else
  1279. {
  1280. DebugTrace( "CEcbStream::AsyncFillBuf() - IEcb::ScAsyncRead() failed with error 0x%08lX\n", sc );
  1281. m_hr = sc;
  1282. FillComplete();
  1283. }
  1284. }
  1285. }
  1286. // ------------------------------------------------------------------------
  1287. //
  1288. // CEcbStream::FillComplete()
  1289. //
  1290. VOID
  1291. CEcbStream::FillComplete()
  1292. {
  1293. //
  1294. // Poll the wakeup function pointer now before the ICE() below
  1295. // so that we don't lose the value if another thread immediately
  1296. // starts filling immediately after we transition to IDLE.
  1297. //
  1298. PFNWAKEUP pfnWakeup = m_pfnWakeup;
  1299. //
  1300. // At this point we had better be FILLING or FAULTING because
  1301. // we are completing async I/O started from AsyncFillBuf().
  1302. //
  1303. // We could actually be in WRITE_ERROR as well. See below
  1304. // and CEcbStream::WriteComplete() for why.
  1305. //
  1306. Assert( STATUS_FILLING == m_lBufStatus ||
  1307. STATUS_FAULTING == m_lBufStatus ||
  1308. STATUS_WRITE_ERROR == m_lBufStatus );
  1309. //
  1310. // Attempt to transition to IDLE from FILLING. If successful then
  1311. // we're done. Otherwise we are either FAULTING or in the WRITE_ERROR
  1312. // state. Handle those below.
  1313. //
  1314. LONG lBufStatus = InterlockedCompareExchange(
  1315. &m_lBufStatus,
  1316. STATUS_IDLE,
  1317. STATUS_FILLING );
  1318. if ( STATUS_FAULTING == lBufStatus )
  1319. {
  1320. //
  1321. // We are FAULTING. This means the writing side of things
  1322. // needs to be notified now that data is available. So
  1323. // change state to IDLE (remember: ICE() didn't change state
  1324. // above -- it just told us what the state is) and call
  1325. // the registered wakeup function.
  1326. //
  1327. m_lBufStatus = STATUS_IDLE;
  1328. Assert( pfnWakeup );
  1329. (this->*pfnWakeup)();
  1330. }
  1331. else if ( STATUS_WRITE_ERROR == lBufStatus )
  1332. {
  1333. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::FillComplete() - Error writing while filling. Notifying CopyTo observer\n", GetCurrentThreadId(), this );
  1334. //
  1335. // We are in the WRITE_ERROR state. This state is entered
  1336. // by CEcbStream::WriteComplete() during an async CopyTo operation
  1337. // when a write fails. This terminal state prevents new async fill
  1338. // operations from starting. When WriteComplete() transitioned into
  1339. // this state, it also checked if we were FILLING at the time.
  1340. // If we were then WriteComplete() left the responsibility for notifying
  1341. // the CopyTo observer up to us. See CEcbStream::WriteComplete()
  1342. // for the reason why.
  1343. //
  1344. Assert( m_pobsAsyncCopyTo );
  1345. m_pobsAsyncCopyTo->CopyToComplete( 0, m_hr );
  1346. //
  1347. // Note that once in the WRITE_ERROR state we DO NOT transition
  1348. // back to IDLE. WRITE_ERROR is a terminal state.
  1349. //
  1350. }
  1351. }
  1352. // ------------------------------------------------------------------------
  1353. //
  1354. // CEcbStream::IISIOComplete()
  1355. //
  1356. // Our IIISAsyncIOCompleteObserver method called by CEcb::IISIOComplete()
  1357. // when the async I/O to read from the read-once request body stream
  1358. // completes.
  1359. //
  1360. VOID
  1361. CEcbStream::IISIOComplete( DWORD dwcbRead,
  1362. DWORD dwLastError )
  1363. {
  1364. //
  1365. // Claim the reference to our parent request added in AsyncFillBuf()
  1366. //
  1367. auto_ref_ptr<IRequest> pRef;
  1368. pRef.take_ownership(&m_request);
  1369. //
  1370. // Update the m_dwcbStreamConsumed *before* m_ibBufFill so that
  1371. // we can safely assert at any time on any thread that we never
  1372. // drain more than has been consumed.
  1373. //
  1374. // Chunked requests: If we successfully read 0 bytes then we have
  1375. // reached the end of the request and should report the real
  1376. // stream size.
  1377. //
  1378. if ( ERROR_SUCCESS == dwLastError )
  1379. {
  1380. if ( 0 == dwcbRead )
  1381. m_dwcbStreamSize = m_dwcbStreamConsumed;
  1382. else
  1383. m_dwcbStreamConsumed += dwcbRead;
  1384. }
  1385. else
  1386. {
  1387. DebugTrace( "CEcbStream::IISIOComplete() - Error %d during async read\n", dwLastError );
  1388. m_hr = HRESULT_FROM_WIN32(dwLastError);
  1389. }
  1390. #ifdef DBG
  1391. UINT cbBufAvail = InterlockedExchangeAdd( reinterpret_cast<LONG *>(&dbgm_cbBufAvail), dwcbRead ) + dwcbRead;
  1392. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: !!!CEcbStream::IISIOComplete() %lu left to read (%u in buffer)\n", GetCurrentThreadId(), this, m_dwcbStreamSize - m_dwcbStreamConsumed, cbBufAvail );
  1393. #endif
  1394. // Assert that we didn't just read past the end of our buffer.
  1395. //
  1396. Assert( m_ibBufFill + dwcbRead <= CB_BUF );
  1397. // Update the fill position. If we've reached the end of the buffer
  1398. // then wrap back to the beginning. We must do this here BEFORE
  1399. // calling FillComplete() -- the fill position must be valid (i.e.
  1400. // within the bounds of the buffer) before we start off another
  1401. // fill cycle.
  1402. //
  1403. m_ibBufFill += dwcbRead;
  1404. if ( CB_BUF == m_ibBufFill )
  1405. {
  1406. m_ibBufWrap = CB_BUF;
  1407. m_ibBufFill = 0;
  1408. }
  1409. // If we read more than the last fill hint then we know we
  1410. // can try to read at least this much next time.
  1411. //
  1412. if ( dwcbRead > m_cbBufFillHint )
  1413. {
  1414. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::IISIOComplete() setting m_cbBufFillHint = %lu\n", GetCurrentThreadId(), this, dwcbRead );
  1415. m_cbBufFillHint = dwcbRead;
  1416. }
  1417. EcbStreamTrace( "DAV: TID %3d: 0x%08lX: CEcbStream::IISIOComplete() dwcbRead = %lu, m_ibBufFill = %lu, m_dwcbStreamConsumed = %lu, m_dwcbStreamSize = %lu, dwLastError = %lu\n", GetCurrentThreadId(), this, dwcbRead, m_ibBufFill, m_dwcbStreamConsumed, m_dwcbStreamSize, dwLastError );
  1418. //
  1419. // Indicate that we're done filling. This resets the state from FILLING
  1420. // (or FAULTING) to idle and wakes up the observer if it is blocked.
  1421. //
  1422. FillComplete();
  1423. //
  1424. // Kick off the next read cycle. AsyncFillBuf() checks for error and
  1425. // end-of-stream conditions, so we don't have to.
  1426. //
  1427. AsyncFillBuf();
  1428. }
  1429. // ------------------------------------------------------------------------
  1430. //
  1431. // CEcbStream::HrBufReady()
  1432. //
  1433. // Determines how much and the location of the next block of data that
  1434. // is instantaneously accessible in the buffer. Also determines whether
  1435. // the stream is in an error state (e.g. due to a failure reading
  1436. // from the stream while filling the buffer).
  1437. //
  1438. // The matrix of return results is:
  1439. //
  1440. // HRESULT *pcbBufReady *ppbBufReady Meaning
  1441. // ----------------------------------------------------
  1442. // S_OK > 0 valid Data available
  1443. // S_OK 0 n/a No data available (EOS)
  1444. // E_PENDING n/a n/a No data available (pending)
  1445. // E_xxx n/a n/a Error
  1446. //
  1447. HRESULT
  1448. CEcbStream::HrBufReady( UINT * pcbBufReady,
  1449. const BYTE ** ppbBufReady ) const
  1450. {
  1451. Assert( pcbBufReady );
  1452. Assert( ppbBufReady );
  1453. //
  1454. // If the buffer has data ready, then return the amount and
  1455. // its location.
  1456. //
  1457. *pcbBufReady = CbBufReady();
  1458. if ( *pcbBufReady )
  1459. {
  1460. *ppbBufReady = PbBufReady();
  1461. return S_OK;
  1462. }
  1463. //
  1464. // No data ready. If the buffer is in an error state
  1465. // then return the fact.
  1466. //
  1467. if ( S_OK != m_hr )
  1468. return m_hr;
  1469. //
  1470. // No data ready and we haven't had an error. If the buffer
  1471. // is FILLING then transition to FAULTING and tell it to
  1472. // notify the observer when data becomes ready. Return
  1473. // E_PENDING to the caller to tell it that we will be
  1474. // notifying the observer later.
  1475. //
  1476. // Note that the very instant before we try to transition to FAULTING,
  1477. // the buffer may go from FILLING back to IDLE. If that
  1478. // happens, then data should be ready, so go `round the loop
  1479. // and check again.
  1480. //
  1481. Assert( STATUS_FAULTING != m_lBufStatus );
  1482. if ( STATUS_FILLING == InterlockedCompareExchange(
  1483. &m_lBufStatus,
  1484. STATUS_FAULTING,
  1485. STATUS_FILLING ) )
  1486. return E_PENDING;
  1487. //
  1488. // The buffer must have finished FILLING sometime between
  1489. // when we did the initial poll and now. At this point
  1490. // there must be data ready.
  1491. //
  1492. *pcbBufReady = CbBufReady();
  1493. *ppbBufReady = PbBufReady();
  1494. return S_OK;
  1495. }
  1496. // ========================================================================
  1497. //
  1498. // CLASS CRequest
  1499. //
  1500. // Request class
  1501. //
  1502. class CRequest : public IRequest
  1503. {
  1504. // Extension control block passed in through the ISAPI interface
  1505. //
  1506. auto_ref_ptr<IEcb> m_pecb;
  1507. // Header caches. We retrieve headers as skinny, as no other
  1508. // choice is available.
  1509. // But sometimes we need wide version to operate on, so in
  1510. // that case we will get the skinny version, convert it properly
  1511. // and store in the wide header cache.
  1512. //
  1513. mutable CHeaderCache<CHAR> m_hcHeadersA;
  1514. mutable CHeaderCache<WCHAR> m_hcHeadersW;
  1515. // This flag tells us whether we have cleared the headers
  1516. // and thus whether we should check the ECB when we cannot
  1517. // find a header in the cache. Since we cannot actually remove
  1518. // headers from from the ECB, we just remember not to check the
  1519. // ECB if the headers have ever been "cleared".
  1520. //
  1521. bool m_fClearedHeaders;
  1522. // Request body
  1523. //
  1524. auto_ptr<IBody> m_pBody;
  1525. // NOT IMPLEMENTED
  1526. //
  1527. CRequest& operator=( const CRequest& );
  1528. CRequest( const CRequest& );
  1529. public:
  1530. // CREATORS
  1531. //
  1532. CRequest( IEcb& ecb );
  1533. // ACCESSORS
  1534. //
  1535. LPCSTR LpszGetHeader( LPCSTR pszName ) const;
  1536. LPCWSTR LpwszGetHeader( LPCSTR pszName, BOOL fUrlConversion ) const;
  1537. BOOL FExistsBody() const;
  1538. IStream * GetBodyIStream( IAsyncIStreamObserver& obs ) const;
  1539. VOID AsyncImplPersistBody( IAsyncStream& stm,
  1540. IAsyncPersistObserver& obs ) const;
  1541. // MANIPULATORS
  1542. //
  1543. VOID ClearBody();
  1544. VOID AddBodyText( UINT cbText, LPCSTR pszText );
  1545. VOID AddBodyStream( IStream& stm );
  1546. };
  1547. // ------------------------------------------------------------------------
  1548. //
  1549. // CRequest::CRequest()
  1550. //
  1551. CRequest::CRequest( IEcb& ecb ) :
  1552. m_pecb(&ecb),
  1553. m_pBody(NewBody()),
  1554. m_fClearedHeaders(false)
  1555. {
  1556. //
  1557. // If the ECB contains a body, then create a body part for it.
  1558. //
  1559. if ( ecb.CbTotalBytes() > 0 )
  1560. m_pBody->AddBodyPart( new CEcbRequestBodyPart(ecb, *this) );
  1561. // HACK: The ECB needs to keep track of two pieces of request info,
  1562. // the Accept-Language and Connection headers.
  1563. // "Prime" the ECB with the Accept-Language value (if one is specified).
  1564. // The Connection header is sneakier -- read about that in
  1565. // CEcb::FKeepAlive. Don't set it here, but do push updates through
  1566. // from SetHeader.
  1567. //
  1568. LPCSTR pszValue = LpszGetHeader( gc_szAccept_Language );
  1569. if (pszValue)
  1570. m_pecb->SetAcceptLanguageHeader( pszValue );
  1571. }
  1572. // ------------------------------------------------------------------------
  1573. //
  1574. // CRequest::LpszGetHeader()
  1575. //
  1576. // Retrieves the value of the specified HTTP request header. If the
  1577. // request does not have the specified header, LpszGetHeader() returns
  1578. // NULL. The header name, pszName, is in the standard HTTP header
  1579. // format (e.g. "Content-Type")
  1580. //
  1581. LPCSTR
  1582. CRequest::LpszGetHeader( LPCSTR pszName ) const
  1583. {
  1584. Assert( pszName );
  1585. LPCSTR pszValue;
  1586. // Check the cache.
  1587. //
  1588. pszValue = m_hcHeadersA.LpszGetHeader( pszName );
  1589. // If we don't find the header in the cache then check
  1590. // the ECB
  1591. //
  1592. if ( !pszValue )
  1593. {
  1594. UINT cbName = static_cast<UINT>(strlen(pszName));
  1595. CStackBuffer<CHAR> pszVariable( gc_cchHTTP_ + cbName + 1 );
  1596. CStackBuffer<CHAR> pszBuf;
  1597. // Headers retrieved via the ECB are named using the ECB's
  1598. // server variable format (e.g. "HTTP_CONTENT_TYPE"), so we must
  1599. // convert our header name from its HTTP format to its ECB
  1600. // server variable equivalent.
  1601. //
  1602. // Start with the header, prepended with "HTTP_"
  1603. //
  1604. memcpy( pszVariable.get(), gc_szHTTP_, gc_cchHTTP_ );
  1605. memcpy( pszVariable.get() + gc_cchHTTP_, pszName, cbName + 1 );
  1606. // Replace all occurrences of '-' with '_'
  1607. //
  1608. for ( CHAR * pch = pszVariable.get(); *pch; pch++ )
  1609. {
  1610. if ( *pch == '-' )
  1611. *pch = '_';
  1612. }
  1613. // And uppercasify the whole thing
  1614. //
  1615. _strupr( pszVariable.get() );
  1616. // Get the value of this server variable from the ECB and
  1617. // add it to the header cache using its real (HTTP) name
  1618. //
  1619. for ( DWORD cbValue = 256; cbValue > 0; )
  1620. {
  1621. if (NULL == pszBuf.resize(cbValue))
  1622. {
  1623. SetLastError(E_OUTOFMEMORY);
  1624. DebugTrace("CRequest::LpszGetHeader() - Error while allocating memory 0x%08lX\n", E_OUTOFMEMORY);
  1625. throw CLastErrorException();
  1626. }
  1627. if ( m_pecb->FGetServerVariable( pszVariable.get(),
  1628. pszBuf.get(),
  1629. &cbValue ))
  1630. {
  1631. pszValue = m_hcHeadersA.SetHeader( pszName, pszBuf.get() );
  1632. break;
  1633. }
  1634. }
  1635. }
  1636. return pszValue;
  1637. }
  1638. // ------------------------------------------------------------------------
  1639. //
  1640. // CRequest::LpwszGetHeader()
  1641. //
  1642. // Provides and caches wide version of the header value
  1643. //
  1644. // PARAMETERS:
  1645. //
  1646. // pszName - header name
  1647. // fUrlConversion - flag that if set to TRUE indicates that special
  1648. // conversion rules should be applied. I.e. the
  1649. // header contains URL-s, that need escaping and
  1650. // codepage lookup. If set to FALSE the header will
  1651. // simply be converted using UTF-8 codepage. E.g.
  1652. // we do expect only US-ASCII characters in that
  1653. // header (or any other subset of UTF-8).
  1654. // Flag is ignored once wide version gets cached.
  1655. //
  1656. LPCWSTR
  1657. CRequest::LpwszGetHeader( LPCSTR pszName, BOOL fUrlConversion ) const
  1658. {
  1659. Assert( pszName );
  1660. // Check the cache
  1661. //
  1662. LPCWSTR pwszValue = m_hcHeadersW.LpszGetHeader( pszName );
  1663. // If we don't find the header in the cache then out for
  1664. // the skinny version, convert it and cache.
  1665. //
  1666. if ( !pwszValue )
  1667. {
  1668. // Check the skinny cache
  1669. //
  1670. LPCSTR pszValue = LpszGetHeader( pszName );
  1671. if (pszValue)
  1672. {
  1673. SCODE sc;
  1674. CStackBuffer<WCHAR> pwszBuf;
  1675. UINT cbValue = static_cast<UINT>(strlen(pszValue));
  1676. UINT cchValue = cbValue + 1;
  1677. // Make sure we have sufficient buffer for conversion
  1678. //
  1679. if (NULL == pwszBuf.resize(CbSizeWsz(cbValue)))
  1680. {
  1681. sc = E_OUTOFMEMORY;
  1682. SetLastError(sc);
  1683. DebugTrace("CRequest::LpwszGetHeader() - Error while allocating memory 0x%08lX\n", sc);
  1684. throw CLastErrorException();
  1685. }
  1686. sc = ScConvertToWide(pszValue,
  1687. &cchValue,
  1688. pwszBuf.get(),
  1689. LpszGetHeader(gc_szAccept_Language),
  1690. fUrlConversion);
  1691. if (S_OK != sc)
  1692. {
  1693. // We gave sufficient buffer
  1694. //
  1695. Assert(S_FALSE != sc);
  1696. SetLastError(sc);
  1697. throw CLastErrorException();
  1698. }
  1699. pwszValue = m_hcHeadersW.SetHeader( pszName, pwszBuf.get() );
  1700. }
  1701. }
  1702. return pwszValue;
  1703. }
  1704. // ------------------------------------------------------------------------
  1705. //
  1706. // CRequest::FExistsBody()
  1707. //
  1708. BOOL
  1709. CRequest::FExistsBody() const
  1710. {
  1711. return !m_pBody->FIsEmpty();
  1712. }
  1713. // ------------------------------------------------------------------------
  1714. //
  1715. // CRequest::GetBodyIStream()
  1716. //
  1717. IStream *
  1718. CRequest::GetBodyIStream( IAsyncIStreamObserver& obs ) const
  1719. {
  1720. //
  1721. // With the assumption above in mind, persist the request body.
  1722. //
  1723. return m_pBody->GetIStream( obs );
  1724. }
  1725. // ------------------------------------------------------------------------
  1726. //
  1727. // CRequest::AsyncImplPersistBody()
  1728. //
  1729. VOID
  1730. CRequest::AsyncImplPersistBody( IAsyncStream& stm,
  1731. IAsyncPersistObserver& obs ) const
  1732. {
  1733. m_pBody->AsyncPersist( stm, obs );
  1734. }
  1735. // ------------------------------------------------------------------------
  1736. //
  1737. // CRequest::ClearBody()
  1738. //
  1739. VOID
  1740. CRequest::ClearBody()
  1741. {
  1742. m_pBody->Clear();
  1743. }
  1744. // ------------------------------------------------------------------------
  1745. //
  1746. // CRequest::AddBodyText()
  1747. //
  1748. // Adds the specified text to the end of the request body.
  1749. //
  1750. VOID
  1751. CRequest::AddBodyText( UINT cbText, LPCSTR pszText )
  1752. {
  1753. m_pBody->AddText( pszText, cbText );
  1754. }
  1755. // ------------------------------------------------------------------------
  1756. //
  1757. // CRequest::AddBodyStream()
  1758. //
  1759. // Adds the specified stream to the end of the request body.
  1760. //
  1761. VOID
  1762. CRequest::AddBodyStream( IStream& stm )
  1763. {
  1764. m_pBody->AddStream( stm );
  1765. }
  1766. // ========================================================================
  1767. //
  1768. // FREE FUNCTIONS
  1769. //
  1770. // ------------------------------------------------------------------------
  1771. //
  1772. // NewRequest
  1773. //
  1774. IRequest *
  1775. NewRequest( IEcb& ecb )
  1776. {
  1777. return new CRequest(ecb);
  1778. }