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.

973 lines
26 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: protmgr.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 10-29-1996 JohannP (Johann Posch) Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <trans.h>
  18. #include <shlwapip.h>
  19. #include "oinet.hxx"
  20. PerfDbgTag(tagCProtMgr, "Urlmon", "Log CProtMgr", DEB_PROT);
  21. //+---------------------------------------------------------------------------
  22. //
  23. // Method: CProtMgr::Register
  24. //
  25. // Synopsis:
  26. //
  27. // Arguments: [LPOLESTR] --
  28. // [ULONG] --
  29. // [cProtocols] --
  30. //
  31. // Returns:
  32. //
  33. // History: 10-29-1996 JohannP (Johann Posch) Created
  34. //
  35. // Notes:
  36. //
  37. //----------------------------------------------------------------------------
  38. STDMETHODIMP CProtMgr::Register(IClassFactory *pCF, REFCLSID rclsid, LPCWSTR pszProtocol,
  39. ULONG cPatterns, const LPCWSTR *ppwzPatterns, DWORD dwReserved)
  40. {
  41. DEBUG_ENTER((DBG_TRANS,
  42. Hresult,
  43. "CProtMgr::Register",
  44. "this=%#x, %#x, %#x, %.80wq, %#x, %#x, %#x",
  45. this, pCF, &rclsid, pszProtocol, cPatterns, ppwzPatterns, dwReserved
  46. ));
  47. PerfDbgLog(tagCProtMgr, this, "+CProtMgr::Register");
  48. HRESULT hr = NOERROR;
  49. TransAssert((pCF && pszProtocol));
  50. CLock lck(_mxs);
  51. if (pCF && pszProtocol)
  52. {
  53. char szStr[ULPROTOCOLLEN];
  54. W2A(pszProtocol, szStr, ULPROTOCOLLEN);
  55. ATOM atom = AddAtom(szStr);
  56. CNodeData *pNodeIns = new CNodeData(atom, pCF, rclsid);
  57. if (pNodeIns)
  58. {
  59. if (_cElements < 0)
  60. {
  61. _cElements = 0;
  62. }
  63. pNodeIns->_pNextNode = _pNextNode;
  64. _pNextNode = pNodeIns;
  65. _cElements++;
  66. }
  67. }
  68. else
  69. {
  70. hr = E_INVALIDARG;
  71. }
  72. PerfDbgLog1(tagCProtMgr, this, "-CProtMgr::Register (hr:%lx)", hr);
  73. DEBUG_LEAVE(hr);
  74. return hr;
  75. }
  76. //+---------------------------------------------------------------------------
  77. //
  78. // Method: CProtMgr::Unregister
  79. //
  80. // Synopsis:
  81. //
  82. // Arguments: [pUnk] --
  83. //
  84. // Returns:
  85. //
  86. // History: 10-29-1996 JohannP (Johann Posch) Created
  87. //
  88. // Notes:
  89. //
  90. //----------------------------------------------------------------------------
  91. STDMETHODIMP CProtMgr::Unregister(IClassFactory *pCF, LPCWSTR pszProtocol)
  92. {
  93. DEBUG_ENTER((DBG_TRANS,
  94. Hresult,
  95. "CProtMgr::Unregister",
  96. "this=%#x, %#x, %.80wq",
  97. this, pCF, pszProtocol
  98. ));
  99. PerfDbgLog(tagCProtMgr, this, "+CProtMgr::Unregister");
  100. HRESULT hr = NOERROR;
  101. TransAssert((pCF && pszProtocol));
  102. CLock lck(_mxs);
  103. if (pCF && pszProtocol)
  104. {
  105. char szStr[ULPROTOCOLLEN];
  106. W2A(pszProtocol, szStr, ULPROTOCOLLEN);
  107. ATOM atom = AddAtom(szStr);
  108. CNodeData *pNode = _pNextNode;
  109. CNodeData *pPrevNode = NULL;
  110. while (pNode)
  111. {
  112. if (pNode->_pCFProt == pCF && pNode->_atom == atom)
  113. {
  114. // found the node
  115. if (pPrevNode)
  116. {
  117. pPrevNode->_pNextNode = pNode->_pNextNode;
  118. }
  119. else
  120. {
  121. // remove first node
  122. _pNextNode = pNode->_pNextNode;
  123. pPrevNode = pNode->_pNextNode;
  124. }
  125. _cElements--;
  126. delete pNode;
  127. pNode = NULL;
  128. }
  129. else
  130. {
  131. pPrevNode = pNode;
  132. pNode = pNode->_pNextNode;
  133. }
  134. }
  135. //no previous node - the first
  136. if (pPrevNode == NULL)
  137. {
  138. _pNextNode = 0;
  139. }
  140. }
  141. else
  142. {
  143. hr = E_INVALIDARG;
  144. }
  145. PerfDbgLog1(tagCProtMgr, this, "-CProtMgr::Unregister (hr:%lx)", hr);
  146. DEBUG_LEAVE(hr);
  147. return hr;
  148. }
  149. DWORD IsKnownHandler(LPCWSTR wzHandler);
  150. CLSID *GetKnownHandlerClsID(DWORD dwID);
  151. //+---------------------------------------------------------------------------
  152. //
  153. // Method: CProtMgr::FindFirstCF
  154. //
  155. // Synopsis:
  156. //
  157. // Arguments: [pszProt] --
  158. // [ppUnk] --
  159. // [pclsid] --
  160. //
  161. // Returns:
  162. //
  163. // History: 11-16-1996 JohannP (Johann Posch) Created
  164. //
  165. // Notes:
  166. //
  167. //----------------------------------------------------------------------------
  168. STDMETHODIMP CProtMgr::FindFirstCF(LPCWSTR pszProt, IClassFactory **ppUnk, CLSID *pclsid)
  169. {
  170. DEBUG_ENTER((DBG_TRANS,
  171. Hresult,
  172. "CProtMgr::FindFirstCF",
  173. "this=%#x, %.80wq, %#x, %#x",
  174. this, pszProt, ppUnk, pclsid
  175. ));
  176. PerfDbgLog(tagCProtMgr, this, "+CProtMgr::FindFirstCF");
  177. HRESULT hr = INET_E_UNKNOWN_PROTOCOL;
  178. CNodeData *pNode;
  179. DWORD dwEl = 1;
  180. BOOL fIsKnownHandler = FALSE;
  181. HRESULT hrGetClsId = NOERROR;
  182. CLock lck(_mxs);
  183. _pPosNode = 0;
  184. if (_cElements < 0)
  185. {
  186. _cElements = 0;
  187. }
  188. else if (_cElements > 0)
  189. {
  190. char szStr[ULPROTOCOLLEN];
  191. W2A(pszProt, szStr, ULPROTOCOLLEN);
  192. ATOM atom = FindAtom(szStr);
  193. if (atom)
  194. {
  195. pNode = _pNextNode;
  196. while (pNode && pNode->_atom != atom)
  197. {
  198. pNode = pNode->_pNextNode;
  199. }
  200. if (pNode)
  201. {
  202. *ppUnk = pNode->_pCFProt;
  203. if (*ppUnk)
  204. {
  205. pNode->_pCFProt->AddRef();
  206. *pclsid = pNode->_clsidProt;
  207. hr = NOERROR;
  208. }
  209. else
  210. {
  211. hr = INET_E_UNKNOWN_PROTOCOL;
  212. }
  213. }
  214. }
  215. }
  216. if( hr != NOERROR)
  217. {
  218. DWORD dwID = 0;
  219. dwID = IsKnownHandler(pszProt);
  220. if( dwID)
  221. {
  222. *pclsid = *GetKnownHandlerClsID(dwID);
  223. fIsKnownHandler = TRUE;
  224. }
  225. else
  226. {
  227. hrGetClsId = LookupClsIDFromReg(pszProt, pclsid, &dwEl);
  228. }
  229. }
  230. if ( (hr != NOERROR) && (hrGetClsId == NOERROR) )
  231. {
  232. IClassFactory *pCF = 0;
  233. hr = CoGetClassObject(*pclsid, CLSCTX_INPROC_SERVER,NULL,IID_IClassFactory, (void**)&pCF);
  234. if (hr == NOERROR)
  235. {
  236. *ppUnk = pCF;
  237. if(fIsKnownHandler)
  238. {
  239. char szStr[ULPROTOCOLLEN];
  240. W2A(pszProt, szStr, ULPROTOCOLLEN);
  241. *ppUnk = pCF;
  242. ATOM atom = AddAtom(szStr);
  243. pNode = new CNodeData(atom, pCF, *pclsid);
  244. if (pNode)
  245. {
  246. pNode->_pNextNode = _pNextNode;
  247. _pNextNode = pNode;
  248. _cElements++;
  249. }
  250. // no release of CF since it is given out
  251. }
  252. }
  253. }
  254. PerfDbgLog1(tagCProtMgr, this, "-CProtMgr::FindFirstCF (hr:%lx)", hr);
  255. DEBUG_LEAVE(hr);
  256. return hr;
  257. }
  258. //+---------------------------------------------------------------------------
  259. //
  260. // Method: CProtMgr::FindNextCF
  261. //
  262. // Synopsis:
  263. //
  264. // Arguments: [pszProt] --
  265. // [ppUnk] --
  266. // [pclsid] --
  267. //
  268. // Returns:
  269. //
  270. // History: 11-16-1996 JohannP (Johann Posch) Created
  271. //
  272. // Notes:
  273. //
  274. //----------------------------------------------------------------------------
  275. STDMETHODIMP CProtMgr::FindNextCF(LPCWSTR pszProt, IClassFactory **ppUnk, CLSID *pclsid)
  276. {
  277. DEBUG_ENTER((DBG_TRANS,
  278. Hresult,
  279. "CProtMgr::FindNextCF",
  280. "this=%#x, %.80wq, %#x, %#x",
  281. this, pszProt, ppUnk, pclsid
  282. ));
  283. PerfDbgLog(tagCProtMgr, this, "+CProtMgr::FindNextCF");
  284. HRESULT hr = INET_E_UNKNOWN_PROTOCOL;
  285. TransAssert((FALSE));
  286. PerfDbgLog1(tagCProtMgr, this, "-CProtMgr::FindNextCF (hr:%lx)", hr);
  287. DEBUG_LEAVE(hr);
  288. return hr;
  289. }
  290. //+---------------------------------------------------------------------------
  291. //
  292. // Method: CProtMgr::LookupClsIDFromReg
  293. //
  294. // Synopsis:
  295. //
  296. // Arguments: [pwzProt] --
  297. // [pclsid] --
  298. // [pcClsIds] --
  299. //
  300. // Returns:
  301. //
  302. // History: 11-20-1996 JohannP (Johann Posch) Created
  303. //
  304. // Notes:
  305. //
  306. //----------------------------------------------------------------------------
  307. STDMETHODIMP CProtMgr::LookupClsIDFromReg(LPCWSTR pwzProt, CLSID *pclsid, DWORD *pcClsIds, DWORD *pdwFlags, DWORD dwOpt)
  308. {
  309. DEBUG_ENTER((DBG_TRANS,
  310. Hresult,
  311. "CProtMgr::LookupClsIDFromReg",
  312. "this=%#x, %.80wq, %#x, %#x, %#x, %#x",
  313. this, pwzProt, pclsid, pcClsIds, pdwFlags, dwOpt
  314. ));
  315. PerfDbgLog1(tagCProtMgr, this, "+CProtMgr::LookupClsIDFromReg (pszProt:%ws)", pwzProt);
  316. HRESULT hr = INET_E_UNKNOWN_PROTOCOL;
  317. DWORD dwType;
  318. TransAssert((pwzProt && pclsid));
  319. if (pwzProt)
  320. {
  321. char pszProt[ULPROTOCOLLEN+1];
  322. W2A(pwzProt, pszProt, ULPROTOCOLLEN);
  323. pszProt[ULPROTOCOLLEN] = '\0';
  324. char szDelimiter = ':';
  325. LPSTR pszDel = StrChr(pszProt, szDelimiter);
  326. if (pszDel)
  327. {
  328. *pszDel = '\0';
  329. }
  330. DWORD dwLen = 256;
  331. char szProtocolKey[256];
  332. char szCLSID[256];
  333. strcpy(szProtocolKey, SZ_SH_PROTOCOLROOT);
  334. strcat(szProtocolKey, pszProt);
  335. char pszOptFlag[16];
  336. if(dwOpt)
  337. {
  338. wsprintf(pszOptFlag, "\\0x%08x", dwOpt);
  339. strcat(szProtocolKey, pszOptFlag);
  340. }
  341. if (SHRegGetUSValue(
  342. szProtocolKey,
  343. SZCLASS,
  344. NULL,
  345. (LPBYTE)szCLSID,
  346. &dwLen,
  347. FALSE,
  348. NULL,
  349. 0) == ERROR_SUCCESS)
  350. {
  351. hr = CLSIDFromStringA(szCLSID, pclsid);
  352. PerfDbgLog2(
  353. tagCProtMgr,
  354. this,
  355. "API FOUND LookupProtocolClsIDFromReg(hr:%lx, ClsId:%s)",
  356. hr,
  357. szCLSID);
  358. }
  359. }
  360. PerfDbgLog1(tagCProtMgr, this, "-CProtMgr::LookupClsIDFromReg (hr:%lx)", hr);
  361. DEBUG_LEAVE(hr);
  362. return hr;
  363. }
  364. //+---------------------------------------------------------------------------
  365. //
  366. // Method: CProtMgrNameSpace::ShouldLookupRegistry
  367. //
  368. // Synopsis:
  369. //
  370. // Arguments: [pszProt] --
  371. //
  372. // Returns: S_OK if registry should be looked up, S_FALSE if not. E_* if it encounters an error
  373. // of some sort.
  374. //
  375. // History: 11-16-1996 JohannP (Johann Posch) Created
  376. //
  377. // Notes:
  378. //
  379. //----------------------------------------------------------------------------
  380. STDMETHODIMP CProtMgrNameSpace::ShouldLookupRegistry(LPCWSTR pszProt)
  381. {
  382. DEBUG_ENTER((DBG_TRANS,
  383. Hresult,
  384. "CProtMgrNameSpace::ShouldLookupRegistry",
  385. "this=%#x, %.80wq",
  386. this, pszProt
  387. ));
  388. PerfDbgLog1(tagCProtMgr, this, "+CProtMgr::ShouldLookupRegistry (pszProt:%ws)", pszProt);
  389. HRESULT hr = E_FAIL;
  390. if (pszProt == NULL)
  391. {
  392. DEBUG_LEAVE(E_INVALIDARG);
  393. return E_INVALIDARG;
  394. }
  395. BOOL bFound = FALSE;
  396. for (CProtocolData *pCurrent = _pProtList ; pCurrent != NULL; pCurrent = pCurrent->GetNext())
  397. {
  398. // Found the protocol.
  399. if (0 == StrCmpICW(pszProt, pCurrent->GetProtocol()))
  400. {
  401. bFound = TRUE;
  402. break;
  403. }
  404. }
  405. if (bFound)
  406. {
  407. hr = S_FALSE;
  408. }
  409. else
  410. {
  411. // Append to list.
  412. CProtocolData *pProtNew = new CProtocolData;
  413. if (pProtNew != NULL)
  414. {
  415. if (pProtNew->Init(pszProt, _pProtList))
  416. {
  417. _pProtList = pProtNew;
  418. hr = S_OK;
  419. }
  420. else
  421. {
  422. // only way init can fail today is if we are out of memory
  423. delete pProtNew;
  424. hr = E_OUTOFMEMORY;
  425. }
  426. }
  427. else
  428. {
  429. hr = E_OUTOFMEMORY;
  430. }
  431. }
  432. PerfDbgLog1(tagCProtMgr, this, "-CProtMgr::ShouldLookupRegistry (hr:%lx)", hr);
  433. DEBUG_LEAVE(hr);
  434. return hr;
  435. }
  436. //+---------------------------------------------------------------------------
  437. //
  438. // Method: CProtMgrNameSpace::FindFirstCF
  439. //
  440. // Synopsis:
  441. //
  442. // Arguments: [pszProt] --
  443. // [ppUnk] --
  444. // [pclsid] --
  445. //
  446. // Returns:
  447. //
  448. // History: 11-16-1996 JohannP (Johann Posch) Created
  449. //
  450. // Notes:
  451. //
  452. //----------------------------------------------------------------------------
  453. STDMETHODIMP CProtMgrNameSpace::FindFirstCF(LPCWSTR pszProt, IClassFactory **ppUnk, CLSID *pclsid)
  454. {
  455. DEBUG_ENTER((DBG_TRANS,
  456. Hresult,
  457. "CProtMgrNameSpace::FindFirstCF",
  458. "this=%#x, %.80wq, %#x, %#x",
  459. this, pszProt, ppUnk, pclsid
  460. ));
  461. PerfDbgLog1(tagCProtMgr, this, "+CProtMgrNameSpace::FindFirstCF (pszProt:%ws)", pszProt);
  462. HRESULT hr = INET_E_UNKNOWN_PROTOCOL;
  463. CLock lck(_mxs);
  464. _pPosNode = 0;
  465. //
  466. // check the registered protocols first
  467. //
  468. if (_cElements > 0)
  469. {
  470. char szStr[ULPROTOCOLLEN];
  471. W2A(pszProt, szStr, ULPROTOCOLLEN);
  472. ATOM atom = FindAtom(szStr);
  473. if (atom)
  474. {
  475. _pPosNode = _pNextNode;
  476. while (_pPosNode && _pPosNode->_atom != atom)
  477. {
  478. _pPosNode = _pPosNode->_pNextNode;
  479. }
  480. }
  481. }
  482. //
  483. // look up the registry once
  484. //
  485. if ( (!_pPosNode)
  486. && (ShouldLookupRegistry(pszProt) == S_OK))
  487. {
  488. // BUG-WORK: 64 plugable namespace are max!
  489. CLSID rgclsid[64];
  490. DWORD dwEl = 64;
  491. if ((hr = LookupClsIDFromReg(pszProt, rgclsid, &dwEl)) == NOERROR)
  492. {
  493. char szStr[ULPROTOCOLLEN];
  494. W2A(pszProt, szStr, ULPROTOCOLLEN);
  495. ATOM atom = AddAtom(szStr);
  496. for (DWORD i = 0; i < dwEl; i++)
  497. {
  498. CLSID *pclsid = &rgclsid[i];
  499. CNodeData *pNodeIns = new CNodeData(atom, NULL, *pclsid);
  500. if (pNodeIns)
  501. {
  502. pNodeIns->_pNextNode = _pNextNode;
  503. _pNextNode = pNodeIns;
  504. _cElements++;
  505. }
  506. if (!_pPosNode)
  507. {
  508. _pPosNode = pNodeIns;
  509. }
  510. }
  511. }
  512. }
  513. /*
  514. else if (_cElements > 0)
  515. {
  516. char szStr[ULPROTOCOLLEN];
  517. W2A(pszProt, szStr, ULPROTOCOLLEN);
  518. ATOM atom = FindAtom(szStr);
  519. if (atom)
  520. {
  521. _pPosNode = _pNextNode;
  522. while (_pPosNode && _pPosNode->_atom != atom)
  523. {
  524. _pPosNode = _pPosNode->_pNextNode;
  525. }
  526. }
  527. }
  528. */
  529. if (_pPosNode)
  530. {
  531. *pclsid = _pPosNode->_clsidProt;
  532. if (_pPosNode->_pCFProt == NULL)
  533. {
  534. IClassFactory *pCF = 0;
  535. hr = CoGetClassObject(*pclsid, CLSCTX_INPROC_SERVER,NULL,IID_IClassFactory, (void**)&pCF);
  536. if (hr == NOERROR)
  537. {
  538. *ppUnk = pCF;//make sure we don't cache the class factory.
  539. }
  540. }
  541. else
  542. {
  543. *ppUnk = _pPosNode->_pCFProt;
  544. _pPosNode->_pCFProt->AddRef();
  545. hr = NOERROR;
  546. }
  547. //advance to the next node for further findnextcf calls
  548. _pPosNode = _pPosNode->_pNextNode;
  549. }
  550. PerfDbgLog1(tagCProtMgr, this, "-CProtMgrNameSpace::FindFirstCF (hr:%lx)", hr);
  551. DEBUG_LEAVE(hr);
  552. return hr;
  553. }
  554. //+---------------------------------------------------------------------------
  555. //
  556. // Method: CProtMgrNameSpace::FindNextCF
  557. //
  558. // Synopsis:
  559. //
  560. // Arguments: [pszProt] --
  561. // [ppUnk] --
  562. // [pclsid] --
  563. //
  564. // Returns:
  565. //
  566. // History: 11-16-1996 JohannP (Johann Posch) Created
  567. //
  568. // Notes:
  569. //
  570. //----------------------------------------------------------------------------
  571. STDMETHODIMP CProtMgrNameSpace::FindNextCF(LPCWSTR pszProt, IClassFactory **ppUnk, CLSID *pclsid)
  572. {
  573. DEBUG_ENTER((DBG_TRANS,
  574. Hresult,
  575. "CProtMgrNameSpace::FindNextCF",
  576. "this=%#x, %.80wq, %#x, %#x",
  577. this, pszProt, ppUnk, pclsid
  578. ));
  579. PerfDbgLog(tagCProtMgr, this, "+CProtMgrNameSpace::FindNextCF");
  580. HRESULT hr = INET_E_UNKNOWN_PROTOCOL;
  581. CLock lck(_mxs);
  582. if (_cElements > 0 && _pPosNode)
  583. {
  584. char szStr[ULPROTOCOLLEN];
  585. W2A(pszProt, szStr, ULPROTOCOLLEN);
  586. ATOM atom = FindAtom(szStr);
  587. if (atom)
  588. {
  589. do
  590. {
  591. // find next matching node
  592. while (_pPosNode && _pPosNode->_atom != atom)
  593. {
  594. _pPosNode = _pPosNode->_pNextNode;
  595. }
  596. if (_pPosNode)
  597. {
  598. IClassFactory *pCF = 0;
  599. *pclsid = _pPosNode->_clsidProt;
  600. if (_pPosNode->_pCFProt == NULL)
  601. {
  602. hr = CoGetClassObject(*pclsid, CLSCTX_INPROC_SERVER,NULL,IID_IClassFactory, (void**)&pCF);
  603. if (hr == NOERROR)
  604. {
  605. *ppUnk = pCF;//make sure we don't cache the class factory.
  606. }
  607. }
  608. else
  609. {
  610. *ppUnk = _pPosNode->_pCFProt;
  611. _pPosNode->_pCFProt->AddRef();
  612. hr = NOERROR;
  613. }
  614. //advance to the next node for further findnextcf calls
  615. _pPosNode = _pPosNode->_pNextNode;
  616. }
  617. } while (hr != NOERROR && _pPosNode);
  618. }
  619. }
  620. PerfDbgLog1(tagCProtMgr, this, "-CProtMgrNameSpace::FindNextCF (hr:%lx)", hr);
  621. DEBUG_LEAVE(hr);
  622. return hr;
  623. }
  624. //+---------------------------------------------------------------------------
  625. //
  626. // Method: CProtMgrNameSpace::LookupClsIDFromReg
  627. //
  628. // Synopsis:
  629. //
  630. // Arguments: [pszProt] --
  631. // [ppclsid] --
  632. // [pcClsIds] --
  633. //
  634. // Returns:
  635. //
  636. // History: 11-20-1996 JohannP (Johann Posch) Created
  637. //
  638. // Notes:
  639. //
  640. //----------------------------------------------------------------------------
  641. STDMETHODIMP CProtMgrNameSpace::LookupClsIDFromReg(LPCWSTR pwzProt, CLSID *ppclsid, DWORD *pcClsIds, DWORD *pdwFlags, DWORD dwOpt)
  642. {
  643. DEBUG_ENTER((DBG_TRANS,
  644. Hresult,
  645. "CProtMgrNameSpace::LookupClsIDFromReg",
  646. "this=%#x, %.80wq, %#x, %#x, %#x, %#x",
  647. this, pwzProt, ppclsid, pcClsIds, pdwFlags, dwOpt
  648. ));
  649. PerfDbgLog1(tagCProtMgr, this, "+CProtMgrNameSpace::LookupClsIDFromReg (pwzProt:%ws)", pwzProt);
  650. HRESULT hr = INET_E_UNKNOWN_PROTOCOL;
  651. DWORD dwType;
  652. DWORD cFound = 0;
  653. HKEY hNameSpaceKey = NULL;
  654. TransAssert((pwzProt && ppclsid));
  655. char pszProt[ULPROTOCOLLEN];
  656. W2A(pwzProt, pszProt, ULPROTOCOLLEN);
  657. char szDelimiter = ':';
  658. LPSTR pszDel = StrChr(pszProt, szDelimiter);
  659. if (pszDel)
  660. {
  661. *pszDel = '\0';
  662. }
  663. #define LENNAMEMAX 256
  664. DWORD dwLen = LENNAMEMAX;
  665. DWORD dwLenName = LENNAMEMAX;
  666. char szNameSpaceKey[LENNAMEMAX];
  667. char szName[LENNAMEMAX];
  668. strcpy(szNameSpaceKey, SZNAMESPACEROOT);
  669. LPSTR pszKey = szNameSpaceKey + strlen(szNameSpaceKey);
  670. if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szNameSpaceKey, 0, KEY_READ | KEY_QUERY_VALUE, &hNameSpaceKey) != ERROR_SUCCESS)
  671. {
  672. TransAssert((hNameSpaceKey == NULL));
  673. }
  674. if (hNameSpaceKey)
  675. {
  676. HKEY hProtKey = NULL;
  677. DWORD dwIndex = 0;
  678. DWORD dwCheck = 2;
  679. do
  680. {
  681. *pszKey = '\0';
  682. LPSTR pszKeyProt = pszKey;
  683. if (dwCheck == 2)
  684. {
  685. strcat(pszKeyProt, pszProt);
  686. }
  687. else if (dwCheck == 1)
  688. {
  689. strcat(pszKeyProt, SZALL);
  690. }
  691. else
  692. {
  693. TransAssert((FALSE));
  694. }
  695. strcat(pszKeyProt, "\\");
  696. if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szNameSpaceKey, 0, KEY_READ | KEY_QUERY_VALUE, &hProtKey) != ERROR_SUCCESS)
  697. {
  698. hProtKey = 0;
  699. }
  700. dwCheck--;
  701. if (hProtKey)
  702. {
  703. DWORD dwResult;
  704. dwLenName = LENNAMEMAX;
  705. LPSTR pszName = szNameSpaceKey + strlen(szNameSpaceKey);
  706. dwIndex = 0;
  707. // enum all sub keys
  708. while ( (dwResult = (RegEnumKeyEx(hProtKey, dwIndex, szName, &dwLenName, 0, 0, 0, 0)) == ERROR_SUCCESS)
  709. && (cFound < *pcClsIds)
  710. )
  711. {
  712. BOOL fFound = FALSE;
  713. HKEY hNameKey = NULL;
  714. *pszName = '\0';
  715. strcat(pszName, szName);
  716. // open the Name-Space Handler root + protocols
  717. if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szNameSpaceKey, 0, KEY_QUERY_VALUE, &hNameKey) == ERROR_SUCCESS)
  718. {
  719. DWORD dwLenClass = LENNAMEMAX;
  720. char szClass[LENNAMEMAX];
  721. // get the class id
  722. if (RegQueryValueEx(hNameKey, SZCLASS, NULL, &dwType, (LPBYTE)szClass, &dwLenClass) == ERROR_SUCCESS)
  723. {
  724. hr = CLSIDFromStringA(szClass, (ppclsid + cFound));
  725. if (hr == NOERROR)
  726. {
  727. cFound++;
  728. }
  729. DbgLog2(tagCProtMgr, this, "LookupNameSpaceClsIDFromReg(hr:%lx, ClsId:%s) >FOUND<", hr, szClass);
  730. }
  731. RegCloseKey(hNameKey);
  732. }
  733. dwIndex++;
  734. dwLenName = LENNAMEMAX;
  735. }
  736. RegCloseKey(hProtKey);
  737. }
  738. } while (dwCheck);
  739. RegCloseKey(hNameSpaceKey);
  740. }
  741. if (cFound)
  742. {
  743. *pcClsIds = cFound;
  744. hr = NOERROR;
  745. }
  746. PerfDbgLog1(tagCProtMgr, this, "-CProtMgrNameSpace::LookupClsIDFromReg (hr:%lx)", hr);
  747. DEBUG_LEAVE(hr);
  748. return hr;
  749. }
  750. //+---------------------------------------------------------------------------
  751. //
  752. // Method: CProtMgrMimeHandler::LookupClsIDFromReg
  753. //
  754. // Synopsis:
  755. //
  756. // Arguments: [pwzMime] --
  757. // [pclsid] --
  758. // [pcClsIds] --
  759. //
  760. // Returns:
  761. //
  762. // History: 11-20-1996 JohannP (Johann Posch) Created
  763. //
  764. // Notes:
  765. //
  766. //----------------------------------------------------------------------------
  767. STDMETHODIMP CProtMgrMimeHandler::LookupClsIDFromReg(LPCWSTR pwzMime, CLSID *pclsid, DWORD *pcClsIds, DWORD *pdwFlags, DWORD dwOpt)
  768. {
  769. DEBUG_ENTER((DBG_TRANS,
  770. Hresult,
  771. "CProtMgrNameSpace::LookupClsIDFromReg",
  772. "this=%#x, %.80wq, %#x, %#x, %#x, %#x",
  773. this, pwzMime, pclsid, pcClsIds, pdwFlags, dwOpt
  774. ));
  775. PerfDbgLog1(tagCProtMgr, this, "+CProtMgrMimeHandler::LookupClsIDFromReg (pwzMime:%ws)", pwzMime);
  776. HRESULT hr = INET_E_UNKNOWN_PROTOCOL;
  777. HKEY hMimeKey = NULL;
  778. DWORD dwError;
  779. DWORD dwType;
  780. char szValue[256];
  781. DWORD dwValueLen = 256;
  782. char szKey[SZMIMESIZE_MAX + 256];
  783. TransAssert((pwzMime));
  784. char szStr[ULPROTOCOLLEN+1];
  785. W2A(pwzMime, szStr, ULPROTOCOLLEN);
  786. szStr[ULPROTOCOLLEN] = 0;
  787. strcpy(szKey, SZ_SH_FILTERROOT);
  788. strcat(szKey, szStr);
  789. if (SHRegGetUSValue(
  790. szKey,
  791. SZCLASS,
  792. NULL,
  793. (LPBYTE)szValue,
  794. &dwValueLen,
  795. FALSE,
  796. NULL,
  797. 0) == ERROR_SUCCESS)
  798. {
  799. hr = CLSIDFromStringA(szValue, pclsid);
  800. PerfDbgLog2(
  801. tagCProtMgr,
  802. this,
  803. "API FOUND LookupFilterClsIDFromReg(hr:%lx, ClsId:%s)",
  804. hr,
  805. szValue);
  806. }
  807. // there are some machine incorrectly installed text/html and point to
  808. // PlugProt.dll and urlmon.dll. so if we find out the ksy is point to
  809. // these dll, we still return error, otherwise (the key might be
  810. // installed by 3rd party) we uses the key.
  811. // const GUID CLSID_MimeHandlerTest1 = {0x79eaca02, 0xbaf9, 0x11ce, {0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b}};
  812. if( !wcsicmp(pwzMime, L"text/html")
  813. && IsEqualGUID(*pclsid ,CLSID_ClassInstallFilter )
  814. )
  815. {
  816. hr = INET_E_UNKNOWN_PROTOCOL;
  817. *pclsid = CLSID_NULL;
  818. }
  819. PerfDbgLog1(tagCProtMgr, this, "-CProtMgrMimeHandler::LookupClsIDFromReg (hr:%lx)", hr);
  820. DEBUG_LEAVE(hr);
  821. return hr;
  822. }