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.

1880 lines
51 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: oinet.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 11-07-1996 JohannP (Johann Posch) Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <trans.h>
  18. #include "oinet.hxx"
  19. #ifndef unix
  20. #include "..\mon\urlcf.hxx"
  21. #else
  22. #include "../mon/urlcf.hxx"
  23. #endif /* unix */
  24. #define BREAK_ONERROR(hrBreak) if (FAILED(hrBreak)) { break; }
  25. PerfDbgTag(tagCOInetSession, "Urlmon", "Log COInetSession", DEB_SESSION);
  26. COInetSession *g_pCOInetSession = 0;
  27. CMutexSem g_mxsOInet; // single access to media holder
  28. #define SESSIONOPTIONF_SHORTCIRCUIT_KNOWN_PROTOCOLS (0x00000040)
  29. BYTE g_bShortcircuitKnownProtocols = TRUE;
  30. typedef enum _tagOISM_FLAG
  31. {
  32. OISM_NOADDREF = 0x00000001
  33. } OISM_FLAGS;
  34. extern BOOL g_bCanUseSimpleBinding;
  35. extern LONG g_cTransLevelHandler;
  36. //+---------------------------------------------------------------------------
  37. //
  38. // Function: CoInternetGetSession
  39. //
  40. // Synopsis: exported API
  41. //
  42. // Arguments: [ppOInetSession] --
  43. // [dwReserved] --
  44. //
  45. // Returns:
  46. //
  47. // History: 4-14-1997 JohannP (Johann Posch) Created
  48. //
  49. // Notes:
  50. //
  51. //----------------------------------------------------------------------------
  52. STDAPI CoInternetGetSession(DWORD dwMode, IOInetSession **ppOInetSession, DWORD dwReserved)
  53. {
  54. DEBUG_ENTER_API((DBG_TRANS,
  55. Hresult,
  56. "CoInternetGetSession",
  57. "%#x, %#x, %#x",
  58. dwMode, ppOInetSession, dwReserved
  59. ));
  60. HRESULT hr = NOERROR;
  61. PerfDbgLog(tagCOInetSession, NULL, "+CoInternetGetSession");
  62. COInetSession *pCOInetSession = 0;
  63. hr = GetCOInetSession(dwMode, &pCOInetSession, dwReserved);
  64. if (hr == NOERROR )
  65. {
  66. *ppOInetSession = (IOInetSession *)pCOInetSession;
  67. }
  68. PerfDbgLog1(tagCOInetSession, NULL, "-CoInternetGetSession (hr:%lx)", hr);
  69. DEBUG_LEAVE_API(hr);
  70. return hr;
  71. }
  72. //+---------------------------------------------------------------------------
  73. //
  74. // Function: DeleteOInetSession
  75. //
  76. // Synopsis: deletes the global OInetSession
  77. // called by tls.cxx
  78. //
  79. // Arguments: [dwReserved] --
  80. //
  81. // Returns:
  82. //
  83. // History: 1-22-1997 JohannP (Johann Posch) Created
  84. //
  85. // Notes:
  86. //
  87. //----------------------------------------------------------------------------
  88. HRESULT DeleteOInetSession(DWORD dwReserved)
  89. {
  90. DEBUG_ENTER((DBG_TRANS,
  91. Hresult,
  92. "DeleteOInetSession",
  93. "%#x",
  94. dwReserved
  95. ));
  96. PerfDbgLog(tagCOInetSession, NULL, "+DeleteOInetSession");
  97. HRESULT hr = NOERROR;
  98. CLock lck(g_mxsOInet);
  99. if (g_pCOInetSession)
  100. {
  101. delete g_pCOInetSession;
  102. g_pCOInetSession = 0;
  103. }
  104. PerfDbgLog1(tagCOInetSession, NULL, "-DeleteOInetSession (hr:%lx)", hr);
  105. DEBUG_LEAVE(hr);
  106. return hr;
  107. }
  108. //+---------------------------------------------------------------------------
  109. //
  110. // Function: GetOInetSession
  111. //
  112. // Synopsis:
  113. //
  114. // Arguments: [dwMode] --
  115. // [ppOInetSession] --
  116. // [dwReserved] --
  117. //
  118. // Returns:
  119. //
  120. // History: 11-07-1996 JohannP (Johann Posch) Created
  121. //
  122. // Notes:
  123. //
  124. //----------------------------------------------------------------------------
  125. HRESULT GetCOInetSession(DWORD dwMode, COInetSession **ppOInetSession, DWORD dwReserved)
  126. {
  127. DEBUG_ENTER((DBG_TRANS,
  128. Hresult,
  129. "GetCOInetSession",
  130. "%#x, %#x, %#x",
  131. dwMode, ppOInetSession, dwReserved
  132. ));
  133. HRESULT hr = NOERROR;
  134. PerfDbgLog(tagCOInetSession, NULL, "+GetOInetSession");
  135. CLock lck(g_mxsOInet);
  136. TransAssert(( (ppOInetSession != NULL) && (dwReserved == 0) && "Invalid argument"));
  137. if (ppOInetSession && !dwReserved)
  138. {
  139. if (g_pCOInetSession == 0)
  140. {
  141. hr = COInetSession::Create(0, &g_pCOInetSession);
  142. }
  143. if (g_pCOInetSession)
  144. {
  145. if (!(dwMode & OISM_NOADDREF))
  146. {
  147. g_pCOInetSession->AddRef();
  148. }
  149. *ppOInetSession = g_pCOInetSession;
  150. }
  151. else
  152. {
  153. hr = E_OUTOFMEMORY;
  154. }
  155. }
  156. else
  157. {
  158. hr = E_INVALIDARG;
  159. }
  160. PerfDbgLog1(tagCOInetSession, NULL, "-GetOInetSession (hr:%lx)", hr);
  161. DEBUG_LEAVE(hr);
  162. return hr;
  163. }
  164. //+---------------------------------------------------------------------------
  165. //
  166. // Method: COInetSession::Create
  167. //
  168. // Synopsis:
  169. //
  170. // Arguments: [dwMode] --
  171. // [ppCOInetSession] --
  172. //
  173. // Returns:
  174. //
  175. // History: 11-15-1996 JohannP (Johann Posch) Created
  176. //
  177. // Notes:
  178. //
  179. //----------------------------------------------------------------------------
  180. HRESULT COInetSession::Create(DWORD dwMode, COInetSession **ppCOInetSession)
  181. {
  182. DEBUG_ENTER((DBG_TRANS,
  183. Hresult,
  184. "COInetSession::Create",
  185. "%#x, %#x",
  186. dwMode, ppCOInetSession
  187. ));
  188. PerfDbgLog(tagCOInetSession, NULL, "+GetOInetSession::Create");
  189. HRESULT hr = NOERROR;
  190. COInetSession *pSes = 0;
  191. TransAssert(( (ppCOInetSession != NULL) && (dwMode == 0) && "Invalid argument"));
  192. if (ppCOInetSession)
  193. {
  194. pSes = new COInetSession();
  195. if (pSes)
  196. {
  197. *ppCOInetSession = pSes;
  198. }
  199. else
  200. {
  201. hr = E_OUTOFMEMORY;
  202. }
  203. }
  204. else
  205. {
  206. hr = E_INVALIDARG;
  207. }
  208. PerfDbgLog1(tagCOInetSession, NULL, "-GetOInetSession::Create (hr:%lx)", hr);
  209. DEBUG_LEAVE(hr);
  210. return hr;
  211. }
  212. //+---------------------------------------------------------------------------
  213. //
  214. // Method: COInetSession::QueryInterface
  215. //
  216. // Synopsis:
  217. //
  218. // Arguments: [riid] --
  219. // [ppvObj] --
  220. //
  221. // Returns:
  222. //
  223. // History: 1-27-96 JohannP (Johann Posch) Created
  224. //
  225. // Notes:
  226. //
  227. //----------------------------------------------------------------------------
  228. STDMETHODIMP COInetSession::QueryInterface(REFIID riid, void **ppvObj)
  229. {
  230. DEBUG_ENTER((DBG_TRANS,
  231. Hresult,
  232. "COInetSession::IUnknown::QueryInterface",
  233. "this=%#x, %#x, %#x",
  234. this, &riid, ppvObj
  235. ));
  236. PerfDbgLog(tagCOInetSession, this, "+COInetSession::QueryInterface");
  237. VDATEPTROUT(ppvObj, void *);
  238. VDATETHIS(this);
  239. HRESULT hr = NOERROR;
  240. *ppvObj = NULL;
  241. if ((riid == IID_IUnknown) || (riid == IID_IOInetSession) )
  242. {
  243. *ppvObj = this;
  244. AddRef();
  245. }
  246. else
  247. {
  248. hr = E_NOINTERFACE;
  249. }
  250. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::QueryInterface (hr:%lx)", hr);
  251. DEBUG_LEAVE(hr);
  252. return hr;
  253. }
  254. //+---------------------------------------------------------------------------
  255. //
  256. // Function: COInetSession::AddRef
  257. //
  258. // Synopsis:
  259. //
  260. // Arguments: [ULONG] --
  261. //
  262. // Returns:
  263. //
  264. // History: 1-27-96 JohannP (Johann Posch) Created
  265. //
  266. // Notes:
  267. //
  268. //----------------------------------------------------------------------------
  269. STDMETHODIMP_(ULONG) COInetSession::AddRef(void)
  270. {
  271. DEBUG_ENTER((DBG_TRANS,
  272. Dword,
  273. "COInetSession::IUnknown::AddRef",
  274. "this=%#x",
  275. this
  276. ));
  277. LONG lRet = ++_CRefs;
  278. PerfDbgLog1(tagCOInetSession, this, "COInetSession::AddRef (cRefs:%ld)", lRet);
  279. DEBUG_LEAVE(lRet);
  280. return lRet;
  281. }
  282. //+---------------------------------------------------------------------------
  283. //
  284. // Function: COInetSession::Release
  285. //
  286. // Synopsis:
  287. //
  288. // Arguments: [ULONG] --
  289. //
  290. // Returns:
  291. //
  292. // History: 1-27-96 JohannP (Johann Posch) Created
  293. //
  294. // Notes:
  295. //
  296. //----------------------------------------------------------------------------
  297. STDMETHODIMP_(ULONG) COInetSession::Release(void)
  298. {
  299. DEBUG_ENTER((DBG_TRANS,
  300. Dword,
  301. "COInetSession::IUnknown::Release",
  302. "this=%#x",
  303. this
  304. ));
  305. LONG lRet = --_CRefs;
  306. if (_CRefs == 0)
  307. {
  308. // this is global
  309. //delete this;
  310. }
  311. PerfDbgLog1(tagCOInetSession, this, "COInetSession::Release (cRefs:%ld)", lRet);
  312. DEBUG_LEAVE(lRet);
  313. return lRet;
  314. }
  315. //+---------------------------------------------------------------------------
  316. //
  317. // Method: COInetSession::RegisterNameSpace
  318. //
  319. // Synopsis:
  320. //
  321. // Arguments: [pUnk] --
  322. // [ULONG] --
  323. // [cProtocols] --
  324. //
  325. // Returns:
  326. //
  327. // History: 11-07-1996 JohannP (Johann Posch) Created
  328. //
  329. // Notes:
  330. //
  331. //----------------------------------------------------------------------------
  332. STDMETHODIMP COInetSession::RegisterNameSpace(IClassFactory *pCF, REFCLSID rclsid, LPCWSTR pszProtocol,
  333. ULONG cPatterns, const LPCWSTR *ppwzPatterns, DWORD dwReserved)
  334. {
  335. DEBUG_ENTER((DBG_TRANS,
  336. Hresult,
  337. "COInetSession::IInternetSession::RegisterNameSpace",
  338. "this=%#x, %#x, %#x, %.80wq, %#x, %#x, %#x",
  339. this, pCF, &rclsid, pszProtocol, cPatterns, ppwzPatterns, dwReserved
  340. ));
  341. PerfDbgLog(tagCOInetSession, this, "+COInetSession::RegisterNameSpace");
  342. HRESULT hr = E_NOTIMPL;
  343. hr = _CProtMgrNameSpace.Register(pCF,rclsid, pszProtocol);
  344. if( hr == NOERROR &&
  345. (DLD_PROTOCOL_NONE != IsKnownProtocol(pszProtocol) ) )
  346. {
  347. UpdateTransLevelHandlerCount(TRUE);
  348. }
  349. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::RegisterNameSpace (hr:%lx)", hr);
  350. DEBUG_LEAVE(hr);
  351. return hr;
  352. }
  353. //+---------------------------------------------------------------------------
  354. //
  355. // Method: COInetSession::UnregisterNameSpace
  356. //
  357. // Synopsis:
  358. //
  359. // Arguments: [pUnk] --
  360. //
  361. // Returns:
  362. //
  363. // History: 11-07-1996 JohannP (Johann Posch) Created
  364. //
  365. // Notes:
  366. //
  367. //----------------------------------------------------------------------------
  368. STDMETHODIMP COInetSession::UnregisterNameSpace(IClassFactory *pCF, LPCWSTR pszProtocol)
  369. {
  370. DEBUG_ENTER((DBG_TRANS,
  371. Hresult,
  372. "COInetSession::IInternetSession::UnregisterNameSpace",
  373. "this=%#x, %#x, %.80wq",
  374. this, pCF, pszProtocol
  375. ));
  376. PerfDbgLog(tagCOInetSession, this, "+COInetSession::UnregisterNameSpace");
  377. HRESULT hr = E_NOTIMPL;
  378. hr = _CProtMgrNameSpace.Unregister(pCF, pszProtocol);
  379. if( hr == NOERROR &&
  380. (DLD_PROTOCOL_NONE != IsKnownProtocol(pszProtocol) ) )
  381. {
  382. UpdateTransLevelHandlerCount(FALSE);
  383. }
  384. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::UnregisterNameSpace (hr:%lx)", hr);
  385. DEBUG_LEAVE(hr);
  386. return hr;
  387. }
  388. //+---------------------------------------------------------------------------
  389. //
  390. // Method: COInetSession::RegisterMimeFilter
  391. //
  392. // Synopsis:
  393. //
  394. // Arguments: [const] --
  395. // [ULONG] --
  396. // [ctypes] --
  397. //
  398. // Returns:
  399. //
  400. // History: 11-07-1996 JohannP (Johann Posch) Created
  401. //
  402. // Notes:
  403. //
  404. //----------------------------------------------------------------------------
  405. STDMETHODIMP COInetSession::RegisterMimeFilter(IClassFactory *pCF, REFCLSID rclsid, LPCWSTR pwzType)
  406. {
  407. DEBUG_ENTER((DBG_TRANS,
  408. Hresult,
  409. "COInetSession::IInternetSession::RegisterMimeFilter",
  410. "this=%#x, %#x, %#x, %.80wq",
  411. this, pCF, &rclsid, pwzType
  412. ));
  413. PerfDbgLog(tagCOInetSession, this, "+COInetSession::RegisterMimeFilter");
  414. HRESULT hr;
  415. hr = _CProtMgrMimeFilter.Register(pCF,rclsid, pwzType);
  416. if( hr == NOERROR )
  417. {
  418. UpdateTransLevelHandlerCount(TRUE);
  419. }
  420. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::RegisterMimeFilter (hr:%lx)", hr);
  421. DEBUG_LEAVE(hr);
  422. return hr;
  423. }
  424. //+---------------------------------------------------------------------------
  425. //
  426. // Method: COInetSession::UnregisterMimeFilter
  427. //
  428. // Synopsis:
  429. //
  430. // Arguments: [pUnk] --
  431. //
  432. // Returns:
  433. //
  434. // History: 11-07-1996 JohannP (Johann Posch) Created
  435. //
  436. // Notes:
  437. //
  438. //----------------------------------------------------------------------------
  439. STDMETHODIMP COInetSession::UnregisterMimeFilter(IClassFactory *pCF, LPCWSTR pszType)
  440. {
  441. DEBUG_ENTER((DBG_TRANS,
  442. Hresult,
  443. "COInetSession::IInternetSession::UnregisterMimeFilter",
  444. "this=%#x, %#x, %.80wq",
  445. this, pCF, pszType
  446. ));
  447. PerfDbgLog(tagCOInetSession, this, "+COInetSession::UnregisterMimeFilter");
  448. HRESULT hr;
  449. hr = _CProtMgrMimeFilter.Unregister(pCF, pszType);
  450. if( hr == NOERROR )
  451. {
  452. UpdateTransLevelHandlerCount(FALSE);
  453. }
  454. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::UnregisterMimeFilter (hr:%lx)", hr);
  455. DEBUG_LEAVE(hr);
  456. return hr;
  457. }
  458. //+---------------------------------------------------------------------------
  459. //
  460. // Method: COInetSession::CreateBinding
  461. //
  462. // Synopsis:
  463. //
  464. // Arguments: [IUnknown] --
  465. // [REFIID] --
  466. // [IUnknown] --
  467. // [IOInetBinding] --
  468. // [DWORD] --
  469. // [dwOption] --
  470. //
  471. // Returns:
  472. //
  473. // History: 11-07-1996 JohannP (Johann Posch) Created
  474. //
  475. // Notes:
  476. //
  477. //----------------------------------------------------------------------------
  478. STDMETHODIMP COInetSession::CreateBinding(LPBC pBC, LPCWSTR wzUrl,IUnknown *pUnkOuter,
  479. IUnknown **ppUnk,IOInetProtocol **ppOInetProt, DWORD dwOption)
  480. {
  481. DEBUG_ENTER((DBG_TRANS,
  482. Hresult,
  483. "COInetSession::IInternetSession::CreateBinding",
  484. "this=%#x, %#x, %.80wq, %#x, %#x, %#x, %#x",
  485. this, pBC, wzUrl, pUnkOuter, ppUnk, ppOInetProt, dwOption
  486. ));
  487. PerfDbgLog(tagCOInetSession, this, "+COInetSession::CreateBinding");
  488. HRESULT hr = E_NOTIMPL;
  489. DWORD dwLocation = 0;
  490. CLSID clsid = CLSID_NULL;
  491. // NetDocs specific hack (IEv60 Bug# 25642):
  492. if(!g_bShortcircuitKnownProtocols && !(dwOption & PI_PREFERDEFAULTHANDLER))
  493. {
  494. // QueryInfo with QUERY_CAN_NAVIGATE, if true (or failure), let the default action take place.
  495. // If false, add a PI_PREFERDEFAULTHANDLER to dwOption to (preferably) load the internal handler.
  496. // Having NetDocs implement the IInternetProtocolInfo on the Class Factory instead of
  497. // the APP for performance, a CoInternetQueryInfo will work in either case, because
  498. // COInetSession::CreateProtocolInfo (conveniently ;-) ) queries the Class Factory
  499. // first for IInternetProtocolInfo.
  500. DWORD dwCanNavigate = TRUE;
  501. DWORD dwDummy;
  502. // Can NetDocs navigate?:
  503. HRESULT hr = /* CoInternet */ QueryInfo(
  504. wzUrl,
  505. QUERY_CAN_NAVIGATE,
  506. 0,
  507. (LPVOID)&dwCanNavigate,
  508. sizeof(dwCanNavigate),
  509. &dwDummy,
  510. 0);
  511. if ((hr == S_OK) && (!dwCanNavigate))
  512. dwOption |= PI_PREFERDEFAULTHANDLER;
  513. }
  514. if (dwOption & PI_PREFERDEFAULTHANDLER)
  515. {
  516. // allow non-IE urlmon clients to load only the default handlers.
  517. DWORD dwProtID = IsKnownProtocol(wzUrl);
  518. if (dwProtID)
  519. hr = CreateFirstProtocol(wzUrl, NULL, NULL, ppOInetProt, &clsid, &dwLocation, BINDF_PREFERDEFAULTHANDLER);
  520. if (SUCCEEDED(hr))
  521. goto Exit;
  522. dwOption &= ~PI_PREFERDEFAULTHANDLER;
  523. clsid = CLSID_NULL;
  524. }
  525. if (dwOption & PI_LOADAPPDIRECT)
  526. {
  527. hr = CreateFirstProtocol(wzUrl, NULL, NULL, ppOInetProt, &clsid, &dwLocation);
  528. }
  529. else if( pBC || !g_bCanUseSimpleBinding || g_cTransLevelHandler)
  530. {
  531. hr = GetTransactionObjects(pBC, wzUrl, pUnkOuter, ppUnk, ppOInetProt, dwOption, 0);
  532. }
  533. else
  534. {
  535. DWORD dwProtID = 0;
  536. dwProtID = IsKnownProtocol(wzUrl);
  537. if( dwProtID )
  538. {
  539. hr = CreateFirstProtocol(wzUrl, NULL, NULL, ppOInetProt, &clsid, &dwLocation);
  540. }
  541. else
  542. {
  543. hr = GetTransactionObjects(pBC, wzUrl, pUnkOuter, ppUnk,
  544. ppOInetProt, dwOption, 0);
  545. }
  546. }
  547. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::CreateBinding (hr:%lx)", hr);
  548. Exit:
  549. DEBUG_LEAVE(hr);
  550. return hr;
  551. }
  552. //+---------------------------------------------------------------------------
  553. //
  554. // Method: COInetSession::SetSessionOption
  555. //
  556. // Synopsis:
  557. //
  558. // Arguments: [LPVOID] --
  559. // [DWORD] --
  560. // [DWORD] --
  561. // [dwReserved] --
  562. //
  563. // Returns:
  564. //
  565. // History: 11-07-1996 JohannP (Johann Posch) Created
  566. // 02-09-2001 GaneshS (S. Ganesh) NetDocs Hack
  567. // This hack allows NetDocs to (re)set an option to prevent
  568. // short-circuit of (their overridden) known protocols, in
  569. // CoInternetQueryInfo.
  570. //
  571. // Notes:
  572. //
  573. //----------------------------------------------------------------------------
  574. STDMETHODIMP COInetSession::SetSessionOption(DWORD dwOption,LPVOID pBuffer,DWORD dwBufferLength,DWORD dwReserved)
  575. {
  576. DEBUG_ENTER((DBG_TRANS,
  577. Hresult,
  578. "COInetSession::IInternetSession::SetSessionOption",
  579. "this=%#x, %#x, %#x, %#x, %#x",
  580. this, dwOption, pBuffer, dwBufferLength, dwReserved
  581. ));
  582. PerfDbgLog(tagCOInetSession, this, "+COInetSession::SetSessionOption");
  583. HRESULT hr = E_NOTIMPL;
  584. if(SESSIONOPTIONF_SHORTCIRCUIT_KNOWN_PROTOCOLS == dwOption)
  585. {
  586. TransAssert(pBuffer);
  587. TransAssert(dwBufferLength == 1);
  588. g_bShortcircuitKnownProtocols = *(BYTE *)pBuffer;
  589. hr = S_OK;
  590. }
  591. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::SetSessionOption (hr:%lx)", hr);
  592. DEBUG_LEAVE(hr);
  593. return hr;
  594. }
  595. //+---------------------------------------------------------------------------
  596. //
  597. // Method: COInetSession::GetSessionOption
  598. //
  599. // Synopsis:
  600. //
  601. // Arguments: [LPVOID] --
  602. // [DWORD] --
  603. // [DWORD] --
  604. // [dwReserved] --
  605. //
  606. // Returns:
  607. //
  608. // History: 11-07-1996 JohannP (Johann Posch) Created
  609. //
  610. // Notes:
  611. //
  612. //----------------------------------------------------------------------------
  613. STDMETHODIMP COInetSession::GetSessionOption(DWORD dwOption,LPVOID pBuffer,DWORD *pdwBufferLength,DWORD dwReserved)
  614. {
  615. DEBUG_ENTER((DBG_TRANS,
  616. Hresult,
  617. "COInetSession::IInternetSession::GetSessionOption",
  618. "this=%#x, %#x, %#x, %#x, %#x",
  619. this, dwOption, pBuffer, pdwBufferLength, dwReserved
  620. ));
  621. PerfDbgLog(tagCOInetSession, this, "+COInetSession::GetSessionOption");
  622. HRESULT hr = E_NOTIMPL;
  623. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::GetSessionOption (hr:%lx)", hr);
  624. DEBUG_LEAVE(hr);
  625. return hr;
  626. }
  627. //+---------------------------------------------------------------------------
  628. //
  629. // Method: COInetSession::ParseUrl
  630. //
  631. // Synopsis:
  632. //
  633. // Arguments: [pwzUrl] --
  634. // [ParseAction] --
  635. // [dwFlags] --
  636. // [pwzResult] --
  637. // [cchResult] --
  638. // [dwReserved] --
  639. //
  640. // Returns:
  641. //
  642. // History: 4-13-1997 JohannP (Johann Posch) Created
  643. //
  644. // Notes:
  645. //
  646. //----------------------------------------------------------------------------
  647. STDMETHODIMP COInetSession::ParseUrl(
  648. LPCWSTR pwzUrl,
  649. PARSEACTION ParseAction,
  650. DWORD dwFlags,
  651. LPWSTR pwzResult,
  652. DWORD cchResult,
  653. DWORD *pcchResult,
  654. DWORD dwReserved
  655. )
  656. {
  657. DEBUG_ENTER((DBG_TRANS,
  658. Hresult,
  659. "COInetSession::IInternetProtocolInfo::ParseUrl",
  660. "this=%#x, %.80wq, %#x, %#x, %#x, %#x, %#x, %#x",
  661. this, pwzUrl, ParseAction, dwFlags, pwzResult, cchResult, pcchResult, dwReserved
  662. ));
  663. PerfDbgLog(tagCOInetSession, this, "+COInetSession::ParseUrl");
  664. HRESULT hr;
  665. IOInetProtocolInfo *pProtInfo = 0;
  666. do
  667. {
  668. hr = CreateProtocolInfo(pwzUrl, &pProtInfo);
  669. BREAK_ONERROR(hr);
  670. hr = pProtInfo->ParseUrl(pwzUrl, ParseAction, dwFlags, pwzResult, cchResult, pcchResult, dwReserved);
  671. break;
  672. } while (TRUE);
  673. if (pProtInfo)
  674. {
  675. pProtInfo->Release();
  676. }
  677. if (FAILED(hr))
  678. {
  679. hr = INET_E_DEFAULT_ACTION;
  680. }
  681. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::ParseUrl (hr:%lx)", hr);
  682. DEBUG_LEAVE(hr);
  683. return hr;
  684. }
  685. //+---------------------------------------------------------------------------
  686. //
  687. // Method: COInetSession::CombineUrl
  688. //
  689. // Synopsis:
  690. //
  691. // Arguments: [pwzBaseUrl] --
  692. // [pwzRelativeUrl] --
  693. // [dwFlags] --
  694. // [pwzResult] --
  695. // [cchResult] --
  696. // [dwReserved] --
  697. //
  698. // Returns:
  699. //
  700. // History: 4-13-1997 JohannP (Johann Posch) Created
  701. //
  702. // Notes:
  703. //
  704. //----------------------------------------------------------------------------
  705. STDMETHODIMP COInetSession::CombineUrl(
  706. LPCWSTR pwzBaseUrl,
  707. LPCWSTR pwzRelativeUrl,
  708. DWORD dwFlags,
  709. LPWSTR pwzResult,
  710. DWORD cchResult,
  711. DWORD *pcchResult,
  712. DWORD dwReserved
  713. )
  714. {
  715. DEBUG_ENTER((DBG_TRANS,
  716. Hresult,
  717. "COInetSession::IInternetProtocolInfo::CombineUrl",
  718. "this=%#x, %.80wq, %.80wq, %#x, %#x, %#x, %#x, %#x",
  719. this, pwzBaseUrl, pwzRelativeUrl, dwFlags, pwzResult, cchResult, pcchResult, dwReserved
  720. ));
  721. PerfDbgLog(tagCOInetSession, this, "+COInetSession::CombineUrl");
  722. HRESULT hr;
  723. IOInetProtocolInfo *pProtInfo = 0;
  724. do
  725. {
  726. hr = CreateProtocolInfo(pwzBaseUrl, &pProtInfo);
  727. BREAK_ONERROR(hr);
  728. hr = pProtInfo->CombineUrl(pwzBaseUrl, pwzRelativeUrl, dwFlags, pwzResult, cchResult, pcchResult, dwReserved);
  729. break;
  730. } while (TRUE);
  731. if (pProtInfo)
  732. {
  733. pProtInfo->Release();
  734. }
  735. if (FAILED(hr))
  736. {
  737. hr = INET_E_DEFAULT_ACTION;
  738. }
  739. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::CombineUrl (hr:%lx)", hr);
  740. DEBUG_LEAVE(hr);
  741. return hr;
  742. }
  743. //+---------------------------------------------------------------------------
  744. //
  745. // Method: COInetSession::CompareUrl
  746. //
  747. // Synopsis:
  748. //
  749. // Arguments: [pwzUrl1] --
  750. // [pwzUrl2] --
  751. // [dwFlags] --
  752. //
  753. // Returns:
  754. //
  755. // History: 4-13-1997 JohannP (Johann Posch) Created
  756. //
  757. // Notes:
  758. //
  759. //----------------------------------------------------------------------------
  760. STDMETHODIMP COInetSession::CompareUrl(
  761. LPCWSTR pwzUrl1,
  762. LPCWSTR pwzUrl2,
  763. DWORD dwFlags
  764. )
  765. {
  766. DEBUG_ENTER((DBG_TRANS,
  767. Hresult,
  768. "COInetSession::IInternetProtocolInfo::CompareUrl",
  769. "this=%#x, %.80wq, %.80wq, %#x",
  770. this, pwzUrl1, pwzUrl2, dwFlags
  771. ));
  772. PerfDbgLog(tagCOInetSession, this, "+COInetSession::CompareUrl");
  773. HRESULT hr;
  774. IOInetProtocolInfo *pProtInfo = 0;
  775. do
  776. {
  777. hr = CreateProtocolInfo(pwzUrl1, &pProtInfo);
  778. BREAK_ONERROR(hr);
  779. hr = pProtInfo->CompareUrl(pwzUrl1, pwzUrl2, dwFlags);
  780. break;
  781. } while (TRUE);
  782. if (pProtInfo)
  783. {
  784. pProtInfo->Release();
  785. }
  786. if (FAILED(hr))
  787. {
  788. hr = INET_E_DEFAULT_ACTION;
  789. }
  790. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::CompareUrl (hr:%lx)", hr);
  791. DEBUG_LEAVE(hr);
  792. return hr;
  793. }
  794. //+---------------------------------------------------------------------------
  795. //
  796. // Method: COInetSession::QueryInfo
  797. //
  798. // Synopsis:
  799. //
  800. // Arguments: [pwzUrl] --
  801. // [dwOption] --
  802. // [pBuffer] --
  803. // [cbBuffer] --
  804. // [pcbBuf] --
  805. // [dwReserved] --
  806. //
  807. // Returns:
  808. //
  809. // History: 4-14-1997 JohannP (Johann Posch) Created
  810. //
  811. // Notes:
  812. //
  813. //----------------------------------------------------------------------------
  814. STDMETHODIMP COInetSession::QueryInfo(
  815. LPCWSTR pwzUrl,
  816. QUERYOPTION QueryOption,
  817. DWORD dwQueryFlags,
  818. LPVOID pBuffer,
  819. DWORD cbBuffer,
  820. DWORD *pcbBuf,
  821. DWORD dwReserved
  822. )
  823. {
  824. DEBUG_ENTER((DBG_TRANS,
  825. Hresult,
  826. "COInetSession::IInternetProtocolInfo::QueryInfo",
  827. "this=%#x, %.80wq, %#x, %#x, %#x, %#x, %#x, %#x",
  828. this, pwzUrl, QueryOption, dwQueryFlags, pBuffer, cbBuffer, pcbBuf, dwReserved
  829. ));
  830. PerfDbgLog(tagCOInetSession, this, "+COInetSession::QueryInfo");
  831. HRESULT hr;
  832. IOInetProtocolInfo *pProtInfo = 0;
  833. CLSID clsid;
  834. do
  835. {
  836. hr = CreateProtocolInfo(pwzUrl, &pProtInfo);
  837. BREAK_ONERROR(hr);
  838. hr = pProtInfo->QueryInfo(pwzUrl, QueryOption, dwQueryFlags, pBuffer, cbBuffer, pcbBuf, dwReserved);
  839. break;
  840. } while (TRUE);
  841. if (pProtInfo)
  842. {
  843. pProtInfo->Release();
  844. }
  845. if (FAILED(hr))
  846. {
  847. hr = INET_E_DEFAULT_ACTION;
  848. }
  849. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::QueryInfo (hr:%lx)", hr);
  850. DEBUG_LEAVE(hr);
  851. return hr;
  852. }
  853. // internal methods
  854. //+---------------------------------------------------------------------------
  855. //
  856. // Method: COInetSession::FindFirstCF
  857. //
  858. // Synopsis:
  859. //
  860. // Arguments: [pszProt] --
  861. // [ppUnk] --
  862. // [pclsid] --
  863. //
  864. // Returns:
  865. //
  866. // History: 11-15-1996 JohannP (Johann Posch) Created
  867. //
  868. // Notes:
  869. //
  870. //----------------------------------------------------------------------------
  871. STDMETHODIMP COInetSession::FindFirstCF(LPCWSTR pszProt, IClassFactory **ppUnk, CLSID *pclsid,
  872. DWORD* pdwLocation, DWORD dwOpt)
  873. {
  874. DEBUG_ENTER((DBG_TRANS,
  875. Hresult,
  876. "COInetSession::FindFirstCF",
  877. "this=%#x, %.80wq, %#x, %#x, %#x, %#x",
  878. this, pszProt, ppUnk, pclsid, pdwLocation, dwOpt
  879. ));
  880. PerfDbgLog(tagCOInetSession, this, "+COInetSession::FindFirstCF");
  881. HRESULT hr = INET_E_UNKNOWN_PROTOCOL;
  882. TransAssert(pdwLocation);
  883. if( dwOpt )
  884. {
  885. *ppUnk = NULL;
  886. // different loading mechanism
  887. DWORD dwEl = 1;
  888. DWORD dwFlags = 0;
  889. HRESULT hrReg = _CProtMgr.LookupClsIDFromReg(
  890. pszProt, pclsid, &dwEl, &dwFlags, dwOpt);
  891. if( hrReg == NOERROR )
  892. {
  893. hrReg = CoGetClassObject(
  894. *pclsid,
  895. CLSCTX_INPROC_SERVER,
  896. NULL,
  897. IID_IClassFactory,
  898. (void**)ppUnk );
  899. if (hrReg == NOERROR)
  900. {
  901. hr = NOERROR;
  902. }
  903. }
  904. goto End;
  905. }
  906. *pdwLocation = LOC_NAMESPACE;
  907. switch (*pdwLocation)
  908. {
  909. default:
  910. TransAssert((FALSE));
  911. break;
  912. case LOC_NAMESPACE:
  913. hr = _CProtMgrNameSpace.FindFirstCF(pszProt, ppUnk, pclsid);
  914. if (hr == NOERROR)
  915. {
  916. break;
  917. }
  918. *pdwLocation = LOC_INTERNAL;
  919. case LOC_INTERNAL:
  920. hr = FindInternalCF(pszProt, ppUnk, pclsid, pdwLocation);
  921. if (hr == NOERROR)
  922. {
  923. break;
  924. }
  925. *pdwLocation = LOC_EXTERNAL;
  926. case LOC_EXTERNAL:
  927. hr = _CProtMgr.FindFirstCF(pszProt, ppUnk, pclsid);
  928. break;
  929. }
  930. End:
  931. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::FindFirstCF (hr:%lx)", hr);
  932. DEBUG_LEAVE(hr);
  933. return hr;
  934. }
  935. //+---------------------------------------------------------------------------
  936. //
  937. // Method: COInetSession::FindNextCF
  938. //
  939. // Synopsis:
  940. //
  941. // Arguments: [pszProt] --
  942. // [ppUnk] --
  943. // [pclsid] --
  944. //
  945. // Returns:
  946. //
  947. // History: 11-15-1996 JohannP (Johann Posch) Created
  948. //
  949. // Notes:
  950. //
  951. //----------------------------------------------------------------------------
  952. STDMETHODIMP COInetSession::FindNextCF(LPCWSTR pszProt, IClassFactory **ppUnk, CLSID *pclsid, DWORD* pdwLocation)
  953. {
  954. DEBUG_ENTER((DBG_TRANS,
  955. Hresult,
  956. "COInetSession::FindNextCF",
  957. "this=%#x, %.80wq, %#x, %#x, %#x",
  958. this, pszProt, ppUnk, pclsid, pdwLocation
  959. ));
  960. PerfDbgLog(tagCOInetSession, this, "+COInetSession::FindNextCF");
  961. HRESULT hr = INET_E_UNKNOWN_PROTOCOL;
  962. TransAssert(pdwLocation);
  963. switch (*pdwLocation)
  964. {
  965. default:
  966. TransAssert((FALSE));
  967. break;
  968. case LOC_NAMESPACE:
  969. hr = _CProtMgrNameSpace.FindNextCF(pszProt, ppUnk, pclsid);
  970. if (hr == NOERROR)
  971. {
  972. break;
  973. }
  974. *pdwLocation = LOC_INTERNAL;
  975. case LOC_INTERNAL:
  976. hr = FindInternalCF(pszProt, ppUnk, pclsid, pdwLocation);
  977. if (hr != NOERROR)
  978. {
  979. hr = _CProtMgr.FindFirstCF(pszProt, ppUnk, pclsid);
  980. }
  981. *pdwLocation = LOC_EXTERNAL;
  982. break;
  983. case LOC_EXTERNAL:
  984. // valid case - just return INET_E_UNKNOWN_PROTOCOL
  985. break;
  986. }
  987. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::FindNextCF (hr:%lx)", hr);
  988. DEBUG_LEAVE(hr);
  989. return hr;
  990. }
  991. //+---------------------------------------------------------------------------
  992. //
  993. // Method: COInetSession::FindInternalCF
  994. //
  995. // Synopsis:
  996. //
  997. // Arguments: [pszProt] --
  998. // [ppUnk] --
  999. // [pclsid] --
  1000. //
  1001. // Returns:
  1002. //
  1003. // History: 11-15-1996 JohannP (Johann Posch) Created
  1004. //
  1005. // Notes:
  1006. //
  1007. //----------------------------------------------------------------------------
  1008. STDMETHODIMP COInetSession::FindInternalCF(LPCWSTR pszProt, IClassFactory **ppUnk, CLSID *pclsid, DWORD* pdwLocation)
  1009. {
  1010. DEBUG_ENTER((DBG_TRANS,
  1011. Hresult,
  1012. "COInetSession::FindInternalCF",
  1013. "this=%#x, %.80wq, %#x, %#x, %#x",
  1014. this, pszProt, ppUnk, pclsid, pdwLocation
  1015. ));
  1016. PerfDbgLog(tagCOInetSession, this, "+COInetSession::FindInternalCF");
  1017. HRESULT hr = INET_E_UNKNOWN_PROTOCOL;
  1018. TransAssert(pdwLocation && (*pdwLocation == LOC_INTERNAL));
  1019. DWORD dwProtoId;
  1020. if ((dwProtoId = IsKnownProtocol(pszProt)) != DLD_PROTOCOL_NONE)
  1021. {
  1022. *pclsid = *GetKnownOInetProtocolClsID(dwProtoId);
  1023. IClassFactory *pCF = NULL;
  1024. if (_ProtMap[dwProtoId].pCF != 0)
  1025. {
  1026. pCF = _ProtMap[dwProtoId].pCF;
  1027. }
  1028. else
  1029. {
  1030. pCF = (IClassFactory *) new CUrlClsFact(*pclsid, dwProtoId);
  1031. if (pCF)
  1032. {
  1033. _ProtMap[dwProtoId].pCF = pCF;
  1034. }
  1035. }
  1036. if (pCF)
  1037. {
  1038. *ppUnk = pCF;
  1039. pCF->AddRef();
  1040. hr = NOERROR;
  1041. }
  1042. }
  1043. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::FindInternalCF (hr:%lx)", hr);
  1044. DEBUG_LEAVE(hr);
  1045. return hr;
  1046. }
  1047. //+---------------------------------------------------------------------------
  1048. //
  1049. // Method: COInetSession::CreateFirstProtocol
  1050. //
  1051. // Synopsis:
  1052. //
  1053. // Arguments: [pwzUrl] --
  1054. // [pUnkOuter] --
  1055. // [ppUnk] --
  1056. // [ppProt] --
  1057. // [pclsid] --
  1058. //
  1059. // Returns:
  1060. //
  1061. // History: 11-15-1996 JohannP (Johann Posch) Created
  1062. //
  1063. // Notes:
  1064. //
  1065. //----------------------------------------------------------------------------
  1066. STDMETHODIMP COInetSession::CreateFirstProtocol(LPCWSTR pwzUrl, IUnknown *pUnkOuter, IUnknown **ppUnk,
  1067. IOInetProtocol **ppProt, CLSID *pclsid, DWORD* pdwLocation, DWORD dwOpt)
  1068. {
  1069. DEBUG_ENTER((DBG_TRANS,
  1070. Hresult,
  1071. "COInetSession::CreateFirstProtocol",
  1072. "this=%#x, %.80wq, %#x, %#x, %#x, %#x, %#x, %#x",
  1073. this, pwzUrl, pUnkOuter, ppUnk, ppProt, pclsid, pdwLocation, dwOpt
  1074. ));
  1075. PerfDbgLog2(tagCOInetSession, this, "+COInetSession::CreateFirstProtocol (szUrlL:%ws, pUnkOuter:%lx)", pwzUrl, pUnkOuter);
  1076. HRESULT hr = INET_E_UNKNOWN_PROTOCOL;
  1077. IClassFactory *pCF = 0;
  1078. TransAssert((pwzUrl && ppProt && pclsid));
  1079. TransAssert (( (pUnkOuter && ppUnk) || (!pUnkOuter && !ppUnk) ));
  1080. TransAssert(pdwLocation);
  1081. *pclsid = CLSID_NULL;
  1082. // check if protocol part
  1083. WCHAR wzProt[ULPROTOCOLLEN];
  1084. wcsncpy(wzProt, pwzUrl, ULPROTOCOLLEN);
  1085. wzProt[ULPROTOCOLLEN-1] = 0;
  1086. LPWSTR pwzProt = wcschr(wzProt, ':');
  1087. do
  1088. {
  1089. if (!pwzProt)
  1090. {
  1091. break;
  1092. }
  1093. *pwzProt = 0;
  1094. if (dwOpt & BINDF_PREFERDEFAULTHANDLER)
  1095. {
  1096. DWORD tempLocation = *pdwLocation;
  1097. *pdwLocation = LOC_INTERNAL;
  1098. hr = FindInternalCF(wzProt, &pCF, pclsid, pdwLocation);
  1099. if (NOERROR != hr)
  1100. {
  1101. *pdwLocation = tempLocation;
  1102. dwOpt &= ~BINDF_PREFERDEFAULTHANDLER;
  1103. hr = FindFirstCF(wzProt, &pCF, pclsid, pdwLocation, dwOpt);
  1104. }
  1105. }
  1106. else
  1107. hr = FindFirstCF(wzProt, &pCF, pclsid, pdwLocation, dwOpt);
  1108. if (NOERROR == hr)
  1109. {
  1110. TransAssert((pCF));
  1111. if (pUnkOuter)
  1112. {
  1113. TransAssert((ppUnk));
  1114. hr = pCF->CreateInstance(pUnkOuter, IID_IUnknown, (void **)ppUnk);
  1115. if (hr == NOERROR)
  1116. {
  1117. TransAssert((*ppUnk));
  1118. hr = (*ppUnk)->QueryInterface(IID_IOInetProtocol, (void **) ppProt);
  1119. }
  1120. }
  1121. // create an instance without aggregation
  1122. if (!pUnkOuter || (hr == CLASS_E_NOAGGREGATION))
  1123. {
  1124. if( dwOpt == 1)
  1125. {
  1126. hr = pCF->CreateInstance(NULL, IID_IOInetProtocolRoot, (void **)ppProt);
  1127. }
  1128. else
  1129. {
  1130. hr = pCF->CreateInstance(NULL, IID_IOInetProtocol, (void **)ppProt);
  1131. }
  1132. }
  1133. pCF->Release();
  1134. }
  1135. else
  1136. {
  1137. // look up the registry
  1138. hr = MK_E_SYNTAX;
  1139. }
  1140. break;
  1141. }
  1142. while (TRUE);
  1143. if (hr != NOERROR)
  1144. {
  1145. *ppProt = 0;
  1146. }
  1147. TransAssert(( (hr == NOERROR && *pclsid != CLSID_NULL)
  1148. || (hr != NOERROR) ));
  1149. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::CreateFirstProtocol(hr:%lx)", hr);
  1150. DEBUG_LEAVE(hr);
  1151. return hr;
  1152. }
  1153. //+---------------------------------------------------------------------------
  1154. //
  1155. // Method: COInetSession::CreateNextProtocol
  1156. //
  1157. // Synopsis:
  1158. //
  1159. // Arguments: [pwzUrl] --
  1160. // [pUnkOuter] --
  1161. // [ppUnk] --
  1162. // [ppProt] --
  1163. // [pclsid] --
  1164. //
  1165. // Returns:
  1166. //
  1167. // History: 11-15-1996 JohannP (Johann Posch) Created
  1168. //
  1169. // Notes:
  1170. //
  1171. //----------------------------------------------------------------------------
  1172. STDMETHODIMP COInetSession::CreateNextProtocol(LPCWSTR pwzUrl, IUnknown *pUnkOuter, IUnknown **ppUnk,
  1173. IOInetProtocol **ppProt, CLSID *pclsid, DWORD* pdwLocation)
  1174. {
  1175. DEBUG_ENTER((DBG_TRANS,
  1176. Hresult,
  1177. "COInetSession::CreateNextProtocol",
  1178. "this=%#x, %.80wq, %#x, %#x, %#x, %#x, %#x",
  1179. this, pwzUrl, pUnkOuter, ppUnk, ppProt, pclsid, pdwLocation
  1180. ));
  1181. PerfDbgLog2(tagCOInetSession, this, "+COInetSession::CreateNextProtocol (szUrlL:%ws, pUnkOuter:%lx)", pwzUrl?pwzUrl:L"", pUnkOuter);
  1182. HRESULT hr = INET_E_UNKNOWN_PROTOCOL;
  1183. IClassFactory *pCF = 0;
  1184. TransAssert((pwzUrl && ppProt && pclsid));
  1185. TransAssert (( (pUnkOuter && ppUnk) || (!pUnkOuter && !ppUnk) ));
  1186. TransAssert(pdwLocation);
  1187. *pclsid = CLSID_NULL;
  1188. if ( (hr = FindNextCF(pwzUrl, &pCF, pclsid, pdwLocation)) == NOERROR )
  1189. {
  1190. TransAssert((pCF));
  1191. if (pUnkOuter)
  1192. {
  1193. TransAssert((ppUnk));
  1194. hr = pCF->CreateInstance(pUnkOuter, IID_IUnknown, (void **)ppUnk);
  1195. if (hr == NOERROR)
  1196. {
  1197. TransAssert((*ppUnk));
  1198. hr = (*ppUnk)->QueryInterface(IID_IOInetProtocol, (void **) ppProt);
  1199. }
  1200. }
  1201. // create an instance without aggregation
  1202. if (!pUnkOuter || (hr == CLASS_E_NOAGGREGATION))
  1203. {
  1204. hr = pCF->CreateInstance(NULL, IID_IOInetProtocol, (void **)ppProt);
  1205. }
  1206. pCF->Release();
  1207. }
  1208. else
  1209. {
  1210. // look up the registry
  1211. hr = MK_E_SYNTAX;
  1212. }
  1213. if (hr != NOERROR)
  1214. {
  1215. *ppProt = 0;
  1216. }
  1217. TransAssert(( (hr == NOERROR && *pclsid != CLSID_NULL)
  1218. || (hr != NOERROR) ));
  1219. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::CreateNextProtocol(hr:%lx)", hr);
  1220. DEBUG_LEAVE(hr);
  1221. return hr;
  1222. }
  1223. //+---------------------------------------------------------------------------
  1224. //
  1225. // Method: COInetSession::CreateHandler
  1226. //
  1227. // Synopsis:
  1228. //
  1229. // Arguments: [pwzUrl] --
  1230. // [pUnkOuter] --
  1231. // [ppUnk] --
  1232. // [ppProt] --
  1233. // [pclsid] --
  1234. //
  1235. // Returns:
  1236. //
  1237. // History: 11-15-1996 JohannP (Johann Posch) Created
  1238. //
  1239. // Notes:
  1240. //
  1241. //----------------------------------------------------------------------------
  1242. STDMETHODIMP COInetSession::CreateHandler(LPCWSTR pwzUrl, IUnknown *pUnkOuter, IUnknown **ppUnk,
  1243. IOInetProtocol **ppProt, CLSID *pclsid)
  1244. {
  1245. DEBUG_ENTER((DBG_TRANS,
  1246. Hresult,
  1247. "COInetSession::CreateHandler",
  1248. "this=%#x, %.80wq, %#x, %#x, %#x, %#x",
  1249. this, pwzUrl, pUnkOuter, ppUnk, ppProt, pclsid
  1250. ));
  1251. PerfDbgLog2(tagCOInetSession, this, "+COInetSession::CreateHandler (szUrlL:%ws, pUnkOuter:%lx)", pwzUrl?pwzUrl:L"", pUnkOuter);
  1252. HRESULT hr = INET_E_UNKNOWN_PROTOCOL;
  1253. IClassFactory *pCF = 0;
  1254. TransAssert((pwzUrl && ppProt && pclsid));
  1255. TransAssert (( (pUnkOuter && ppUnk) || (!pUnkOuter && !ppUnk) ));
  1256. *pclsid = CLSID_NULL;
  1257. if ( (hr = _CProtMgrMimeFilter.FindFirstCF(pwzUrl, &pCF, pclsid)) == NOERROR )
  1258. {
  1259. TransAssert((pCF));
  1260. if (pUnkOuter)
  1261. {
  1262. hr = pCF->CreateInstance(pUnkOuter, IID_IUnknown, (void **)ppUnk);
  1263. if (hr == NOERROR)
  1264. {
  1265. TransAssert((*ppUnk));
  1266. hr = (*ppUnk)->QueryInterface(IID_IOInetProtocol, (void **) ppProt);
  1267. }
  1268. }
  1269. // create an instance without aggregation
  1270. if (!pUnkOuter || (hr == CLASS_E_NOAGGREGATION))
  1271. {
  1272. hr = pCF->CreateInstance(NULL, IID_IOInetProtocol, (void **)ppProt);
  1273. }
  1274. pCF->Release();
  1275. }
  1276. else
  1277. {
  1278. // look up the registry
  1279. hr = MK_E_SYNTAX;
  1280. }
  1281. TransAssert(( (hr == NOERROR && *pclsid != CLSID_NULL)
  1282. || (hr != NOERROR) ));
  1283. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::CreateHandler(hr:%lx)", hr);
  1284. DEBUG_LEAVE(hr);
  1285. return hr;
  1286. }
  1287. //+---------------------------------------------------------------------------
  1288. //
  1289. // Method: COInetSession::FindOInetProtocolClsID
  1290. //
  1291. // Synopsis:
  1292. //
  1293. // Arguments: [pwzUrl] --
  1294. // [pclsid] --
  1295. //
  1296. // Returns:
  1297. //
  1298. // History: 11-20-1996 JohannP (Johann Posch) Created
  1299. //
  1300. // Notes:
  1301. //
  1302. //----------------------------------------------------------------------------
  1303. STDMETHODIMP COInetSession::FindOInetProtocolClsID(LPCWSTR pwzUrl, CLSID *pclsid)
  1304. {
  1305. DEBUG_ENTER((DBG_TRANS,
  1306. Hresult,
  1307. "COInetSession::FindOInetProtocolClsID",
  1308. "this=%#x, %.80wq, %#x",
  1309. this, pwzUrl, pclsid
  1310. ));
  1311. PerfDbgLog1(tagCOInetSession, this, "+COInetSession::FindOInetProtocolClsID (pwzUrl:%ws)", pwzUrl?pwzUrl:L"");
  1312. HRESULT hr = INET_E_UNKNOWN_PROTOCOL;
  1313. DWORD dwProtId = IsKnownProtocol(pwzUrl);
  1314. DWORD dwLocation = 0;
  1315. if (dwProtId != DLD_PROTOCOL_NONE)
  1316. {
  1317. *pclsid = *GetKnownOInetProtocolClsID(dwProtId);
  1318. hr = NOERROR;
  1319. }
  1320. else
  1321. {
  1322. // try to find the first protocol
  1323. {
  1324. IClassFactory *pCF = 0;
  1325. // check if protocol part
  1326. WCHAR wzProt[ULPROTOCOLLEN];
  1327. wcsncpy(wzProt, pwzUrl, ULPROTOCOLLEN);
  1328. wzProt[ULPROTOCOLLEN-1] = 0;
  1329. LPWSTR pwzProt = wcschr(wzProt, ':');
  1330. if (pwzProt)
  1331. {
  1332. *pwzProt = 0;
  1333. hr = FindFirstCF(wzProt, &pCF, pclsid, &dwLocation);
  1334. }
  1335. if (pCF)
  1336. {
  1337. pCF->Release();
  1338. }
  1339. }
  1340. // lookup the registry
  1341. if (hr != NOERROR)
  1342. {
  1343. hr = _CProtMgr.LookupClsIDFromReg(pwzUrl, pclsid);
  1344. }
  1345. }
  1346. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::FindOInetProtocolClsID(hr:%lx)", hr);
  1347. DEBUG_LEAVE(hr);
  1348. return hr;
  1349. }
  1350. //+---------------------------------------------------------------------------
  1351. //
  1352. // Function: IsOInetProtocol
  1353. //
  1354. // Synopsis:
  1355. //
  1356. // Arguments: [pwzUrl] --
  1357. //
  1358. // Returns:
  1359. //
  1360. // History: 11-11-1996 JohannP (Johann Posch) Created
  1361. //
  1362. // Notes:
  1363. //
  1364. //----------------------------------------------------------------------------
  1365. BOOL IsOInetProtocol(IBindCtx *pbc, LPCWSTR pwzUrl)
  1366. {
  1367. DEBUG_ENTER((DBG_TRANS,
  1368. Bool,
  1369. "IsOInetProtocol",
  1370. "%#x, %.80wq",
  1371. pbc, pwzUrl
  1372. ));
  1373. PerfDbgLog1(tagCOInetSession, NULL, "+IOInetProtocol (pwzUrl:%ws)", pwzUrl?pwzUrl:L"");
  1374. BOOL fRet = FALSE;
  1375. CLSID clsid;
  1376. COInetSession *pCOInetSession = 0;
  1377. HRESULT hr;
  1378. // check if a BSC is registerted if not register our own one - for Office!
  1379. IUnknown *pUnk = NULL;
  1380. hr = GetObjectParam(pbc, REG_BSCB_HOLDER, IID_IBindStatusCallback, (IUnknown**)&pUnk);
  1381. if (SUCCEEDED(hr))
  1382. {
  1383. TransAssert((pUnk));
  1384. IServiceProvider *pServiceProv = 0;
  1385. hr = pUnk->QueryInterface(IID_IServiceProvider,(void **) &pServiceProv);
  1386. if (SUCCEEDED(hr))
  1387. {
  1388. TransAssert((pServiceProv));
  1389. IOInetProtocol *pIOInetProt = 0;
  1390. hr = pServiceProv->QueryService(IID_IOInetProtocol, IID_IOInetProtocol, (void **) &pIOInetProt);
  1391. if (SUCCEEDED(hr) && pIOInetProt)
  1392. {
  1393. // always check for a valid out pointer - some service provider return
  1394. // S_OK and null for the out parameter
  1395. pIOInetProt->Release();
  1396. fRet = TRUE;
  1397. }
  1398. pServiceProv->Release();
  1399. }
  1400. pUnk->Release();
  1401. }
  1402. if ( (fRet == FALSE)
  1403. && ((GetCOInetSession(0,&pCOInetSession,0)) == NOERROR))
  1404. {
  1405. if (pCOInetSession->FindOInetProtocolClsID(pwzUrl, &clsid) == NOERROR)
  1406. {
  1407. fRet = TRUE;
  1408. }
  1409. pCOInetSession->Release();
  1410. }
  1411. PerfDbgLog1(tagCOInetSession, NULL, "-IsOInetProtocol (fRet:%ld)", fRet);
  1412. DEBUG_LEAVE(fRet);
  1413. return fRet;
  1414. }
  1415. //+---------------------------------------------------------------------------
  1416. //
  1417. // Method: COInetSession::CreateProtocolInfo
  1418. //
  1419. // Synopsis:
  1420. //
  1421. // Arguments: [pwzUrl] --
  1422. // [ppProtInfo] --
  1423. //
  1424. // Returns:
  1425. //
  1426. // History: 04-20-1997 JohannP (Johann Posch) Created
  1427. //
  1428. // Notes:
  1429. //
  1430. //----------------------------------------------------------------------------
  1431. STDMETHODIMP COInetSession::CreateProtocolInfo(LPCWSTR pwzUrl, IOInetProtocolInfo **ppProtInfo)
  1432. {
  1433. DEBUG_ENTER((DBG_TRANS,
  1434. Hresult,
  1435. "COInetSession::CreateProtocolInfo",
  1436. "this=%#x, %.80wq, %#x",
  1437. this, pwzUrl, ppProtInfo
  1438. ));
  1439. PerfDbgLog1(tagCOInetSession, this, "+COInetSession::CreateProtocolInfo (szUrlL:%ws)", pwzUrl);
  1440. HRESULT hr = INET_E_UNKNOWN_PROTOCOL;
  1441. IClassFactory *pCF = 0;
  1442. CLSID clsid;
  1443. TransAssert((pwzUrl && ppProtInfo));
  1444. DWORD dwLocation = 0;
  1445. // check if protocol part
  1446. WCHAR wzProt[ULPROTOCOLLEN];
  1447. wcsncpy(wzProt, pwzUrl, ULPROTOCOLLEN);
  1448. wzProt[ULPROTOCOLLEN-1] = 0;
  1449. LPWSTR pwzProt = wcschr(wzProt, ':');
  1450. do
  1451. {
  1452. if (!pwzProt)
  1453. {
  1454. break;
  1455. }
  1456. *pwzProt = 0;
  1457. if ( (hr = FindFirstCF(wzProt, &pCF, &clsid, &dwLocation)) == NOERROR )
  1458. {
  1459. TransAssert((pCF));
  1460. hr = pCF->QueryInterface(IID_IOInetProtocolInfo, (void **)ppProtInfo);
  1461. if (hr != NOERROR)
  1462. {
  1463. hr = pCF->CreateInstance(NULL, IID_IOInetProtocolInfo, (void **)ppProtInfo);
  1464. }
  1465. pCF->Release();
  1466. }
  1467. else
  1468. {
  1469. // look up the registry
  1470. hr = MK_E_SYNTAX;
  1471. }
  1472. if (hr != NOERROR)
  1473. {
  1474. *ppProtInfo = 0;
  1475. }
  1476. break;
  1477. } while (TRUE);
  1478. TransAssert(( (hr == NOERROR && clsid != CLSID_NULL)
  1479. || (hr != NOERROR) ));
  1480. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::CreateProtocolInfo(hr:%lx)", hr);
  1481. DEBUG_LEAVE(hr);
  1482. return hr;
  1483. }
  1484. //+---------------------------------------------------------------------------
  1485. //
  1486. // Method: COInetSession::CreateSecurityMgr
  1487. //
  1488. // Synopsis:
  1489. //
  1490. // Arguments: [pwzUrl] --
  1491. // [ppSecMgr] --
  1492. //
  1493. // Returns:
  1494. //
  1495. // History: 4-28-1997 JohannP (Johann Posch) Created
  1496. //
  1497. // Notes:
  1498. //
  1499. //----------------------------------------------------------------------------
  1500. STDMETHODIMP COInetSession::CreateSecurityMgr(LPCWSTR pwzUrl, IInternetSecurityManager **ppSecMgr)
  1501. {
  1502. DEBUG_ENTER((DBG_TRANS,
  1503. Hresult,
  1504. "COInetSession::CreateSecurityMgr",
  1505. "this=%#x, %.80wq, %#x",
  1506. this, pwzUrl, ppSecMgr
  1507. ));
  1508. PerfDbgLog1(tagCOInetSession, this, "+COInetSession::CreateSecurityMgr (szUrlL:%ws)", pwzUrl);
  1509. HRESULT hr = INET_E_UNKNOWN_PROTOCOL;
  1510. IClassFactory *pCF = 0;
  1511. CLSID clsid;
  1512. TransAssert((pwzUrl && ppSecMgr));
  1513. DWORD dwLocation = 0;
  1514. // check if protocol part
  1515. WCHAR wzProt[ULPROTOCOLLEN];
  1516. wcsncpy(wzProt, pwzUrl, ULPROTOCOLLEN);
  1517. wzProt[ULPROTOCOLLEN-1] = 0;
  1518. LPWSTR pwzProt = wcschr(wzProt, ':');
  1519. do
  1520. {
  1521. if (!pwzProt)
  1522. {
  1523. break;
  1524. }
  1525. *pwzProt = 0;
  1526. if ( (hr = FindFirstCF(wzProt, &pCF, &clsid, &dwLocation)) == NOERROR )
  1527. {
  1528. TransAssert((pCF));
  1529. hr = pCF->CreateInstance(NULL, IID_IInternetSecurityManager, (void **)ppSecMgr);
  1530. pCF->Release();
  1531. }
  1532. else
  1533. {
  1534. // look up the registry
  1535. hr = MK_E_SYNTAX;
  1536. }
  1537. if (hr != NOERROR)
  1538. {
  1539. *ppSecMgr = 0;
  1540. }
  1541. break;
  1542. } while (TRUE);
  1543. TransAssert(( (hr == NOERROR && clsid != CLSID_NULL)
  1544. || (hr != NOERROR) ));
  1545. PerfDbgLog1(tagCOInetSession, this, "-COInetSession::CreateSecurityMgr(hr:%lx)", hr);
  1546. DEBUG_LEAVE(hr);
  1547. return hr;
  1548. }
  1549. BOOL CanUseSimpleBinding()
  1550. {
  1551. DEBUG_ENTER((DBG_TRANS,
  1552. Bool,
  1553. "CanUseSimpleBinding",
  1554. NULL
  1555. ));
  1556. HKEY hNSRoot;
  1557. if( RegOpenKey(HKEY_CLASSES_ROOT, SZNAMESPACEROOT, &hNSRoot)
  1558. == ERROR_SUCCESS)
  1559. {
  1560. DWORD dwIndex = 0;
  1561. char szName[256];
  1562. LONG ret = ERROR_SUCCESS;
  1563. while(1)
  1564. {
  1565. szName[0] = '\0';
  1566. ret = RegEnumKey(hNSRoot, dwIndex, szName, 256);
  1567. if( ret == ERROR_SUCCESS )
  1568. {
  1569. if( !StrCmpNI(szName, "http", strlen("http") )
  1570. || !StrCmpNI(szName, "ftp", strlen("ftp") )
  1571. || !StrCmpNI(szName, "gopher", strlen("gopher") )
  1572. || !StrCmpNI(szName, "https", strlen("https") )
  1573. || !StrCmpNI(szName, "file", strlen("file") )
  1574. )
  1575. {
  1576. RegCloseKey(hNSRoot);
  1577. DEBUG_LEAVE(FALSE);
  1578. return FALSE;
  1579. }
  1580. dwIndex ++;
  1581. }
  1582. else
  1583. {
  1584. RegCloseKey(hNSRoot);
  1585. DEBUG_LEAVE(TRUE);
  1586. return TRUE;
  1587. }
  1588. }
  1589. }
  1590. DEBUG_LEAVE(TRUE);
  1591. return TRUE;
  1592. }
  1593. VOID
  1594. COInetSession::UpdateTransLevelHandlerCount(BOOL bAttach)
  1595. {
  1596. DEBUG_ENTER((DBG_TRANS,
  1597. None,
  1598. "COInetSession::UpdateTransLevelHandlerCount",
  1599. "this=%#x, %B",
  1600. this, bAttach
  1601. ));
  1602. CLock lck(g_mxsOInet);
  1603. if( bAttach )
  1604. {
  1605. g_cTransLevelHandler++;
  1606. }
  1607. else
  1608. {
  1609. g_cTransLevelHandler--;
  1610. if( g_cTransLevelHandler < 0 )
  1611. g_cTransLevelHandler = 0;
  1612. }
  1613. DEBUG_LEAVE(0);
  1614. }