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.

1634 lines
47 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: transact.cxx
  7. //
  8. // Contents: Class that performs the download of a particular request.
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 12-04-95 JohannP (Johann Posch) Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <trans.h>
  18. #include <shlwapi.h>
  19. #include "oinet.hxx"
  20. PerfDbgTag(tagCTransaction, "Urlmon", "Log CTransaction", DEB_TRANS);
  21. DbgTag(tagCTransactionErr, "Urlmon", "Log CTransaction Errors", DEB_TRANS|DEB_ERROR);
  22. HRESULT GetClassDocFileBuffer(LPVOID pbuffer, DWORD dwSize, CLSID *pclsid);
  23. HRESULT GetCodeBaseFromDocFile(LPBYTE pBuffer, ULONG ulSize, LPWSTR *pwzClassStr,
  24. LPWSTR pwzBaseUrl, DWORD *lpdwVersionMS, DWORD *lpdwVersionLS);
  25. HRESULT IsHandlerAvailable(LPWSTR pwzUrl, LPWSTR pwzMime, CLSID *pclsid,
  26. LPBYTE pBuffer, ULONG cbSize);
  27. #if 0
  28. //+---------------------------------------------------------------------------
  29. //
  30. // Method: COInetProtSnk::QueryInterface
  31. //
  32. // Synopsis:
  33. //
  34. // Arguments: [riid] --
  35. // [ppvObj] --
  36. //
  37. // Returns:
  38. //
  39. // History: 10-29-1996 JohannP (Johann Posch) Created
  40. //
  41. // Notes:
  42. //
  43. //----------------------------------------------------------------------------
  44. STDMETHODIMP COInetProtSnk::QueryInterface(REFIID riid, void **ppvObj)
  45. {
  46. VDATEPTROUT(ppvObj, void *);
  47. VDATETHIS(this);
  48. HRESULT hr = NOERROR;
  49. PerfDbgLog(tagCTransaction, this, "+COInetProtSnk::QueryInterface");
  50. *ppvObj = NULL;
  51. if (_pUnk)
  52. {
  53. hr = _pUnk->QueryInterface(riid, ppvObj);
  54. }
  55. else
  56. {
  57. if ( (riid == IID_IUnknown)
  58. || (riid == IID_IOInetProtocol))
  59. {
  60. *ppvObj = (IOInetProtocol *) this;
  61. AddRef();
  62. }
  63. else if (riid == IID_IOInetProtocolSink)
  64. {
  65. *ppvObj = (IOInetProtocolSink *) this;
  66. AddRef();
  67. }
  68. else
  69. {
  70. hr = E_NOINTERFACE;
  71. }
  72. }
  73. PerfDbgLog1(tagCTransaction, this, "-COInetProtSnk::QueryInterface (hr:%lx)", hr);
  74. return hr;
  75. }
  76. //+---------------------------------------------------------------------------
  77. //
  78. // Function: COInetProtSnk::AddRef
  79. //
  80. // Synopsis:
  81. //
  82. // Arguments: [ULONG] --
  83. //
  84. // Returns:
  85. //
  86. // History: 10-29-1996 JohannP (Johann Posch) Created
  87. //
  88. // Notes:
  89. //
  90. //----------------------------------------------------------------------------
  91. STDMETHODIMP_(ULONG) COInetProtSnk::AddRef(void)
  92. {
  93. PerfDbgLog(tagCTransaction, this, "+COInetProtSnk::AddRef");
  94. LONG lRet = _pProtSnk->AddRef();
  95. PerfDbgLog1(tagCTransaction, this, "-COInetProtSnk::AddRef (cRefs:%ld)", lRet);
  96. return lRet;
  97. }
  98. //+---------------------------------------------------------------------------
  99. //
  100. // Function: COInetProtSnk::Release
  101. //
  102. // Synopsis:
  103. //
  104. // Arguments: [ULONG] --
  105. //
  106. // Returns:
  107. //
  108. // History: 10-29-1996 JohannP (Johann Posch) Created
  109. //
  110. // Notes:
  111. //
  112. //----------------------------------------------------------------------------
  113. STDMETHODIMP_(ULONG) COInetProtSnk::Release(void)
  114. {
  115. PerfDbgLog(tagCTransaction, this, "+COInetProtSnk::Release");
  116. LONG lRet = _pProtSnk->Release();
  117. PerfDbgLog1(tagCTransaction, this, "-COInetProtSnk::Release (cRefs:%ld)", lRet);
  118. return lRet;
  119. }
  120. //+---------------------------------------------------------------------------
  121. //
  122. // Method: COInetProtSnk::Switch
  123. //
  124. // Synopsis:
  125. //
  126. // Arguments: [pStateInfo] --
  127. //
  128. // Returns:
  129. //
  130. // History: 11-07-1996 JohannP (Johann Posch) Created
  131. //
  132. // Notes:
  133. //
  134. //----------------------------------------------------------------------------
  135. STDMETHODIMP COInetProtSnk::Switch(PROTOCOLDATA *pStateInfo)
  136. {
  137. PerfDbgLog(tagCTransaction, this, "+COInetProtSnk::Switch");
  138. HRESULT hr = NOERROR;
  139. hr = _pProtSnk->Switch(pStateInfo);
  140. PerfDbgLog1(tagCTransaction, this, "-COInetProtSnk::Switch (hr:%lx)", hr);
  141. return hr;
  142. }
  143. //+---------------------------------------------------------------------------
  144. //
  145. // Method: COInetProtSnk::ReportProgress
  146. //
  147. // Synopsis:
  148. //
  149. // Arguments: [NotMsg] --
  150. // [szStatusText] --
  151. //
  152. // Returns:
  153. //
  154. // History: 11-07-1996 JohannP (Johann Posch) Created
  155. //
  156. // Notes:
  157. //
  158. //----------------------------------------------------------------------------
  159. STDMETHODIMP COInetProtSnk::ReportProgress(ULONG NotMsg, LPCWSTR pwzStatusText)
  160. {
  161. PerfDbgLog1(tagCTransaction, this, "+COInetProtSnk::ReportProgress pwzStatusText:%ws", pwzStatusText);
  162. HRESULT hr = NOERROR;
  163. hr = _pProtSnk->ReportProgress(NotMsg, pwzStatusText);
  164. PerfDbgLog2(tagCTransaction, this, "-COInetProtSnk::ReportProgress (pwzStatusText:%ws, hr:%lx)", pwzStatusText, hr);
  165. return hr;
  166. }
  167. //+---------------------------------------------------------------------------
  168. //
  169. // Method: COInetProtSnk::ReportData
  170. //
  171. // Synopsis:
  172. //
  173. // Arguments: [grfBSCF] --
  174. // [ULONG] --
  175. // [ulProgressMax] --
  176. //
  177. // Returns:
  178. //
  179. // History: 11-07-1996 JohannP (Johann Posch) Created
  180. //
  181. // Notes:
  182. //
  183. //----------------------------------------------------------------------------
  184. STDMETHODIMP COInetProtSnk::ReportData(DWORD grfBSCF, ULONG ulProgress,ULONG ulProgressMax)
  185. {
  186. PerfDbgLog3(tagCTransaction, this, "+COInetProtSnk::ReportData(grfBSCF:%lx, ulProgress:%ld, ulProgressMax:%ld)",
  187. grfBSCF, ulProgress, ulProgressMax);
  188. HRESULT hr = NOERROR;
  189. hr = _pProtSnk->ReportData( grfBSCF, ulProgress, ulProgressMax);
  190. PerfDbgLog1(tagCTransaction, this, "-COInetProtSnk::ReportData (hr:%lx)", hr);
  191. return hr;
  192. }
  193. //+---------------------------------------------------------------------------
  194. //
  195. // Method: COInetProtSnk::ReportResult
  196. //
  197. // Synopsis:
  198. //
  199. // Arguments: [DWORD] --
  200. // [dwError] --
  201. // [wzResult] --
  202. //
  203. // Returns:
  204. //
  205. // History: 11-07-1996 JohannP (Johann Posch) Created
  206. //
  207. // Notes:
  208. //
  209. //----------------------------------------------------------------------------
  210. STDMETHODIMP COInetProtSnk::ReportResult(HRESULT hrResult, DWORD dwError, LPCWSTR wzResult)
  211. {
  212. PerfDbgLog(tagCTransaction, this, "+COInetProtSnk::ReportResult");
  213. HRESULT hr = NOERROR;
  214. hr = _pProtSnk->ReportResult(hrResult, dwError, wzResult);
  215. PerfDbgLog1(tagCTransaction, this, "-COInetProtSnk::ReportResult (hr:%lx)", hr);
  216. return hr;
  217. }
  218. #endif // 0
  219. //+---------------------------------------------------------------------------
  220. //
  221. // Method: COInetProt::QueryInterface
  222. //
  223. // Synopsis:
  224. //
  225. // Arguments: [riid] --
  226. // [ppvObj] --
  227. //
  228. // Returns:
  229. //
  230. // History: 10-29-1996 JohannP (Johann Posch) Created
  231. //
  232. // Notes:
  233. //
  234. //----------------------------------------------------------------------------
  235. STDMETHODIMP COInetProt::QueryInterface(REFIID riid, void **ppvObj)
  236. {
  237. DEBUG_ENTER((DBG_TRANS,
  238. Hresult,
  239. "COInetProt::IUnknown::QueryInterface",
  240. "this=%#x, %#x, %#x",
  241. this, &riid, ppvObj
  242. ));
  243. VDATEPTROUT(ppvObj, void *);
  244. VDATETHIS(this);
  245. HRESULT hr = NOERROR;
  246. PerfDbgLog(tagCTransaction, this, "+COInetProt::QueryInterface");
  247. *ppvObj = NULL;
  248. if (_pUnk)
  249. {
  250. hr = _pUnk->QueryInterface(riid, ppvObj);
  251. }
  252. else
  253. {
  254. if ( (riid == IID_IUnknown)
  255. || (riid == IID_IOInetProtocol))
  256. {
  257. *ppvObj = (IOInetProtocol *) this;
  258. AddRef();
  259. }
  260. else if (riid == IID_IOInetProtocolSink)
  261. {
  262. *ppvObj = (IOInetProtocolSink *) this;
  263. AddRef();
  264. }
  265. else if (riid == IID_IServiceProvider)
  266. {
  267. *ppvObj = (IServiceProvider *) this;
  268. AddRef();
  269. }
  270. else if (riid == IID_IOInetPriority)
  271. {
  272. *ppvObj = (IOInetPriority *) this;
  273. AddRef();
  274. }
  275. else
  276. {
  277. hr = E_NOINTERFACE;
  278. }
  279. }
  280. PerfDbgLog1(tagCTransaction, this, "-COInetProt::QueryInterface (hr:%lx)", hr);
  281. DEBUG_LEAVE(hr);
  282. return hr;
  283. }
  284. //+---------------------------------------------------------------------------
  285. //
  286. // Function: COInetProt::AddRef
  287. //
  288. // Synopsis:
  289. //
  290. // Arguments: [ULONG] --
  291. //
  292. // Returns:
  293. //
  294. // History: 10-29-1996 JohannP (Johann Posch) Created
  295. //
  296. // Notes:
  297. //
  298. //----------------------------------------------------------------------------
  299. STDMETHODIMP_(ULONG) COInetProt::AddRef(void)
  300. {
  301. DEBUG_ENTER((DBG_TRANS,
  302. Dword,
  303. "COInetProt::IUnknown::AddRef",
  304. "this=%#x",
  305. this
  306. ));
  307. PerfDbgLog(tagCTransaction, this, "+COInetProt::AddRef");
  308. LONG lRet;
  309. if (_pUnk)
  310. {
  311. lRet = _pUnk->AddRef();
  312. }
  313. else
  314. {
  315. lRet = ++_CRefs;
  316. }
  317. PerfDbgLog1(tagCTransaction, this, "-COInetProt::AddRef (cRefs:%ld)", lRet);
  318. DEBUG_LEAVE(lRet);
  319. return lRet;
  320. }
  321. //+---------------------------------------------------------------------------
  322. //
  323. // Function: COInetProt::Release
  324. //
  325. // Synopsis:
  326. //
  327. // Arguments: [ULONG] --
  328. //
  329. // Returns:
  330. //
  331. // History: 10-29-1996 JohannP (Johann Posch) Created
  332. //
  333. // Notes:
  334. //
  335. //----------------------------------------------------------------------------
  336. STDMETHODIMP_(ULONG) COInetProt::Release(void)
  337. {
  338. DEBUG_ENTER((DBG_TRANS,
  339. Dword,
  340. "COInetProt::IUnknown::Release",
  341. "this=%#x",
  342. this
  343. ));
  344. PerfDbgLog(tagCTransaction, this, "+COInetProt::Release");
  345. LONG lRet;
  346. if (_pUnk)
  347. {
  348. lRet = _pUnk->Release();
  349. }
  350. else
  351. {
  352. lRet = --_CRefs;
  353. if (_CRefs == 0)
  354. {
  355. //
  356. // release all objects
  357. if (_pProtSnk)
  358. {
  359. _pProtSnk->Release();
  360. }
  361. if (_pProt)
  362. {
  363. _pProt->Release();
  364. }
  365. if (_dwMode & PP_DELETE)
  366. {
  367. delete this;
  368. }
  369. }
  370. }
  371. PerfDbgLog1(tagCTransaction, this, "-COInetProt::Release (cRefs:%ld)", lRet);
  372. DEBUG_LEAVE(lRet);
  373. return lRet;
  374. }
  375. //+---------------------------------------------------------------------------
  376. //
  377. // Method: COInetProt::Start
  378. //
  379. // Synopsis:
  380. //
  381. // Arguments: [pwzUrl] --
  382. // [pTrans] --
  383. // [pOIBindInfo] --
  384. // [grfSTI] --
  385. // [dwReserved] --
  386. //
  387. // Returns:
  388. //
  389. // History: 10-29-1996 JohannP (Johann Posch) Created
  390. //
  391. // Notes:
  392. //
  393. //----------------------------------------------------------------------------
  394. STDMETHODIMP COInetProt::Start(LPCWSTR pwzUrl, IOInetProtocolSink *pOInetProtSnk, IOInetBindInfo *pOIBindInfo,
  395. DWORD grfSTI, DWORD_PTR dwReserved)
  396. {
  397. DEBUG_ENTER((DBG_TRANS,
  398. Hresult,
  399. "COInetProt::IInternetProtocolRoot::Start",
  400. "this=%#x, %.80wq, %#x, %#x, %#x, %#x",
  401. this, pwzUrl, pOInetProtSnk, pOIBindInfo, grfSTI, dwReserved
  402. ));
  403. PerfDbgLog(tagCTransaction, this, "+COInetProt::Start\n");
  404. HRESULT hr = NOERROR;
  405. TransAssert((pOIBindInfo && pOInetProtSnk && pwzUrl));
  406. // Just before starting the transaction give it the priority.
  407. IOInetPriority * pOInetPriority = NULL;
  408. if (_pProt->QueryInterface(IID_IOInetPriority, (void **) &pOInetPriority) == S_OK)
  409. {
  410. pOInetPriority->SetPriority(_nPriority);
  411. pOInetPriority->Release();
  412. }
  413. delete [] _pwzUrl;
  414. _pwzUrl = OLESTRDuplicate(pwzUrl);
  415. hr = _pProt->Start(pwzUrl, pOInetProtSnk, pOIBindInfo, grfSTI, dwReserved);
  416. PerfDbgLog1(tagCTransaction, this, "-COInetProt::Start (hr:%lx)\n", hr);
  417. DEBUG_LEAVE(hr);
  418. return hr;
  419. }
  420. //+---------------------------------------------------------------------------
  421. //
  422. // Method: COInetProt::Continue
  423. //
  424. // Synopsis:
  425. //
  426. // Arguments: [pStateInfoIn] --
  427. //
  428. // Returns:
  429. //
  430. // History: 10-29-1996 JohannP (Johann Posch) Created
  431. //
  432. // Notes:
  433. //
  434. //----------------------------------------------------------------------------
  435. STDMETHODIMP COInetProt::Continue(PROTOCOLDATA *pStateInfoIn)
  436. {
  437. DEBUG_ENTER((DBG_TRANS,
  438. Hresult,
  439. "COInetProt::IInternetProtocolRoot::Continue",
  440. "this=%#x, %#x",
  441. this, pStateInfoIn
  442. ));
  443. PerfDbgLog(tagCTransaction, this, "+COInetProt::Continue\n");
  444. HRESULT hr = _pProt->Continue(pStateInfoIn);
  445. PerfDbgLog1(tagCTransaction, this, "-COInetProt::Continue (hr:%lx)\n",hr);
  446. DEBUG_LEAVE(hr);
  447. return hr;
  448. }
  449. //+---------------------------------------------------------------------------
  450. //
  451. // Method: COInetProt::Abort
  452. //
  453. // Synopsis:
  454. //
  455. // Arguments: [hrReason] --
  456. // [dwOptions] --
  457. //
  458. // Returns:
  459. //
  460. // History: 11-09-1996 JohannP (Johann Posch) Created
  461. //
  462. // Notes:
  463. //
  464. //----------------------------------------------------------------------------
  465. STDMETHODIMP COInetProt::Abort(HRESULT hrReason, DWORD dwOptions)
  466. {
  467. DEBUG_ENTER((DBG_TRANS,
  468. Hresult,
  469. "COInetProt::IInternetProtocolRoot::Abort",
  470. "this=%#x, %#x, %#x",
  471. this, hrReason, dwOptions
  472. ));
  473. PerfDbgLog(tagCTransaction, this, "+COInetProt::Abort\n");
  474. HRESULT hr = NOERROR;
  475. hr = _pProt->Abort(hrReason, dwOptions);
  476. PerfDbgLog1(tagCTransaction, this, "-COInetProt::Abort (hr:%lx)\n", hr);
  477. DEBUG_LEAVE(hr);
  478. return hr;
  479. }
  480. //+---------------------------------------------------------------------------
  481. //
  482. // Method: COInetProt::Terminate
  483. //
  484. // Synopsis:
  485. //
  486. // Arguments: [dwOptions] --
  487. //
  488. // Returns:
  489. //
  490. // History: 10-29-1996 JohannP (Johann Posch) Created
  491. //
  492. // Notes:
  493. //
  494. //----------------------------------------------------------------------------
  495. STDMETHODIMP COInetProt::Terminate(DWORD dwOptions)
  496. {
  497. DEBUG_ENTER((DBG_TRANS,
  498. Hresult,
  499. "COInetProt::IInternetProtocolRoot::Terminate",
  500. "this=%#x, %#x",
  501. this, dwOptions
  502. ));
  503. PerfDbgLog(tagCTransaction, this, "+COInetProt::Terminate\n");
  504. HRESULT hr = NOERROR;
  505. TransAssert((_pProt));
  506. hr = _pProt->Terminate(dwOptions);
  507. SetProtocolSink(0);
  508. SetServiceProvider(0);
  509. PerfDbgLog1(tagCTransaction, this, "-COInetProt::Terminate (hr:%lx)\n", hr);
  510. DEBUG_LEAVE(hr);
  511. return hr;
  512. }
  513. //+---------------------------------------------------------------------------
  514. //
  515. // Method: COInetProt::Suspend
  516. //
  517. // Synopsis:
  518. //
  519. // Arguments: (none)
  520. //
  521. // Returns:
  522. //
  523. // History: 10-29-1996 JohannP (Johann Posch) Created
  524. //
  525. // Notes:
  526. //
  527. //----------------------------------------------------------------------------
  528. STDMETHODIMP COInetProt::Suspend()
  529. {
  530. DEBUG_ENTER((DBG_TRANS,
  531. Hresult,
  532. "COInetProt::IInternetProtocolRoot::Suspend",
  533. "this=%#x",
  534. this
  535. ));
  536. PerfDbgLog(tagCTransaction, this, "+COInetProt::Suspend\n");
  537. HRESULT hr = _pProt->Suspend();
  538. PerfDbgLog1(tagCTransaction, this, "-COInetProt::Suspend (hr:%lx)\n", hr);
  539. DEBUG_LEAVE(hr);
  540. return hr;
  541. }
  542. //+---------------------------------------------------------------------------
  543. //
  544. // Method: COInetProt::Resume
  545. //
  546. // Synopsis:
  547. //
  548. // Arguments: (none)
  549. //
  550. // Returns:
  551. //
  552. // History: 10-29-1996 JohannP (Johann Posch) Created
  553. //
  554. // Notes:
  555. //
  556. //----------------------------------------------------------------------------
  557. STDMETHODIMP COInetProt::Resume()
  558. {
  559. DEBUG_ENTER((DBG_TRANS,
  560. Hresult,
  561. "COInetProt::IInternetProtocolRoot::Resume",
  562. "this=%#x",
  563. this
  564. ));
  565. PerfDbgLog(tagCTransaction, this, "+COInetProt::Resume\n");
  566. HRESULT hr = _pProt->Resume();
  567. PerfDbgLog1(tagCTransaction, this, "-COInetProt::Resume (hr:%lx)\n", hr);
  568. DEBUG_LEAVE(hr);
  569. return hr;
  570. }
  571. //+---------------------------------------------------------------------------
  572. //
  573. // Method: COInetProt::Read
  574. //
  575. // Synopsis:
  576. //
  577. // Arguments: [ULONG] --
  578. // [ULONG] --
  579. // [pcbRead] --
  580. //
  581. // Returns:
  582. //
  583. // History: 10-29-1996 JohannP (Johann Posch) Created
  584. //
  585. // Notes:
  586. //
  587. //----------------------------------------------------------------------------
  588. STDMETHODIMP COInetProt::Read(void *pBuffer, ULONG cbBuffer,ULONG *pcbRead)
  589. {
  590. DEBUG_ENTER((DBG_TRANS,
  591. Hresult,
  592. "COInetProt::IInternetProtocol::Read",
  593. "this=%#x, %#x, %#x, %#x",
  594. this, pBuffer, cbBuffer, pcbRead
  595. ));
  596. PerfDbgLog(tagCTransaction, this, "+COInetProt::Read\n");
  597. HRESULT hr = E_FAIL;
  598. BOOL fRead = TRUE;
  599. DWORD dwCopy = 0;
  600. DWORD dwCopyNew = 0;
  601. if ((_dwOInetBdgFlags & (PI_MIMEVERIFICATION | PI_DOCFILECLSIDLOOKUP))
  602. && _cbBufferUnread)
  603. {
  604. fRead = FALSE;
  605. // copy data form the local buffer to the provide buffer
  606. if (cbBuffer <= _cbBufferUnread)
  607. {
  608. dwCopy = cbBuffer;
  609. hr = S_OK;
  610. }
  611. else
  612. {
  613. dwCopy = _cbBufferUnread;
  614. fRead = TRUE;
  615. }
  616. memcpy(pBuffer, _pBuffer+(_cbBufferFilled-_cbBufferUnread), dwCopy);
  617. _cbBufferUnread -= dwCopy;
  618. }
  619. if (fRead)
  620. {
  621. if (_pProt)
  622. {
  623. hr = _pProt->Read( ((LPBYTE)pBuffer) + dwCopy, cbBuffer - dwCopy, &dwCopyNew);
  624. _cbTotalBytesRead += dwCopyNew;
  625. }
  626. else
  627. {
  628. hr = S_FALSE;
  629. }
  630. }
  631. if (pcbRead)
  632. {
  633. *pcbRead = dwCopy + dwCopyNew;
  634. }
  635. PerfDbgLog1(tagCTransaction, this, "-COInetProt::Read (hr:%lx)\n",hr);
  636. DEBUG_LEAVE(hr);
  637. return hr;
  638. }
  639. //+---------------------------------------------------------------------------
  640. //
  641. // Method: COInetProt::Seek
  642. //
  643. // Synopsis:
  644. //
  645. // Arguments: [DWORD] --
  646. // [ULARGE_INTEGER] --
  647. // [plibNewPosition] --
  648. //
  649. // Returns:
  650. //
  651. // History: 10-29-1996 JohannP (Johann Posch) Created
  652. //
  653. // Notes:
  654. //
  655. //----------------------------------------------------------------------------
  656. STDMETHODIMP COInetProt::Seek(LARGE_INTEGER dlibMove,DWORD dwOrigin,ULARGE_INTEGER *plibNewPosition)
  657. {
  658. DEBUG_ENTER((DBG_TRANS,
  659. Hresult,
  660. "COInetProt::IInternetProtocol::Seek",
  661. "this=%#x, %#x, %#x, %#x",
  662. this, dlibMove, dwOrigin, plibNewPosition
  663. ));
  664. PerfDbgLog(tagCTransaction, this, "+COInetProt::Seek\n");
  665. HRESULT hr = _pProt->Seek(dlibMove, dwOrigin, plibNewPosition);
  666. PerfDbgLog1(tagCTransaction, this, "-COInetProt::Seek (hr:%lx)\n", hr);
  667. DEBUG_LEAVE(hr);
  668. return hr;
  669. }
  670. //+---------------------------------------------------------------------------
  671. //
  672. // Method: COInetProt::LockRequest
  673. //
  674. // Synopsis:
  675. //
  676. // Arguments: [dwOptions] --
  677. //
  678. // Returns:
  679. //
  680. // History: 10-29-1996 JohannP (Johann Posch) Created
  681. //
  682. // Notes:
  683. //
  684. //----------------------------------------------------------------------------
  685. STDMETHODIMP COInetProt::LockRequest(DWORD dwOptions)
  686. {
  687. DEBUG_ENTER((DBG_TRANS,
  688. Hresult,
  689. "COInetProt::IInternetProtocol::LockRequest",
  690. "this=%#x, %#x",
  691. this, dwOptions
  692. ));
  693. PerfDbgLog(tagCTransaction, this, "+COInetProt::LockRequest\n");
  694. HRESULT hr = hr = _pProt->LockRequest(dwOptions);
  695. PerfDbgLog1(tagCTransaction, this, "-COInetProt::LockRequest (hr:%lx)\n",hr);
  696. DEBUG_LEAVE(hr);
  697. return hr;
  698. }
  699. //+---------------------------------------------------------------------------
  700. //
  701. // Method: COInetProt::UnlockRequest
  702. //
  703. // Synopsis:
  704. //
  705. // Arguments: (none)
  706. //
  707. // Returns:
  708. //
  709. // History: 10-29-1996 JohannP (Johann Posch) Created
  710. //
  711. // Notes:
  712. //
  713. //----------------------------------------------------------------------------
  714. STDMETHODIMP COInetProt::UnlockRequest()
  715. {
  716. DEBUG_ENTER((DBG_TRANS,
  717. Hresult,
  718. "COInetProt::IInternetProtocol::UnlockRequest",
  719. "this=%#x",
  720. this
  721. ));
  722. PerfDbgLog(tagCTransaction, this, "+COInetProt::UnlockRequest\n");
  723. HRESULT hr = NOERROR;
  724. hr = _pProt->UnlockRequest();
  725. PerfDbgLog1(tagCTransaction, this, "-COInetProt::UnlockRequest (hr:%lx)\n", hr);
  726. DEBUG_LEAVE(hr);
  727. return hr;
  728. }
  729. //+---------------------------------------------------------------------------
  730. //
  731. // Method: CTransaction::OnDataReceived
  732. //
  733. // Synopsis:
  734. //
  735. // Arguments: [grfBSC] --
  736. // [cbBytesAvailable] --
  737. // [dwTotalSize] --
  738. // [pcbNewAvailable] --
  739. //
  740. // Returns:
  741. //
  742. // History: 4-15-1997 JohannP (Johann Posch) Created
  743. //
  744. // Notes:
  745. //
  746. //----------------------------------------------------------------------------
  747. STDMETHODIMP COInetProt::OnDataReceived(DWORD *pgrfBSC, DWORD *pcbBytesAvailable, DWORD *pdwTotalSize)
  748. {
  749. DEBUG_ENTER((DBG_TRANS,
  750. Hresult,
  751. "COInetProt::OnDataReceived",
  752. "this=%#x, %#x, %#x, %#x",
  753. this, pgrfBSC, pcbBytesAvailable, pdwTotalSize
  754. ));
  755. PerfDbgLog3(tagCTransaction, this, "+COInetProt::OnDataReceived (grfBSC:%lx, *pcbBytesAvailable:%ld, _cbTotalBytesRead:%ld)",
  756. *pgrfBSC, *pcbBytesAvailable, _cbTotalBytesRead);
  757. HRESULT hr = NOERROR;
  758. DWORD grfBSC = *pgrfBSC;
  759. BOOL fEndOfData = FALSE;
  760. if (_fWaitOnHandler)
  761. {
  762. hr = S_NEEDMOREDATA;
  763. }
  764. else if (
  765. ((_dwOInetBdgFlags & (PI_MIMEVERIFICATION | PI_DOCFILECLSIDLOOKUP | PI_CLASSINSTALL))
  766. && (!_fMimeVerified || _fNeedMoreData))
  767. ||
  768. ((_dwOInetBdgFlags & PI_CLASSINSTALL) && !_fClassInstallChecked)
  769. )
  770. {
  771. DWORD dwNewData = 0;
  772. TransAssert((_pProt && _cbDataSniffMin));
  773. //TransAssert((pcbBytesAvailable && *pcbBytesAvailable));
  774. //TransAssert((pdwTotalSize));
  775. // _cbTotalBytesRead = # of bytes read so far
  776. if (_cbBufferFilled < _cbDataSniffMin)
  777. {
  778. // no bytes read so far
  779. TransAssert((_cbTotalBytesRead < _cbDataSniffMin));
  780. // read data into buffer and report progess
  781. do
  782. {
  783. PProtAssert((_pBuffer && (_pBuffer + _cbBufferFilled) ));
  784. hr = _pProt->Read(_pBuffer + _cbBufferFilled, _cbBufferSize - _cbBufferFilled, &dwNewData);
  785. _cbTotalBytesRead += dwNewData;
  786. _cbBufferFilled += dwNewData;
  787. _cbBufferUnread += dwNewData;
  788. } while ((hr == S_OK) && (_cbBufferFilled < _cbDataSniffMin));
  789. // now check if this is docfile
  790. // if so download at least 2k
  791. if (!_fDocFile && _cbBufferFilled && (IsDocFile(_pBuffer, _cbBufferFilled) == S_OK))
  792. {
  793. _fDocFile = TRUE;
  794. // we may need to sniff to maximum to find handler
  795. if (_cbBufferSize < DATASNIFSIZEDOCFILE_MAX)
  796. {
  797. LPBYTE pBufferTemp;
  798. pBufferTemp = (LPBYTE) new BYTE[DATASNIFSIZEDOCFILE_MAX];
  799. if (pBufferTemp)
  800. {
  801. memcpy(pBufferTemp, _pBuffer, _cbBufferFilled);
  802. delete [] _pBuffer;
  803. _pBuffer = pBufferTemp;
  804. _cbBufferSize = DATASNIFSIZEDOCFILE_MAX;
  805. if (hr == NOERROR)
  806. {
  807. //since we increased the buffersize and we want to drain DATASNIFSIZEDOCFILE_MAX bytes.
  808. do
  809. {
  810. PProtAssert((_pBuffer && (_pBuffer + _cbBufferFilled) ));
  811. hr = _pProt->Read(_pBuffer + _cbBufferFilled, _cbBufferSize - _cbBufferFilled, &dwNewData);
  812. _cbTotalBytesRead += dwNewData;
  813. _cbBufferFilled += dwNewData;
  814. _cbBufferUnread += dwNewData;
  815. } while ((hr == S_OK) && (_cbBufferFilled < _cbBufferSize));
  816. }
  817. }
  818. }
  819. _cbDataSniffMin = (*pdwTotalSize && *pdwTotalSize < _cbBufferSize) ? *pdwTotalSize : _cbBufferSize;
  820. }
  821. if ((hr == E_PENDING) && (_cbBufferFilled < _cbDataSniffMin))
  822. {
  823. // do not report anything - wait until we get more data
  824. // a request is pending at this time
  825. // need more data to sniff properly
  826. hr = S_NEEDMOREDATA;
  827. }
  828. else if (hr == NOERROR || hr == E_PENDING)
  829. {
  830. TransAssert((_cbTotalBytesRead != 0));
  831. // report the data we have in the buffer or
  832. // the available #
  833. DWORD cbBytesReport = (*pcbBytesAvailable > _cbTotalBytesRead) ? *pcbBytesAvailable : _cbTotalBytesRead + 1;
  834. if (*pdwTotalSize && ((cbBytesReport > *pdwTotalSize)))
  835. {
  836. cbBytesReport = *pdwTotalSize;
  837. }
  838. *pcbBytesAvailable = cbBytesReport;
  839. }
  840. else if (hr == S_FALSE)
  841. {
  842. // end of stream
  843. *pgrfBSC |= (BSCF_LASTDATANOTIFICATION & BSCF_DATAFULLYAVAILABLE);
  844. *pcbBytesAvailable = *pdwTotalSize = _cbTotalBytesRead;
  845. fEndOfData = TRUE;
  846. }
  847. if ( (!_fMimeVerified)
  848. && ( (*pcbBytesAvailable >= _cbDataSniffMin)
  849. || (hr == S_FALSE)) )
  850. {
  851. // enough data or end of stream
  852. _fMimeVerified = TRUE;
  853. LPWSTR pwzStr = 0;
  854. DWORD dwMimeFlags = FMFD_DEFAULT;
  855. if( !_pwzFileName )
  856. {
  857. dwMimeFlags = FMFD_URLASFILENAME;
  858. }
  859. hr = FindMimeFromData(NULL, (_pwzFileName) ? _pwzFileName : _pwzUrl, _pBuffer, _cbBufferFilled, _pwzMimeSuggested, dwMimeFlags, &pwzStr, 0);
  860. TransAssert(pwzStr);
  861. // note: _pwzUrl & _pwzFileName may be used later for composing URL
  862. // in code base attribute of active document (deleted in destructor)
  863. if (pwzStr)
  864. {
  865. _fMimeReported = 1;
  866. _pProtSnk->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, pwzStr);
  867. }
  868. else
  869. {
  870. TransAssert((!_pwzMimeSuggested));
  871. }
  872. if (pwzStr)
  873. {
  874. delete [] _pwzMimeSuggested;
  875. _pwzMimeSuggested = pwzStr;
  876. pwzStr = 0;
  877. }
  878. if ( _fDocFile
  879. && (_dwOInetBdgFlags & PI_DOCFILECLSIDLOOKUP))
  880. {
  881. // find the class id and send it on
  882. CLSID clsid;
  883. HRESULT hr1 = GetClassDocFileBuffer(_pBuffer, _cbBufferFilled, &clsid);
  884. if (hr1 == NOERROR)
  885. {
  886. if (_pwzStrClsId)
  887. {
  888. delete [] _pwzStrClsId;
  889. _pwzStrClsId = NULL;
  890. }
  891. StringFromCLSID(clsid, &_pwzStrClsId);
  892. if (_pwzStrClsId)
  893. {
  894. _fReportedClassId = TRUE;
  895. _pProtSnk->ReportProgress(BINDSTATUS_CLASSIDAVAILABLE, _pwzStrClsId);
  896. }
  897. }
  898. }
  899. }
  900. }
  901. //On a BTS->BTO scenario, we should get into this loop with the lesser of DATASNIFSIZEDOCFILE_MIN or TOTAL_SIZE.
  902. //On a BTO scenario, the situation is the same as before, except hr=S_NEEDMOREDATA if size<DATASNIF_MIN.
  903. //On a BTS scenario, this block will not be entered.
  904. if ( (_dwOInetBdgFlags & PI_CLASSINSTALL)
  905. && !_fGotHandler )
  906. {
  907. _fClassInstallChecked = TRUE;
  908. BOOL fIgnoreMimeClsid = FALSE;
  909. DWORD dwVersionMS = 0, dwVersionLS = 0;
  910. LPWSTR pwzCodeBase = 0, pwzVerInfo = 0;
  911. CLSID clsid;
  912. HRESULT hr1;
  913. if (!_fReportedClassId && _pwzStrClsId && _pProtSnk)
  914. {
  915. _fReportedClassId = TRUE;
  916. _pProtSnk->ReportProgress(BINDSTATUS_CLASSIDAVAILABLE, _pwzStrClsId);
  917. }
  918. if (IsHandlerAvailable((_pwzFileName) ? _pwzFileName : _pwzUrl, _pwzMimeSuggested, &clsid, _pBuffer, _cbBufferFilled) == S_OK)
  919. {
  920. _fGotHandler = TRUE;
  921. }
  922. else if (_fDocFile)
  923. {
  924. // try get code base + version information
  925. // even if handler is installed, a newer version may be required for this doc file
  926. hr1 = GetCodeBaseFromDocFile(_pBuffer, _cbBufferFilled, &pwzCodeBase, _pwzUrl, &dwVersionMS, &dwVersionLS);
  927. // convert version info. to string
  928. if (SUCCEEDED(hr1) && (dwVersionMS || dwVersionLS))
  929. {
  930. CHAR szVerInfo[MAX_PATH];
  931. wsprintfA(szVerInfo,"%ld,%ld", dwVersionMS, dwVersionLS);
  932. pwzVerInfo = DupA2W(szVerInfo);
  933. }
  934. // if failed to get codebase, keep sniffing
  935. // if we are at end of bits then go with out a code base
  936. _fNeedMoreData = FAILED(hr1) && (_cbBufferFilled < _cbDataSniffMin) && (!fEndOfData);
  937. }
  938. //BUGBUG #51944: This currently requires a DocFile and CodeBase property
  939. if (!_fNeedMoreData && !_fGotHandler && _fDocFile && pwzCodeBase)
  940. {
  941. LPOLESTR pwzClsId = 0;
  942. if (!IsEqualCLSID(clsid, CLSID_NULL))
  943. {
  944. StringFromCLSID(clsid, &pwzClsId);
  945. }
  946. else if (_pwzMimeSuggested)
  947. {
  948. // this is an optimization, if no CLSID and only this as mime type
  949. // then we won't find anything in ObjectStore
  950. if (!StrCmpNIW(_pwzMimeSuggested, L"application/octet-stream", 24))
  951. {
  952. _fGotHandler = TRUE;
  953. }
  954. }
  955. if (!_fGotHandler && (pwzClsId || _pwzMimeSuggested))
  956. {
  957. LPWSTR pwzClassStr = 0;
  958. int cbClassStr;
  959. cbClassStr = (pwzCodeBase ? lstrlenW(pwzCodeBase) : 0)
  960. + (pwzClsId ? lstrlenW(pwzClsId) : 0)
  961. + (_pwzMimeSuggested ? lstrlenW(_pwzMimeSuggested) : 0)
  962. + (pwzVerInfo ? (lstrlenW(pwzVerInfo) + 1) : 0)
  963. + 3;
  964. pwzClassStr = new WCHAR[cbClassStr];
  965. if (pwzClassStr)
  966. {
  967. //BUGBUG: This is a bit of a hack, we have a collection of
  968. //info to pass into filter, we concatenate it into one long
  969. //string and send it in.
  970. *pwzClassStr = '\0';
  971. if (pwzCodeBase && *pwzCodeBase)
  972. {
  973. StrCpyW(pwzClassStr, pwzCodeBase);
  974. }
  975. StrCatW(pwzClassStr, L"?");
  976. if (pwzClsId)
  977. {
  978. StrCatW(pwzClassStr, pwzClsId);
  979. }
  980. else if (_pwzMimeSuggested)
  981. {
  982. StrCatW(pwzClassStr, _pwzMimeSuggested);
  983. }
  984. if (pwzVerInfo)
  985. {
  986. StrCatW(pwzClassStr, L"?");
  987. StrCatW(pwzClassStr, pwzVerInfo);
  988. }
  989. _pCTrans->ReportProgress(BINDSTATUS_CLASSINSTALLLOCATION,
  990. pwzClassStr);
  991. delete [] pwzClassStr;
  992. // don't process this code branch again
  993. _fGotHandler = TRUE;
  994. // wait on more data now
  995. hr = S_NEEDMOREDATA;
  996. // wait on more data for future calls
  997. _fWaitOnHandler = TRUE;
  998. // wait for more data to sniff
  999. _fNeedMoreData = TRUE;
  1000. }
  1001. delete [] pwzClsId;
  1002. } // pwzClsId || _pwzMimeSuggested
  1003. } // !_fNeedMoreData
  1004. if (pwzCodeBase)
  1005. {
  1006. CoTaskMemFree(pwzCodeBase);
  1007. }
  1008. if (pwzVerInfo)
  1009. {
  1010. delete [] pwzVerInfo;
  1011. }
  1012. // if we don't need to sniff any more, curb _cbDataSniffMin
  1013. if (_fDocFile && _fGotHandler)
  1014. {
  1015. _cbDataSniffMin = (*pdwTotalSize && *pdwTotalSize < DATASNIFSIZEDOCFILE_MIN) ? *pdwTotalSize : DATASNIFSIZEDOCFILE_MIN;
  1016. }
  1017. // once we have a handler we can release pwzUrl & pwzFilename
  1018. if (_fGotHandler)
  1019. {
  1020. delete [] _pwzUrl;
  1021. _pwzUrl = 0;
  1022. delete [] _pwzFileName;
  1023. _pwzFileName = 0;
  1024. }
  1025. // report the data we have in the buffer or
  1026. // the available #
  1027. *pcbBytesAvailable = (*pcbBytesAvailable > _cbTotalBytesRead) ? *pcbBytesAvailable : _cbTotalBytesRead + 1;
  1028. } // PI_CLASSINSTALL && !_fGotHandler
  1029. if (*pdwTotalSize && (*pdwTotalSize < *pcbBytesAvailable))
  1030. {
  1031. *pcbBytesAvailable = *pdwTotalSize;
  1032. }
  1033. if (hr == S_FALSE)
  1034. {
  1035. hr = NOERROR;
  1036. }
  1037. }
  1038. {
  1039. CLock lck(_mxs);
  1040. _cbBytesReported = *pcbBytesAvailable;
  1041. }
  1042. //TransAssert((pcbBytesAvailable && *pcbBytesAvailable));
  1043. //TransAssert((hr == NOERROR || hr == S_NEEDMOREDATA));
  1044. PerfDbgLog2(tagCTransaction, this, "-COInetProt::OnDataReceived (hr:%lx, _cbBufferFilled:%ld)", hr, _cbBufferFilled);
  1045. DEBUG_LEAVE(hr);
  1046. return hr;
  1047. }
  1048. //+---------------------------------------------------------------------------
  1049. //
  1050. // Method: COInetProt::Switch
  1051. //
  1052. // Synopsis:
  1053. //
  1054. // Arguments: [pStateInfo] --
  1055. //
  1056. // Returns:
  1057. //
  1058. // History: 11-07-1996 JohannP (Johann Posch) Created
  1059. //
  1060. // Notes:
  1061. //
  1062. //----------------------------------------------------------------------------
  1063. STDMETHODIMP COInetProt::Switch(PROTOCOLDATA *pStateInfo)
  1064. {
  1065. DEBUG_ENTER((DBG_TRANS,
  1066. Hresult,
  1067. "COInetProt::IInternetProtocolSink::Switch",
  1068. "this=%#x, %#x",
  1069. this, pStateInfo
  1070. ));
  1071. PerfDbgLog(tagCTransaction, this, "+COInetProt::Switch");
  1072. HRESULT hr = NOERROR;
  1073. hr = _pProtSnk->Switch(pStateInfo);
  1074. PerfDbgLog1(tagCTransaction, this, "-COInetProt::Switch (hr:%lx)", hr);
  1075. DEBUG_LEAVE(hr);
  1076. return hr;
  1077. }
  1078. //+---------------------------------------------------------------------------
  1079. //
  1080. // Method: COInetProt::ReportProgress
  1081. //
  1082. // Synopsis:
  1083. //
  1084. // Arguments: [NotMsg] --
  1085. // [szStatusText] --
  1086. //
  1087. // Returns:
  1088. //
  1089. // History: 11-07-1996 JohannP (Johann Posch) Created
  1090. //
  1091. // Notes:
  1092. //
  1093. //----------------------------------------------------------------------------
  1094. STDMETHODIMP COInetProt::ReportProgress(ULONG NotMsg, LPCWSTR pwzStatusText)
  1095. {
  1096. DEBUG_ENTER((DBG_TRANS,
  1097. Hresult,
  1098. "COInetProt::IInternetProtocolSink::ReportProgress",
  1099. "this=%#x, %#x, %.80wq",
  1100. this, NotMsg, pwzStatusText
  1101. ));
  1102. PerfDbgLog(tagCTransaction, this, "+COInetProt::ReportProgress");
  1103. HRESULT hr = NOERROR;
  1104. switch (NotMsg)
  1105. {
  1106. case BINDSTATUS_FILTERREPORTMIMETYPE:
  1107. {
  1108. if( _pCTrans && pwzStatusText )
  1109. {
  1110. // mime filter sending signal to tell us the true mime type
  1111. _pCTrans->UpdateVerifiedMimeType(pwzStatusText);
  1112. }
  1113. }
  1114. break;
  1115. case BINDSTATUS_MIMETYPEAVAILABLE:
  1116. if (_dwOInetBdgFlags & (PI_MIMEVERIFICATION | PI_DOCFILECLSIDLOOKUP | PI_CLASSINSTALL))
  1117. {
  1118. // report the mime later after sniffing data
  1119. _pwzMimeSuggested = OLESTRDuplicate(pwzStatusText);
  1120. }
  1121. else
  1122. {
  1123. hr = _pProtSnk->ReportProgress(NotMsg, pwzStatusText);
  1124. }
  1125. break;
  1126. case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
  1127. {
  1128. // disable mime sniffing
  1129. _dwOInetBdgFlags &= (~PI_MIMEVERIFICATION &~PI_DOCFILECLSIDLOOKUP &~PI_CLASSINSTALL);
  1130. hr = _pProtSnk->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, pwzStatusText);
  1131. }
  1132. break;
  1133. case BINDSTATUS_CACHEFILENAMEAVAILABLE :
  1134. _pwzFileName = OLESTRDuplicate(pwzStatusText);
  1135. hr = _pProtSnk->ReportProgress(NotMsg, pwzStatusText);
  1136. break;
  1137. case BINDSTATUS_DIRECTBIND:
  1138. _fMimeVerified = TRUE;
  1139. break;
  1140. case BINDSTATUS_ENDDOWNLOADCOMPONENTS :
  1141. if (_fWaitOnHandler)
  1142. {
  1143. // don't stall ReportData any more
  1144. _fWaitOnHandler = FALSE;
  1145. // we're done with our stuff, skip sniffing
  1146. _fNeedMoreData = FALSE;
  1147. }
  1148. default:
  1149. {
  1150. hr = _pProtSnk->ReportProgress(NotMsg, pwzStatusText);
  1151. }
  1152. } // end switch
  1153. PerfDbgLog1(tagCTransaction, this, "-COInetProt::ReportProgress (hr:%lx)", hr);
  1154. DEBUG_LEAVE(hr);
  1155. return hr;
  1156. }
  1157. //+---------------------------------------------------------------------------
  1158. //
  1159. // Method: COInetProt::ReportData
  1160. //
  1161. // Synopsis:
  1162. //
  1163. // Arguments: [grfBSCF] --
  1164. // [ULONG] --
  1165. // [ulProgressMax] --
  1166. //
  1167. // Returns:
  1168. //
  1169. // History: 11-07-1996 JohannP (Johann Posch) Created
  1170. //
  1171. // Notes:
  1172. //
  1173. //----------------------------------------------------------------------------
  1174. STDMETHODIMP COInetProt::ReportData(DWORD grfBSCF, ULONG ulProgress,ULONG ulProgressMax)
  1175. {
  1176. DEBUG_ENTER((DBG_TRANS,
  1177. Hresult,
  1178. "COInetProt::IInternetProtocolSink::ReportData",
  1179. "this=%#x, %#x, %#x, %#x",
  1180. this, grfBSCF, ulProgress, ulProgressMax
  1181. ));
  1182. PerfDbgLog3(tagCTransaction, this, "+COInetProt::ReportData(grfBSCF:%lx, ulProgress:%ld, ulProgressMax:%ld)",
  1183. grfBSCF, ulProgress, ulProgressMax);
  1184. HRESULT hr = NOERROR, hr2;
  1185. TransAssert((ulProgress));
  1186. if ( ((_dwOInetBdgFlags & (PI_MIMEVERIFICATION | PI_DOCFILECLSIDLOOKUP | PI_CLASSINSTALL))
  1187. && (!_fMimeVerified || _fNeedMoreData))
  1188. ||
  1189. ((_dwOInetBdgFlags & PI_CLASSINSTALL) && !_fClassInstallChecked)
  1190. )
  1191. {
  1192. if ( (OnDataReceived(&grfBSCF, &ulProgress, &ulProgressMax) == NOERROR)
  1193. && _pProtSnk
  1194. && (ulProgress || (!ulProgress && !ulProgressMax)) )
  1195. {
  1196. // OnDataReceived sniffs data and calls Read - EOF with ReportResult might occure
  1197. //TransAssert((ulProgress));
  1198. TransAssert((_fMimeReported));
  1199. hr = _pProtSnk->ReportData( grfBSCF, ulProgress, ulProgressMax);
  1200. }
  1201. }
  1202. else
  1203. {
  1204. TransAssert((ulProgress));
  1205. hr = _pProtSnk->ReportData( grfBSCF, ulProgress, ulProgressMax);
  1206. }
  1207. PerfDbgLog1(tagCTransaction, this, "-COInetProt::ReportData (hr:%lx)", hr);
  1208. DEBUG_LEAVE(hr);
  1209. return hr;
  1210. }
  1211. //+---------------------------------------------------------------------------
  1212. //
  1213. // Method: COInetProt::ReportResult
  1214. //
  1215. // Synopsis:
  1216. //
  1217. // Arguments: [DWORD] --
  1218. // [dwError] --
  1219. // [wzResult] --
  1220. //
  1221. // Returns:
  1222. //
  1223. // History: 11-07-1996 JohannP (Johann Posch) Created
  1224. //
  1225. // Notes:
  1226. //
  1227. //----------------------------------------------------------------------------
  1228. STDMETHODIMP COInetProt::ReportResult(HRESULT hrResult, DWORD dwError, LPCWSTR wzResult)
  1229. {
  1230. DEBUG_ENTER((DBG_TRANS,
  1231. Hresult,
  1232. "COInetProt::IInternetProtocolSink::ReportResult",
  1233. "this=%#x, %#x, %#x, %.80wq",
  1234. this, hrResult, dwError, wzResult
  1235. ));
  1236. PerfDbgLog(tagCTransaction, this, "+COInetProt::ReportResult");
  1237. HRESULT hr = NOERROR;
  1238. hr = _pProtSnk->ReportResult(hrResult, dwError, wzResult);
  1239. PerfDbgLog1(tagCTransaction, this, "-COInetProt::ReportResult (hr:%lx)", hr);
  1240. DEBUG_LEAVE(hr);
  1241. return hr;
  1242. }
  1243. //+---------------------------------------------------------------------------
  1244. //
  1245. // Method: COInetProt::Initialize
  1246. //
  1247. // Synopsis:
  1248. //
  1249. // Arguments: [pCTrans] --
  1250. // [dwMode] --
  1251. // [dwOptions] --
  1252. // [pUnk] --
  1253. // [pProt] --
  1254. // [pProtSnk] --
  1255. //
  1256. // Returns:
  1257. //
  1258. // History: 11-07-1996 JohannP (Johann Posch) Created
  1259. //
  1260. // Notes:
  1261. //
  1262. //----------------------------------------------------------------------------
  1263. STDMETHODIMP COInetProt::Initialize(CTransaction *pCTrans,IServiceProvider *pSrvPrv, DWORD dwMode, DWORD dwOptions,
  1264. IUnknown *pUnk, IOInetProtocol *pProt, IOInetProtocolSink *pProtSnk, LPWSTR pwzUrl)
  1265. {
  1266. DEBUG_ENTER((DBG_TRANS,
  1267. Hresult,
  1268. "COInetProt::Initialize",
  1269. "this=%#x, %#x, %#x, %#x, %#x, %#x, %#x, %#x, %.80wq",
  1270. this, pCTrans, pSrvPrv, dwMode, dwOptions, pUnk, pProt, pProtSnk, pwzUrl
  1271. ));
  1272. HRESULT hr = NOERROR;
  1273. _dwMode = dwMode;
  1274. _pUnk = pUnk;
  1275. //_pProt = pProt;
  1276. //_pProtSnk = pProtSnk;
  1277. _pCTrans = pCTrans;
  1278. _pSrvPrv = pSrvPrv;
  1279. if (_pSrvPrv)
  1280. {
  1281. _pSrvPrv->AddRef();
  1282. }
  1283. SetProtocolSink(pProtSnk);
  1284. SetProtocol(pProt);
  1285. _dwOInetBdgFlags = dwOptions;
  1286. if (_dwOInetBdgFlags & (PI_MIMEVERIFICATION | PI_DOCFILECLSIDLOOKUP))
  1287. {
  1288. ULONG cbBufferSize;
  1289. TransAssert(( DATASNIFSIZE_MIN <= DATASNIFSIZEDOCFILE_MIN));
  1290. if (_dwOInetBdgFlags & PI_CLASSINSTALL)
  1291. {
  1292. cbBufferSize = DATASNIFSIZEDOCFILE_MAX;
  1293. }
  1294. else
  1295. {
  1296. cbBufferSize = DATASNIFSIZEDOCFILE_MIN; //DATASNIFSIZE_MIN;
  1297. }
  1298. if (cbBufferSize != _cbBufferSize)
  1299. {
  1300. _cbBufferSize = cbBufferSize;
  1301. delete [] _pBuffer;
  1302. _pBuffer = (LPBYTE) new BYTE[_cbBufferSize];
  1303. }
  1304. if (!_pBuffer)
  1305. {
  1306. _cbBufferSize = 0;
  1307. hr = E_OUTOFMEMORY;
  1308. }
  1309. else
  1310. {
  1311. _cbDataSniffMin = DATASNIFSIZE_MIN;
  1312. }
  1313. if (pwzUrl)
  1314. {
  1315. delete [] _pwzUrl;
  1316. _pwzUrl = OLESTRDuplicate(pwzUrl);
  1317. }
  1318. }
  1319. TransAssert((_pProt && _pProtSnk));
  1320. DEBUG_LEAVE(hr);
  1321. return hr;
  1322. }
  1323. //+---------------------------------------------------------------------------
  1324. //
  1325. // Method: COInetProt::QueryService
  1326. //
  1327. // Synopsis:
  1328. //
  1329. // Arguments: [rsid] --
  1330. // [riid] --
  1331. // [ppvObj] --
  1332. //
  1333. // Returns:
  1334. //
  1335. // History: 11-07-1996 JohannP (Johann Posch) Created
  1336. //
  1337. // Notes:
  1338. //
  1339. //----------------------------------------------------------------------------
  1340. HRESULT IUnknown_QueryService(IUnknown* punk, REFGUID rsid, REFIID riid, void ** ppvObj);
  1341. HRESULT COInetProt::QueryService(REFGUID rsid, REFIID riid, void ** ppvObj)
  1342. {
  1343. DEBUG_ENTER((DBG_TRANS,
  1344. Hresult,
  1345. "COInetProt::IServiceProvider::QueryService",
  1346. "this=%#x, %#x, %#x, %#x",
  1347. this, &rsid, &riid, ppvObj
  1348. ));
  1349. PerfDbgLog(tagCTransaction, this, "+COInetProt::QueryService");
  1350. HRESULT hr = NOERROR;
  1351. VDATETHIS(this);
  1352. TransAssert((ppvObj));
  1353. if (_pSrvPrv)
  1354. {
  1355. hr = _pSrvPrv->QueryService(rsid,riid, ppvObj);
  1356. }
  1357. else
  1358. {
  1359. hr = IUnknown_QueryService(_pProtSnk, rsid, riid, ppvObj);
  1360. }
  1361. TransAssert(( ((hr == E_NOINTERFACE) && !*ppvObj) || ((hr == NOERROR) && *ppvObj) ));
  1362. PerfDbgLog1(tagCTransaction, this, "-COInetProt::QueryService (hr:%lx)", hr);
  1363. DEBUG_LEAVE(hr);
  1364. return hr;
  1365. }
  1366. STDMETHODIMP COInetProt::SetPriority(LONG nPriority)
  1367. {
  1368. DEBUG_ENTER((DBG_TRANS,
  1369. Hresult,
  1370. "COInetProt::IInternetPriority::SetPriority",
  1371. "this=%#x, %#x",
  1372. this, nPriority
  1373. ));
  1374. PerfDbgLog1(tagCTransaction, this, "+COInetProt::SetPriority (%ld)", nPriority);
  1375. HRESULT hr = S_OK;
  1376. _nPriority = nPriority;
  1377. PerfDbgLog1(tagCTransaction, this, "-COInetProt::SetPriority (hr:%lx)", hr);
  1378. DEBUG_LEAVE(hr);
  1379. return hr;
  1380. }
  1381. STDMETHODIMP COInetProt::GetPriority(LONG * pnPriority)
  1382. {
  1383. DEBUG_ENTER((DBG_TRANS,
  1384. Hresult,
  1385. "COInetProt::IInternetPriority::GetPriority",
  1386. "this=%#x, %#x",
  1387. this, pnPriority
  1388. ));
  1389. PerfDbgLog(tagCTransaction, this, "+COInetProt::GetPriority");
  1390. HRESULT hr;
  1391. if (!pnPriority)
  1392. {
  1393. hr = E_INVALIDARG;
  1394. }
  1395. else
  1396. {
  1397. *pnPriority = _nPriority;
  1398. hr = S_OK;
  1399. }
  1400. PerfDbgLog1(tagCTransaction, this, "-COInetProt::GetPriority (hr:%lx)", hr);
  1401. DEBUG_LEAVE(hr);
  1402. return hr;
  1403. }