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.

4467 lines
129 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: cbinding.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 11-11-95 JohannP (Johann Posch) Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <trans.h>
  18. #include "oinet.hxx"
  19. #include "cdl.h" // defined in urlmon\download\
  20. // from helpers.cxx
  21. HRESULT IsMimeHandled(LPCWSTR pwszMimeType);
  22. // From shlwapip.h
  23. LWSTDAPI_(HRESULT) CLSIDFromStringWrap(LPOLESTR lpsz, LPCLSID pclsid);
  24. PerfDbgTag(tagCBinding, "Urlmon", "Log CBinding", DEB_BINDING);
  25. DbgTag(tagCBindingErr, "Urlmon", "Log CBinding Errors", DEB_BINDING|DEB_ERROR);
  26. extern DWORD g_dwSettings;
  27. #define MAX_PROTOCOL_LEN 32 // protocl string length in ASCII BUGBUG is there a standard?
  28. #define PROTOCOL_DELIMITER ':'
  29. #define REG_PROTOCOL_HANDLER L"ProtocolHandler"
  30. WCHAR *rglpProto[] =
  31. {
  32. L"https",
  33. L"http",
  34. L"ftp",
  35. L"gopher",
  36. L"file",
  37. L"local",
  38. L"mk",
  39. NULL,
  40. };
  41. HRESULT GetTransactionObjects(LPBC pBndCtx, LPCWSTR wzUrl, IUnknown *pUnkOuter, IUnknown **ppUnk, IOInetProtocol **ppCTrans, DWORD dwOption, CTransData **pCTransData);
  42. BOOL PDFNeedProgressiveDownload();
  43. EXTERN_C const GUID CLSID_MsHtml;
  44. EXTERN_C const GUID IID_ITransactionData;
  45. //+---------------------------------------------------------------------------
  46. //
  47. // Function: CreateURLBinding
  48. //
  49. // Synopsis:
  50. //
  51. // Arguments: [lpszUrl] --
  52. // [pbc] --
  53. // [ppBdg] --
  54. //
  55. // Returns:
  56. //
  57. // History: 12-04-95 JohannP (Johann Posch) Created
  58. //
  59. // Notes:
  60. //
  61. //----------------------------------------------------------------------------
  62. HRESULT CreateURLBinding(LPWSTR lpszUrl, IBindCtx *pbc, IBinding **ppBdg)
  63. {
  64. DEBUG_ENTER_API((DBG_BINDING,
  65. Hresult,
  66. "CreateURLBinding",
  67. "%.80wq, %#x, %#x",
  68. lpszUrl, pbc, ppBdg
  69. ));
  70. PerfDbgLog(tagCBinding, NULL, "+CreateURLBinding");
  71. HRESULT hr = NOERROR;
  72. PerfDbgLog1(tagCBinding, NULL, "-CreateURLBinding (IBinding:%lx)", *ppBdg);
  73. DEBUG_LEAVE_API(hr);
  74. return hr;
  75. }
  76. //+---------------------------------------------------------------------------
  77. //
  78. // Method: CBinding::Create
  79. //
  80. // Synopsis:
  81. //
  82. // Arguments: [pUnkOuter] --
  83. // [LPBC] --
  84. // [pbc] --
  85. //
  86. // Returns:
  87. //
  88. // History: 12-06-95 JohannP (Johann Posch) Created
  89. //
  90. // Notes:
  91. //
  92. //----------------------------------------------------------------------------
  93. HRESULT CBinding::Create(IUnknown *pUnkOuter, LPCWSTR szUrl, LPBC pbc, REFIID riid, BOOL fBindToObject, CBinding **ppCBdg)
  94. {
  95. DEBUG_ENTER((DBG_BINDING,
  96. Hresult,
  97. "CBinding::Create",
  98. "%#x, %.80wq, %#x, %#x, %B, %#x",
  99. pUnkOuter, szUrl, pbc, &riid, fBindToObject, ppCBdg
  100. ));
  101. PerfDbgLog1(tagCBinding, NULL, "+CBinding::Create (szUrl:%ws)", szUrl);
  102. HRESULT hr = NOERROR;
  103. CBinding *pCBdg;
  104. UrlMkAssert((ppCBdg != NULL));
  105. // Create and initialize the cbinding object
  106. pCBdg = new CBinding(NULL);
  107. if (pCBdg == NULL)
  108. {
  109. hr = E_OUTOFMEMORY;
  110. }
  111. *ppCBdg = pCBdg;
  112. PerfDbgLog2(tagCBinding, NULL, "-CBinding::Create (hr:%lx,IBinding:%lx)", hr, pCBdg);
  113. DEBUG_LEAVE(hr);
  114. return hr;
  115. }
  116. //+---------------------------------------------------------------------------
  117. //
  118. // Method: CBinding::Initialize
  119. //
  120. // Synopsis:
  121. //
  122. // Arguments: [szUrl] --
  123. // [pbc] --
  124. //
  125. // Returns:
  126. //
  127. // History: 12-04-95 JohannP (Johann Posch) Created
  128. //
  129. // Notes:
  130. //
  131. //----------------------------------------------------------------------------
  132. HRESULT CBinding::Initialize(LPCWSTR szUrl, IBindCtx *pbc, DWORD grfBindF, REFIID riid, BOOL fBindToObject)
  133. {
  134. DEBUG_ENTER((DBG_BINDING,
  135. Hresult,
  136. "CBinding::Initialize",
  137. "this=%#x, %.80wq, %#x, %#x, %#x, %B",
  138. this, szUrl, pbc, grfBindF, &riid, fBindToObject
  139. ));
  140. HRESULT hr = NOERROR;
  141. PerfDbgLog(tagCBinding, this, "+CBinding::Initialize");
  142. _fBindToObject = fBindToObject;
  143. if (fBindToObject)
  144. {
  145. // Get the bind options from the bind context
  146. _bindopts.cbStruct = sizeof(BIND_OPTS);
  147. hr = pbc->GetBindOptions(&_bindopts);
  148. if (FAILED(hr))
  149. {
  150. goto End;
  151. }
  152. }
  153. hr = CBindCtx::Create(&_pBndCtx, pbc);
  154. if ((hr == NOERROR) && szUrl)
  155. {
  156. TransAssert((_pBndCtx));
  157. int cchWideChar;
  158. cchWideChar = wcslen(szUrl) + 2;
  159. _lpwszUrl = (LPWSTR) new WCHAR [cchWideChar];
  160. if( !_lpwszUrl )
  161. {
  162. hr = E_OUTOFMEMORY;
  163. goto End;
  164. }
  165. wcscpy(_lpwszUrl, szUrl);
  166. // Try to get an IBindStatusCallback pointer from the bind context
  167. hr = GetObjectParam(pbc, REG_BSCB_HOLDER, IID_IBindStatusCallback, (IUnknown**)&_pBSCB);
  168. UrlMkAssert(( (hr == NOERROR) && _pBSCB ));
  169. PerfDbgLog2(tagCBinding, this, "=== CBinding::Initialize (pbc:%lx -> _pBSCB:%lx)", pbc, _pBSCB);
  170. hr = GetTransactionObjects(_pBndCtx, _lpwszUrl, NULL, NULL, &_pOInetBdg,OIBDG_APARTMENTTHREADED, &_pCTransData);
  171. if (hr == S_OK)
  172. {
  173. TransAssert((!_pCTransData));
  174. // create the transaction data object
  175. // Note: the transdat object has a refcount
  176. // and must be released when done
  177. hr = CTransData::Create(_lpwszUrl, grfBindF, riid, _pBndCtx, _fBindToObject, &_pCTransData);
  178. if (FAILED(hr))
  179. {
  180. //goto End;
  181. }
  182. else
  183. {
  184. UrlMkAssert((_pCTransData != NULL && "CTransData invalid"));
  185. _pBndCtx->SetTransData(_pCTransData);
  186. }
  187. }
  188. else if (hr == S_FALSE)
  189. {
  190. UrlMkAssert((_pCTransData != NULL && "CTransData invalid"));
  191. if (fBindToObject)
  192. _grfInternalFlags |= BDGFLAGS_BTS_BTO;
  193. else
  194. _grfInternalFlags |= BDGFLAGS_ATTACHED;
  195. hr = _pCTransData->Initialize(_lpwszUrl, grfBindF, riid, _pBndCtx);
  196. }
  197. else
  198. {
  199. hr = E_OUTOFMEMORY;
  200. }
  201. if (_fBindToObject)
  202. {
  203. _piidRes = (IID *) &riid;
  204. }
  205. }
  206. else
  207. {
  208. hr = E_OUTOFMEMORY;
  209. }
  210. End:
  211. PerfDbgLog1(tagCBinding, this, "-CBinding::Initialize (hr:%lx)", hr);
  212. DEBUG_LEAVE(hr);
  213. return hr;
  214. }
  215. //+---------------------------------------------------------------------------
  216. //
  217. // Method: CBinding::CBinding
  218. //
  219. // Synopsis:
  220. //
  221. // Arguments: [pUnk] --
  222. //
  223. // Returns:
  224. //
  225. // History: 11-11-95 JohannP (Johann Posch) Created
  226. //
  227. // Notes:
  228. //
  229. //----------------------------------------------------------------------------
  230. CBinding::CBinding(IUnknown *pUnk) : _CRefs()
  231. {
  232. DEBUG_ENTER((DBG_BINDING,
  233. None,
  234. "CBinding::CBinding",
  235. "this=%#x, %#x",
  236. this, pUnk
  237. ));
  238. _pUnk = pUnk;
  239. if (_pUnk)
  240. {
  241. _pUnk->AddRef();
  242. }
  243. _dwThreadId = GetCurrentThreadId();
  244. _pBSCB = 0;
  245. _nPriority = THREAD_PRIORITY_NORMAL;
  246. _dwState = 0;
  247. _OperationState = OPS_Initialized;
  248. _hwndNotify = 0;
  249. _grfBINDF = 0;
  250. _dwLastSize = 0;
  251. _lpwszUrl = 0;
  252. _pOInetBdg = 0;
  253. _fSentLastNotification = 0;
  254. _fSentFirstNotification = 0;
  255. _fCreateStgMed = 0;
  256. _fCompleteDownloadHere = FALSE;
  257. _fForceBindToObjFail = FALSE;
  258. _fAcceptRanges = FALSE;
  259. _fClsidFromProt = FALSE;
  260. _pMnk = NULL;
  261. _pBndCtx = NULL;
  262. _piidRes = (IID*)&IID_IUnknown; // NULL;
  263. _pUnkObject = NULL;
  264. _pBasicAuth = NULL;
  265. _hrBindResult = NOERROR;
  266. _hrInstantiate = NOERROR;
  267. _dwBindError = 0;
  268. _grfInternalFlags = BDGFLAGS_NOTIFICATIONS;
  269. _pwzRedirectUrl = 0;
  270. _pwzResult = 0;
  271. _pBindInfo = 0;
  272. _clsidIn = CLSID_NULL;
  273. _fCanGetIWinInetInfo = FALSE;
  274. _fCanGetIWinInetHttpInfo = FALSE;
  275. _fBTS_BTO = FALSE;
  276. DEBUG_LEAVE(0);
  277. }
  278. //+---------------------------------------------------------------------------
  279. //
  280. // Method: CBinding::~CBinding
  281. //
  282. // Synopsis:
  283. //
  284. // Arguments: (none)
  285. //
  286. // Returns:
  287. //
  288. // History: 11-11-95 JohannP (Johann Posch) Created
  289. //
  290. // Notes:
  291. //
  292. //----------------------------------------------------------------------------
  293. CBinding::~CBinding()
  294. {
  295. DEBUG_ENTER((DBG_BINDING,
  296. None,
  297. "CBinding::~CBinding",
  298. "this=%#x",
  299. this
  300. ));
  301. PerfDbgLog(tagCBinding, this, "+CBinding::~CBinding");
  302. if (_pBindInfo)
  303. {
  304. _pBindInfo->Release();
  305. }
  306. if (_pUnk)
  307. {
  308. DbgLog(tagCBinding, this, "CBinding::~CBinding Release on _pUnk");
  309. _pUnk->Release();
  310. }
  311. if (_pBasicAuth)
  312. {
  313. DbgLog1(tagCBinding, this, "CBinding::~CBinding Release on _pBasicAuth (%lx)", _pBasicAuth);
  314. _pBasicAuth->Release();
  315. }
  316. if (_pBSCB)
  317. {
  318. DbgLog1(tagCBinding, this, "CBinding::~CBinding Release on IBSCB (%lx)", _pBSCB);
  319. _pBSCB->Release();
  320. }
  321. if (_pOInetBdg)
  322. {
  323. _pOInetBdg->Release();
  324. }
  325. if (_pMnk)
  326. {
  327. _pMnk->Release();
  328. }
  329. if (_pBndCtx)
  330. {
  331. _pBndCtx->Release();
  332. }
  333. if (_pCTransData)
  334. {
  335. DbgLog1(tagCBinding, this, "CBinding::~CBinding Release TransData (%lx)", _pCTransData);
  336. _pCTransData->Release();
  337. }
  338. if (_pUnkObject)
  339. {
  340. _pUnkObject->Release();
  341. }
  342. if (_lpwszUrl)
  343. {
  344. delete [] _lpwszUrl;
  345. }
  346. if (_pwzRedirectUrl)
  347. {
  348. delete [] _pwzRedirectUrl;
  349. }
  350. if (_pwzResult)
  351. {
  352. delete [] _pwzResult;
  353. }
  354. ReleaseBindInfo(&_BndInfo);
  355. PerfDbgLog(tagCBinding, this, "-CBinding::~CBinding");
  356. DEBUG_LEAVE(0);
  357. }
  358. LPWSTR CBinding::GetFileName()
  359. {
  360. DEBUG_ENTER((DBG_BINDING,
  361. String,
  362. "CBinding::GetFileName",
  363. "this=%#x",
  364. this
  365. ));
  366. LPWSTR wzFilename = _pCTransData->GetFileName();
  367. DEBUG_LEAVE(wzFilename);
  368. return wzFilename;
  369. }
  370. //+---------------------------------------------------------------------------
  371. //
  372. // Method: CBinding::QueryInterface
  373. //
  374. // Synopsis:
  375. //
  376. // Arguments: [riid] --
  377. // [ppv] --
  378. //
  379. // Returns:
  380. //
  381. // History: 11-11-95 JohannP (Johann Posch) Created
  382. //
  383. // Notes:
  384. //
  385. //----------------------------------------------------------------------------
  386. STDMETHODIMP CBinding::QueryInterface( REFIID riid, void **ppv )
  387. {
  388. DEBUG_ENTER((DBG_BINDING,
  389. Hresult,
  390. "CBinding::IUnknown::QueryInterface",
  391. "this=%#x, %#x, %#x",
  392. this, &riid, ppv
  393. ));
  394. PerfDbgLog2(tagCBinding, this, "+CBinding::QueryInterface (%lx, %lx)", riid, ppv);
  395. HRESULT hr = NOERROR;
  396. *ppv = NULL;
  397. //UrlMkAssert(( !IsEqualIID(GetProtocolClassID(),CLSID_NULL) ));
  398. if ( IsEqualIID(riid, IID_IUnknown)
  399. || IsEqualIID(riid, IID_IBinding) )
  400. {
  401. *ppv = (void FAR *)(IBinding *)this;
  402. AddRef();
  403. }
  404. else if (IsEqualIID(riid, IID_IOInetProtocolSink))
  405. {
  406. *ppv = (void FAR *)(IOInetProtocolSink *)this;
  407. AddRef();
  408. }
  409. else if (IsEqualIID(riid, IID_IOInetBindInfo))
  410. {
  411. *ppv = (void FAR *)(IOInetBindInfo *)this;
  412. AddRef();
  413. }
  414. else if (IsEqualIID(riid, IID_IServiceProvider))
  415. {
  416. *ppv = (void FAR *)(IServiceProvider *)this;
  417. AddRef();
  418. }
  419. else if (IsEqualIID(riid, IID_IWinInetInfo))
  420. {
  421. if (_pOInetBdg)
  422. {
  423. IWinInetInfo *pIWinInetInfo;
  424. hr = _pOInetBdg->QueryInterface(riid, (void **)&pIWinInetInfo);
  425. if (S_FALSE == hr)
  426. hr = E_NOINTERFACE;//see bug 99754
  427. //dont keep the reference..release it immdly.
  428. if (SUCCEEDED(hr))
  429. {
  430. pIWinInetInfo->Release();
  431. _fCanGetIWinInetInfo = TRUE;
  432. *ppv = (void FAR *) (IWinInetInfo *)this;
  433. AddRef();
  434. }
  435. }
  436. else
  437. {
  438. hr = E_NOINTERFACE;
  439. }
  440. }
  441. else if (IsEqualIID(riid, IID_IWinInetHttpInfo))
  442. {
  443. if (_pOInetBdg)
  444. {
  445. IWinInetHttpInfo *pIWinInetHttpInfo;
  446. hr = _pOInetBdg->QueryInterface(riid, (void **)&pIWinInetHttpInfo);
  447. if (S_FALSE == hr)
  448. hr = E_NOINTERFACE;//see bug 99754
  449. if (SUCCEEDED(hr))
  450. {
  451. pIWinInetHttpInfo->Release();
  452. _fCanGetIWinInetHttpInfo = TRUE;
  453. *ppv = (void FAR *) (IWinInetHttpInfo *)this;
  454. AddRef();
  455. }
  456. }
  457. else
  458. {
  459. hr = E_NOINTERFACE;
  460. }
  461. }
  462. else
  463. {
  464. *ppv = NULL;
  465. hr = E_NOINTERFACE;
  466. #if DBG==1
  467. //LPSTR lpszName = GetInterfaceName(riid);
  468. //DbgLog3(tagCBinding, this, "CBinding::QI(pUnkObj) >%s< hr:%lx [%lx]", lpszName, hr, *ppv));
  469. #endif // DBG==1
  470. }
  471. PerfDbgLog2(tagCBinding, this, "-CBinding::QueryInterface (%lx)[%lx]", hr, *ppv);
  472. DEBUG_LEAVE(hr);
  473. return hr;
  474. }
  475. //+---------------------------------------------------------------------------
  476. //
  477. // Method: CBinding::AddRef
  478. //
  479. // Synopsis:
  480. //
  481. // Arguments: [void] --
  482. //
  483. // Returns:
  484. //
  485. // History: 11-11-95 JohannP (Johann Posch) Created
  486. //
  487. // Notes:
  488. //
  489. //----------------------------------------------------------------------------
  490. STDMETHODIMP_(ULONG) CBinding::AddRef( void )
  491. {
  492. DEBUG_ENTER((DBG_BINDING,
  493. Dword,
  494. "CBinding::IUnknown::AddRef",
  495. "this=%#x",
  496. this
  497. ));
  498. LONG lRet = ++_CRefs;
  499. PerfDbgLog1(tagCBinding, this, "CBinding::AddRef (%ld)", lRet);
  500. DEBUG_LEAVE(lRet);
  501. return lRet;
  502. }
  503. //+---------------------------------------------------------------------------
  504. //
  505. // Method: CBinding::Release
  506. //
  507. // Synopsis:
  508. //
  509. // Arguments: [void] --
  510. //
  511. // Returns:
  512. //
  513. // History: 11-11-95 JohannP (Johann Posch) Created
  514. //
  515. // Notes:
  516. //
  517. //----------------------------------------------------------------------------
  518. STDMETHODIMP_(ULONG) CBinding::Release( void )
  519. {
  520. DEBUG_ENTER((DBG_BINDING,
  521. Dword,
  522. "CBinding::IUnknown::Release",
  523. "this=%#x",
  524. this
  525. ));
  526. PerfDbgLog(tagCBinding, this, "+CBinding::Release");
  527. LONG lRet = --_CRefs;
  528. if (_CRefs == 0)
  529. {
  530. delete this;
  531. }
  532. PerfDbgLog1(tagCBinding, this, "-CBinding::Release (%ld)", lRet);
  533. DEBUG_LEAVE(lRet);
  534. return lRet;
  535. }
  536. //+---------------------------------------------------------------------------
  537. //
  538. // Method: CBinding::Abort
  539. //
  540. // Synopsis:
  541. //
  542. // Arguments: [void] --
  543. //
  544. // Returns:
  545. //
  546. // History: 11-11-95 JohannP (Johann Posch) Created
  547. //
  548. // Notes:
  549. //
  550. //----------------------------------------------------------------------------
  551. STDMETHODIMP CBinding::Abort( void )
  552. {
  553. DEBUG_ENTER((DBG_BINDING,
  554. Hresult,
  555. "CBinding::IBinding::Abort",
  556. "this=%#x",
  557. this
  558. ));
  559. PerfDbgLog(tagCBinding, this, "+CBinding::Abort");
  560. HRESULT hr = NOERROR;
  561. // AddRef - Release pair to guard this function since it may
  562. // call OnStopBinding() and client will re-enter this
  563. // Object with a Release() call.
  564. AddRef();
  565. if ( (GetOperationState() < OPS_Abort)
  566. && (GetOperationState() > OPS_Initialized))
  567. {
  568. DbgLog(tagCBindingErr, this, ">>> CBinding::Abort");
  569. // Abort will call OnStopBinding
  570. TransAssert((_pOInetBdg));
  571. hr = _pOInetBdg->Abort(E_ABORT, 0);
  572. if( hr != INET_E_RESULT_DISPATCHED )
  573. {
  574. //
  575. // only set state to OPS_Abort if the the ReportResult
  576. // has not been dispatched already
  577. //
  578. DbgLog(tagCBindingErr, this, ">>> Result already dispatched");
  579. SetOperationState(OPS_Abort);
  580. }
  581. }
  582. else
  583. {
  584. UrlMkAssert(( ( (GetOperationState() < OPS_Stopped)
  585. && (GetOperationState() > OPS_Initialized)) ));
  586. hr = E_FAIL;
  587. }
  588. PerfDbgLog1(tagCBinding, this, "-CBinding::Abort (hr:%lx)", hr);
  589. // release
  590. Release();
  591. DEBUG_LEAVE(hr);
  592. return hr;
  593. }
  594. //+---------------------------------------------------------------------------
  595. //
  596. // Method: CBinding::Suspend
  597. //
  598. // Synopsis:
  599. //
  600. // Arguments: [void] --
  601. //
  602. // Returns:
  603. //
  604. // History: 11-11-95 JohannP (Johann Posch) Created
  605. //
  606. // Notes:
  607. //
  608. //----------------------------------------------------------------------------
  609. STDMETHODIMP CBinding::Suspend( void )
  610. {
  611. DEBUG_ENTER((DBG_BINDING,
  612. Hresult,
  613. "CBinding::IBinding::Suspend",
  614. "this=%#x",
  615. this
  616. ));
  617. PerfDbgLog(tagCBinding, this, "+CBinding::Suspend");
  618. HRESULT hr = E_FAIL;
  619. #ifdef SUSPEND_WORKING
  620. if ( (GetOperationState() < OPS_Stopped)
  621. && (GetOperationState() > OPS_Initialized))
  622. {
  623. SetOperationState(OPS_Suspend);
  624. }
  625. else
  626. {
  627. UrlMkAssert(( ( (GetOperationState() < OPS_Stopped)
  628. && (GetOperationState() > OPS_Initialized)) ));
  629. }
  630. #endif //SUSPEND_WORKING
  631. hr = _pOInetBdg->Suspend();
  632. #ifdef UNUSED
  633. UrlMkAssert((_dwState == OPS_Downloading));
  634. _dwState = OPS_Suspend;
  635. if (_pOInetBdg)
  636. {
  637. _pOInetBdg->SetOperationState(OPS_Suspend);
  638. }
  639. #endif //UNUSED
  640. PerfDbgLog1(tagCBinding, this, "-CBinding::Suspend (hr:%lx)", hr);
  641. DEBUG_LEAVE(hr);
  642. return hr;
  643. }
  644. //+---------------------------------------------------------------------------
  645. //
  646. // Method: CBinding::Resume
  647. //
  648. // Synopsis:
  649. //
  650. // Arguments: [void] --
  651. //
  652. // Returns:
  653. //
  654. // History: 11-11-95 JohannP (Johann Posch) Created
  655. //
  656. // Notes:
  657. //
  658. //----------------------------------------------------------------------------
  659. STDMETHODIMP CBinding::Resume( void )
  660. {
  661. DEBUG_ENTER((DBG_BINDING,
  662. Hresult,
  663. "CBinding::IBinding::Resume",
  664. "this=%#x",
  665. this
  666. ));
  667. PerfDbgLog(tagCBinding, this, "+CBinding::Resume");
  668. HRESULT hr = NOERROR;
  669. if (GetOperationState() == OPS_Suspend)
  670. {
  671. SetOperationState(OPS_Downloading);
  672. }
  673. else
  674. {
  675. UrlMkAssert(( GetOperationState() == OPS_Suspend ));
  676. }
  677. hr = _pOInetBdg->Resume();
  678. PerfDbgLog1(tagCBinding, this, "-CBinding::Resume (hr:%lx)", hr);
  679. DEBUG_LEAVE(hr);
  680. return hr;
  681. }
  682. //+---------------------------------------------------------------------------
  683. //
  684. // Method: CBinding::SetPriority
  685. //
  686. // Synopsis:
  687. //
  688. // Arguments: [nPriority] --
  689. //
  690. // Returns:
  691. //
  692. // History: 11-11-95 JohannP (Johann Posch) Created
  693. //
  694. // Notes:
  695. //
  696. //----------------------------------------------------------------------------
  697. STDMETHODIMP CBinding::SetPriority(LONG nPriority)
  698. {
  699. DEBUG_ENTER((DBG_BINDING,
  700. Hresult,
  701. "CBinding::IBinding::SetPriority",
  702. "this=%#x, %d",
  703. this, nPriority
  704. ));
  705. PerfDbgLog1(tagCBinding, this, "+CBinding::SetPriority (%ld)", nPriority);
  706. HRESULT hr = NOERROR;
  707. _nPriority = nPriority;
  708. PerfDbgLog1(tagCBinding, this, "-CBinding::SetPriority (hr:%lx)", hr);
  709. DEBUG_LEAVE(hr);
  710. return hr;
  711. }
  712. //+---------------------------------------------------------------------------
  713. //
  714. // Method: CBinding::GetPriority
  715. //
  716. // Synopsis:
  717. //
  718. // Arguments: [pnPriority] --
  719. //
  720. // Returns:
  721. //
  722. // History: 11-11-95 JohannP (Johann Posch) Created
  723. //
  724. // Notes:
  725. //
  726. //----------------------------------------------------------------------------
  727. STDMETHODIMP CBinding::GetPriority(LONG *pnPriority)
  728. {
  729. DEBUG_ENTER((DBG_BINDING,
  730. Hresult,
  731. "CBinding::IBinding::GetPriority",
  732. "this=%#x, %#x",
  733. this, pnPriority
  734. ));
  735. PerfDbgLog(tagCBinding, this, "+CBinding::GetPriority");
  736. HRESULT hr = NOERROR;
  737. if (!pnPriority)
  738. {
  739. hr = E_INVALIDARG;
  740. }
  741. else
  742. {
  743. *pnPriority = _nPriority;
  744. }
  745. PerfDbgLog1(tagCBinding, this, "-CBinding::GetPriority (hr:%lx)", hr);
  746. DEBUG_LEAVE(hr);
  747. return hr;
  748. }
  749. //+---------------------------------------------------------------------------
  750. //
  751. // Method: CBinding::GetBindResult
  752. //
  753. // Synopsis:
  754. //
  755. // Arguments: [pnPriority] --
  756. //
  757. // Returns:
  758. //
  759. // History: 11-11-95 JohannP (Johann Posch) Created
  760. //
  761. // Notes:
  762. //
  763. //----------------------------------------------------------------------------
  764. STDMETHODIMP CBinding::GetBindResult(CLSID *pclsidProtocol, DWORD *pdwResult, LPWSTR *pszResult,DWORD *pdwReserved)
  765. {
  766. DEBUG_ENTER((DBG_BINDING,
  767. Hresult,
  768. "CBinding::IBinding::GetBindResult",
  769. "this=%#x, %#x, %#x, %#x, %#x",
  770. this, pclsidProtocol, pdwResult, pszResult, pdwReserved
  771. ));
  772. PerfDbgLog(tagCBinding, this, "+CBinding::GetBindResult");
  773. HRESULT hr = NOERROR;
  774. if (!pdwResult || !pszResult || pdwReserved)
  775. {
  776. hr = E_INVALIDARG;
  777. }
  778. else
  779. {
  780. HRESULT hrRet = NOERROR;
  781. *pdwResult = 0;
  782. *pszResult = 0;
  783. *pclsidProtocol = CLSID_NULL;
  784. if ((hrRet = GetInstantiateHresult()) != NOERROR)
  785. {
  786. *pdwResult = (DWORD) hrRet;
  787. TransAssert (( (_hrBindResult == INET_E_CANNOT_INSTANTIATE_OBJECT)
  788. || (_hrBindResult == INET_E_CANNOT_LOAD_DATA) ));
  789. }
  790. else if (_hrBindResult != NOERROR)
  791. {
  792. *pclsidProtocol = _clsidProtocol;
  793. *pszResult = OLESTRDuplicate(_pwzResult);
  794. UrlMkAssert(( (_dwBindError != 0) || (_hrBindResult != NOERROR) ));
  795. if (_dwBindError == 0)
  796. {
  797. _dwBindError = _hrBindResult;
  798. }
  799. *pdwResult = _dwBindError;
  800. }
  801. }
  802. PerfDbgLog3(tagCBinding, this, "-CBinding::GetBindResult (hr:%lx,_hrBindResult;%lx, pdwResult:%lx)", hr, _hrBindResult, *pdwResult);
  803. DEBUG_LEAVE(hr);
  804. return hr;
  805. }
  806. //+---------------------------------------------------------------------------
  807. //
  808. // Method: CBinding::QueryOption
  809. //
  810. // Synopsis: Calls QueryOptions on
  811. //
  812. // Arguments: [dwOption] --
  813. // [pBuffer] --
  814. // [pcbBuf] --
  815. //
  816. // Returns:
  817. //
  818. // History: 4-10-96 JohannP (Johann Posch) Created
  819. //
  820. // Notes:
  821. //
  822. //----------------------------------------------------------------------------
  823. STDMETHODIMP CBinding::QueryOption(DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf)
  824. {
  825. DEBUG_ENTER((DBG_BINDING,
  826. Hresult,
  827. "CBinding::IWinInetHttpInfo::QueryOption",
  828. "this=%#x, %#x, %#x, %#x",
  829. this, dwOption, pBuffer, pcbBuf
  830. ));
  831. HRESULT hr = NOERROR;
  832. PerfDbgLog(tagCBinding, this, "+CBinding::QueryOption");
  833. VDATEPTROUT(pcbBuf, DWORD*);
  834. if ( (GetOperationState() < OPS_Stopped)
  835. && (GetOperationState() > OPS_Initialized))
  836. {
  837. TransAssert((_fCanGetIWinInetInfo || _fCanGetIWinInetHttpInfo));
  838. if (_fCanGetIWinInetInfo)
  839. {
  840. IWinInetInfo *pIWinInetInfo;
  841. hr = _pOInetBdg->QueryInterface(IID_IWinInetInfo, (void **)&pIWinInetInfo);
  842. if (S_FALSE == hr)
  843. hr = E_NOINTERFACE;//see bug 99754
  844. if (SUCCEEDED(hr))
  845. {
  846. hr = pIWinInetInfo->QueryOption(dwOption, pBuffer, pcbBuf);
  847. //dont keep the reference..release it immdly.
  848. pIWinInetInfo->Release();
  849. }
  850. }
  851. else if (_fCanGetIWinInetHttpInfo)
  852. {
  853. IWinInetHttpInfo *pIWinInetHttpInfo;
  854. hr = _pOInetBdg->QueryInterface(IID_IWinInetHttpInfo, (void **)&pIWinInetHttpInfo);
  855. if (S_FALSE == hr)
  856. hr = E_NOINTERFACE;//see bug 99754
  857. if (SUCCEEDED(hr))
  858. {
  859. hr = pIWinInetHttpInfo->QueryOption(dwOption, pBuffer, pcbBuf);
  860. //dont keep the reference..release it immdly.
  861. pIWinInetHttpInfo->Release();
  862. }
  863. }
  864. }
  865. else
  866. {
  867. hr = E_FAIL;
  868. }
  869. PerfDbgLog1(tagCBinding, this, "-CBinding::QueryOption (hr:%lx)", hr);
  870. DEBUG_LEAVE(hr);
  871. return hr;
  872. }
  873. //+---------------------------------------------------------------------------
  874. //
  875. // Method: CBinding::QueryInfo
  876. //
  877. // Synopsis: Calls QueryInfos on
  878. //
  879. // Arguments: [dwOption] --
  880. // [pBuffer] --
  881. // [pcbBuf] --
  882. // [pdwFlags] --
  883. // [pdwReserved] --
  884. //
  885. // Returns:
  886. //
  887. // History: 4-10-96 JohannP (Johann Posch) Created
  888. //
  889. // Notes:
  890. //
  891. //----------------------------------------------------------------------------
  892. STDMETHODIMP CBinding::QueryInfo(DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf, DWORD *pdwFlags, DWORD *pdwReserved)
  893. {
  894. DEBUG_ENTER((DBG_BINDING,
  895. Hresult,
  896. "CBinding::IWinInetHttpInfo::QueryInfo",
  897. "this=%#x, %#x, %#x, %#x, %#x, %#x",
  898. this, dwOption, pBuffer, pcbBuf, pdwFlags, pdwReserved
  899. ));
  900. HRESULT hr = NOERROR;
  901. PerfDbgLog(tagCBinding, this, "+CBinding::QueryInfo");
  902. VDATEPTROUT(pcbBuf, DWORD*);
  903. if ( (GetOperationState() < OPS_Stopped)
  904. && (GetOperationState() > OPS_Initialized))
  905. {
  906. TransAssert((_fCanGetIWinInetHttpInfo));
  907. IWinInetHttpInfo *pIWinInetHttpInfo;
  908. hr = _pOInetBdg->QueryInterface(IID_IWinInetHttpInfo, (void **)&pIWinInetHttpInfo);
  909. if (S_FALSE == hr)
  910. hr = E_NOINTERFACE;//see bug 99754
  911. if (SUCCEEDED(hr))
  912. {
  913. hr = pIWinInetHttpInfo->QueryInfo(dwOption, pBuffer, pcbBuf, pdwFlags, pdwReserved);
  914. //dont keep the reference..release it immdly.
  915. pIWinInetHttpInfo->Release();
  916. }
  917. }
  918. else
  919. {
  920. hr = E_FAIL;
  921. }
  922. PerfDbgLog1(tagCBinding, this, "-CBinding::QueryInfo (hr:%lx)", hr);
  923. DEBUG_LEAVE(hr);
  924. return hr;
  925. }
  926. // IServiceProvider methods
  927. //+---------------------------------------------------------------------------
  928. //
  929. // Method: CBinding::QueryService
  930. //
  931. // Synopsis: Calls QueryInfos on
  932. //
  933. // Arguments: [rsid] --
  934. // [riid] --
  935. // [ppvObj] --
  936. //
  937. // Returns:
  938. //
  939. // History: 4-10-96 JohannP (Johann Posch) Created
  940. //
  941. // Notes:
  942. //
  943. //----------------------------------------------------------------------------
  944. HRESULT IUnknown_QueryService(IUnknown* punk, REFGUID rsid, REFIID riid, void ** ppvObj)
  945. {
  946. DEBUG_ENTER((DBG_BINDING,
  947. Hresult,
  948. "IUnknown_QueryService",
  949. "%#x, %#x, %#x, %#x",
  950. punk, &rsid, &riid, ppvObj
  951. ));
  952. HRESULT hr = E_NOINTERFACE;
  953. *ppvObj = 0;
  954. if (punk)
  955. {
  956. IServiceProvider *pSrvPrv;
  957. hr = punk->QueryInterface(IID_IServiceProvider, (void **) &pSrvPrv);
  958. if (hr == NOERROR)
  959. {
  960. hr = pSrvPrv->QueryService(rsid,riid, ppvObj);
  961. pSrvPrv->Release();
  962. }
  963. }
  964. DEBUG_LEAVE(hr);
  965. return hr;
  966. }
  967. HRESULT CBinding::QueryService(REFGUID rsid, REFIID riid, void ** ppvObj)
  968. {
  969. DEBUG_ENTER((DBG_BINDING,
  970. Hresult,
  971. "CBinding::IServiceProvider::QueryService",
  972. "this=%#x, %#x, %#x, %#x",
  973. this, &rsid, &riid, ppvObj
  974. ));
  975. PerfDbgLog(tagCBinding, this, "+CBinding::QueryService");
  976. HRESULT hr = E_NOINTERFACE;
  977. VDATETHIS(this);
  978. UrlMkAssert((ppvObj));
  979. hr = IUnknown_QueryService(_pBSCB, rsid, riid, ppvObj);
  980. PerfDbgLog1(tagCBinding, this, "-CBinding::QueryService (hr:%lx)", hr);
  981. DEBUG_LEAVE(hr);
  982. return hr;
  983. }
  984. //IOInetBindInfo methods
  985. //+---------------------------------------------------------------------------
  986. //
  987. // Method: CBinding::GetBindInfo
  988. //
  989. // Synopsis:
  990. //
  991. // Arguments: [pdwBINDF] --
  992. // [pbindinfo] --
  993. //
  994. // Returns:
  995. //
  996. // History: 11-07-1996 JohannP (Johann Posch) Created
  997. //
  998. // Notes:
  999. //
  1000. //----------------------------------------------------------------------------
  1001. HRESULT CBinding::GetBindInfo(DWORD *pdwBINDF, BINDINFO *pbindinfo)
  1002. {
  1003. DEBUG_ENTER((DBG_BINDING,
  1004. Hresult,
  1005. "CBinding::IInternetBindInfo::GetBindInfo",
  1006. "this=%#x, %#x, %#x",
  1007. this, pdwBINDF, pbindinfo
  1008. ));
  1009. PerfDbgLog(tagCBinding, this, "+CBinding::GetBindInfo");
  1010. HRESULT hr = NOERROR;
  1011. TransAssert((pdwBINDF && pbindinfo));
  1012. *pdwBINDF = _grfBINDF;
  1013. hr = CopyBindInfo(&_BndInfo, pbindinfo ); // Src->Dest
  1014. //for IE6 bug 1898.
  1015. //For hglobals, copybindinfo allocates new handle and copies over the source data,
  1016. //but uses the source as pUnkForRelease and AddRefs it.. but the source has no reference
  1017. //to the new handle to free.
  1018. //So free the addrefed pUnkForRelease and NULL it, so that ReleaseStgMedium() calls
  1019. //GlobalFree().
  1020. //There is also a bug in ReleaseBindInfo(), where we always call ReleaseStgMedium(),
  1021. //irrespective of the pUnkForRelease member - this fix doesn't depend on that behavior,
  1022. //but it does need the receiver of the stgmed in this bindinfo to ReleaseStgMedium() either
  1023. //indirectly through ReleaseBindInfo() or directly.
  1024. if (SUCCEEDED(hr))
  1025. {
  1026. STGMEDIUM* pStgmed = &(pbindinfo->stgmedData);
  1027. if ( (pStgmed->tymed == TYMED_HGLOBAL) &&
  1028. (pStgmed->hGlobal) &&
  1029. (pStgmed->pUnkForRelease) )
  1030. {
  1031. pStgmed->pUnkForRelease->Release();
  1032. pStgmed->pUnkForRelease = NULL;
  1033. }
  1034. }
  1035. PerfDbgLog1(tagCBinding, this, "-CBinding::GetBindInfo (hr:%lx)", hr);
  1036. DEBUG_LEAVE(hr);
  1037. return hr;
  1038. }
  1039. //+---------------------------------------------------------------------------
  1040. //
  1041. // Method: CBinding::GetBindString
  1042. //
  1043. // Synopsis:
  1044. //
  1045. // Arguments: [ulStringType] --
  1046. // [ppwzStr] --
  1047. // [cEl] --
  1048. // [pcElFetched] --
  1049. //
  1050. // Returns:
  1051. //
  1052. // History: 11-07-1996 JohannP (Johann Posch) Created
  1053. //
  1054. // Notes:
  1055. //
  1056. //----------------------------------------------------------------------------
  1057. HRESULT CBinding::GetBindString(ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
  1058. {
  1059. DEBUG_ENTER((DBG_BINDING,
  1060. Hresult,
  1061. "CBinding::IInternetBindInfo::GetBindString",
  1062. "this=%#x, %#x, %#x, %#x, %#x",
  1063. this, ulStringType, ppwzStr, cEl, pcElFetched
  1064. ));
  1065. PerfDbgLog(tagCBinding, this, "+CTransaction::GetBindString");
  1066. HRESULT hr = INET_E_USE_DEFAULT_SETTING;
  1067. switch (ulStringType)
  1068. {
  1069. case BINDSTRING_HEADERS :
  1070. break;
  1071. case BINDSTRING_ACCEPT_MIMES:
  1072. hr = _pCTransData->GetAcceptMimes(ppwzStr,cEl, pcElFetched);
  1073. break;
  1074. case BINDSTRING_EXTRA_URL :
  1075. break;
  1076. case BINDSTRING_LANGUAGE :
  1077. break;
  1078. case BINDSTRING_USERNAME :
  1079. break;
  1080. case BINDSTRING_PASSWORD :
  1081. break;
  1082. case BINDSTRING_ACCEPT_ENCODINGS:
  1083. break;
  1084. case BINDSTRING_URL:
  1085. if( _lpwszUrl )
  1086. {
  1087. LPWSTR pwzURL = NULL;
  1088. pwzURL = OLESTRDuplicate(_lpwszUrl);
  1089. if( pwzURL )
  1090. {
  1091. *ppwzStr = pwzURL,
  1092. *pcElFetched = 1;
  1093. hr = NOERROR;
  1094. }
  1095. else
  1096. {
  1097. hr = E_OUTOFMEMORY;
  1098. *pcElFetched = 0;
  1099. }
  1100. }
  1101. break;
  1102. case BINDSTRING_USER_AGENT :
  1103. case BINDSTRING_POST_COOKIE :
  1104. case BINDSTRING_POST_DATA_MIME:
  1105. {
  1106. hr = NOERROR;
  1107. // QI on IBSC for interface
  1108. if (_pBindInfo == NULL)
  1109. {
  1110. hr = LocalQueryInterface(IID_IInternetBindInfo, (void **)&_pBindInfo);
  1111. }
  1112. if ( (hr == NOERROR) && _pBindInfo)
  1113. {
  1114. hr = _pBindInfo->GetBindString(ulStringType, ppwzStr, cEl, pcElFetched);
  1115. }
  1116. }
  1117. break;
  1118. case BINDSTRING_IID:
  1119. TransAssert(_piidRes);
  1120. if (_piidRes)
  1121. {
  1122. hr = StringFromCLSID(*_piidRes, ppwzStr);
  1123. if (pcElFetched)
  1124. {
  1125. *pcElFetched = (SUCCEEDED(hr)) ? (1) : (0);
  1126. }
  1127. }
  1128. else
  1129. {
  1130. hr = E_UNEXPECTED;
  1131. *pcElFetched = 0;
  1132. }
  1133. break;
  1134. case BINDSTRING_FLAG_BIND_TO_OBJECT:
  1135. *ppwzStr = new WCHAR[FLAG_BTO_STR_LENGTH];
  1136. if (*ppwzStr)
  1137. {
  1138. if (_fBindToObject)
  1139. {
  1140. StrCpyNW(*ppwzStr, FLAG_BTO_STR_TRUE,
  1141. lstrlenW(FLAG_BTO_STR_TRUE) + 1);
  1142. }
  1143. else
  1144. {
  1145. StrCpyNW(*ppwzStr, FLAG_BTO_STR_FALSE,
  1146. lstrlenW(FLAG_BTO_STR_FALSE) + 1);
  1147. }
  1148. *pcElFetched = 1;
  1149. hr = S_OK;
  1150. }
  1151. else
  1152. {
  1153. *pcElFetched = 0;
  1154. hr = E_OUTOFMEMORY;
  1155. }
  1156. break;
  1157. case BINDSTRING_PTR_BIND_CONTEXT:
  1158. if (!_pBndCtx) {
  1159. hr = E_UNEXPECTED;
  1160. *pcElFetched = 0;
  1161. }
  1162. else {
  1163. *ppwzStr = new WCHAR[MAX_DWORD_DIGITS + 1];
  1164. if (*ppwzStr)
  1165. {
  1166. wnsprintfW(*ppwzStr, MAX_DWORD_DIGITS,
  1167. #ifdef _WIN64
  1168. L"%I64d",
  1169. #else
  1170. L"%ld",
  1171. #endif
  1172. (DWORD_PTR)_pBndCtx);
  1173. *pcElFetched = 1;
  1174. _pBndCtx->AddRef();
  1175. hr = S_OK;
  1176. }
  1177. else
  1178. {
  1179. *pcElFetched = 0;
  1180. hr = E_OUTOFMEMORY;
  1181. }
  1182. }
  1183. break;
  1184. default:
  1185. TransAssert((FALSE));
  1186. }
  1187. PerfDbgLog1(tagCBinding, this, "-CBinding::GetBindString (hr:%lx)", hr);
  1188. DEBUG_LEAVE(hr);
  1189. return hr;
  1190. }
  1191. //+---------------------------------------------------------------------------
  1192. //
  1193. // Method: CBindProtocol::CBindProtocol
  1194. //
  1195. // Synopsis:
  1196. //
  1197. // Arguments: [pUnk] --
  1198. //
  1199. // Returns:
  1200. //
  1201. // History: 11-11-95 JohannP (Johann Posch) Created
  1202. //
  1203. // Notes:
  1204. //
  1205. //----------------------------------------------------------------------------
  1206. CBindProtocol::CBindProtocol() : _CRefs()
  1207. {
  1208. DEBUG_ENTER((DBG_BINDING,
  1209. None,
  1210. "CBindProtocol::CBindProtocol",
  1211. "this=%#x",
  1212. this
  1213. ));
  1214. _pUnk = NULL;
  1215. DEBUG_LEAVE(0);
  1216. }
  1217. //+---------------------------------------------------------------------------
  1218. //
  1219. // Method: CBindProtocol::~CBindProtocol
  1220. //
  1221. // Synopsis:
  1222. //
  1223. // Arguments: (none)
  1224. //
  1225. // Returns:
  1226. //
  1227. // History: 11-11-95 JohannP (Johann Posch) Created
  1228. //
  1229. // Notes:
  1230. //
  1231. //----------------------------------------------------------------------------
  1232. CBindProtocol::~CBindProtocol()
  1233. {
  1234. DEBUG_ENTER((DBG_BINDING,
  1235. None,
  1236. "CBindProtocol::~CBindProtocol",
  1237. "this=%#x",
  1238. this
  1239. ));
  1240. DEBUG_LEAVE(0);
  1241. }
  1242. //+---------------------------------------------------------------------------
  1243. //
  1244. // Method: CBindProtocol::QueryInterface
  1245. //
  1246. // Synopsis:
  1247. //
  1248. // Arguments: [riid] --
  1249. // [ppv] --
  1250. //
  1251. // Returns:
  1252. //
  1253. // History: 11-11-95 JohannP (Johann Posch) Created
  1254. //
  1255. // Notes:
  1256. //
  1257. //----------------------------------------------------------------------------
  1258. STDMETHODIMP CBindProtocol::QueryInterface( REFIID riid, void **ppv )
  1259. {
  1260. DEBUG_ENTER((DBG_BINDING,
  1261. Hresult,
  1262. "CBindProtocol::IUnknown::QueryInterface",
  1263. "this=%#x, %#x, %#x",
  1264. this, &riid, ppv
  1265. ));
  1266. HRESULT hr = NOERROR;
  1267. PerfDbgLog2(tagCBinding, this, "+CBindProtocol::QueryInterface (%lx, %lx)", riid, ppv);
  1268. if ( IsEqualIID(riid, IID_IUnknown)
  1269. || IsEqualIID(riid, IID_IBindProtocol) )
  1270. {
  1271. *ppv = (void FAR *)this;
  1272. AddRef();
  1273. }
  1274. else
  1275. {
  1276. *ppv = NULL;
  1277. hr = E_NOINTERFACE;
  1278. #if DBG==1
  1279. //LPSTR lpszName = GetInterfaceName(riid);
  1280. //DbgLog3(tagCBinding, this, "CBindProtocol::QI(pUnkObj) >%s< hr:%lx [%lx]", lpszName, hr, *ppv);
  1281. #endif // DBG==1
  1282. }
  1283. PerfDbgLog2(tagCBinding, this, "-CBindProtocol::QueryInterface (%lx)[%lx]", hr, *ppv);
  1284. DEBUG_LEAVE(hr);
  1285. return hr;
  1286. }
  1287. //+---------------------------------------------------------------------------
  1288. //
  1289. // Method: CBindProtocol::AddRef
  1290. //
  1291. // Synopsis:
  1292. //
  1293. // Arguments: [void] --
  1294. //
  1295. // Returns:
  1296. //
  1297. // History: 11-11-95 JohannP (Johann Posch) Created
  1298. //
  1299. // Notes:
  1300. //
  1301. //----------------------------------------------------------------------------
  1302. STDMETHODIMP_(ULONG) CBindProtocol::AddRef( void )
  1303. {
  1304. DEBUG_ENTER((DBG_BINDING,
  1305. Dword,
  1306. "CBindProtocol::IUnknown::AddRef",
  1307. "this=%#x",
  1308. this
  1309. ));
  1310. LONG lRet = _CRefs++;
  1311. PerfDbgLog1(tagCBinding, this, "CBindProtocol::AddRef (%ld)", lRet);
  1312. DEBUG_LEAVE(lRet);
  1313. return lRet;
  1314. }
  1315. //+---------------------------------------------------------------------------
  1316. //
  1317. // Method: CBindProtocol::Release
  1318. //
  1319. // Synopsis:
  1320. //
  1321. // Arguments: [void] --
  1322. //
  1323. // Returns:
  1324. //
  1325. // History: 11-11-95 JohannP (Johann Posch) Created
  1326. //
  1327. // Notes:
  1328. //
  1329. //----------------------------------------------------------------------------
  1330. STDMETHODIMP_(ULONG) CBindProtocol::Release( void )
  1331. {
  1332. DEBUG_ENTER((DBG_BINDING,
  1333. Dword,
  1334. "CBindProtocol::IUnknown::Release",
  1335. "this=%#x",
  1336. this
  1337. ));
  1338. PerfDbgLog(tagCBinding, this, "+CBindProtocol::Release");
  1339. LONG lRet = --_CRefs;
  1340. if (_CRefs == 0)
  1341. {
  1342. if (_pUnk)
  1343. {
  1344. PerfDbgLog(tagCBinding, this, "+CBindProtocol::Release _pUnk");
  1345. _pUnk->Release();
  1346. _pUnk = NULL;
  1347. PerfDbgLog(tagCBinding, this, "-CBindProtocol::Release _pUnk");
  1348. }
  1349. delete this;
  1350. }
  1351. PerfDbgLog1(tagCBinding, this, "-CBindProtocol::Release (%ld)", lRet);
  1352. DEBUG_LEAVE(lRet);
  1353. return lRet;
  1354. }
  1355. //+---------------------------------------------------------------------------
  1356. //
  1357. // Method: CBindProtocol::CreateBinding
  1358. //
  1359. // Synopsis:
  1360. //
  1361. // Arguments: [url] --
  1362. // [pBCtx] --
  1363. // [ppBdg] --
  1364. //
  1365. // Returns:
  1366. //
  1367. // History: 11-11-95 JohannP (Johann Posch) Created
  1368. //
  1369. // Notes:
  1370. //
  1371. //----------------------------------------------------------------------------
  1372. STDMETHODIMP CBindProtocol::CreateBinding(LPCWSTR szUrl, IBindCtx *pBCtx, IBinding **ppBdg)
  1373. {
  1374. DEBUG_ENTER((DBG_BINDING,
  1375. Dword,
  1376. "CBindProtocol::IBindProtocol::CreateBinding",
  1377. "this=%#x, %.80wq, %#x, %#x",
  1378. this, szUrl, pBCtx, ppBdg
  1379. ));
  1380. PerfDbgLog(tagCBinding, this, "+CBindProtocol::CreateBinding");
  1381. HRESULT hr = NOERROR;
  1382. BIND_OPTS bindopts;
  1383. CBinding *pCBdg = NULL;
  1384. VDATEPTROUT(ppBdg, LPVOID);
  1385. VDATEIFACE(pBCtx);
  1386. *ppBdg = NULL;
  1387. // Get the bind options from the bind context
  1388. bindopts.cbStruct = sizeof(BIND_OPTS);
  1389. hr = pBCtx->GetBindOptions(&bindopts);
  1390. ChkHResult(hr);
  1391. hr = CBinding::Create(NULL, szUrl, pBCtx, IID_IStream, FALSE, &pCBdg );
  1392. if (hr != NOERROR)
  1393. {
  1394. DEBUG_LEAVE(hr);
  1395. return hr;
  1396. }
  1397. // Start the download transaction
  1398. {
  1399. LPWSTR pwzExtra = NULL;
  1400. hr = pCBdg->StartBinding(szUrl, pBCtx, IID_IStream, FALSE, &pwzExtra, NULL);
  1401. }
  1402. if (FAILED(hr))
  1403. {
  1404. // the transaction could not be started
  1405. goto End;
  1406. }
  1407. // if the caller doesn't support IBindStatusCallback
  1408. if ( pCBdg->IsAsyncBinding() )
  1409. {
  1410. // Async case: interface is passed on in OnDataAvailable
  1411. *ppBdg = pCBdg;
  1412. }
  1413. End:
  1414. if (pCBdg)
  1415. {
  1416. pCBdg->Release();
  1417. }
  1418. PerfDbgLog1(tagCBinding, this, "-CBindProtocol::CreateBinding (hr:%lx)", hr);
  1419. DEBUG_LEAVE(hr);
  1420. return hr;
  1421. }
  1422. //+---------------------------------------------------------------------------
  1423. //
  1424. // Function: GetObjectParam
  1425. //
  1426. // Synopsis:
  1427. //
  1428. // Arguments: [pbc] --
  1429. // [pszKey] --
  1430. // [riid] --
  1431. // [ppUnk] --
  1432. //
  1433. // Returns:
  1434. //
  1435. // History: 12-04-95 JohannP (Johann Posch) Created
  1436. //
  1437. // Notes:
  1438. //
  1439. //----------------------------------------------------------------------------
  1440. HRESULT GetObjectParam(IBindCtx *pbc, LPOLESTR pszKey, REFIID riid, IUnknown **ppUnk)
  1441. {
  1442. DEBUG_ENTER((DBG_BINDING,
  1443. Hresult,
  1444. "GetObjectParam",
  1445. "%#x, %#x, %#x, %#x",
  1446. pbc, pszKey, &riid, ppUnk
  1447. ));
  1448. PerfDbgLog1(tagCBinding, NULL, "+GetObjectParam (IBindCtx:%lx)", pbc);
  1449. HRESULT hr = E_FAIL;
  1450. IUnknown *pUnk;
  1451. // Try to get an IUnknown pointer from the bind context
  1452. if (pbc)
  1453. {
  1454. hr = pbc->GetObjectParam(pszKey, &pUnk);
  1455. }
  1456. if (FAILED(hr))
  1457. {
  1458. *ppUnk = NULL;
  1459. }
  1460. else
  1461. {
  1462. // Query for riid
  1463. hr = pUnk->QueryInterface(riid, (void **)ppUnk);
  1464. pUnk->Release();
  1465. if (FAILED(hr))
  1466. {
  1467. *ppUnk = NULL;
  1468. DumpIID(riid);
  1469. }
  1470. }
  1471. PerfDbgLog2(tagCBinding, NULL, "-GetObjectParam (IBindCtx:%lx, hr:%lx)", pbc, hr);
  1472. DEBUG_LEAVE(hr);
  1473. return hr;
  1474. }
  1475. //+---------------------------------------------------------------------------
  1476. //
  1477. // Method: CBinding::StartBinding
  1478. //
  1479. // Synopsis:
  1480. //
  1481. // Arguments: [fBindToObject] --
  1482. //
  1483. // Returns:
  1484. //
  1485. // History: 12-04-95 JohannP (Johann Posch) Created
  1486. //
  1487. // Notes:
  1488. //
  1489. //----------------------------------------------------------------------------
  1490. HRESULT CBinding::StartBinding(LPCWSTR szUrl, IBindCtx *pbc, REFIID riid, BOOL fBindToObject, LPWSTR *ppwzExtra, LPVOID *ppv )
  1491. {
  1492. DEBUG_ENTER((DBG_BINDING,
  1493. Hresult,
  1494. "CBinding::StartBinding",
  1495. "this=%#x, %.80wq, %#x, %#x, %B, %#x, %#x",
  1496. this, szUrl, pbc, &riid, fBindToObject, ppwzExtra, ppv
  1497. ));
  1498. PerfDbgLog(tagCBinding, this, "+CBinding::StartTransaction");
  1499. //DbgLog1(tagCBindingErr, this, ">>> CBinding::Start(url=%ws)", szUrl);
  1500. HRESULT hr;
  1501. BOOL fBindingStarted = FALSE;
  1502. UrlMkAssert((ppwzExtra));
  1503. UrlMkAssert((_pBSCB == NULL));
  1504. do
  1505. {
  1506. // Try to get an IBindStatusCallback pointer from the bind context
  1507. hr = GetObjectParam(pbc, REG_BSCB_HOLDER, IID_IBindStatusCallback, (IUnknown**)&_pBSCB);
  1508. if (FAILED(hr))
  1509. {
  1510. break;
  1511. }
  1512. UrlMkAssert(( (hr == NOERROR) && _pBSCB ));
  1513. if (_pBSCB == NULL)
  1514. {
  1515. hr = E_INVALIDARG;
  1516. break;
  1517. }
  1518. _fBindToObject = fBindToObject;
  1519. if (_fBindToObject)
  1520. {
  1521. _grfInternalFlags |= BDGFLAGS_PARTIAL;
  1522. _piidRes = (IID *) &riid;
  1523. // Get the bind options from the bind context
  1524. _bindopts.cbStruct = sizeof(BIND_OPTS);
  1525. hr = pbc->GetBindOptions(&_bindopts);
  1526. if (FAILED(hr))
  1527. {
  1528. break;
  1529. }
  1530. }
  1531. hr = CBindCtx::Create(&_pBndCtx, pbc);
  1532. if (FAILED(hr))
  1533. {
  1534. hr = E_OUTOFMEMORY;
  1535. break;
  1536. }
  1537. {
  1538. int cchWideChar;
  1539. cchWideChar = wcslen(szUrl) + 2;
  1540. _lpwszUrl = (LPWSTR) new WCHAR [cchWideChar];
  1541. if( !_lpwszUrl )
  1542. {
  1543. hr = E_OUTOFMEMORY;
  1544. break;
  1545. }
  1546. wcscpy(_lpwszUrl, szUrl);
  1547. }
  1548. // call GetBindInfo
  1549. _BndInfo.cbSize = sizeof(BINDINFO);
  1550. #if DBG==1
  1551. if (_BndInfo.stgmedData.tymed != TYMED_NULL)
  1552. {
  1553. PerfDbgLog1(tagCBinding, this, "CBinding::StartTransaction ReleaseStgMedium (%lx)", _BndInfo.stgmedData);
  1554. }
  1555. #endif // DBG==1
  1556. // Make sure the BINDINFO is released and empty
  1557. ReleaseBindInfo(&_BndInfo);
  1558. _grfBINDF = 0;
  1559. // call IBSC::GetBindInfo
  1560. TransAssert((_BndInfo.stgmedData.tymed == TYMED_NULL));
  1561. hr = CallGetBindInfo(&_grfBINDF, &_BndInfo);
  1562. if( hr == NOERROR && !IsAsyncTransaction() )
  1563. {
  1564. // we need to turn off BINDF_ASYNCSTORAGE for sync binding
  1565. _grfBINDF &= ~BINDF_ASYNCSTORAGE;
  1566. }
  1567. // this call should not fail
  1568. if (FAILED(hr))
  1569. {
  1570. break;
  1571. }
  1572. // turn on direct read - not documented yet for APPs
  1573. if (g_dwSettings & 0x20000000)
  1574. {
  1575. _grfBINDF |= BINDF_DIRECT_READ;
  1576. }
  1577. // check for extend binding (rosebud)
  1578. // get the bind option for extend binding (low bits)
  1579. // the highest 16 bits is used for additional flags (e.g. wininet flag)
  1580. DWORD dwExtBindOption = _BndInfo.dwOptions & 0x0000ffff;
  1581. if( dwExtBindOption && !fBindToObject)
  1582. {
  1583. // extend binding (rosebud)
  1584. COInetSession* pSession = NULL;
  1585. IOInetProtocol* pProt = NULL;
  1586. hr = GetCOInetSession(0, &pSession, 0);
  1587. if( hr != NOERROR )
  1588. {
  1589. break;
  1590. }
  1591. CLSID clsid = CLSID_NULL;
  1592. DWORD dwLocation = 0;
  1593. hr = pSession->CreateFirstProtocol(
  1594. _lpwszUrl, NULL, NULL, &pProt, &clsid, &dwLocation, dwExtBindOption);
  1595. pSession->Release();
  1596. if( hr != NOERROR )
  1597. {
  1598. break;
  1599. }
  1600. StartParam param;
  1601. param.iid = riid;
  1602. param.pIBindCtx = pbc;
  1603. param.pItf = NULL;
  1604. // the interface ptr is returned via param.pItf
  1605. hr = pProt->Start(_lpwszUrl, NULL, NULL, 0, (DWORD_PTR) &param );
  1606. // release the pluggable protocol
  1607. pProt->Release();
  1608. if( hr == NOERROR && param.pItf )
  1609. {
  1610. // we are done, return the pointer
  1611. *ppv = param.pItf;
  1612. hr = INET_E_USE_EXTEND_BINDING;
  1613. break;
  1614. }
  1615. else
  1616. if( hr != INET_E_USE_DEFAULT_PROTOCOLHANDLER )
  1617. {
  1618. break;
  1619. }
  1620. // continue with the normal binding process...
  1621. }
  1622. {
  1623. // check for iid (only for BindToStorage)
  1624. if( !fBindToObject && (IsRequestedIIDValid(riid) == FALSE) )
  1625. {
  1626. hr = E_INVALIDARG;
  1627. break;
  1628. }
  1629. if (!IsOInetProtocol(pbc, szUrl))
  1630. {
  1631. hr = INET_E_UNKNOWN_PROTOCOL;
  1632. break;
  1633. }
  1634. DWORD dwObjectsFlags = OIBDG_APARTMENTTHREADED;
  1635. if (_fBindToObject)
  1636. {
  1637. dwObjectsFlags |= BDGFLAGS_PARTIAL;
  1638. }
  1639. hr = GetTransactionObjects(_pBndCtx, _lpwszUrl, NULL, NULL, &_pOInetBdg, dwObjectsFlags, &_pCTransData);
  1640. }
  1641. if (hr == S_OK)
  1642. {
  1643. TransAssert((!_pCTransData));
  1644. // create the transaction data object
  1645. // Note: the transdat object has a refcount
  1646. // and must be released when done
  1647. hr = CTransData::Create(_lpwszUrl, _grfBINDF, riid, _pBndCtx, _fBindToObject, &_pCTransData);
  1648. if (SUCCEEDED(hr))
  1649. {
  1650. UrlMkAssert((_pCTransData != NULL && "CTransData invalid"));
  1651. _pBndCtx->SetTransData(_pCTransData);
  1652. }
  1653. }
  1654. else if (hr == S_FALSE)
  1655. {
  1656. // found an existing transaction
  1657. UrlMkAssert((_pCTransData != NULL && "CTransData invalid"));
  1658. if (fBindToObject)
  1659. _grfInternalFlags |= BDGFLAGS_BTS_BTO;
  1660. else
  1661. _grfInternalFlags |= BDGFLAGS_ATTACHED;
  1662. hr = _pCTransData->Initialize(_lpwszUrl, _grfBINDF, riid, _pBndCtx, fBindToObject);
  1663. }
  1664. else
  1665. {
  1666. hr = E_OUTOFMEMORY;
  1667. }
  1668. if (FAILED(hr))
  1669. {
  1670. break;
  1671. }
  1672. // hand back to pointer to of extra info
  1673. // to update the url
  1674. *ppwzExtra = (_BndInfo.szExtraInfo) ? _BndInfo.szExtraInfo : NULL;
  1675. if (_pCTransData->SetDataSink(_grfBINDF) == DataSink_Unknown)
  1676. {
  1677. hr = E_INVALIDARG;
  1678. }
  1679. if ( (_pCTransData->IsFileRequired())
  1680. || (IsKnownProtocol(_lpwszUrl) == DLD_PROTOCOL_NONE) )
  1681. {
  1682. PerfDbgLog(tagCBinding, this, "---TURN ON NEEDFILE!---");
  1683. // turn on flag to request file from protocol
  1684. _grfBINDF |= BINDF_NEEDFILE;
  1685. }
  1686. if (SUCCEEDED(hr))
  1687. {
  1688. PerfDbgLog(tagCBinding, this, "---BINDF_FROMURLMON---");
  1689. // turn on flag indicating the binding is from urlmon
  1690. _grfBINDF |= BINDF_FROMURLMON;
  1691. if( _fBindToObject )
  1692. {
  1693. _BndInfo.dwOptions |= BINDINFO_OPTIONS_BINDTOOBJECT;
  1694. }
  1695. }
  1696. if (FAILED(hr))
  1697. {
  1698. break;
  1699. }
  1700. // send the OnStartBinding notification
  1701. hr = CallOnStartBinding(NULL, this);
  1702. fBindingStarted = TRUE;
  1703. // check if the user did abort
  1704. if (SUCCEEDED(hr))
  1705. {
  1706. OperationState opSt = GetOperationState();
  1707. UrlMkAssert((opSt > OPS_Initialized));
  1708. if (opSt == OPS_Abort)
  1709. {
  1710. hr = E_ABORT;
  1711. }
  1712. }
  1713. BOOL fIsSync = (IsAsyncTransaction() == FALSE);
  1714. if ( SUCCEEDED(hr))
  1715. {
  1716. // Note: check if url got redirected
  1717. // and report redirection url
  1718. if (_pwzRedirectUrl)
  1719. {
  1720. PerfDbgLog1(tagCBinding, this, "StartTransaction OnProgress REDIRECTING _pBSCP(%lx)", _pBSCB);
  1721. hr = CallOnProgress( 0, 0, BINDSTATUS_REDIRECTING,_pwzRedirectUrl );
  1722. PerfDbgLog1(tagCBinding, this, "StartTransaction OnProgress REDIRECTING _pBSCP(%lx)", _pBSCB);
  1723. }
  1724. }
  1725. if ( SUCCEEDED(hr))
  1726. {
  1727. DWORD dwBindFlags = OIBDG_APARTMENTTHREADED | PI_MIMEVERIFICATION | PI_DOCFILECLSIDLOOKUP;
  1728. if (fIsSync)
  1729. {
  1730. dwBindFlags |= PI_SYNCHRONOUS;
  1731. }
  1732. if(_grfBINDF & BINDF_PREFERDEFAULTHANDLER)
  1733. {
  1734. dwBindFlags |= BINDF_PREFERDEFAULTHANDLER;
  1735. }
  1736. if (_grfBINDF & BINDF_FREE_THREADED)
  1737. {
  1738. dwBindFlags &= ~OIBDG_APARTMENTTHREADED;
  1739. }
  1740. if (_fBindToObject)
  1741. {
  1742. dwBindFlags |= BDGFLAGS_PARTIAL | PI_CLASSINSTALL;
  1743. }
  1744. if (_grfInternalFlags & BDGFLAGS_BTS_BTO)
  1745. {
  1746. dwBindFlags |= BDGFLAGS_BTS_BTO;
  1747. }
  1748. if (_grfInternalFlags & BDGFLAGS_ATTACHED)
  1749. {
  1750. dwBindFlags |= BDGFLAGS_ATTACHED;
  1751. }
  1752. if (_pOInetBdg)
  1753. {
  1754. // Just before starting the transaction give it the priority.
  1755. IOInetPriority * pOInetPriority = NULL;
  1756. if (_pOInetBdg->QueryInterface(IID_IOInetPriority, (void **) &pOInetPriority) == S_OK)
  1757. {
  1758. pOInetPriority->SetPriority(_nPriority);
  1759. pOInetPriority->Release();
  1760. }
  1761. }
  1762. if ( _pCTransData->InProgress() != S_FALSE
  1763. || !_pCTransData->IsRemoteObjectReady() )
  1764. {
  1765. // guard the transaction object
  1766. // the operation might complete synchronous
  1767. _pOInetBdg->AddRef();
  1768. hr = _pCTransData->OnStart(_pOInetBdg);
  1769. TransAssert((hr == NOERROR));
  1770. if (hr == NOERROR)
  1771. {
  1772. hr = _pOInetBdg->Start(_lpwszUrl, (IOInetProtocolSink *) this, (IOInetBindInfo *) this, dwBindFlags, 0);
  1773. }
  1774. _pOInetBdg->Release();
  1775. }
  1776. else
  1777. {
  1778. // call OnProgress for mime type and filename
  1779. //
  1780. DWORD dwSize = _pCTransData->GetDataSize();
  1781. if (_pCTransData->GetMimeType())
  1782. {
  1783. OnTransNotification(BINDSTATUS_MIMETYPEAVAILABLE, dwSize, dwSize, (LPWSTR)_pCTransData->GetMimeType(), NOERROR);
  1784. }
  1785. if (_pCTransData->GetFileName())
  1786. {
  1787. OnTransNotification(BINDSTATUS_CACHEFILENAMEAVAILABLE, dwSize, dwSize, _pCTransData->GetFileName(), NOERROR );
  1788. }
  1789. // report data - will call OnStopBinding
  1790. OnTransNotification(BINDSTATUS_ENDDOWNLOADDATA, dwSize, dwSize,0 , NOERROR);
  1791. }
  1792. }
  1793. break;
  1794. } while (TRUE);
  1795. if ( FAILED(hr))
  1796. {
  1797. // call OnStopBinding in case of error
  1798. HRESULT hr1 = NOERROR;
  1799. if ((_pBSCB != NULL) && fBindingStarted)
  1800. {
  1801. _hrBindResult = hr;
  1802. hr1 = CallOnStopBinding(hr, NULL);
  1803. }
  1804. if (_pOInetBdg)
  1805. {
  1806. _pOInetBdg->Terminate(0);
  1807. _pOInetBdg->Release();
  1808. _pOInetBdg = NULL;
  1809. }
  1810. }
  1811. PerfDbgLog(tagCBinding, this, "-CBinding::StartTransaction");
  1812. DEBUG_LEAVE(hr);
  1813. return hr;
  1814. }
  1815. //+---------------------------------------------------------------------------
  1816. //
  1817. // Method: CBinding::CompleteTransaction
  1818. //
  1819. // Synopsis:
  1820. //
  1821. // Arguments: (none)
  1822. //
  1823. // Returns:
  1824. //
  1825. // History: 12-22-95 JohannP (Johann Posch) Created
  1826. //
  1827. // Notes:
  1828. //
  1829. //----------------------------------------------------------------------------
  1830. STDMETHODIMP CBinding::CompleteTransaction()
  1831. {
  1832. DEBUG_ENTER((DBG_BINDING,
  1833. Hresult,
  1834. "CBinding::CompleteTransaction",
  1835. "this=%#x",
  1836. this
  1837. ));
  1838. HRESULT hr = NOERROR;
  1839. PerfDbgLog(tagCBinding, this, "+CBinding::CompleteTransaction");
  1840. if (_hrBindResult != NOERROR)
  1841. {
  1842. hr = _hrBindResult;
  1843. }
  1844. PerfDbgLog1(tagCBinding, this, "-CBinding::CompleteTransaction (hr:%lx)", hr);
  1845. DEBUG_LEAVE(hr);
  1846. return hr;
  1847. }
  1848. //+---------------------------------------------------------------------------
  1849. //
  1850. // Method: CBinding::OnTransNotification
  1851. //
  1852. // Synopsis:
  1853. //
  1854. // Arguments: [pCTP] --
  1855. //
  1856. // Returns:
  1857. //
  1858. // History: 12-11-95 JohannP (Johann Posch) Created
  1859. //
  1860. // Notes:
  1861. //
  1862. //----------------------------------------------------------------------------
  1863. STDMETHODIMP_(BOOL) CBinding::OnTransNotification(BINDSTATUS NotMsg, DWORD dwCurrentSize, DWORD dwTotalSize,
  1864. LPWSTR pwzStr, HRESULT hrINet)
  1865. {
  1866. DEBUG_ENTER((DBG_BINDING,
  1867. Bool,
  1868. "CBinding::OnTransNotification",
  1869. "this=%#x, %#x, %#x, %#x, %.80wq, %#x",
  1870. this, NotMsg, dwCurrentSize, dwTotalSize, pwzStr, hrINet
  1871. ));
  1872. PerfDbgLog(tagCBinding, this, "+CBinding::OnTransNotification");
  1873. BOOL fRelease = FALSE;
  1874. HRESULT hr = NOERROR;
  1875. UrlMkAssert((_dwThreadId));
  1876. if ( ( (_dwThreadId == GetCurrentThreadId())
  1877. || (_grfBINDF & BINDF_FREE_THREADED))
  1878. && (_grfInternalFlags & BDGFLAGS_NOTIFICATIONS)
  1879. && (_pBSCB != NULL))
  1880. {
  1881. switch (NotMsg)
  1882. {
  1883. case BINDSTATUS_PROTOCOLCLASSID:
  1884. UrlMkAssert((pwzStr));
  1885. CLSIDFromString(pwzStr, &_clsidProtocol);
  1886. break;
  1887. case BINDSTATUS_MIMETYPEAVAILABLE:
  1888. UrlMkAssert((pwzStr));
  1889. _pCTransData->SetMimeType(pwzStr);
  1890. CallOnProgress(0,0,BINDSTATUS_MIMETYPEAVAILABLE, pwzStr);
  1891. break;
  1892. case BINDSTATUS_CLASSIDAVAILABLE:
  1893. UrlMkAssert((pwzStr));
  1894. CLSIDFromString(pwzStr, &_clsidIn);
  1895. break;
  1896. case BINDSTATUS_IUNKNOWNAVAILABLE:
  1897. if( _fBindToObject )
  1898. {
  1899. IUnknown *pUnk = NULL;
  1900. _fClsidFromProt = TRUE;
  1901. // the object should be instantiated now
  1902. if (SUCCEEDED(hr))
  1903. {
  1904. hr = _pBndCtx->GetObjectParam(SZ_IUNKNOWN_PTR, &pUnk);
  1905. }
  1906. if (SUCCEEDED(hr))
  1907. {
  1908. // The following four lines of code are a fix for bug#89397.
  1909. // There are only a couple of clients who are already using
  1910. // this notification, so we can ensure this state change doesn't
  1911. // affect their protocols.
  1912. OperationState opSt = GetOperationState();
  1913. if (opSt >= OPS_StartBinding && opSt < OPS_Downloading)
  1914. {
  1915. SetOperationState(OPS_Downloading);
  1916. }
  1917. hr = CallOnObjectAvailable(*_piidRes, pUnk);
  1918. pUnk->Release();
  1919. }
  1920. if (hr != NOERROR)
  1921. {
  1922. SetInstantiateHresult(hr);
  1923. }
  1924. // return the download result in case if no error
  1925. if (hr == NOERROR || GetHResult() != NOERROR)
  1926. {
  1927. hr = GetHResult();
  1928. }
  1929. _hrBindResult = hr;
  1930. hr = CallOnStopBinding(hr, NULL);
  1931. fRelease = TRUE;
  1932. }
  1933. break;
  1934. case BINDSTATUS_CLSIDCANINSTANTIATE:
  1935. if(IsEqualGUID(_clsidIn, CLSID_NULL) && pwzStr)
  1936. {
  1937. CLSIDFromString(pwzStr, &_clsidIn);
  1938. }
  1939. if( _fBindToObject )
  1940. {
  1941. _fClsidFromProt = TRUE;
  1942. // the object should be instantiated now
  1943. hr = OnObjectAvailable(0,dwCurrentSize,dwTotalSize,TRUE);
  1944. if (hr != NOERROR)
  1945. {
  1946. SetInstantiateHresult(hr);
  1947. }
  1948. // return the download result in case if no error
  1949. if (hr == NOERROR || GetHResult() != NOERROR)
  1950. {
  1951. hr = GetHResult();
  1952. }
  1953. _hrBindResult = hr;
  1954. hr = CallOnStopBinding(hr, NULL);
  1955. fRelease = TRUE;
  1956. }
  1957. break;
  1958. case BINDSTATUS_PROXYDETECTING :
  1959. // indicate resolving proxyserver
  1960. if (hrINet == NOERROR)
  1961. {
  1962. hr = CallOnProgress(0,0,BINDSTATUS_PROXYDETECTING,NULL );
  1963. }
  1964. break;
  1965. case BINDSTATUS_CACHEFILENAMEAVAILABLE :
  1966. UrlMkAssert((pwzStr));
  1967. _pCTransData->SetFileName(pwzStr);
  1968. break;
  1969. case BINDSTATUS_FINDINGRESOURCE :
  1970. // indicate resolving name - pass on server/proxy name
  1971. if (hrINet == NOERROR)
  1972. {
  1973. hr = CallOnProgress(0,0,BINDSTATUS_FINDINGRESOURCE,pwzStr );
  1974. PerfDbgLog1(tagCBinding, this, "OnTransNotification done on OnProgress _pBSCP(%lx)", _pBSCB);
  1975. }
  1976. break;
  1977. case BINDSTATUS_SENDINGREQUEST :
  1978. // indicate resolving name - pass on server/proxy name
  1979. if (hrINet == NOERROR)
  1980. {
  1981. hr = CallOnProgress(0,0,BINDSTATUS_SENDINGREQUEST,pwzStr );
  1982. PerfDbgLog1(tagCBinding, this, "OnTransNotification done on OnProgress _pBSCP(%lx)", _pBSCB);
  1983. }
  1984. break;
  1985. case BINDSTATUS_CONNECTING :
  1986. // inidicate progress connecting - pass on address
  1987. if (hrINet == NOERROR)
  1988. {
  1989. hr = CallOnProgress(0,0,BINDSTATUS_CONNECTING, pwzStr);
  1990. PerfDbgLog1(tagCBinding, this, "OnTransNotification done on OnProgress _pBSCP(%lx)", _pBSCB);
  1991. }
  1992. break;
  1993. case BINDSTATUS_REDIRECTING :
  1994. if (hrINet == NOERROR)
  1995. {
  1996. TransAssert((pwzStr));
  1997. PerfDbgLog1(tagCBinding, this, "OnTransNotification calling OnProgress _pBSCP(%lx)", _pBSCB);
  1998. hr = CallOnProgress(
  1999. dwCurrentSize, // ulProgress
  2000. dwTotalSize, // ulProgressMax
  2001. BINDSTATUS_REDIRECTING,
  2002. pwzStr // new url
  2003. );
  2004. PerfDbgLog1(tagCBinding, this, "OnTransNotification done on OnProgress _pBSCP(%lx)", _pBSCB);
  2005. TransAssert((_lpwszUrl));
  2006. {
  2007. DWORD dwLenOld = wcslen(_lpwszUrl);
  2008. DWORD dwLenNew = wcslen(pwzStr);
  2009. if (dwLenOld < dwLenNew)
  2010. {
  2011. delete _lpwszUrl;
  2012. _lpwszUrl = (LPWSTR) new WCHAR [dwLenNew + 1];
  2013. }
  2014. if (_lpwszUrl && pwzStr)
  2015. {
  2016. wcscpy(_lpwszUrl, pwzStr);
  2017. }
  2018. }
  2019. _pCTransData->SetRedirectUrl(pwzStr);
  2020. }
  2021. break;
  2022. case BINDSTATUS_ENDDOWNLOADDATA:
  2023. PerfDbgLog(tagCBinding, this, "CBinding::OnTransNotification Notify_Done");
  2024. // more work here for data notification
  2025. //UrlMkAssert((errCode == INLERR_OK && "Notify_Done with Error"));
  2026. if (hrINet == NOERROR)
  2027. {
  2028. PerfDbgLog1(tagCBinding, this, "OnTransNotification calling OnProgress _pBSCP(%lx)", _pBSCB);
  2029. if (!_fSentFirstNotification)
  2030. {
  2031. hr = CallOnProgress(dwCurrentSize, dwTotalSize,
  2032. BINDSTATUS_BEGINDOWNLOADDATA, _lpwszUrl);
  2033. LPCWSTR pwzFilename = _pCTransData->GetFileName();
  2034. // a filename is not always available
  2035. if (pwzFilename)
  2036. {
  2037. hr = CallOnProgress(dwCurrentSize, dwTotalSize,
  2038. BINDSTATUS_CACHEFILENAMEAVAILABLE, pwzFilename);
  2039. }
  2040. }
  2041. hr = CallOnProgress(dwCurrentSize,dwTotalSize,
  2042. BINDSTATUS_ENDDOWNLOADDATA,_lpwszUrl);
  2043. PerfDbgLog1(tagCBinding, this, "OnTransNotification done on OnProgress _pBSCP(%lx)", _pBSCB);
  2044. // In some cases (e.g. data is in cache or progress notifications
  2045. // are disbled) we may not get progress notifications
  2046. // We might directly get the DONE notitification
  2047. // In anycase we do not want to send data notification if it is a
  2048. if (!_fBindToObject)
  2049. {
  2050. hr = OnDataNotification(0,dwCurrentSize,dwTotalSize, TRUE);
  2051. }
  2052. else
  2053. {
  2054. // the object should be instanciate now
  2055. hr = OnObjectAvailable(0,dwCurrentSize,dwTotalSize,TRUE);
  2056. if (hr != NOERROR)
  2057. {
  2058. SetInstantiateHresult(hr);
  2059. }
  2060. }
  2061. }
  2062. if (_fBTS_BTO)
  2063. {
  2064. //special Trident BTS->BTO scenario.
  2065. //Trident needs to get back the INET_E_TERMINATED_BIND error message to
  2066. //realize we understand this is where we don't double-bind
  2067. hr = INET_E_TERMINATED_BIND;
  2068. }
  2069. // return the download result in case if no error
  2070. else if (hr == NOERROR || GetHResult() != NOERROR)
  2071. {
  2072. hr = GetHResult();
  2073. }
  2074. PerfDbgLog2(tagCBinding, this, "OnTransNotification calling OnStopBinding _pBSCP(%lx) HR:%lx", _pBSCB, hr);
  2075. _hrBindResult = hr;
  2076. hr = CallOnStopBinding(hr, NULL);
  2077. fRelease = TRUE;
  2078. PerfDbgLog1(tagCBinding, this, "OnTransNotification done on OnStopBinding _pBSCP(%lx)", _pBSCB);
  2079. break;
  2080. case BINDSTATUS_BEGINDOWNLOADDATA:
  2081. case BINDSTATUS_DOWNLOADINGDATA:
  2082. PerfDbgLog(tagCBinding, this, "CBinding::OnTransNotification Notify_Update");
  2083. // Call OnProgress once if data are from cache
  2084. if (!_fSentFirstNotification)
  2085. {
  2086. if (_pCTransData->IsFromCache())
  2087. {
  2088. hr = CallOnProgress(0,0,BINDSTATUS_USINGCACHEDCOPY, NULL);
  2089. }
  2090. }
  2091. hr = CallOnProgress(dwCurrentSize, dwTotalSize,
  2092. (!_fSentFirstNotification) ? BINDSTATUS_BEGINDOWNLOADDATA : BINDSTATUS_DOWNLOADINGDATA,
  2093. _lpwszUrl);
  2094. if (!_fSentFirstNotification)
  2095. {
  2096. LPCWSTR pwzFilename = _pCTransData->GetFileName();
  2097. // a filename is not always available
  2098. if (pwzFilename)
  2099. {
  2100. hr = CallOnProgress(dwCurrentSize, dwTotalSize,
  2101. BINDSTATUS_CACHEFILENAMEAVAILABLE, pwzFilename);
  2102. }
  2103. }
  2104. PerfDbgLog1(tagCBinding, this, "OnTransNotification done on OnProgress _pBSCP(%lx)", _pBSCB);
  2105. if (!_fBindToObject)
  2106. {
  2107. OnDataNotification(0,dwCurrentSize,dwTotalSize, FALSE);
  2108. if (_fBTS_BTO)
  2109. {
  2110. //special Trident BTS->BTO scenario.
  2111. //Trident needs to get back the INET_E_TERMINATED_BIND error message to
  2112. //realize we understand this is where we don't double-bind
  2113. _hrBindResult = INET_E_TERMINATED_BIND;
  2114. hr = CallOnStopBinding(INET_E_TERMINATED_BIND, NULL);
  2115. fRelease = TRUE;
  2116. }
  2117. }
  2118. else
  2119. {
  2120. //
  2121. // here is the hack for ms-its:
  2122. // if they are sending dwCurrent==dwTotal, we need to flip
  2123. // the FALSE to TRUE in order to make word/excel doc host
  2124. // working under IE5 (IE5 #71203)
  2125. //
  2126. BOOL fFullData = FALSE;
  2127. if( dwCurrentSize == dwTotalSize &&
  2128. dwCurrentSize &&
  2129. _lpwszUrl &&
  2130. wcslen(_lpwszUrl) > 7 &&
  2131. !StrCmpNIW(_lpwszUrl, L"ms-its:", 7) )
  2132. {
  2133. fFullData = TRUE;
  2134. }
  2135. // check here if the object can be create already
  2136. //hr = OnObjectAvailable(pCTP, FALSE);
  2137. hr = OnObjectAvailable(0,dwCurrentSize,dwTotalSize, fFullData);
  2138. // mark the transobject for completion
  2139. if (hr == S_OK)
  2140. {
  2141. hr = CallOnStopBinding(NOERROR, NULL);
  2142. fRelease = TRUE;
  2143. }
  2144. else if ((hr != S_OK ) && (hr != S_FALSE))
  2145. {
  2146. _hrBindResult = hr;
  2147. hr = CallOnStopBinding(hr, NULL);
  2148. fRelease = TRUE;
  2149. }
  2150. }
  2151. break;
  2152. case BINDSTATUS_ERROR:
  2153. PerfDbgLog2(tagCBinding, this, "CBinding::OnTransNotification Notify_Error[hr%lx, dwResutl;%lx]", _hrBindResult, _dwBindError);
  2154. // call StopBinding witht error code
  2155. UrlMkAssert(( (_hrBindResult != NOERROR) && (_dwBindError != 0) ));
  2156. hr = CallOnStopBinding(_hrBindResult, NULL);
  2157. fRelease = TRUE;
  2158. break;
  2159. case BINDSTATUS_RESULT:
  2160. PerfDbgLog2(tagCBinding, this, "CBinding::OnTransNotification Notify_Error[hr%lx, dwResutl;%lx]", _hrBindResult, _dwBindError);
  2161. if( _hrBindResult == INET_E_REDIRECT_TO_DIR )
  2162. {
  2163. hr = CallOnStopBinding(_hrBindResult, _pwzResult);
  2164. }
  2165. else
  2166. {
  2167. hr = CallOnStopBinding(_hrBindResult, NULL);
  2168. }
  2169. fRelease = TRUE;
  2170. break;
  2171. case BINDSTATUS_DECODING:
  2172. hr = CallOnProgress(0,0,BINDSTATUS_DECODING,pwzStr );
  2173. break;
  2174. case BINDSTATUS_LOADINGMIMEHANDLER:
  2175. hr = CallOnProgress(0,0,BINDSTATUS_LOADINGMIMEHANDLER,pwzStr);
  2176. break;
  2177. case BINDSTATUS_INTERNAL:
  2178. case BINDSTATUS_INTERNALASYNC:
  2179. break;
  2180. case BINDSTATUS_CONTENTDISPOSITIONATTACH:
  2181. _fForceBindToObjFail = TRUE;
  2182. hr = CallOnProgress(0,0,BINDSTATUS_CONTENTDISPOSITIONATTACH, pwzStr);
  2183. break;
  2184. case BINDSTATUS_ACCEPTRANGES:
  2185. _fAcceptRanges= TRUE;
  2186. break;
  2187. case BINDSTATUS_COOKIE_SENT:
  2188. case BINDSTATUS_COMPACT_POLICY_RECEIVED:
  2189. case BINDSTATUS_COOKIE_SUPPRESSED:
  2190. case BINDSTATUS_COOKIE_STATE_UNKNOWN:
  2191. case BINDSTATUS_COOKIE_STATE_ACCEPT:
  2192. case BINDSTATUS_COOKIE_STATE_REJECT:
  2193. case BINDSTATUS_COOKIE_STATE_LEASH:
  2194. case BINDSTATUS_COOKIE_STATE_DOWNGRADE:
  2195. case BINDSTATUS_COOKIE_STATE_PROMPT:
  2196. case BINDSTATUS_POLICY_HREF:
  2197. case BINDSTATUS_P3P_HEADER:
  2198. case BINDSTATUS_SESSION_COOKIE_RECEIVED:
  2199. case BINDSTATUS_PERSISTENT_COOKIE_RECEIVED:
  2200. case BINDSTATUS_SESSION_COOKIES_ALLOWED:
  2201. hr = CallOnProgress(0,0,NotMsg, pwzStr);
  2202. break;
  2203. default:
  2204. DbgLog1(tagCBindingErr, this, "CBinding::OnTransNotification Unknown (NMsg:%lx)", NotMsg);
  2205. UrlMkAssert((FALSE));
  2206. break;
  2207. }
  2208. }
  2209. PerfDbgLog(tagCBinding, this, "-CBinding::OnTransNotification");
  2210. DEBUG_LEAVE(fRelease);
  2211. return fRelease;
  2212. }
  2213. //+---------------------------------------------------------------------------
  2214. //
  2215. // Method: CBinding::OnDataNotification
  2216. //
  2217. // Synopsis:
  2218. //
  2219. // Arguments: [pCTP] --
  2220. // [fLastNotification] --
  2221. //
  2222. // Returns:
  2223. //
  2224. // History: 12-22-95 JohannP (Johann Posch) Created
  2225. //
  2226. // Notes:
  2227. //
  2228. //----------------------------------------------------------------------------
  2229. STDMETHODIMP CBinding::OnDataNotification(DWORD grfBSCF, DWORD dwCurrentSize, DWORD dwTotalSize, BOOL fLastNotification)
  2230. {
  2231. DEBUG_ENTER((DBG_BINDING,
  2232. Hresult,
  2233. "CBinding::OnDataNotification",
  2234. "this=%#x, %#x, %#x, %#x, %B",
  2235. this, grfBSCF, dwCurrentSize, dwTotalSize, fLastNotification
  2236. ));
  2237. HRESULT hr = NOERROR;
  2238. PerfDbgLog3(tagCBinding, this, "+CBinding::OnDataNotification (dwLastSize:%ld, dwCurrentSize:%ld, dwTotalSize:%ld)",
  2239. _dwLastSize, dwCurrentSize, dwTotalSize);
  2240. STGMEDIUM *pStgMed = 0;
  2241. FORMATETC *pFmtETC = 0;
  2242. // We shouldn't have less data than last time
  2243. #if 0
  2244. UrlMkAssert(( (dwTotalSize == 0)
  2245. || (dwTotalSize != 0 && dwCurrentSize > _dwLastSize)
  2246. || (dwTotalSize == dwCurrentSize && dwCurrentSize == _dwLastSize)
  2247. ));
  2248. #endif // 0
  2249. // must be BindToStorage scenario
  2250. UrlMkAssert((!_fBindToObject));
  2251. // should never end up here after the last data notification
  2252. //UrlMkAssert((!_fSentLastNotification));
  2253. if ( ((dwCurrentSize > 0) || fLastNotification)
  2254. && (!_fSentLastNotification))
  2255. {
  2256. grfBSCF = 0;
  2257. // Check if this will be the first data notification
  2258. if (!_fSentFirstNotification)
  2259. {
  2260. grfBSCF |= BSCF_FIRSTDATANOTIFICATION;
  2261. _fSentFirstNotification = TRUE;
  2262. }
  2263. if (fLastNotification)
  2264. {
  2265. // Check if this will be the last data notification
  2266. grfBSCF |= BSCF_LASTDATANOTIFICATION;
  2267. _fSentLastNotification = TRUE;
  2268. }
  2269. // all other notifications are intermediate
  2270. if (grfBSCF == 0)
  2271. {
  2272. grfBSCF |= BSCF_INTERMEDIATEDATANOTIFICATION;
  2273. }
  2274. // get the stgmed for this
  2275. if (_fCreateStgMed == FALSE)
  2276. {
  2277. hr = _pCTransData->GetData(&pFmtETC, &pStgMed, grfBSCF);
  2278. if (hr == S_OK)
  2279. {
  2280. // BUGBUG: Looks like _fCreateStgMed is always going to be false.
  2281. // Either the following line can be de-commented out
  2282. // or _fCreateStgMed can be eliminated:
  2283. //_fCreateStgMed = TRUE;
  2284. TransAssert((pStgMed));
  2285. //
  2286. // hold on to the stream or storage
  2287. //
  2288. if ( (_pUnkObject == NULL)
  2289. && ( pStgMed->tymed == TYMED_ISTREAM
  2290. || pStgMed->tymed == TYMED_ISTORAGE))
  2291. {
  2292. _pUnkObject = pStgMed->pstm;
  2293. _pUnkObject->AddRef();
  2294. }
  2295. }
  2296. }
  2297. if ( hr == S_OK && fLastNotification )
  2298. {
  2299. _pCTransData->OnEndofData();
  2300. }
  2301. if (hr == S_OK)
  2302. {
  2303. PerfDbgLog5(tagCBinding, this,
  2304. ">>> %lx::OnDataNotification (Options:%ld,Size:%ld,FmtEtc:%lx,StgMed:%lx)",
  2305. _pBSCB, grfBSCF, dwCurrentSize, pFmtETC, pStgMed);
  2306. UrlMkAssert((grfBSCF != 0));
  2307. hr = CallOnDataAvailable(grfBSCF, dwCurrentSize, pFmtETC, pStgMed);
  2308. if (pStgMed)
  2309. {
  2310. DEBUG_ENTER((DBG_BINDING,
  2311. None,
  2312. "EXTERNAL::ReleaseStgMedium",
  2313. "%#x",
  2314. pStgMed
  2315. ));
  2316. ReleaseStgMedium(pStgMed);
  2317. DEBUG_LEAVE(0);
  2318. //NOTES: if tymed was TYMED_FILE, lpszFilename ZEROED out,
  2319. // else if tymed == TYMED_STREAM, pstm NOT ZEROED out.
  2320. // We DEPEND on this behavior in CTransDat::GetData()
  2321. //
  2322. // Ideally, we should just do this->
  2323. // memset( pStgMed, 0, sizeof(STGMEDIUM) );
  2324. // and save state in the transDat object.
  2325. }
  2326. }
  2327. }
  2328. _dwLastSize = dwCurrentSize;
  2329. PerfDbgLog2(tagCBinding, this, "-CBinding::OnDataNotification (hr:%lx, dwLastSize:%ld)", hr, _dwLastSize);
  2330. DEBUG_LEAVE(hr);
  2331. return hr;
  2332. }
  2333. //+---------------------------------------------------------------------------
  2334. //
  2335. // Method: CBinding::OnObjectAvailable
  2336. //
  2337. // Synopsis:
  2338. //
  2339. // Arguments: [pCTP] --
  2340. // [fLastNotification] --
  2341. //
  2342. // Returns:
  2343. //
  2344. // History: 12-22-95 JohannP (Johann Posch) Created
  2345. //
  2346. // Notes:
  2347. //
  2348. //----------------------------------------------------------------------------
  2349. STDMETHODIMP CBinding::OnObjectAvailable(DWORD grfBSCF, DWORD dwCurrentSize, DWORD dwTotalSize, BOOL fLastNotification)
  2350. {
  2351. DEBUG_ENTER((DBG_BINDING,
  2352. Hresult,
  2353. "CBinding::OnObjectAvailable",
  2354. "this=%#x, %#x, %#x, %#x, %B",
  2355. this, grfBSCF, dwCurrentSize, dwTotalSize, fLastNotification
  2356. ));
  2357. HRESULT hr = NOERROR;
  2358. PerfDbgLog3(tagCBinding, this, "+CBinding::OnObjectAvailable (dwCurrentSize:%ld, dwTotalSize:%ld, LastNotification:%d)",
  2359. dwCurrentSize, dwTotalSize, fLastNotification);
  2360. CLSID clsid = CLSID_NULL;
  2361. // We shouldn't have less data than last time
  2362. UrlMkAssert(( (dwTotalSize == 0)
  2363. || (dwTotalSize != 0 && dwCurrentSize != 0)
  2364. ));
  2365. // must be BindToObject scenario
  2366. UrlMkAssert((_fBindToObject));
  2367. if (!fLastNotification && !_fSentFirstNotification)
  2368. {
  2369. // check if we've instantiated the object yet
  2370. if (_pUnkObject == NULL)
  2371. {
  2372. hr = _pCTransData->GetClassID(_clsidIn, &clsid);
  2373. if (FAILED(hr)) {
  2374. hr = InstallIEFeature();
  2375. if (SUCCEEDED(hr))
  2376. hr = _pCTransData->GetClassID(_clsidIn, &clsid);
  2377. }
  2378. if( _fForceBindToObjFail )
  2379. {
  2380. hr = REGDB_E_CLASSNOTREG;
  2381. }
  2382. if (hr == S_OK)
  2383. {
  2384. // instantiate the object now and call pass it on in OnDataAvailable
  2385. hr = InstantiateObject(&clsid, *_piidRes, &_pUnkObject, FALSE);
  2386. if (hr == S_FALSE)
  2387. {
  2388. // switch to datasink file
  2389. _pCTransData->SwitchDataSink(DataSink_File);
  2390. if( _pCTransData->IsEOFOnSwitchSink() )
  2391. {
  2392. hr = ObjectPersistMnkLoad(_pUnkObject, _fLocal, TRUE);
  2393. if (hr != NOERROR && hr != E_ABORT)
  2394. {
  2395. hr = ObjectPersistFileLoad(_pUnkObject);
  2396. }
  2397. }
  2398. }
  2399. // Don't send notifications after the 'last' one.
  2400. if ((hr == S_OK) && (_pUnkObject != NULL))
  2401. {
  2402. hr = CallOnObjectAvailable(*_piidRes,_pUnkObject);
  2403. // release the object in case transaction is async
  2404. // the object is passed back via *ppvObj in sync case
  2405. if (IsAsyncTransaction())
  2406. {
  2407. _pUnkObject->Release();
  2408. _pUnkObject = NULL;
  2409. }
  2410. UrlMkAssert((SUCCEEDED(hr)));
  2411. hr = S_OK;
  2412. }
  2413. // keep the object until all data here
  2414. }
  2415. else if (hr == S_FALSE)
  2416. {
  2417. //
  2418. // switch the datasink to file
  2419. //
  2420. _pCTransData->SwitchDataSink(DataSink_File);
  2421. }
  2422. else
  2423. {
  2424. hr = REGDB_E_CLASSNOTREG;
  2425. }
  2426. }
  2427. else
  2428. {
  2429. // we got the object loaded but have to wait until all data
  2430. // are available
  2431. hr = S_FALSE;
  2432. }
  2433. if (!_fSentFirstNotification)
  2434. {
  2435. _fSentFirstNotification = TRUE;
  2436. }
  2437. }
  2438. else if (fLastNotification)
  2439. {
  2440. UrlMkAssert((!_fSentLastNotification));
  2441. DWORD grfBSCF = 0;
  2442. // Check if this will be the first data notification
  2443. // Check if this will be the last data notification
  2444. if (fLastNotification)
  2445. {
  2446. grfBSCF |= BSCF_LASTDATANOTIFICATION;
  2447. }
  2448. if (_pUnkObject == NULL)
  2449. {
  2450. if( _fClsidFromProt && !IsEqualGUID(_clsidIn, CLSID_NULL) )
  2451. {
  2452. clsid = _clsidIn;
  2453. hr = NOERROR;
  2454. }
  2455. else
  2456. {
  2457. hr = _pCTransData->GetClassID(_clsidIn, &clsid);
  2458. }
  2459. if (FAILED(hr)) {
  2460. hr = InstallIEFeature();
  2461. if (SUCCEEDED(hr))
  2462. hr = _pCTransData->GetClassID(_clsidIn, &clsid);
  2463. }
  2464. if( _fForceBindToObjFail )
  2465. {
  2466. hr = REGDB_E_CLASSNOTREG;
  2467. }
  2468. if (FAILED(hr))
  2469. {
  2470. hr = REGDB_E_CLASSNOTREG;
  2471. }
  2472. else
  2473. {
  2474. // instanciate the object now and call pass it on in OnDataAvailable
  2475. if( _fClsidFromProt )
  2476. {
  2477. hr = CreateObject(&clsid, *_piidRes, &_pUnkObject);
  2478. }
  2479. else
  2480. {
  2481. hr = InstantiateObject(&clsid, *_piidRes,
  2482. &_pUnkObject, TRUE);
  2483. }
  2484. }
  2485. }
  2486. else
  2487. {
  2488. CallOnProgress( 0, 0, BINDSTATUS_BEGINSYNCOPERATION, 0 );
  2489. hr = ObjectPersistMnkLoad(_pUnkObject,_fLocal,TRUE);
  2490. if (hr != NOERROR && hr != E_ABORT)
  2491. {
  2492. // if all bits are available
  2493. hr = ObjectPersistFileLoad(_pUnkObject);
  2494. }
  2495. CallOnProgress( 0, 0, BINDSTATUS_ENDSYNCOPERATION, 0 );
  2496. }
  2497. // Don't send notifications after the 'last' one.
  2498. if ( SUCCEEDED(hr)
  2499. && (_pUnkObject != NULL)
  2500. && !_fSentLastNotification)
  2501. {
  2502. BOOL bRegisteredTransactionData = FALSE;
  2503. // Note: register the transaction object only
  2504. // in case we are asked to transfer it to the
  2505. // new process/thread where no new download
  2506. // should be started
  2507. if (_grfBINDF & BINDF_COMPLETEDOWNLOAD)
  2508. {
  2509. hr = _pBndCtx->RegisterObjectParam(SZ_TRANSACTIONDATA, (ITransactionData *)_pCTransData);
  2510. if (SUCCEEDED(hr))
  2511. {
  2512. bRegisteredTransactionData = TRUE;
  2513. }
  2514. PerfDbgLog2(tagCBinding, this, "=== CBinding::OnObjectAvailable RegisterObjectParam SZ_TRANSACTIONDATA: pbndctx:%lx, hr:%lx)", _pBndCtx, hr);
  2515. }
  2516. TransAssert((hr == NOERROR));
  2517. hr = CallOnObjectAvailable(*_piidRes,_pUnkObject);
  2518. if (bRegisteredTransactionData)
  2519. {
  2520. _pBndCtx->RevokeObjectParam(SZ_TRANSACTIONDATA);
  2521. }
  2522. // release the object
  2523. if (IsAsyncTransaction())
  2524. {
  2525. _pUnkObject->Release();
  2526. _pUnkObject = NULL;
  2527. }
  2528. UrlMkAssert((SUCCEEDED(hr)));
  2529. }
  2530. else
  2531. {
  2532. // why did it fail
  2533. }
  2534. if (grfBSCF & BSCF_LASTDATANOTIFICATION)
  2535. {
  2536. _fSentLastNotification = TRUE;
  2537. }
  2538. }
  2539. else
  2540. {
  2541. hr = S_FALSE;
  2542. }
  2543. _dwLastSize = dwCurrentSize;
  2544. PerfDbgLog1(tagCBinding, this, "-CBinding::OnObjectAvailable (hr:%lx)", hr);
  2545. DEBUG_LEAVE(hr);
  2546. return hr;
  2547. }
  2548. //+---------------------------------------------------------------------------
  2549. //
  2550. // Method: CBinding::InstallIEFeature
  2551. //
  2552. // Synopsis:
  2553. // called when you can't by comventional registry lookup means
  2554. // find a clsid for a given mime type
  2555. // This code then checks to see if this is an IE feature
  2556. // and if so installs it by calling the IE JIT API.
  2557. //
  2558. // Arguments:
  2559. //
  2560. // Returns:
  2561. //
  2562. // Notes:
  2563. //
  2564. //----------------------------------------------------------------------------
  2565. STDMETHODIMP CBinding::InstallIEFeature()
  2566. {
  2567. DEBUG_ENTER((DBG_BINDING,
  2568. Hresult,
  2569. "CBinding::InstallIEFeature",
  2570. "this=%#x",
  2571. this
  2572. ));
  2573. PerfDbgLog(tagCBinding, this, "+CBinding::InstallIEFeature");
  2574. HRESULT hr = INET_E_CANNOT_INSTANTIATE_OBJECT;
  2575. uCLSSPEC classpec;
  2576. IWindowForBindingUI *pWindowForBindingUI = NULL;
  2577. HWND hWnd = NULL;
  2578. REFGUID rguidReason = IID_ICodeInstall;
  2579. LPCWSTR pwszMimeType = _pCTransData->GetMimeType();
  2580. DWORD dwJITFlags;
  2581. // BUGBUG: Cannot extern vwzApplicationCDF from datasnif.cxx
  2582. // For some reason, vwzApplicationCDF contains bogus data in some scenarios!
  2583. static WCHAR vwzAppCDF[] = L"application/x-cdf";
  2584. if (!pwszMimeType) {
  2585. DEBUG_LEAVE(hr);
  2586. return hr;
  2587. }
  2588. if (SUCCEEDED(IsMimeHandled(pwszMimeType))) {
  2589. // if the mime has been handled by an EXE out of proc
  2590. // then fail to instantiate the obj. shdocvw will call
  2591. // shellexecute on this url which will succeed.
  2592. // we assume here that we enter InstallIEfeature only
  2593. // after a conversion MimeToClsid has failed!
  2594. hr = INET_E_CANNOT_INSTANTIATE_OBJECT;
  2595. DEBUG_LEAVE(hr);
  2596. return hr;
  2597. }
  2598. CallOnProgress( 0, 0, BINDSTATUS_BEGINSYNCOPERATION, 0 );
  2599. // Get IWindowForBindingUI ptr
  2600. hr = _pBSCB->QueryInterface(IID_IWindowForBindingUI,
  2601. (LPVOID *)&pWindowForBindingUI);
  2602. if (FAILED(hr)) {
  2603. IServiceProvider *pServProv;
  2604. hr = _pBSCB->QueryInterface(IID_IServiceProvider,
  2605. (LPVOID *)&pServProv);
  2606. if (hr == NOERROR) {
  2607. pServProv->QueryService(IID_IWindowForBindingUI,IID_IWindowForBindingUI,
  2608. (LPVOID *)&pWindowForBindingUI);
  2609. pServProv->Release();
  2610. }
  2611. }
  2612. hr = INET_E_CANNOT_INSTANTIATE_OBJECT; // init to fail
  2613. // get hWnd
  2614. if (pWindowForBindingUI) {
  2615. pWindowForBindingUI->GetWindow(rguidReason, &hWnd);
  2616. pWindowForBindingUI->Release();
  2617. QUERYCONTEXT qc;
  2618. memset(&qc, 0, sizeof(qc));
  2619. // fill in the minimum version number of the component you need
  2620. //qc.dwVersionHi =
  2621. //qc.dwVersionLo =
  2622. classpec.tyspec=TYSPEC_MIMETYPE;
  2623. classpec.tagged_union.pMimeType=(LPWSTR)pwszMimeType;
  2624. if (pwszMimeType) {
  2625. dwJITFlags = (!StrCmpIW(pwszMimeType, vwzAppCDF)) ?
  2626. (FIEF_FLAG_FORCE_JITUI) : (0);
  2627. }
  2628. else {
  2629. dwJITFlags = 0;
  2630. }
  2631. hr = FaultInIEFeature(hWnd, &classpec, &qc, dwJITFlags);
  2632. }
  2633. CallOnProgress( 0, 0, BINDSTATUS_ENDSYNCOPERATION, 0 );
  2634. PerfDbgLog1(tagCBinding, this, "-CBinding::InstallIEFeature (hr:%lx)", hr);
  2635. DEBUG_LEAVE(hr);
  2636. return hr;
  2637. }
  2638. //+---------------------------------------------------------------------------
  2639. //
  2640. // Method: CBinding::InstantiateObject
  2641. //
  2642. // Synopsis:
  2643. //
  2644. // Arguments: [pclsid] --
  2645. // [riidResult] --
  2646. // [ppUnk] --
  2647. //
  2648. // Returns:
  2649. //
  2650. // History: 1-12-96 JohannP (Johann Posch) Created
  2651. //
  2652. // Notes:
  2653. //
  2654. //----------------------------------------------------------------------------
  2655. STDMETHODIMP CBinding::InstantiateObject(CLSID *pclsid, REFIID riidResult, IUnknown **ppUnk,BOOL fFullyAvailable)
  2656. {
  2657. DEBUG_ENTER((DBG_BINDING,
  2658. Hresult,
  2659. "CBinding::InstantiateObject",
  2660. "this=%#x, %#x, %#x, %#x, %B",
  2661. this, pclsid, &riidResult, ppUnk, fFullyAvailable
  2662. ));
  2663. PerfDbgLog(tagCBinding, this, "+CBinding::InstantiateObject");
  2664. HRESULT hr;
  2665. IUnknown *pUnk = NULL;
  2666. LPOLESTR pszStr = NULL;
  2667. BOOL fLocal = FALSE;
  2668. //call OnProgress with CLASSID_AVAILABLE
  2669. hr = StringFromCLSID(*pclsid, &pszStr);
  2670. if (hr == NOERROR)
  2671. {
  2672. PerfDbgLog1(tagCBinding, this, "CBinding::InstantiateObject (Class ID:%ws)", pszStr);
  2673. hr = CallOnProgress( 0, 0, BINDSTATUS_CLASSIDAVAILABLE, pszStr );
  2674. if(hr == E_ABORT)
  2675. SetOperationState(OPS_Abort);
  2676. else
  2677. UrlMkAssert((hr == NOERROR));
  2678. }
  2679. if (GetOperationState() == OPS_Abort)
  2680. {
  2681. // stop now - the client aborted the operation
  2682. hr = E_ABORT;
  2683. }
  2684. else
  2685. {
  2686. DumpIID(riidResult);
  2687. CallOnProgress( 0, 0, BINDSTATUS_BEGINSYNCOPERATION, 0 );
  2688. // If CLSID_MsHtml object had to be created to honor scripting access
  2689. // before OnObjectAvailable, BINDSTATUS_CLASSIDAVAILABLE OnProgress
  2690. // message is signal to register such an object in bind context
  2691. hr = _pBndCtx->GetObjectParam(L"__PrecreatedObject", &pUnk);
  2692. if (FAILED(hr))
  2693. {
  2694. // call OleAutoConvert
  2695. {
  2696. CLSID clsidIn = *pclsid;
  2697. CLSID clsidOut;
  2698. hr = OleGetAutoConvert(clsidIn, &clsidOut);
  2699. if (hr == S_OK)
  2700. {
  2701. *pclsid = clsidOut;
  2702. }
  2703. }
  2704. if (_grfBINDF & BINDF_GETCLASSOBJECT)
  2705. {
  2706. // Just want the class object
  2707. DEBUG_ENTER((DBG_BINDING,
  2708. Hresult,
  2709. "EXTERNAL::CoGetClassObject",
  2710. "%#x, CLSCTX_INPROC_SERVER, NULL, %#x, %#x",
  2711. pclsid, &riidResult, &pUnk
  2712. ));
  2713. hr = CoGetClassObject(*pclsid, CLSCTX_INPROC_SERVER,
  2714. NULL, riidResult, (void **)&pUnk);
  2715. DEBUG_LEAVE(hr);
  2716. if (FAILED(hr))
  2717. {
  2718. DEBUG_ENTER((DBG_BINDING,
  2719. Hresult,
  2720. "EXTERNAL::CoGetClassObject",
  2721. "%#x, CLSCTX_LOCAL_SERVER, NULL, %#x, %#x",
  2722. pclsid, &riidResult, &pUnk
  2723. ));
  2724. hr = CoGetClassObject(
  2725. *pclsid, CLSCTX_LOCAL_SERVER,
  2726. NULL, riidResult, (void **)&pUnk);
  2727. DEBUG_LEAVE(hr);
  2728. if (FAILED(hr))
  2729. {
  2730. DEBUG_ENTER((DBG_BINDING,
  2731. Hresult,
  2732. "EXTERNAL::CoGetClassObject",
  2733. "%#x, CLSCTX_INPROC_HANDLER, NULL, %#x, %#x",
  2734. pclsid, &riidResult, &pUnk
  2735. ));
  2736. hr = CoGetClassObject(
  2737. *pclsid, CLSCTX_INPROC_HANDLER,
  2738. NULL, riidResult, (void **)&pUnk);
  2739. DEBUG_LEAVE(hr);
  2740. }
  2741. }
  2742. }
  2743. else
  2744. {
  2745. DEBUG_ENTER((DBG_BINDING,
  2746. Hresult,
  2747. "EXTERNAL::CoCreateInstance",
  2748. "%#x, CLSCTX_INPROC_SERVER, NULL, %#x, %#x",
  2749. pclsid, &riidResult, &pUnk
  2750. ));
  2751. hr = CoCreateInstance(*pclsid, NULL, CLSCTX_INPROC_SERVER,
  2752. riidResult, (void**)&pUnk);
  2753. DEBUG_LEAVE(hr);
  2754. if (FAILED(hr))
  2755. {
  2756. DbgLog1(tagCBindingErr, this, "=== CBinding::InstantiateObject InProcServer (hr:%lx)", hr);
  2757. DEBUG_ENTER((DBG_BINDING,
  2758. Hresult,
  2759. "EXTERNAL::CoCreateInstance",
  2760. "%#x, CLSCTX_LOCAL_SERVER, NULL, %#x, %#x",
  2761. pclsid, &riidResult, &pUnk
  2762. ));
  2763. hr = CoCreateInstance(*pclsid, NULL, CLSCTX_LOCAL_SERVER,
  2764. riidResult, (void**)&pUnk);
  2765. DEBUG_LEAVE(hr);
  2766. _fLocal = fLocal = TRUE;
  2767. if (FAILED(hr))
  2768. {
  2769. DumpIID(*pclsid);
  2770. DbgLog1(tagCBindingErr, this, "=== CBinding::InstantiateObject LocalServer (hr:%lx)", hr);
  2771. DEBUG_ENTER((DBG_BINDING,
  2772. Hresult,
  2773. "EXTERNAL::CoCreateInstance",
  2774. "%#x, CLSCTX_INPROC_HANDLER, NULL, %#x, %#x",
  2775. pclsid, &riidResult, &pUnk
  2776. ));
  2777. hr = CoCreateInstance(*pclsid, NULL, CLSCTX_INPROC_HANDLER, riidResult, (void**)&pUnk);
  2778. DEBUG_LEAVE(hr);
  2779. _fLocal = fLocal = FALSE;
  2780. if( FAILED(hr))
  2781. {
  2782. DbgLog1(tagCBindingErr, this, "=== CBinding::InstantiateObject InProcHandler (hr:%lx)", hr);
  2783. }
  2784. }
  2785. }
  2786. }
  2787. }
  2788. if (SUCCEEDED(hr))
  2789. {
  2790. *ppUnk = pUnk;
  2791. if ( _grfBINDF & BINDF_COMPLETEDOWNLOAD
  2792. && IsEqualGUID(*pclsid, CLSID_MsHtml)
  2793. && fFullyAvailable == FALSE)
  2794. {
  2795. hr = S_FALSE;
  2796. }
  2797. else
  2798. {
  2799. // S_FALSE means try later when all data are available
  2800. hr = ObjectPersistMnkLoad(pUnk,_fLocal,fFullyAvailable, pclsid);
  2801. if (hr == E_NOINTERFACE)
  2802. {
  2803. if (fFullyAvailable)
  2804. {
  2805. hr = ObjectPersistFileLoad(_pUnkObject);
  2806. }
  2807. else
  2808. {
  2809. // call PersistFile::Load later
  2810. hr = S_FALSE;
  2811. }
  2812. }
  2813. else if (hr == S_FALSE)
  2814. {
  2815. // lock the request
  2816. _pOInetBdg->LockRequest(0);
  2817. _fCompleteDownloadHere = TRUE;
  2818. }
  2819. else if (hr != NOERROR && hr != E_ABORT)
  2820. {
  2821. //
  2822. // your last chance of being loaded...
  2823. // this was not needed for IE4 since wininet
  2824. // ALWAYS return async, start from IE5, wininet
  2825. // will return SYNC if the file is in cache
  2826. //
  2827. if (fFullyAvailable)
  2828. {
  2829. HRESULT hr2 = ObjectPersistFileLoad(_pUnkObject);
  2830. if( hr2 == NOERROR )
  2831. {
  2832. // if we succeeded here, needs to return NOERROR
  2833. hr = hr2;
  2834. }
  2835. }
  2836. }
  2837. // else pass back error
  2838. }
  2839. }
  2840. else
  2841. {
  2842. SetInstantiateHresult(hr);
  2843. hr = INET_E_CANNOT_INSTANTIATE_OBJECT;
  2844. }
  2845. CallOnProgress( 0, 0, BINDSTATUS_ENDSYNCOPERATION, 0 );
  2846. }
  2847. if (pszStr)
  2848. {
  2849. delete pszStr;
  2850. }
  2851. PerfDbgLog1(tagCBinding, this, "-CBinding::InstantiateObject (hr:%lx)", hr);
  2852. DEBUG_LEAVE(hr);
  2853. return hr;
  2854. }
  2855. //+---------------------------------------------------------------------------
  2856. //
  2857. // Method: CBinding::ObjectPersistMnkLoad
  2858. //
  2859. // Synopsis:
  2860. //
  2861. // Arguments: [pUnk] --
  2862. //
  2863. // Returns:
  2864. //
  2865. // History: 2-07-96 JohannP (Johann Posch) Created
  2866. //
  2867. // Notes:
  2868. //
  2869. //----------------------------------------------------------------------------
  2870. STDMETHODIMP CBinding::ObjectPersistMnkLoad(IUnknown *pUnk, BOOL fLocal, BOOL fFullyAvailable, CLSID *pclsid)
  2871. {
  2872. DEBUG_ENTER((DBG_BINDING,
  2873. Hresult,
  2874. "CBinding::ObjectPersistMnkLoad",
  2875. "this=%#x, %#x, %B, %B",
  2876. this, pUnk, fLocal, fFullyAvailable
  2877. ));
  2878. PerfDbgLog(tagCBinding, this, "+CBinding::ObjectPersistMnkLoad");
  2879. HRESULT hr;
  2880. IPersistMoniker *pPersistMk = NULL;
  2881. BIND_OPTS bindopts;
  2882. BOOL bRegisteredTransactionData = FALSE;
  2883. if (_grfBINDF & BINDF_GETCLASSOBJECT)
  2884. {
  2885. // GetClassObj, which means there is no need to PersistMnkLoad
  2886. PerfDbgLog(tagCBinding, this, " ObjectPersistMnkLoad : GETCLASSOBJ");
  2887. hr = NOERROR;
  2888. goto exit;
  2889. }
  2890. DEBUG_ENTER((DBG_BINDING,
  2891. Hresult,
  2892. "EXTERNAL::IUnknown::QueryInterface",
  2893. "this=%#x, IID_IPersistMoniker, %#x",
  2894. pUnk, &pPersistMk
  2895. ));
  2896. hr = pUnk->QueryInterface(IID_IPersistMoniker, (void**)&pPersistMk);
  2897. DEBUG_LEAVE(hr);
  2898. if (hr == NOERROR)
  2899. {
  2900. TransAssert((pPersistMk != NULL));
  2901. if (!fLocal)
  2902. {
  2903. hr = _pBndCtx->RegisterObjectParam(SZ_BINDING, (IBinding *)this);
  2904. }
  2905. IUnknown *pUnk = 0;
  2906. // remove the current bindstatuscallback
  2907. hr = _pBndCtx->GetObjectParam(REG_BSCB_HOLDER, &pUnk);
  2908. TransAssert((hr == NOERROR));
  2909. hr = _pBndCtx->RevokeObjectParam(REG_BSCB_HOLDER);
  2910. TransAssert((hr == NOERROR));
  2911. bindopts = _bindopts;
  2912. TransAssert(( bindopts.grfMode & (STGM_READWRITE | STGM_SHARE_EXCLUSIVE) ));
  2913. if ( !(bindopts.grfMode & (STGM_READWRITE | STGM_SHARE_EXCLUSIVE)) )
  2914. {
  2915. bindopts.grfMode |= (STGM_READWRITE | STGM_SHARE_EXCLUSIVE);
  2916. }
  2917. // Note:
  2918. // switch of flag do not receive notifications on this cbinding
  2919. // BindToStorage synchronous might be called
  2920. _grfInternalFlags &= ~BDGFLAGS_NOTIFICATIONS;
  2921. if ( (fFullyAvailable)
  2922. && ( ( !(_grfBINDF & BINDF_COMPLETEDOWNLOAD)
  2923. && _fCompleteDownloadHere )
  2924. ||
  2925. (_fLocal)
  2926. )
  2927. )
  2928. {
  2929. _grfBINDF |= BINDF_COMPLETEDOWNLOAD;
  2930. hr = _pBndCtx->RegisterObjectParam(SZ_TRANSACTIONDATA, (ITransactionData *)_pCTransData);
  2931. if (SUCCEEDED(hr))
  2932. {
  2933. bRegisteredTransactionData = TRUE;
  2934. }
  2935. PerfDbgLog2(tagCBinding, this, "=== CBinding::OnObjectAvailable RegisterObjectParam SZ_TRANSACTIONDATA: pbndctx:%lx, hr:%lx)", _pBndCtx, hr);
  2936. // swtich the _ds back to StreamOnFile so that the BindToStorage
  2937. // can get the IStream from pbc (inproc server only)
  2938. if( !_fLocal )
  2939. {
  2940. _pCTransData->SetFileAsStmFile();
  2941. }
  2942. }
  2943. LPCWSTR pwszMimeType = _pCTransData->GetMimeType();
  2944. // Now, we try to shove the mimetype down the throat of pPersistMk
  2945. IMonikerProp *pmkp = NULL;
  2946. DEBUG_ENTER((DBG_BINDING,
  2947. Hresult,
  2948. "EXTERNAL::IUnknown::QueryInterface",
  2949. "this=%#x, IID_IMonikerProp, %#x (mimetype = %.80wq)",
  2950. pPersistMk, &pmkp, pwszMimeType
  2951. ));
  2952. if (SUCCEEDED(pPersistMk->QueryInterface(IID_IMonikerProp, (void **)&pmkp)))
  2953. {
  2954. DEBUG_LEAVE(NOERROR);
  2955. pmkp->PutProperty(MIMETYPEPROP, pwszMimeType);
  2956. }
  2957. else
  2958. DEBUG_LEAVE(E_FAIL);
  2959. if( !fFullyAvailable &&
  2960. pwszMimeType &&
  2961. !StrCmpNIW( pwszMimeType, L"application/pdf", 15) )
  2962. {
  2963. // let's find out we are dealing with Acrobat 3.02 and above
  2964. if( _fAcceptRanges && PDFNeedProgressiveDownload() )
  2965. {
  2966. if(pmkp)
  2967. {
  2968. pmkp->PutProperty(USE_SRC_URL, L"1");
  2969. }
  2970. // this is 3.02 and above, go ahead call PMK::Load
  2971. hr = pPersistMk->Load(
  2972. fFullyAvailable, GetMoniker(), _pBndCtx, bindopts.grfMode);
  2973. }
  2974. else
  2975. {
  2976. //
  2977. // this is 3.0 and 3.01,
  2978. // or we are dealing with server does not support Range
  2979. // don't call PMK::Load until fully available
  2980. //
  2981. hr = S_FALSE;
  2982. }
  2983. }
  2984. else
  2985. {
  2986. if( pclsid &&
  2987. !fFullyAvailable &&
  2988. IsEqualGUID(*pclsid, CLSID_PluginHost))
  2989. {
  2990. hr = S_FALSE;
  2991. }
  2992. else
  2993. {
  2994. DEBUG_ENTER((DBG_BINDING,
  2995. Hresult,
  2996. "EXTERNAL::IPersistMoniker::Load",
  2997. "this=%#x, %B, %#x, %#x, %#x",
  2998. pPersistMk, fFullyAvailable, GetMoniker(), _pBndCtx, bindopts.grfMode
  2999. ));
  3000. hr = pPersistMk->Load(fFullyAvailable, GetMoniker(), _pBndCtx, bindopts.grfMode);
  3001. DEBUG_LEAVE(hr);
  3002. }
  3003. }
  3004. if (bRegisteredTransactionData)
  3005. {
  3006. _pBndCtx->RevokeObjectParam(SZ_TRANSACTIONDATA);
  3007. }
  3008. if (FAILED(hr))
  3009. {
  3010. if (hr == E_FAIL)
  3011. {
  3012. hr = CO_E_SERVER_EXEC_FAILURE;
  3013. }
  3014. }
  3015. // Note: OnStopBinding is still called even
  3016. // even the download finished due sync BindToStorage
  3017. // turn the flag back on
  3018. _grfInternalFlags |= BDGFLAGS_NOTIFICATIONS;
  3019. if (!fLocal)
  3020. {
  3021. _pBndCtx->RevokeObjectParam(SZ_BINDING);
  3022. }
  3023. if (pUnk)
  3024. {
  3025. _pBndCtx->RegisterObjectParam(REG_BSCB_HOLDER, pUnk);
  3026. pUnk->Release();
  3027. }
  3028. pPersistMk->Release();
  3029. if(pmkp)
  3030. pmkp->Release();
  3031. }
  3032. exit:
  3033. PerfDbgLog1(tagCBinding, this, "-CBinding::ObjectPersistMnkLoad (hr:%lx)", hr);
  3034. DEBUG_LEAVE(hr);
  3035. return hr;
  3036. }
  3037. //+---------------------------------------------------------------------------
  3038. //
  3039. // Method: CBinding::ObjectPersistFileLoad
  3040. //
  3041. // Synopsis:
  3042. //
  3043. // Arguments: [pUnk] --
  3044. //
  3045. // Returns:
  3046. //
  3047. // History: 2-07-96 JohannP (Johann Posch) Created
  3048. //
  3049. // Notes:
  3050. //
  3051. //----------------------------------------------------------------------------
  3052. STDMETHODIMP CBinding::ObjectPersistFileLoad(IUnknown *pUnk)
  3053. {
  3054. DEBUG_ENTER((DBG_BINDING,
  3055. Hresult,
  3056. "CBinding::ObjectPersistFileLoad",
  3057. "this=%#x, %#x",
  3058. this, pUnk
  3059. ));
  3060. HRESULT hr;
  3061. PerfDbgLog1(tagCBinding, this, "+CBinding::ObjectPersistFileLoad (filename:%ws)", GetFileName());
  3062. IPersistFile *pPersistFile = NULL;
  3063. DEBUG_ENTER((DBG_BINDING,
  3064. Hresult,
  3065. "EXTERNAL::IUnknown::QueryInterface",
  3066. "this=%#x, IID_IPersistFile, %#x",
  3067. pUnk, &pPersistFile
  3068. ));
  3069. hr = pUnk->QueryInterface(IID_IPersistFile, (void**)&pPersistFile);
  3070. DEBUG_LEAVE(hr);
  3071. if (hr == NOERROR)
  3072. {
  3073. DEBUG_ENTER((DBG_BINDING,
  3074. Hresult,
  3075. "EXTERNAL::IPersistFile::Load",
  3076. "this=%#x, %#x, %#x",
  3077. pPersistFile, GetFileName(), 0
  3078. ));
  3079. hr = pPersistFile->Load(GetFileName(), 0);
  3080. DEBUG_LEAVE(hr);
  3081. if (hr != NOERROR)
  3082. {
  3083. SetInstantiateHresult(hr);
  3084. hr = INET_E_CANNOT_LOAD_DATA;
  3085. }
  3086. PerfDbgLog1(tagCBinding, this, "=== CBinding::ObjectPersistFileLoad (Load returned:%lx)", hr);
  3087. pPersistFile->Release();
  3088. }
  3089. PerfDbgLog1(tagCBinding, this, "-CBinding::ObjectPersistFileLoad (hr:%lx)", hr);
  3090. DEBUG_LEAVE(hr);
  3091. return hr;
  3092. }
  3093. //+---------------------------------------------------------------------------
  3094. //
  3095. // Method: CBinding::CallGetBindInfo
  3096. //
  3097. // Synopsis:
  3098. //
  3099. // Arguments: [grfBINDINFOF] --
  3100. // [pBdInfo] --
  3101. //
  3102. // Returns:
  3103. //
  3104. // History: 2-07-96 JohannP (Johann Posch) Created
  3105. //
  3106. // Notes:
  3107. //
  3108. //----------------------------------------------------------------------------
  3109. STDMETHODIMP CBinding::CallGetBindInfo(DWORD *grfBINDINFOF, BINDINFO *pBdInfo)
  3110. {
  3111. DEBUG_ENTER((DBG_BINDING,
  3112. Hresult,
  3113. "CBinding::CallGetBindInfo",
  3114. "this=%#x, %#x, %#x",
  3115. this, grfBINDINFOF, pBdInfo
  3116. ));
  3117. HRESULT hr = E_FAIL;
  3118. UrlMkAssert((grfBINDINFOF != NULL));
  3119. PerfDbgLog1(tagCBinding, this, "+CBinding::CallGetBindInfo (grfBINDINFOF:%ld)", *grfBINDINFOF);
  3120. if (GetOperationState() == OPS_Initialized)
  3121. {
  3122. hr = _pBSCB->GetBindInfo(grfBINDINFOF, pBdInfo);
  3123. SetOperationState(OPS_GetBindInfo);
  3124. }
  3125. else
  3126. {
  3127. UrlMkAssert((GetOperationState() == OPS_Initialized));
  3128. }
  3129. if ( (*grfBINDINFOF & BINDF_ASYNCSTORAGE)
  3130. && (*grfBINDINFOF & BINDF_PULLDATA) )
  3131. {
  3132. PerfDbgLog2(tagCBinding, this, "=== grfBINDINFOF:%lx, (%s)", *grfBINDINFOF, "BINDF_ASYNCSTORAGE | BINDF_PULLDATA");
  3133. }
  3134. PerfDbgLog2(tagCBinding, this, "-CBinding::CallGetBindInfo (grfBINDINFOF:%lx, hr:%lx)", *grfBINDINFOF, hr);
  3135. DEBUG_LEAVE(hr);
  3136. return hr;
  3137. }
  3138. //+---------------------------------------------------------------------------
  3139. //
  3140. // Method: CBinding::CallOnStartBinding
  3141. //
  3142. // Synopsis:
  3143. //
  3144. // Arguments: [grfBINDINFOF] --
  3145. // [pib] --
  3146. //
  3147. // Returns:
  3148. //
  3149. // History: 2-07-96 JohannP (Johann Posch) Created
  3150. //
  3151. // Notes:
  3152. //
  3153. //----------------------------------------------------------------------------
  3154. STDMETHODIMP CBinding::CallOnStartBinding(DWORD grfBINDINFOF, IBinding * pib)
  3155. {
  3156. DEBUG_ENTER((DBG_BINDING,
  3157. Hresult,
  3158. "CBinding::CallOnStartBinding",
  3159. "this=%#x, %#x, %#x",
  3160. this, grfBINDINFOF, pib
  3161. ));
  3162. HRESULT hr = E_FAIL;
  3163. PerfDbgLog1(tagCBinding, this, "+CBinding::CallOnStartBinding (grfBINDINFOF:%lx)", grfBINDINFOF);
  3164. if (GetOperationState() == OPS_GetBindInfo)
  3165. {
  3166. hr = _pBSCB->OnStartBinding(NULL, this);
  3167. SetOperationState(OPS_StartBinding);
  3168. }
  3169. else
  3170. {
  3171. UrlMkAssert((GetOperationState() == OPS_GetBindInfo));
  3172. }
  3173. PerfDbgLog1(tagCBinding, this, "-CBinding::CallOnStartBinding (hr:%lx)", hr);
  3174. DEBUG_LEAVE(hr);
  3175. return hr;
  3176. }
  3177. //+---------------------------------------------------------------------------
  3178. //
  3179. // Method: CBinding::CallOnProgress
  3180. //
  3181. // Synopsis:
  3182. //
  3183. // Arguments: [ulProgress] --
  3184. // [ulProgressMax] --
  3185. // [ulStatusCode] --
  3186. // [szStatusText] --
  3187. //
  3188. // Returns:
  3189. //
  3190. // History: 2-14-96 JohannP (Johann Posch) Created
  3191. //
  3192. // Notes:
  3193. //
  3194. //----------------------------------------------------------------------------
  3195. STDMETHODIMP CBinding::CallOnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
  3196. {
  3197. DEBUG_ENTER((DBG_BINDING,
  3198. Hresult,
  3199. "CBinding::CallOnProgress",
  3200. "this=%#x, %#x, %#x, %#x, %.80wq",
  3201. this, ulProgress, ulProgressMax, ulStatusCode, szStatusText
  3202. ));
  3203. HRESULT hr = NOERROR;
  3204. PerfDbgLog(tagCBinding, this, "+CBinding::CallOnProgress");
  3205. if ( GetOperationState() == OPS_StartBinding)
  3206. {
  3207. SetOperationState(OPS_Downloading);
  3208. }
  3209. if (GetOperationState() == OPS_Downloading)
  3210. {
  3211. hr = _pBSCB->OnProgress(ulProgress, ulProgressMax, ulStatusCode, szStatusText);
  3212. }
  3213. PerfDbgLog1(tagCBinding, this, "-CBinding::CallOnProgress hr:%lx", hr);
  3214. DEBUG_LEAVE(hr);
  3215. return hr;
  3216. }
  3217. //+---------------------------------------------------------------------------
  3218. //
  3219. // Method: CBinding::CallOnStopBinding
  3220. //
  3221. // Synopsis:
  3222. //
  3223. // Arguments: [LPCWSTR] --
  3224. // [szError] --
  3225. //
  3226. // Returns:
  3227. //
  3228. // History: 2-14-96 JohannP (Johann Posch) Created
  3229. //
  3230. // Notes:
  3231. //
  3232. //----------------------------------------------------------------------------
  3233. STDMETHODIMP CBinding::CallOnStopBinding(HRESULT hrRet,LPCWSTR szError)
  3234. {
  3235. DEBUG_ENTER((DBG_BINDING,
  3236. Hresult,
  3237. "CBinding::CallOnStopBinding",
  3238. "this=%#x, %#x, %.80wq",
  3239. this, hrRet, szError
  3240. ));
  3241. HRESULT hr = E_FAIL;
  3242. PerfDbgLog1(tagCBinding, this, "+CBinding::CallOnStopBinding ->hrRet:%lx", hrRet);
  3243. if ( (GetOperationState() < OPS_Stopped)
  3244. && (GetOperationState() > OPS_Initialized))
  3245. {
  3246. UrlMkAssert(( (hrRet != S_FALSE && hrRet != E_FAIL) ));
  3247. if (hrRet == E_FAIL)
  3248. {
  3249. hrRet = INET_E_DOWNLOAD_FAILURE;
  3250. }
  3251. TransAssert(( ((hr == NOERROR) && _fSentLastNotification)
  3252. || (hr != NOERROR) ));
  3253. //if( _fBindToObject )
  3254. // DbgLog(tagCBindingErr, this, ">>> OnStopBinding (BindToObject)");
  3255. //else
  3256. // DbgLog(tagCBindingErr, this, ">>> OnStopBinding (BindToStorage)");
  3257. hr = _pBSCB->OnStopBinding(hrRet, NULL);
  3258. SetOperationState(OPS_Stopped);
  3259. }
  3260. TransAssert((_pBndCtx));
  3261. //TRIDENT BTS->BTO
  3262. //Save the transaction objects for BTO
  3263. if (!_fBTS_BTO) //(hrRet != INET_E_TERMINATED_BIND)
  3264. _pBndCtx->SetTransactionObjects(NULL,NULL);
  3265. PerfDbgLog1(tagCBinding, this, "-CBinding::CallOnStopBinding (hr:%lx)", hr);
  3266. DEBUG_LEAVE(hr);
  3267. return hr;
  3268. }
  3269. //+---------------------------------------------------------------------------
  3270. //
  3271. // Method: CBinding::CallOnLowResource
  3272. //
  3273. // Synopsis:
  3274. //
  3275. // Arguments: [reserved] --
  3276. //
  3277. // Returns:
  3278. //
  3279. // History: 2-14-96 JohannP (Johann Posch) Created
  3280. //
  3281. // Notes:
  3282. //
  3283. //----------------------------------------------------------------------------
  3284. STDMETHODIMP CBinding::CallOnLowResource (DWORD reserved)
  3285. {
  3286. DEBUG_ENTER((DBG_BINDING,
  3287. Hresult,
  3288. "CBinding::CallOnLowResource",
  3289. "this=%#x, %#x",
  3290. this, reserved
  3291. ));
  3292. HRESULT hr = E_FAIL;
  3293. PerfDbgLog(tagCBinding, this, "+CBinding::CallOnLowResource");
  3294. PerfDbgLog1(tagCBinding, this, "-CBinding::CallOnLowResource (hr:%lx)", hr);
  3295. DEBUG_LEAVE(hr);
  3296. return hr;
  3297. }
  3298. //+---------------------------------------------------------------------------
  3299. //
  3300. // Method: CBinding::CallGetPriority
  3301. //
  3302. // Synopsis:
  3303. //
  3304. // Arguments: [pnPriority] --
  3305. //
  3306. // Returns:
  3307. //
  3308. // History: 2-14-96 JohannP (Johann Posch) Created
  3309. //
  3310. // Notes:
  3311. //
  3312. //----------------------------------------------------------------------------
  3313. STDMETHODIMP CBinding::CallGetPriority (LONG * pnPriority)
  3314. {
  3315. DEBUG_ENTER((DBG_BINDING,
  3316. Hresult,
  3317. "CBinding::CallGetPriority",
  3318. "this=%#x, %#x",
  3319. this, pnPriority
  3320. ));
  3321. HRESULT hr = E_FAIL;
  3322. PerfDbgLog(tagCBinding, this, "+CBinding::CallGetPriority");
  3323. PerfDbgLog1(tagCBinding, this, "-CBinding::CallGetPriority (hr:%lx)", hr);
  3324. DEBUG_LEAVE(hr);
  3325. return hr;
  3326. }
  3327. //+---------------------------------------------------------------------------
  3328. //
  3329. // Method: CBinding::CallOnDataAvailable
  3330. //
  3331. // Synopsis:
  3332. //
  3333. // Arguments: [DWORD] --
  3334. // [FORMATETC] --
  3335. // [STGMEDIUM] --
  3336. // [pStgMed] --
  3337. //
  3338. // Returns:
  3339. //
  3340. // History: 2-14-96 JohannP (Johann Posch) Created
  3341. //
  3342. // Notes:
  3343. //
  3344. //----------------------------------------------------------------------------
  3345. STDMETHODIMP CBinding::CallOnDataAvailable(DWORD grfBSC,DWORD dwSize,FORMATETC *pFmtETC,STGMEDIUM *pStgMed)
  3346. {
  3347. DEBUG_ENTER((DBG_BINDING,
  3348. Hresult,
  3349. "CBinding::CallOnDataAvailable",
  3350. "this=%#x, %#x, %#x, %#x, %#x",
  3351. this, grfBSC, dwSize, pFmtETC, pStgMed
  3352. ));
  3353. HRESULT hr = E_FAIL;
  3354. PerfDbgLog(tagCBinding, this, "+CBinding::CallOnDataAvailable");
  3355. if (GetOperationState() == OPS_Downloading)
  3356. {
  3357. //DbgLog2(tagCBindingErr, this, ">>> OnDataAvailable (BSC=%lx size=%d)",
  3358. // grfBSC, dwSize);
  3359. hr = _pBSCB->OnDataAvailable(grfBSC, dwSize, pFmtETC, pStgMed);
  3360. if (hr == INET_E_TERMINATED_BIND)
  3361. {
  3362. _fBTS_BTO = TRUE;
  3363. hr = NOERROR; //restore back to value which was previous value being returned
  3364. }
  3365. }
  3366. else if (GetOperationState() == OPS_Abort)
  3367. {
  3368. hr = E_ABORT;
  3369. }
  3370. PerfDbgLog1(tagCBinding, this, "-CBinding::CallOnDataAvailable (hr:%lx)", hr);
  3371. DEBUG_LEAVE(hr);
  3372. return hr;
  3373. }
  3374. //+---------------------------------------------------------------------------
  3375. //
  3376. // Method: CBinding::CallOnObjectAvailable
  3377. //
  3378. // Synopsis:
  3379. //
  3380. // Arguments: [IUnknown] --
  3381. // [punk] --
  3382. //
  3383. // Returns:
  3384. //
  3385. // History: 2-14-96 JohannP (Johann Posch) Created
  3386. //
  3387. // Notes:
  3388. //
  3389. //----------------------------------------------------------------------------
  3390. STDMETHODIMP CBinding::CallOnObjectAvailable (REFIID riid,IUnknown *punk)
  3391. {
  3392. DEBUG_ENTER((DBG_BINDING,
  3393. Hresult,
  3394. "CBinding::CallOnObjectAvailable",
  3395. "this=%#x, %#x, %#x",
  3396. this, &riid, punk
  3397. ));
  3398. HRESULT hr = E_FAIL;
  3399. PerfDbgLog(tagCBinding, this, "+CBinding::CallOnObjectAvailable");
  3400. if (GetOperationState() == OPS_Downloading || _grfBINDF & BINDF_GETCLASSOBJECT)
  3401. {
  3402. hr = _pBSCB->OnObjectAvailable(riid, punk);
  3403. SetOperationState(OPS_ObjectAvailable);
  3404. }
  3405. else
  3406. {
  3407. UrlMkAssert((GetOperationState() == OPS_Downloading));
  3408. }
  3409. PerfDbgLog1(tagCBinding, this, "-CBinding::CallOnObjectAvailable (hr:%lx)", hr);
  3410. DEBUG_LEAVE(hr);
  3411. return hr;
  3412. }
  3413. //+---------------------------------------------------------------------------
  3414. //
  3415. // Method: CBinding::GetRequestedObject
  3416. //
  3417. // Synopsis:
  3418. //
  3419. // Arguments: [pbc] --
  3420. // [ppUnk] --
  3421. //
  3422. // Returns:
  3423. //
  3424. // History: 7-04-96 JohannP (Johann Posch) Created
  3425. //
  3426. // Notes:
  3427. //
  3428. //----------------------------------------------------------------------------
  3429. STDMETHODIMP CBinding::GetRequestedObject(IBindCtx *pbc, IUnknown **ppUnk)
  3430. {
  3431. DEBUG_ENTER((DBG_BINDING,
  3432. Hresult,
  3433. "CBinding::GetRequestedObject",
  3434. "this=%#x, %#x, %#x",
  3435. this, pbc, ppUnk
  3436. ));
  3437. HRESULT hr = NOERROR;
  3438. PerfDbgLog(tagCBinding, this, "+CBinding::GetRequestedObject");
  3439. UrlMkAssert((ppUnk));
  3440. *ppUnk = NULL;
  3441. if (_pUnkObject)
  3442. {
  3443. *ppUnk = _pUnkObject;
  3444. _pUnkObject->AddRef();
  3445. }
  3446. else if ( IsAsyncTransaction() )
  3447. {
  3448. //object is not available yet
  3449. hr = MK_S_ASYNCHRONOUS;
  3450. }
  3451. else
  3452. {
  3453. // BUGBUG: JohanP - this is bogus for the case of returning a filename in stgmed; either we return a new success code or
  3454. // the punk of the punkforrelease of the stgmed
  3455. hr = NOERROR;
  3456. }
  3457. PerfDbgLog1(tagCBinding, this, "-CBinding::GetRequestedObject (hr:%lx)", hr);
  3458. DEBUG_LEAVE(hr);
  3459. return hr;
  3460. }
  3461. //+---------------------------------------------------------------------------
  3462. //
  3463. // Method: CBinding::CallAuthenticate
  3464. //
  3465. // Synopsis:
  3466. //
  3467. // Arguments: [phwnd] --
  3468. // [LPWSTR] --
  3469. // [pszPassword] --
  3470. //
  3471. // Returns:
  3472. //
  3473. // History: 2-08-96 JohannP (Johann Posch) Created
  3474. //
  3475. // Notes:
  3476. //
  3477. //----------------------------------------------------------------------------
  3478. HRESULT CBinding::CallAuthenticate(HWND* phwnd, LPWSTR *pszUsername,LPWSTR *pszPassword)
  3479. {
  3480. DEBUG_ENTER((DBG_BINDING,
  3481. Hresult,
  3482. "CBinding::CallAuthenticate",
  3483. "this=%#x, %#x, %#x, %#x",
  3484. this, phwnd, pszUsername, pszPassword
  3485. ));
  3486. PerfDbgLog(tagCBinding, this, "+CBinding::CallAuthenticate");
  3487. HRESULT hr = NOERROR;
  3488. if (_pBasicAuth == NULL)
  3489. {
  3490. hr = LocalQueryInterface(IID_IAuthenticate, (void **) &_pBasicAuth);
  3491. }
  3492. if ((hr == NOERROR) && _pBasicAuth)
  3493. {
  3494. hr = _pBasicAuth->Authenticate(phwnd, pszUsername,pszPassword);
  3495. }
  3496. else
  3497. {
  3498. UrlMkAssert((_pBasicAuth == NULL));
  3499. *phwnd = 0;
  3500. *pszUsername = 0;
  3501. *pszPassword = 0;
  3502. }
  3503. PerfDbgLog4(tagCBinding, this, "-CBinding::CallAuthenticate (hr:%lx, hwnd:%lx, username:%ws, password:%ws)",
  3504. hr, *phwnd, *pszUsername?*pszUsername:L"", *pszPassword?*pszPassword:L"");
  3505. DEBUG_LEAVE(hr);
  3506. return hr;
  3507. }
  3508. //+---------------------------------------------------------------------------
  3509. //
  3510. // Method: CBinding::LocalQueryInterface
  3511. //
  3512. // Synopsis:
  3513. //
  3514. // Arguments: [iid] --
  3515. // [ppvObj] --
  3516. //
  3517. // Returns:
  3518. //
  3519. // History: 4-09-96 JohannP (Johann Posch) Created
  3520. //
  3521. // Notes:
  3522. //
  3523. //----------------------------------------------------------------------------
  3524. STDMETHODIMP CBinding::LocalQueryInterface(REFIID riid, void **ppvObj)
  3525. {
  3526. DEBUG_ENTER((DBG_BINDING,
  3527. Hresult,
  3528. "CBinding::LocalQueryInterface",
  3529. "this=%#x, %#x, %#x",
  3530. this, &riid, ppvObj
  3531. ));
  3532. PerfDbgLog2(tagCBinding, this, "+CBinding::LocalQueryInterface (%lx, %lx)", riid, ppvObj);
  3533. HRESULT hr = E_NOINTERFACE;
  3534. *ppvObj = 0;
  3535. if (_pBSCB)
  3536. {
  3537. IServiceProvider *pSrvPrv;
  3538. hr = _pBSCB->QueryInterface(IID_IServiceProvider, (void **) &pSrvPrv);
  3539. if (hr == NOERROR)
  3540. {
  3541. hr = pSrvPrv->QueryService(riid,riid, ppvObj);
  3542. pSrvPrv->Release();
  3543. }
  3544. else
  3545. {
  3546. hr = E_NOINTERFACE;
  3547. *ppvObj = 0;
  3548. }
  3549. }
  3550. PerfDbgLog2(tagCBinding, this, "-CBinding::LocalQueryInterface (%lx)[%lx]", hr, *ppvObj);
  3551. DEBUG_LEAVE(hr);
  3552. return hr;
  3553. }
  3554. //+---------------------------------------------------------------------------
  3555. //
  3556. // Method: CBinding::Switch
  3557. //
  3558. // Synopsis:
  3559. //
  3560. // Arguments: [pStateInfo] --
  3561. //
  3562. // Returns:
  3563. //
  3564. // History: 4-10-1997 JohannP (Johann Posch) Created
  3565. //
  3566. // Notes:
  3567. //
  3568. //----------------------------------------------------------------------------
  3569. STDMETHODIMP CBinding::Switch(PROTOCOLDATA *pStateInfo)
  3570. {
  3571. DEBUG_ENTER((DBG_BINDING,
  3572. Hresult,
  3573. "CBinding::IInternetProtocolSink::Switch",
  3574. "this=%#x, %#x",
  3575. this, pStateInfo
  3576. ));
  3577. PerfDbgLog(tagCBinding, this, "+CBinding::Switch");
  3578. HRESULT hr = E_FAIL;
  3579. TransAssert((FALSE));
  3580. PerfDbgLog1(tagCBinding, this, "-CBinding::Switch (%lx)", hr);
  3581. DEBUG_LEAVE(hr);
  3582. return hr;
  3583. }
  3584. //+---------------------------------------------------------------------------
  3585. //
  3586. // Method: CBinding::ReportProgress
  3587. //
  3588. // Synopsis:
  3589. //
  3590. // Arguments: [ulStatusCode] --
  3591. // [szStatusText] --
  3592. //
  3593. // Returns:
  3594. //
  3595. // History: 4-10-1997 JohannP (Johann Posch) Created
  3596. //
  3597. // Notes:
  3598. //
  3599. //----------------------------------------------------------------------------
  3600. STDMETHODIMP CBinding::ReportProgress(ULONG ulStatusCode, LPCWSTR szStatusText)
  3601. {
  3602. DEBUG_ENTER((DBG_BINDING,
  3603. Hresult,
  3604. "CBinding::IInternetProtocolSink::ReportProgress",
  3605. "this=%#x, %#x, %.80wq",
  3606. this, ulStatusCode, szStatusText
  3607. ));
  3608. PerfDbgLog(tagCBinding, this, "+CBinding::ReportProgress");
  3609. HRESULT hr = NOERROR;
  3610. if ( (ulStatusCode == BINDSTATUS_BEGINDOWNLOADDATA)
  3611. || (ulStatusCode == BINDSTATUS_DOWNLOADINGDATA)
  3612. || (ulStatusCode == BINDSTATUS_ENDDOWNLOADDATA) )
  3613. {
  3614. }
  3615. else
  3616. {
  3617. BOOL fRet = OnTransNotification(
  3618. (BINDSTATUS) ulStatusCode //BINDSTATUS NotMsg,
  3619. ,0 //ulProgress //DWORD dwCurrentSize,
  3620. ,0 //ulProgressMax //DWORD dwTotalSize,
  3621. ,( LPWSTR)szStatusText //LPWSTR pwzStr,
  3622. ,NOERROR //HRESULT hrINet
  3623. );
  3624. }
  3625. PerfDbgLog1(tagCBinding, this, "-CBinding::ReportProgress (%lx)", hr);
  3626. DEBUG_LEAVE(hr);
  3627. return hr;
  3628. }
  3629. //+---------------------------------------------------------------------------
  3630. //
  3631. // Method: CBinding::ReportData
  3632. //
  3633. // Synopsis:
  3634. //
  3635. // Arguments: [grfBSCF] --
  3636. // [ulProgress] --
  3637. // [ulProgressMax] --
  3638. //
  3639. // Returns:
  3640. //
  3641. // History: 4-10-1997 JohannP (Johann Posch) Created
  3642. //
  3643. // Notes:
  3644. //
  3645. //----------------------------------------------------------------------------
  3646. STDMETHODIMP CBinding::ReportData(DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
  3647. {
  3648. DEBUG_ENTER((DBG_BINDING,
  3649. Hresult,
  3650. "CBinding::IInternetProtocolSink::ReportData",
  3651. "this=%#x, %#x, %#x, %#x",
  3652. this, grfBSCF, ulProgress, ulProgressMax
  3653. ));
  3654. PerfDbgLog(tagCBinding, this, "+CBinding::ReportData");
  3655. HRESULT hr = NOERROR;
  3656. BOOL fLastNotification = (grfBSCF & BSCF_LASTDATANOTIFICATION) ? TRUE : FALSE;
  3657. ULONG ulStatusCode = BINDSTATUS_DOWNLOADINGDATA;
  3658. ULONG dwNew;
  3659. AddRef();
  3660. if (grfBSCF & BSCF_LASTDATANOTIFICATION)
  3661. {
  3662. ulStatusCode = BINDSTATUS_ENDDOWNLOADDATA;
  3663. }
  3664. else if (grfBSCF & BSCF_FIRSTDATANOTIFICATION)
  3665. {
  3666. ulStatusCode = BINDSTATUS_BEGINDOWNLOADDATA;
  3667. }
  3668. HRESULT hr1 = _pCTransData->OnDataReceived(grfBSCF, ulProgress, ulProgressMax,&dwNew);
  3669. ulProgress = dwNew;
  3670. if (hr1 == S_FALSE)
  3671. {
  3672. // end of data
  3673. ulStatusCode = BINDSTATUS_ENDDOWNLOADDATA;
  3674. }
  3675. else if ( (hr1 != S_NEEDMOREDATA)
  3676. && (hr1 != E_PENDING)
  3677. && (hr1 != NOERROR))
  3678. {
  3679. ulStatusCode = BINDSTATUS_ERROR;
  3680. }
  3681. if (hr1 != S_NEEDMOREDATA)
  3682. {
  3683. BOOL fRet = OnTransNotification(
  3684. (BINDSTATUS) ulStatusCode //BINDSTATUS NotMsg,
  3685. ,ulProgress //DWORD dwCurrentSize,
  3686. ,ulProgressMax //DWORD dwTotalSize,
  3687. ,NULL //LPWSTR pwzStr,
  3688. ,NOERROR //HRESULT hrINet
  3689. );
  3690. if (fRet == TRUE)
  3691. {
  3692. _pCTransData->OnTerminate();
  3693. if (_fBindToObject)
  3694. {
  3695. hr = S_FALSE;
  3696. TransAssert((_grfInternalFlags | ~BDGFLAGS_ATTACHED));
  3697. TransAssert((_grfInternalFlags & BDGFLAGS_PARTIAL));
  3698. _pOInetBdg->Terminate(BDGFLAGS_PARTIAL);
  3699. }
  3700. else if(_fBTS_BTO)
  3701. {
  3702. _pOInetBdg->Terminate(BDGFLAGS_BTS_BTO);
  3703. }
  3704. }
  3705. }
  3706. //TRIDENT BTS->BTO
  3707. //used to return only NOERROR and S_FALSE(only for certain BTO sitns.-not returned for BTS)
  3708. //Return INET_E_TERMINATED_BIND to let the Trans object know about the transfer.
  3709. if (_fBTS_BTO)
  3710. hr = INET_E_TERMINATED_BIND;
  3711. Release();
  3712. PerfDbgLog1(tagCBinding, this, "-CBinding::ReportData (%lx)", hr);
  3713. DEBUG_LEAVE(hr);
  3714. return hr;
  3715. }
  3716. //+---------------------------------------------------------------------------
  3717. //
  3718. // Method: CBinding::ReportResult
  3719. //
  3720. // Synopsis:
  3721. //
  3722. // Arguments: [hrResult] --
  3723. // [dwError] --
  3724. // [pwzResult] --
  3725. //
  3726. // Returns:
  3727. //
  3728. // History: 4-10-1997 JohannP (Johann Posch) Created
  3729. //
  3730. // Notes:
  3731. //
  3732. //----------------------------------------------------------------------------
  3733. STDMETHODIMP CBinding::ReportResult(HRESULT hrResult, DWORD dwError, LPCWSTR pwzResult)
  3734. {
  3735. DEBUG_ENTER((DBG_BINDING,
  3736. Hresult,
  3737. "CBinding::IInternetProtocolSink::ReportResult",
  3738. "this=%#x, %#x, %#x, %.80wq",
  3739. this, hrResult, dwError, pwzResult
  3740. ));
  3741. PerfDbgLog(tagCBinding, this, "+CBinding::ReportResult");
  3742. HRESULT hr = NOERROR;
  3743. AddRef();
  3744. _dwBindError = dwError;
  3745. _hrBindResult = hrResult;
  3746. if (pwzResult)
  3747. {
  3748. if (_pwzResult)
  3749. {
  3750. delete [] _pwzResult;
  3751. }
  3752. _pwzResult = OLESTRDuplicate((LPWSTR)pwzResult);
  3753. }
  3754. BOOL fRet = OnTransNotification(
  3755. BINDSTATUS_RESULT //BINDSTATUS NotMsg,
  3756. ,0 //ulProgress //DWORD dwCurrentSize,
  3757. ,0 //ulProgressMax //DWORD dwTotalSize,
  3758. ,(LPWSTR)pwzResult //LPWSTR pwzStr,
  3759. ,hrResult //HRESULT hrINet
  3760. );
  3761. if (fRet == TRUE)
  3762. {
  3763. hr = S_FALSE;
  3764. DWORD dwFlags = (_fBindToObject) ? BDGFLAGS_PARTIAL : 0;
  3765. _pCTransData->OnTerminate();
  3766. _pOInetBdg->Terminate(dwFlags);
  3767. }
  3768. Release();
  3769. PerfDbgLog1(tagCBinding, this, "-CBinding::ReportResult (%lx)", hr);
  3770. DEBUG_LEAVE(hr);
  3771. return hr;
  3772. }
  3773. STDMETHODIMP CBinding::CreateObject(CLSID *pclsid, REFIID riidResult, IUnknown **ppUnk)
  3774. {
  3775. DEBUG_ENTER((DBG_BINDING,
  3776. Hresult,
  3777. "CBinding::CreateObject",
  3778. "this=%#x, %#x, %#x, %#x",
  3779. this, pclsid, &riidResult, ppUnk
  3780. ));
  3781. PerfDbgLog(tagCBinding, this, "+CBinding::CreateObj");
  3782. HRESULT hr;
  3783. IUnknown *pUnk = NULL;
  3784. if (GetOperationState() == OPS_Abort)
  3785. {
  3786. // stop now - the client aborted the operation
  3787. hr = E_ABORT;
  3788. }
  3789. else
  3790. {
  3791. DumpIID(riidResult);
  3792. // call OleAutoConvert
  3793. {
  3794. CLSID clsidIn = *pclsid;
  3795. CLSID clsidOut;
  3796. hr = OleGetAutoConvert(clsidIn, &clsidOut);
  3797. if (hr == S_OK)
  3798. {
  3799. *pclsid = clsidOut;
  3800. }
  3801. }
  3802. if (_grfBINDF & BINDF_GETCLASSOBJECT)
  3803. {
  3804. // Just want the class object
  3805. hr = CoGetClassObject(*pclsid, CLSCTX_INPROC_SERVER,
  3806. NULL, riidResult, (void **)&pUnk);
  3807. if (FAILED(hr))
  3808. {
  3809. hr = CoGetClassObject(*pclsid, CLSCTX_LOCAL_SERVER,
  3810. NULL, riidResult, (void **)&pUnk);
  3811. if (FAILED(hr))
  3812. {
  3813. hr = CoGetClassObject(*pclsid, CLSCTX_INPROC_HANDLER,
  3814. NULL, riidResult, (void **)&pUnk);
  3815. }
  3816. }
  3817. }
  3818. else
  3819. {
  3820. hr = CoCreateInstance(*pclsid, NULL, CLSCTX_INPROC_SERVER,
  3821. riidResult, (void**)&pUnk);
  3822. if (FAILED(hr))
  3823. {
  3824. hr = CoCreateInstance(*pclsid, NULL, CLSCTX_LOCAL_SERVER,
  3825. riidResult, (void**)&pUnk);
  3826. if (FAILED(hr))
  3827. {
  3828. hr = CoCreateInstance(*pclsid, NULL, CLSCTX_INPROC_HANDLER,
  3829. riidResult, (void**)&pUnk);
  3830. }
  3831. }
  3832. }
  3833. if (SUCCEEDED(hr))
  3834. {
  3835. *ppUnk = pUnk;
  3836. }
  3837. else
  3838. {
  3839. SetInstantiateHresult(hr);
  3840. hr = INET_E_CANNOT_INSTANTIATE_OBJECT;
  3841. }
  3842. CallOnProgress( 0, 0, BINDSTATUS_ENDSYNCOPERATION, 0 );
  3843. }
  3844. PerfDbgLog1(tagCBinding, this, "-CBinding::CreateObject (hr:%lx)", hr);
  3845. DEBUG_LEAVE(hr);
  3846. return hr;
  3847. }