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.

2783 lines
74 KiB

  1. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  2. //
  3. // xmlutil.cpp
  4. //
  5. // XML item helper functions.
  6. //
  7. // History:
  8. //
  9. // 4/1/97 edwardp Created.
  10. //
  11. ////////////////////////////////////////////////////////////////////////////////
  12. //
  13. // Includes
  14. //
  15. #include "stdinc.h"
  16. #include "cdfidl.h"
  17. #include "xmlutil.h"
  18. #include "winineti.h"
  19. #include <ocidl.h> // IPersistStreamInit.
  20. //
  21. // Function prototypes.
  22. //
  23. //
  24. // XML helper functions.
  25. //
  26. ////////////////////////////////////////////////////////////////////////////////
  27. //
  28. // *** XML_MarkCacheEntrySticky ***
  29. //
  30. // Description:
  31. // Marks the cache entry for the given URL as sticky by setting its
  32. // expiration delta to be very high
  33. //
  34. // Parameters:
  35. // [In] lpszUrl - url for cache entry to make sticky
  36. //
  37. // Return:
  38. // S_OK if the url entry was successfully marked sticky
  39. // E_FAIL otherwise.
  40. //
  41. ////////////////////////////////////////////////////////////////////////////////
  42. HRESULT XML_MarkCacheEntrySticky(LPTSTR lpszURL)
  43. {
  44. char chBuf[MAX_CACHE_ENTRY_INFO_SIZE];
  45. LPINTERNET_CACHE_ENTRY_INFO lpInfo = (LPINTERNET_CACHE_ENTRY_INFO) chBuf;
  46. DWORD dwSize = sizeof(chBuf);
  47. lpInfo->dwStructSize = dwSize;
  48. if (GetUrlCacheEntryInfo(lpszURL, lpInfo, &dwSize))
  49. {
  50. lpInfo->dwExemptDelta = 0xFFFFFFFF; // make VERY sticky
  51. if (SetUrlCacheEntryInfo(lpszURL, lpInfo, CACHE_ENTRY_EXEMPT_DELTA_FC))
  52. {
  53. return S_OK;
  54. }
  55. }
  56. return E_FAIL;
  57. }
  58. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  59. //
  60. // *** XML_SynchronousParse ***
  61. //
  62. //
  63. // Description:
  64. // Synchronously parses the given URL.
  65. //
  66. // Parameters:
  67. // [In] pIXMLDocument - An interface pointer to an XML document object.
  68. // [In] pidl - The pidl of the cdf file (contains the full path).
  69. //
  70. // Return:
  71. // S_OK if the object was parsed successfully.
  72. // E_FAIL otherwise.
  73. //
  74. // Comments:
  75. //
  76. //
  77. ////////////////////////////////////////////////////////////////////////////////
  78. HRESULT
  79. XML_SynchronousParse(
  80. IXMLDocument* pIXMLDocument,
  81. LPTSTR szPath
  82. )
  83. {
  84. ASSERT(pIXMLDocument);
  85. ASSERT(szPath);
  86. HRESULT hr;
  87. IPersistStreamInit* pIPersistStreamInit;
  88. hr = pIXMLDocument->QueryInterface(IID_IPersistStreamInit,
  89. (void**)&pIPersistStreamInit);
  90. if (SUCCEEDED(hr))
  91. {
  92. ASSERT(pIPersistStreamInit);
  93. IStream* pIStream;
  94. //
  95. // URLOpenBlockingStream pumps window messages! Don't use it!
  96. //
  97. //hr = URLOpenBlockingStream(NULL, szPath, &pIStream, 0, NULL);
  98. hr = SHCreateStreamOnFile(szPath, STGM_READ, &pIStream);
  99. TraceMsg(TF_CDFPARSE, "[%s SHCreateStreamOnFileW %s %s %s]",
  100. PathIsURL(szPath) ? TEXT("*** ") : TEXT(""), szPath,
  101. SUCCEEDED(hr) ? TEXT("SUCCEEDED") : TEXT("FAILED"),
  102. PathIsURL(szPath) ? TEXT("***") : TEXT(""));
  103. if (SUCCEEDED(hr))
  104. {
  105. ASSERT(pIStream);
  106. //
  107. // Load loads and parses the file. If this call succeeds the cdf
  108. // will be displayed. If it fails none of the cdf is displayed.
  109. //
  110. hr = pIPersistStreamInit->Load(pIStream);
  111. TraceMsg(TF_CDFPARSE, "[XML Parser %s]",
  112. SUCCEEDED(hr) ? TEXT("SUCCEEDED") : TEXT("FAILED"));
  113. pIStream->Release();
  114. //
  115. // If CDFVIEW is downloading a CDF from the net mark it as sticky
  116. // in the cache
  117. //
  118. if (PathIsURL(szPath))
  119. {
  120. XML_MarkCacheEntrySticky(szPath);
  121. }
  122. }
  123. pIPersistStreamInit->Release();
  124. }
  125. return hr;
  126. }
  127. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  128. //
  129. // *** XML_DownloadImages ***
  130. //
  131. //
  132. // Description:
  133. //
  134. //
  135. // Parameters:
  136. //
  137. //
  138. // Return:
  139. //
  140. //
  141. // Comments:
  142. //
  143. //
  144. ////////////////////////////////////////////////////////////////////////////////
  145. HRESULT
  146. XML_DownloadLogo(
  147. IXMLDocument *pIXMLDocument
  148. )
  149. {
  150. ASSERT(pIXMLDocument);
  151. HRESULT hr;
  152. IXMLElement* pIXMLElement;
  153. LONG nIndex;
  154. hr = XML_GetFirstChannelElement(pIXMLDocument, &pIXMLElement, &nIndex);
  155. if (SUCCEEDED(hr))
  156. {
  157. ASSERT(pIXMLElement);
  158. BSTR bstrURL = XML_GetAttribute(pIXMLElement, XML_LOGO);
  159. if (bstrURL)
  160. {
  161. hr = XML_DownloadImage(bstrURL);
  162. SysFreeString(bstrURL);
  163. }
  164. //
  165. // Download the wide logo also.
  166. //
  167. bstrURL = XML_GetAttribute(pIXMLElement, XML_LOGO_WIDE);
  168. if (bstrURL)
  169. {
  170. hr = XML_DownloadImage(bstrURL);
  171. SysFreeString(bstrURL);
  172. }
  173. pIXMLElement->Release();
  174. }
  175. return hr;
  176. }
  177. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  178. //
  179. // *** XML_DownloadImages ***
  180. //
  181. //
  182. // Description:
  183. //
  184. //
  185. // Parameters:
  186. //
  187. //
  188. // Return:
  189. //
  190. //
  191. // Comments:
  192. //
  193. //
  194. ////////////////////////////////////////////////////////////////////////////////
  195. HRESULT
  196. XML_DownloadImages(
  197. IXMLDocument *pIXMLDocument
  198. )
  199. {
  200. ASSERT(pIXMLDocument);
  201. HRESULT hr;
  202. IXMLElement* pIXMLElement;
  203. LONG nIndex;
  204. hr = XML_GetFirstChannelElement(pIXMLDocument, &pIXMLElement, &nIndex);
  205. if (SUCCEEDED(hr))
  206. {
  207. ASSERT(pIXMLElement);
  208. hr = XML_RecursiveImageDownload(pIXMLElement);
  209. pIXMLElement->Release();
  210. }
  211. return hr;
  212. }
  213. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  214. //
  215. // *** XML_RecuriveImageDownload ***
  216. //
  217. //
  218. // Description:
  219. //
  220. //
  221. // Parameters:
  222. //
  223. //
  224. // Return:
  225. //
  226. //
  227. // Comments:
  228. //
  229. //
  230. ////////////////////////////////////////////////////////////////////////////////
  231. HRESULT
  232. XML_RecursiveImageDownload(
  233. IXMLElement* pIXMLElement
  234. )
  235. {
  236. ASSERT(pIXMLElement);
  237. HRESULT hr = S_OK;
  238. BSTR bstrTagName;
  239. HRESULT hr2 = pIXMLElement->get_tagName(&bstrTagName);
  240. if (SUCCEEDED(hr2) && bstrTagName)
  241. {
  242. if (StrEqlW(bstrTagName, WSTR_LOGO))
  243. {
  244. BSTR bstrURL = XML_GetAttribute(pIXMLElement, XML_HREF);
  245. if (bstrURL && *bstrURL != 0)
  246. {
  247. hr = XML_DownloadImage(bstrURL);
  248. SysFreeString(bstrURL);
  249. }
  250. }
  251. else if (XML_IsCdfDisplayable(pIXMLElement))
  252. {
  253. IXMLElementCollection* pIXMLElementCollection;
  254. hr2 = pIXMLElement->get_children(&pIXMLElementCollection);
  255. if (SUCCEEDED(hr2) && pIXMLElementCollection)
  256. {
  257. ASSERT(pIXMLElementCollection);
  258. LONG nCount;
  259. hr2 = pIXMLElementCollection->get_length(&nCount);
  260. ASSERT(SUCCEEDED(hr2) || (FAILED(hr2) && 0 == nCount));
  261. for (int i = 0; i < nCount; i++)
  262. {
  263. IXMLElement* pIXMLElementChild;
  264. hr2 = XML_GetElementByIndex(pIXMLElementCollection, i,
  265. &pIXMLElementChild);
  266. if (SUCCEEDED(hr2))
  267. {
  268. ASSERT (pIXMLElementChild);
  269. XML_RecursiveImageDownload(pIXMLElementChild);
  270. pIXMLElementChild->Release();
  271. }
  272. }
  273. pIXMLElementCollection->Release();
  274. }
  275. }
  276. SysFreeString(bstrTagName);
  277. }
  278. return hr;
  279. }
  280. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  281. //
  282. // *** XML_DownloadImage ***
  283. //
  284. //
  285. // Description:
  286. //
  287. //
  288. // Parameters:
  289. //
  290. //
  291. // Return:
  292. //
  293. //
  294. // Comments:
  295. //
  296. //
  297. ////////////////////////////////////////////////////////////////////////////////
  298. HRESULT
  299. XML_DownloadImage(
  300. LPCWSTR pwszURL
  301. )
  302. {
  303. ASSERT (pwszURL);
  304. HRESULT hr;
  305. WCHAR szFileW[MAX_PATH];
  306. hr = URLDownloadToCacheFileW(NULL, pwszURL, szFileW,
  307. ARRAYSIZE(szFileW), 0, NULL);
  308. //
  309. // Mark the logo in the cache as sticky
  310. //
  311. if (SUCCEEDED(hr))
  312. {
  313. TCHAR szURL[INTERNET_MAX_URL_LENGTH];
  314. SHUnicodeToTChar(pwszURL, szURL, ARRAYSIZE(szURL));
  315. XML_MarkCacheEntrySticky(szURL);
  316. }
  317. #ifdef DEBUG
  318. TCHAR szURL[INTERNET_MAX_URL_LENGTH];
  319. SHUnicodeToTChar(pwszURL, szURL, ARRAYSIZE(szURL));
  320. TraceMsg(TF_CDFPARSE,
  321. "[*** Image URLDownloadToCacheFileW %s %s ***]",
  322. szURL, SUCCEEDED(hr) ? TEXT("SUCCEEDED") :
  323. TEXT("FAILED"));
  324. #endif // DEBUG
  325. return hr;
  326. }
  327. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  328. //
  329. // *** XML_GetDocType ***
  330. //
  331. //
  332. // Description:
  333. // Returns the type of the given xml document.
  334. //
  335. // Parameters:
  336. // [In] pIXMLDocument - A pointer to the xml document.
  337. //
  338. // Return:
  339. // DOC_CHANNEL, DOC_DESKTOPCOMPONENT, DOC_SOFTWAREUPDATE, or DOC_UNKNOWN.
  340. //
  341. // Comments:
  342. // If at the root level of a channel an ITEM contains a USAGE type of
  343. // DesktopComponent then the document is a Desktop Component otherwise
  344. // it is a channel.
  345. //
  346. ////////////////////////////////////////////////////////////////////////////////
  347. XMLDOCTYPE
  348. XML_GetDocType(IXMLDocument* pIXMLDocument)
  349. {
  350. ASSERT(pIXMLDocument);
  351. XMLDOCTYPE xdtRet;
  352. IXMLElement* pIXMLElement;
  353. LONG nIndex;
  354. HRESULT hr = XML_GetFirstDesktopComponentElement(pIXMLDocument,
  355. &pIXMLElement,
  356. &nIndex);
  357. if (SUCCEEDED(hr))
  358. {
  359. ASSERT(pIXMLElement);
  360. xdtRet = DOC_DESKTOPCOMPONENT;
  361. pIXMLElement->Release();
  362. }
  363. else
  364. {
  365. hr = XML_GetFirstChannelElement(pIXMLDocument, &pIXMLElement,
  366. &nIndex);
  367. if (SUCCEEDED(hr))
  368. {
  369. ASSERT(pIXMLElement);
  370. BSTR bstr = XML_GetAttribute( pIXMLElement, XML_USAGE_SOFTWAREUPDATE );
  371. if (bstr)
  372. {
  373. SysFreeString(bstr);
  374. xdtRet = DOC_SOFTWAREUPDATE;
  375. }
  376. else
  377. {
  378. xdtRet = DOC_CHANNEL;
  379. }
  380. pIXMLElement->Release();
  381. }
  382. else
  383. {
  384. xdtRet = DOC_UNKNOWN;
  385. }
  386. }
  387. return xdtRet;
  388. }
  389. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  390. //
  391. // *** XML_GetChildElementCollection ***
  392. //
  393. //
  394. // Description:
  395. // Returns an element collection given the parent collection and an index.
  396. //
  397. // Parameters:
  398. // [In] pParentIXMLElementCollection - The parent collection.
  399. // [In] nIndex - Index to the requested collection.
  400. // [Out] ppIXMLElementCollection - A pointer that receives the
  401. // requested collection.
  402. //
  403. // Return:
  404. // S_OK if the collection is returned.
  405. // E_FAIL otherwise.
  406. //
  407. // Comments:
  408. // The caller is responsible for calling Release() on the returned interface
  409. // pointer.
  410. //
  411. ////////////////////////////////////////////////////////////////////////////////
  412. HRESULT
  413. XML_GetChildElementCollection(
  414. IXMLElementCollection *pParentIXMLElementCollection,
  415. LONG nIndex,
  416. IXMLElementCollection** ppIXMLElementCollection
  417. )
  418. {
  419. ASSERT(pParentIXMLElementCollection);
  420. ASSERT(ppIXMLElementCollection);
  421. HRESULT hr;
  422. IXMLElement* pIXMLElement;
  423. hr = XML_GetElementByIndex(pParentIXMLElementCollection, nIndex,
  424. &pIXMLElement);
  425. if (SUCCEEDED(hr))
  426. {
  427. ASSERT(pIXMLElement);
  428. hr = pIXMLElement->get_children(ppIXMLElementCollection);
  429. if(SUCCEEDED(hr) && !(*ppIXMLElementCollection))
  430. hr = E_FAIL;
  431. pIXMLElement->Release();
  432. }
  433. ASSERT((SUCCEEDED(hr) && (*ppIXMLElementCollection)) || FAILED(hr));
  434. return hr;
  435. }
  436. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  437. //
  438. // *** XML_GetElementByIndex ***
  439. //
  440. //
  441. // Description:
  442. // Returns the nIndex'th element of the given collection.
  443. //
  444. // Parameters:
  445. // [In] pIXMLElementCollection - A pointer to the collection.
  446. // [In] nIndex - The index of the item to retrieve.
  447. // [Out] ppIXMLElement - A pointer that receives the item.
  448. //
  449. // Return:
  450. // S_OK if the item was retrieved.
  451. // E_FAIL otherwise.
  452. //
  453. // Comments:
  454. // The caller is responsible for calling Release() on the returned interface
  455. // pointer.
  456. //
  457. ////////////////////////////////////////////////////////////////////////////////
  458. HRESULT
  459. XML_GetElementByIndex(
  460. IXMLElementCollection* pIXMLElementCollection,
  461. LONG nIndex,
  462. IXMLElement** ppIXMLElement
  463. )
  464. {
  465. ASSERT(pIXMLElementCollection);
  466. ASSERT(ppIXMLElement);
  467. HRESULT hr;
  468. VARIANT var1, var2;
  469. VariantInit(&var1);
  470. VariantInit(&var2);
  471. var1.vt = VT_I4;
  472. var1.lVal = nIndex;
  473. IDispatch* pIDispatch;
  474. hr = pIXMLElementCollection->item(var1, var2, &pIDispatch);
  475. if (SUCCEEDED(hr))
  476. {
  477. ASSERT(pIDispatch);
  478. hr = pIDispatch->QueryInterface(IID_IXMLElement, (void**)ppIXMLElement);
  479. pIDispatch->Release();
  480. }
  481. else
  482. {
  483. *ppIXMLElement = NULL;
  484. }
  485. ASSERT((SUCCEEDED(hr) && *ppIXMLElement) ||
  486. (FAILED(hr) && NULL == *ppIXMLElement));
  487. return hr;
  488. }
  489. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  490. //
  491. // *** XML_GetElementByName ***
  492. //
  493. //
  494. // Description:
  495. // Returns the first element with the given tag name.
  496. //
  497. // Parameters:
  498. // [In] pIXMLElementCollection - A pointer to the collection.
  499. // [In] nszNameW - The tag name of the item to retrieve.
  500. // [Out] ppIXMLElement - A pointer that receives the item.
  501. //
  502. // Return:
  503. // S_OK if the item was retrieved.
  504. // E_OUTOFMEMORY if a sys string could not be allocated.
  505. // E_FAIL otherwise.
  506. //
  507. // Comments:
  508. // The caller is responsible for calling Release() on the returned interface
  509. // pointer.
  510. //
  511. ////////////////////////////////////////////////////////////////////////////////
  512. HRESULT
  513. XML_GetElementByName(
  514. IXMLElementCollection* pIXMLElementCollection,
  515. LPWSTR szNameW,
  516. IXMLElement** ppIXMLElement
  517. )
  518. {
  519. ASSERT(pIXMLElementCollection);
  520. ASSERT(ppIXMLElement);
  521. HRESULT hr = E_FAIL;
  522. LONG nCount;
  523. HRESULT hr2 = pIXMLElementCollection->get_length(&nCount);
  524. ASSERT(SUCCEEDED(hr2) || (FAILED(hr2) && 0 == nCount));
  525. for (int i = 0, bElement = FALSE; (i < nCount) && !bElement; i++)
  526. {
  527. IXMLElement* pIXMLElement;
  528. hr2 = XML_GetElementByIndex(pIXMLElementCollection, i, &pIXMLElement);
  529. if (SUCCEEDED(hr2))
  530. {
  531. ASSERT(pIXMLElement);
  532. BSTR pStr;
  533. hr2 = pIXMLElement->get_tagName(&pStr);
  534. if (SUCCEEDED(hr2) && pStr)
  535. {
  536. ASSERT(pStr);
  537. if (bElement = StrEqlW(pStr, szNameW))
  538. {
  539. pIXMLElement->AddRef();
  540. *ppIXMLElement = pIXMLElement;
  541. hr = S_OK;
  542. }
  543. SysFreeString(pStr);
  544. }
  545. pIXMLElement->Release();
  546. }
  547. }
  548. hr = FAILED(hr2) ? hr2 : hr;
  549. /* Enable this when pIXMLElementCollection->item works with VT_BSTR
  550. VARIANT var1, var2;
  551. VariantInit(&var1);
  552. VariantInit(&var2);
  553. var1.vt = VT_BSTR;
  554. var1.bstrVal = SysAllocString(szNameW);
  555. var2.vt = VT_I4
  556. var2.lVal = 1;
  557. if (var1.bstrVal)
  558. {
  559. IDispatch* pIDispatch;
  560. hr = pIXMLElementCollection->item(var1, var2, &pIDispatch);
  561. if (SUCCEEDED(hr))
  562. {
  563. ASSERT(pIDispatch);
  564. hr = pIDispatch->QueryInterface(IID_IXMLElement,
  565. (void**)ppIXMLElement);
  566. pIDispatch->Release();
  567. }
  568. SysFreeString(var1.bstrVal);
  569. }
  570. else
  571. {
  572. hr = E_OUTOFMEMORY;
  573. }
  574. */
  575. ASSERT((SUCCEEDED(hr) && ppIXMLElement) || FAILED(hr));
  576. return hr;
  577. }
  578. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  579. //
  580. // *** XML_GetFirstChannelElement ***
  581. //
  582. //
  583. // Description:
  584. // Returns the IXMLElement of the first channel in the XML document.
  585. //
  586. // Parameters:
  587. // [In] pIXMLDocument - A pointer to the XML document object.
  588. // [Out] ppIXMLElement - The pointer that receives the element.
  589. // [Out] pnIndex - The index of the element.
  590. //
  591. // Return:
  592. // S_OK if the first channel element was returned.
  593. // E_FAIL if the element couldn't be returned.
  594. //
  595. // Comments:
  596. // This function can't call XML_GetElementByName to find the first channel.
  597. // XML channels can have a tag name of "Channel" or "CHAN".
  598. // XML_GetElementByName wouldn't be able to determine which of the items
  599. // came first if both where present in the XML doc.
  600. //
  601. // The caller is responsible for calling Release() on the returned interface
  602. // pointer. The return pointer is not NULL'ed out on error.
  603. //
  604. ////////////////////////////////////////////////////////////////////////////////
  605. HRESULT
  606. XML_GetFirstChannelElement(
  607. IXMLDocument* pIXMLDocument,
  608. IXMLElement** ppIXMLElement,
  609. PLONG pnIndex)
  610. {
  611. ASSERT(pIXMLDocument);
  612. ASSERT(ppIXMLElement);
  613. ASSERT(pnIndex);
  614. IXMLElement *pRootElem = NULL;
  615. HRESULT hr = E_FAIL;
  616. *pnIndex = 0;
  617. hr = pIXMLDocument->get_root(&pRootElem);
  618. if (SUCCEEDED(hr) && pRootElem)
  619. {
  620. ASSERT(pRootElem);
  621. if (XML_IsChannel(pRootElem))
  622. {
  623. *ppIXMLElement = pRootElem;
  624. hr = S_OK;
  625. }
  626. else
  627. {
  628. pRootElem->Release();
  629. hr = E_FAIL;
  630. }
  631. }
  632. else
  633. {
  634. hr = E_FAIL;
  635. }
  636. ASSERT((SUCCEEDED(hr) && (*ppIXMLElement)) || FAILED(hr));
  637. return hr;
  638. }
  639. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  640. //
  641. // *** XML_GetDesktopElementFromChannelElement ***
  642. //
  643. //
  644. // Description:
  645. // Returns the IXMLElement of the first dekstop component in the channel.
  646. //
  647. // Parameters:
  648. // [In] pChannelIXMLElement - A pointer to the XML channel element.
  649. // [Out] ppIXMLElement - The pointer that receives the element.
  650. // [Out] pnIndex - The index of the element.
  651. //
  652. // Return:
  653. // S_OK if the first desktop element was returned.
  654. // E_FAIL if the element couldn't be returned.
  655. //
  656. // Comments:
  657. // This looks for the first ITEM with a usage of DesktopComponent.
  658. //
  659. ////////////////////////////////////////////////////////////////////////////////
  660. HRESULT
  661. XML_GetDesktopElementFromChannelElement(
  662. IXMLElement* pChannelIXMLElement,
  663. IXMLElement** ppIXMLElement,
  664. PLONG pnIndex)
  665. {
  666. ASSERT(pChannelIXMLElement);
  667. ASSERT(ppIXMLElement);
  668. ASSERT(pnIndex);
  669. HRESULT hr;
  670. IXMLElementCollection* pIXMLElementCollection;
  671. hr = pChannelIXMLElement->get_children(&pIXMLElementCollection);
  672. if (SUCCEEDED(hr) && pIXMLElementCollection)
  673. {
  674. ASSERT(pIXMLElementCollection);
  675. LONG nCount;
  676. hr = pIXMLElementCollection->get_length(&nCount);
  677. ASSERT(SUCCEEDED(hr) || (FAILED(hr) && 0 == nCount));
  678. hr = E_FAIL;
  679. for (int i = 0, bComponent = FALSE; (i < nCount) && !bComponent;
  680. i++)
  681. {
  682. IXMLElement* pIXMLElement;
  683. HRESULT hr2 = XML_GetElementByIndex(pIXMLElementCollection, i,
  684. &pIXMLElement);
  685. if (SUCCEEDED(hr2))
  686. {
  687. ASSERT(pIXMLElement);
  688. if (bComponent = XML_IsDesktopComponent(pIXMLElement))
  689. {
  690. pIXMLElement->AddRef();
  691. *ppIXMLElement = pIXMLElement;
  692. *pnIndex = i;
  693. hr = S_OK;
  694. }
  695. pIXMLElement->Release();
  696. }
  697. hr = FAILED(hr2) ? hr2 : hr;
  698. }
  699. pIXMLElementCollection->Release();
  700. }
  701. else
  702. {
  703. hr = E_FAIL;
  704. }
  705. return hr;
  706. }
  707. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  708. //
  709. // *** XML_GetFirstDesktopComponentElement ***
  710. //
  711. //
  712. // Description:
  713. // Returns the IXMLElement of the first dekstop component in the channel.
  714. //
  715. // Parameters:
  716. // [In] pIXMLDocument - A pointer to the XML document object.
  717. // [Out] ppIXMLElement - The pointer that receives the element.
  718. // [Out] pnIndex - The index of the element.
  719. //
  720. // Return:
  721. // S_OK if the first channel element was returned.
  722. // E_FAIL if the element couldn't be returned.
  723. //
  724. // Comments:
  725. // This function gets the first channel and then looks for the first
  726. // top-level ITEM with a usage of DesktopComponent.
  727. //
  728. ////////////////////////////////////////////////////////////////////////////////
  729. HRESULT
  730. XML_GetFirstDesktopComponentElement(
  731. IXMLDocument* pIXMLDocument,
  732. IXMLElement** ppIXMLElement,
  733. PLONG pnIndex)
  734. {
  735. ASSERT(pIXMLDocument);
  736. ASSERT(ppIXMLElement);
  737. ASSERT(pnIndex);
  738. HRESULT hr;
  739. IXMLElement* pChannelIXMLElement;
  740. LONG nIndex;
  741. hr = XML_GetFirstChannelElement(pIXMLDocument, &pChannelIXMLElement,
  742. &nIndex);
  743. if (SUCCEEDED(hr))
  744. {
  745. ASSERT(pChannelIXMLElement);
  746. hr = XML_GetDesktopElementFromChannelElement(pChannelIXMLElement,
  747. ppIXMLElement,
  748. pnIndex);
  749. pChannelIXMLElement->Release();
  750. }
  751. ASSERT((SUCCEEDED(hr) && *ppIXMLElement) || FAILED(hr));
  752. return hr;
  753. }
  754. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  755. //
  756. // *** XML_GetFirstDesktopComponentUsageElement ***
  757. //
  758. //
  759. // Description:
  760. // Returns the first USAGE VALUE="DesktopComponent" element of the first
  761. // desktop component.
  762. //
  763. // Parameters:
  764. // [In] pIXMLDocument - A pointer to the the document.
  765. // [Out] pIXMLElement - A pointer the receives the element.
  766. //
  767. // Return:
  768. // S_OK if the element was found.
  769. // E_FAIL if the element wasn't found.
  770. //
  771. // Comments:
  772. //
  773. //
  774. ////////////////////////////////////////////////////////////////////////////////
  775. HRESULT
  776. XML_GetFirstDesktopComponentUsageElement(
  777. IXMLDocument* pIXMLDocument,
  778. IXMLElement** ppIXMLElement
  779. )
  780. {
  781. ASSERT(pIXMLDocument);
  782. ASSERT(ppIXMLElement);
  783. HRESULT hr;
  784. IXMLElement* pParentIXMLElement;
  785. LONG nIndex;
  786. hr = XML_GetFirstDesktopComponentElement(pIXMLDocument, &pParentIXMLElement,
  787. &nIndex);
  788. if (SUCCEEDED(hr))
  789. {
  790. IXMLElementCollection* pIXMLElementCollection;
  791. hr = pParentIXMLElement->get_children(&pIXMLElementCollection);
  792. if (SUCCEEDED(hr) && pIXMLElementCollection)
  793. {
  794. ASSERT(pIXMLElementCollection);
  795. LONG nCount;
  796. hr = pIXMLElementCollection->get_length(&nCount);
  797. ASSERT(SUCCEEDED(hr) || (FAILED(hr) && 0 == nCount));
  798. hr = E_FAIL;
  799. for (int i = 0, bUsage = FALSE; (i < nCount) && !bUsage; i++)
  800. {
  801. IXMLElement* pIXMLElement;
  802. HRESULT hr2 = XML_GetElementByIndex(pIXMLElementCollection, i,
  803. &pIXMLElement);
  804. if (SUCCEEDED(hr2))
  805. {
  806. ASSERT(pIXMLElement);
  807. if (bUsage = XML_IsDesktopComponentUsage(pIXMLElement))
  808. {
  809. pIXMLElement->AddRef();
  810. *ppIXMLElement = pIXMLElement;
  811. //*pnIndex = i;
  812. hr = S_OK;
  813. }
  814. pIXMLElement->Release();
  815. }
  816. hr = FAILED(hr2) ? hr2 : hr;
  817. }
  818. pIXMLElementCollection->Release();
  819. }
  820. else
  821. {
  822. hr = E_FAIL;
  823. }
  824. pParentIXMLElement->Release();
  825. }
  826. return hr;
  827. }
  828. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  829. //
  830. // *** XML_GetDesktopComponentInfo ***
  831. //
  832. //
  833. // Description:
  834. // Fills in the desktop component information structure.
  835. //
  836. // Parameters:
  837. // [In] pIXMLDocument - A ponter to the document.
  838. // [Out] pInfo - A desktop component information structure.
  839. //
  840. // Return:
  841. // S_OK if the given document is desktop component document.
  842. // E_FAIL otherwise.
  843. //
  844. // Comments:
  845. //
  846. //
  847. ////////////////////////////////////////////////////////////////////////////////
  848. HRESULT
  849. XML_GetDesktopComponentInfo(
  850. IXMLDocument* pIXMLDocument,
  851. COMPONENT* pInfo
  852. )
  853. {
  854. ASSERT(pIXMLDocument);
  855. ASSERT(pInfo);
  856. HRESULT hr;
  857. IXMLElement* pIXMLElement;
  858. hr = XML_GetFirstDesktopComponentUsageElement(pIXMLDocument, &pIXMLElement);
  859. if (SUCCEEDED(hr))
  860. {
  861. ASSERT(pIXMLElement);
  862. ZeroMemory(pInfo, sizeof(COMPONENT));
  863. pInfo->dwSize = sizeof(COMPONENT);
  864. pInfo->fChecked = TRUE;
  865. pInfo->fDirty = TRUE;
  866. pInfo->fNoScroll = FALSE;
  867. pInfo->cpPos.dwSize = sizeof(COMPPOS);
  868. pInfo->cpPos.izIndex = COMPONENT_TOP;
  869. pInfo->dwCurItemState = IS_NORMAL;
  870. BSTR bstrValue;
  871. if (bstrValue = XML_GetAttribute(pIXMLElement, XML_OPENAS))
  872. {
  873. if (!(0 == StrCmpIW(bstrValue, WSTR_IMAGE)))
  874. {
  875. pInfo->iComponentType = COMP_TYPE_WEBSITE;
  876. }
  877. else
  878. {
  879. pInfo->iComponentType = COMP_TYPE_PICTURE;
  880. }
  881. SysFreeString(bstrValue);
  882. }
  883. if (bstrValue = XML_GetAttribute(pIXMLElement, XML_WIDTH))
  884. {
  885. pInfo->cpPos.dwWidth = StrToIntW(bstrValue);
  886. SysFreeString(bstrValue);
  887. }
  888. if (bstrValue = XML_GetAttribute(pIXMLElement, XML_HEIGHT))
  889. {
  890. pInfo->cpPos.dwHeight = StrToIntW(bstrValue);
  891. SysFreeString(bstrValue);
  892. }
  893. if (bstrValue = XML_GetAttribute(pIXMLElement, XML_ITEMSTATE))
  894. {
  895. if(!StrCmpIW(bstrValue, WSTR_NORMAL))
  896. pInfo->dwCurItemState = IS_NORMAL;
  897. else
  898. {
  899. if(!StrCmpIW(bstrValue, WSTR_FULLSCREEN))
  900. pInfo->dwCurItemState = IS_FULLSCREEN;
  901. else
  902. pInfo->dwCurItemState = IS_SPLIT;
  903. }
  904. SysFreeString(bstrValue);
  905. }
  906. if (bstrValue = XML_GetAttribute(pIXMLElement, XML_CANRESIZE))
  907. {
  908. pInfo->cpPos.fCanResize = StrEqlW(bstrValue, WSTR_YES);
  909. SysFreeString(bstrValue);
  910. }
  911. else
  912. {
  913. if (bstrValue = XML_GetAttribute(pIXMLElement, XML_CANRESIZEX))
  914. {
  915. pInfo->cpPos.fCanResizeX = StrEqlW(bstrValue, WSTR_YES);
  916. SysFreeString(bstrValue);
  917. }
  918. if (bstrValue = XML_GetAttribute(pIXMLElement, XML_CANRESIZEY))
  919. {
  920. pInfo->cpPos.fCanResizeY = StrEqlW(bstrValue, WSTR_YES);
  921. SysFreeString(bstrValue);
  922. }
  923. }
  924. if (bstrValue = XML_GetAttribute(pIXMLElement, XML_PREFERREDLEFT))
  925. {
  926. if (StrChrW(bstrValue, L'%'))
  927. {
  928. pInfo->cpPos.iPreferredLeftPercent = StrToIntW(bstrValue);
  929. }
  930. else
  931. {
  932. pInfo->cpPos.iLeft = StrToIntW(bstrValue);
  933. }
  934. SysFreeString(bstrValue);
  935. }
  936. if (bstrValue = XML_GetAttribute(pIXMLElement, XML_PREFERREDTOP))
  937. {
  938. if (StrChrW(bstrValue, L'%'))
  939. {
  940. pInfo->cpPos.iPreferredTopPercent = StrToIntW(bstrValue);
  941. }
  942. else
  943. {
  944. pInfo->cpPos.iTop = StrToIntW(bstrValue);
  945. }
  946. SysFreeString(bstrValue);
  947. }
  948. IXMLElement *pIXMLElementParent;
  949. hr = pIXMLElement->get_parent(&pIXMLElementParent);
  950. if(!pIXMLElementParent)
  951. hr = E_FAIL;
  952. if (SUCCEEDED(hr))
  953. {
  954. ASSERT(pIXMLElementParent);
  955. if (bstrValue = XML_GetAttribute(pIXMLElementParent, XML_TITLE))
  956. {
  957. StrCpyNW(pInfo->wszFriendlyName, bstrValue,
  958. ARRAYSIZE(pInfo->wszFriendlyName));
  959. SysFreeString(bstrValue);
  960. }
  961. if (bstrValue = XML_GetAttribute(pIXMLElementParent, XML_HREF))
  962. {
  963. if (*bstrValue)
  964. {
  965. StrCpyNW(pInfo->wszSource, bstrValue,
  966. ARRAYSIZE(pInfo->wszSource));
  967. SysFreeString(bstrValue);
  968. }
  969. else
  970. {
  971. hr = E_FAIL;
  972. }
  973. }
  974. if (SUCCEEDED(hr))
  975. {
  976. IXMLElement *pIXMLChannel;
  977. LONG nIndex;
  978. hr = XML_GetFirstChannelElement(pIXMLDocument, &pIXMLChannel,
  979. &nIndex);
  980. if (SUCCEEDED(hr))
  981. {
  982. ASSERT(pIXMLChannel);
  983. if (bstrValue = XML_GetAttribute(pIXMLChannel, XML_SELF))
  984. {
  985. StrCpyNW(pInfo->wszSubscribedURL, bstrValue,
  986. ARRAYSIZE(pInfo->wszSubscribedURL));
  987. SysFreeString(bstrValue);
  988. }
  989. pIXMLChannel->Release();
  990. }
  991. }
  992. pIXMLElementParent->Release();
  993. }
  994. pIXMLElement->Release();
  995. }
  996. return hr;
  997. }
  998. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  999. //
  1000. // *** XML_GetAttribute ***
  1001. //
  1002. //
  1003. // Description:
  1004. // Returns a bstr representing the requested attribute of the given element.
  1005. //
  1006. // Parameters:
  1007. // [In] pIXMLElement - A pointer to the XML element.
  1008. // [In] attribute - The requested attribute.
  1009. //
  1010. // Return:
  1011. // A bstr with the attribute value.
  1012. // NULL if there wasn't enough memory to allocated the bstr.
  1013. //
  1014. // Comments:
  1015. // This function keeps a table of attributes and their properties. It bases
  1016. // attribute look up on this table.
  1017. //
  1018. ////////////////////////////////////////////////////////////////////////////////
  1019. BSTR
  1020. XML_GetAttribute(
  1021. IXMLElement* pIXMLElement,
  1022. XML_ATTRIBUTE attrIndex
  1023. )
  1024. {
  1025. //
  1026. // A table is used to read values associated with a given xml element. The
  1027. // xml element can have attributes (values inside the elements tag) or child
  1028. // elements (elements between tags).
  1029. //
  1030. // Rules:
  1031. // 1) If child is NULL. Read the Attribute from the current item.
  1032. // 2) If child is not NULL, read the Attribute from the child
  1033. // item.
  1034. // 3) If AttributeType is NULL, use the Attribute value to read the
  1035. // attribute.
  1036. // 4) If AttributeType is not NULL, verify that the item contains
  1037. // the AttributeType attribute before using Attribute to read
  1038. // the value.
  1039. // 5) If the value is not found use Default as the return value.
  1040. //
  1041. static const struct _tagXML_ATTRIBUTE_ARRAY
  1042. {
  1043. LPWSTR szChildW;
  1044. LPWSTR szAttributeW;
  1045. LPWSTR szQualifierW;
  1046. LPWSTR szQualifierValueW;
  1047. XML_ATTRIBUTE attrSecondary;
  1048. LPWSTR szDefaultW;
  1049. BOOL fUseBaseURL;
  1050. XML_ATTRIBUTE attribute; // Only used in ASSERT.
  1051. }
  1052. aAttribTable[] =
  1053. {
  1054. /*
  1055. Child Attribute Qualifier Qual. Value Secondary Lookup Default Base URL Enum Check
  1056. -------------- -------------- ----------- ------------ ----------------- ---------- -------- -----------------*/
  1057. {WSTR_TITLE, NULL, NULL, NULL, XML_TITLE_ATTR, WSTR_EMPTY, FALSE, XML_TITLE },
  1058. {NULL, WSTR_TITLE, NULL, NULL, XML_HREF, WSTR_EMPTY, FALSE, XML_TITLE_ATTR },
  1059. {NULL, WSTR_HREF, NULL, NULL, XML_A_HREF, WSTR_EMPTY, TRUE, XML_HREF },
  1060. {WSTR_ABSTRACT, NULL, NULL, NULL, XML_ABSTRACT_ATTR, WSTR_EMPTY, FALSE, XML_ABSTRACT },
  1061. {NULL, WSTR_ABSTRACT, NULL, NULL, XML_HREF, WSTR_EMPTY, FALSE, XML_ABSTRACT_ATTR},
  1062. {WSTR_LOGO, WSTR_HREF, WSTR_STYLE, WSTR_ICON, XML_NULL, NULL, TRUE, XML_ICON },
  1063. {WSTR_LOGO, WSTR_HREF, WSTR_STYLE, WSTR_IMAGE, XML_LOGO_DEFAULT, NULL, TRUE, XML_LOGO },
  1064. {WSTR_LOGO, WSTR_HREF, NULL, NULL, XML_NULL, NULL, TRUE, XML_LOGO_DEFAULT },
  1065. {NULL, WSTR_SELF, NULL, NULL, XML_SELF_OLD, NULL, TRUE, XML_SELF },
  1066. {WSTR_SELF, WSTR_HREF, NULL, NULL, XML_NULL, NULL, TRUE, XML_SELF_OLD },
  1067. {NULL, WSTR_BASE, NULL, NULL, XML_NULL, NULL, FALSE, XML_BASE },
  1068. {WSTR_USAGE, WSTR_VALUE, NULL, NULL, XML_SHOW, NULL, FALSE, XML_USAGE },
  1069. {WSTR_USAGE, WSTR_VALUE, WSTR_VALUE, WSTR_CHANNEL, XML_SHOW_CHANNEL, NULL, FALSE, XML_USAGE_CHANNEL},
  1070. {WSTR_USAGE, WSTR_VALUE, WSTR_VALUE, WSTR_DSKCMP, XML_SHOW_DSKCMP, NULL, FALSE, XML_USAGE_DSKCMP },
  1071. {WSTR_WIDTH, WSTR_VALUE, NULL, NULL, XML_NULL, WSTR_ZERO, FALSE, XML_WIDTH },
  1072. {WSTR_HEIGHT, WSTR_VALUE, NULL, NULL, XML_NULL, WSTR_ZERO, FALSE, XML_HEIGHT },
  1073. {WSTR_RESIZE, WSTR_VALUE, NULL, NULL, XML_NULL, NULL, FALSE, XML_CANRESIZE },
  1074. {WSTR_RESIZEX, WSTR_VALUE, NULL, NULL, XML_NULL, WSTR_YES, FALSE, XML_CANRESIZEX },
  1075. {WSTR_RESIZEY, WSTR_VALUE, NULL, NULL, XML_NULL, WSTR_YES, FALSE, XML_CANRESIZEY },
  1076. {WSTR_PREFLEFT, WSTR_VALUE, NULL, NULL, XML_NULL, NULL, FALSE, XML_PREFERREDLEFT},
  1077. {WSTR_PREFTOP, WSTR_VALUE, NULL, NULL, XML_NULL, NULL, FALSE, XML_PREFERREDTOP },
  1078. {WSTR_OPENAS, WSTR_VALUE, NULL, NULL, XML_NULL, WSTR_HTML, FALSE, XML_OPENAS },
  1079. {NULL, WSTR_SHOW, NULL, NULL, XML_NULL, NULL, FALSE, XML_SHOW },
  1080. {NULL, WSTR_SHOW, WSTR_SHOW, WSTR_CHANNEL, XML_NULL, NULL, FALSE, XML_SHOW_CHANNEL },
  1081. {NULL, WSTR_SHOW, WSTR_SHOW, WSTR_DSKCMP, XML_NULL, NULL, FALSE, XML_SHOW_DSKCMP },
  1082. {WSTR_A, WSTR_HREF, NULL, NULL, XML_INFOURI, WSTR_EMPTY, TRUE, XML_A_HREF },
  1083. {NULL, WSTR_INFOURI, NULL, NULL, XML_NULL, WSTR_EMPTY, TRUE, XML_INFOURI },
  1084. {WSTR_LOGO, WSTR_HREF, WSTR_STYLE, WSTR_IMAGEW, XML_NULL, NULL, TRUE, XML_LOGO_WIDE },
  1085. {WSTR_LOGIN, NULL, NULL, NULL, XML_NULL, NULL, FALSE, XML_LOGIN },
  1086. {WSTR_USAGE, WSTR_VALUE, WSTR_VALUE, WSTR_SOFTWAREUPDATE, XML_SHOW_SOFTWAREUPDATE, NULL, FALSE, XML_USAGE_SOFTWAREUPDATE},
  1087. {NULL, WSTR_SHOW, WSTR_SHOW, WSTR_SOFTWAREUPDATE, XML_NULL, NULL, FALSE, XML_SHOW_SOFTWAREUPDATE },
  1088. {WSTR_ITEMSTATE,WSTR_VALUE, NULL, NULL, XML_NULL, WSTR_NORMAL,FALSE, XML_ITEMSTATE },
  1089. };
  1090. ASSERT(pIXMLElement);
  1091. //
  1092. // REVIEW: aAttribTable attribute field only used in debug builds.
  1093. //
  1094. ASSERT(attrIndex == aAttribTable[attrIndex].attribute);
  1095. BSTR bstrRet = NULL;
  1096. if (NULL == aAttribTable[attrIndex].szAttributeW)
  1097. {
  1098. bstrRet = XML_GetGrandChildContent(pIXMLElement,
  1099. aAttribTable[attrIndex].szChildW);
  1100. }
  1101. else if (NULL != aAttribTable[attrIndex].szChildW)
  1102. {
  1103. bstrRet = XML_GetChildAttribute(pIXMLElement,
  1104. aAttribTable[attrIndex].szChildW,
  1105. aAttribTable[attrIndex].szAttributeW,
  1106. aAttribTable[attrIndex].szQualifierW,
  1107. aAttribTable[attrIndex].szQualifierValueW);
  1108. }
  1109. else
  1110. {
  1111. bstrRet = XML_GetElementAttribute(pIXMLElement,
  1112. aAttribTable[attrIndex].szAttributeW,
  1113. aAttribTable[attrIndex].szQualifierW,
  1114. aAttribTable[attrIndex].szQualifierValueW);
  1115. }
  1116. //
  1117. // If the title or tooltip aren't displayable on the local system use the
  1118. // URL in their place.
  1119. //
  1120. if (bstrRet && (XML_TITLE == attrIndex || XML_TITLE_ATTR == attrIndex ||
  1121. XML_ABSTRACT == attrIndex))
  1122. {
  1123. if (!StrLocallyDisplayable(bstrRet))
  1124. {
  1125. SysFreeString(bstrRet);
  1126. bstrRet = NULL;
  1127. }
  1128. }
  1129. //
  1130. // Special cases:
  1131. // TITLE can also be an attribute.
  1132. // ABSTRACT can also be an attribute.
  1133. // LOGO elements don't have to have the TYPE="IMAGE"
  1134. // SELF is now an attribute SELF_OLD can be removed in the future.
  1135. // USAGE can also be specified via the SHOW attribute.
  1136. // USAGE_CHANNEL should also check for SHOW="Channel".
  1137. // USAGE_DSKCMP should also check for SHOW="DesktopComponent"
  1138. //
  1139. if (NULL == bstrRet && XML_NULL != aAttribTable[attrIndex].attrSecondary)
  1140. {
  1141. bstrRet = XML_GetAttribute(pIXMLElement,
  1142. aAttribTable[attrIndex].attrSecondary);
  1143. }
  1144. //
  1145. // Combine URL if required.
  1146. //
  1147. if (bstrRet && aAttribTable[attrIndex].fUseBaseURL)
  1148. {
  1149. BSTR bstrBaseURL = XML_GetBaseURL(pIXMLElement);
  1150. if (bstrBaseURL)
  1151. {
  1152. BSTR bstrCombinedURL = XML_CombineURL(bstrBaseURL, bstrRet);
  1153. if (bstrCombinedURL)
  1154. {
  1155. SysFreeString(bstrRet);
  1156. bstrRet = bstrCombinedURL;
  1157. }
  1158. SysFreeString(bstrBaseURL);
  1159. }
  1160. }
  1161. /* The following prevents long urls from over-running the pidl buffer */
  1162. if (bstrRet &&
  1163. (attrIndex == XML_HREF) &&
  1164. (SysStringLen(bstrRet) > INTERNET_MAX_URL_LENGTH))
  1165. {
  1166. SysReAllocStringLen(&bstrRet, bstrRet, INTERNET_MAX_URL_LENGTH-1);
  1167. }
  1168. /* The following prevents long names from over-running the pidl buffer */
  1169. if (bstrRet &&
  1170. (attrIndex == XML_TITLE) &&
  1171. (SysStringLen(bstrRet) > MAX_PATH))
  1172. {
  1173. SysReAllocStringLen(&bstrRet, bstrRet, MAX_PATH-1);
  1174. }
  1175. //
  1176. // Set default return value.
  1177. //
  1178. if (NULL == bstrRet && aAttribTable[attrIndex].szDefaultW)
  1179. bstrRet = SysAllocString(aAttribTable[attrIndex].szDefaultW);
  1180. return bstrRet;
  1181. }
  1182. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  1183. //
  1184. // *** XML_GetFirstChildContent ***
  1185. //
  1186. // Description:
  1187. // Returns a bstr value from first child of the given element.
  1188. //
  1189. // Parameters:
  1190. // [In] pIXMLElement - A pointer to the element.
  1191. // The caller is responsible for freeing the returned bstr.
  1192. //
  1193. // Comments:
  1194. // If pIElement represents
  1195. //
  1196. // <Title>Harvey is a Cool Cat<B>this will be ignored</B></Title>
  1197. //
  1198. // Then this function will return
  1199. //
  1200. // "Harvey is a Cool Cat"
  1201. //
  1202. // REVIEW THIS IS A TEMPORARY ROUTINE UNTIL THE XML PARSER SUPPORTS THIS DIRECTLY
  1203. //
  1204. ////////////////////////////////////////////////////////////////////////////////
  1205. BSTR
  1206. XML_GetFirstChildContent(
  1207. IXMLElement* pIXMLElement
  1208. )
  1209. {
  1210. ASSERT(pIXMLElement);
  1211. BSTR bstrRet = NULL;
  1212. IXMLElementCollection* pIXMLElementCollection;
  1213. if ((SUCCEEDED(pIXMLElement->get_children(&pIXMLElementCollection)))
  1214. && pIXMLElementCollection)
  1215. {
  1216. ASSERT(pIXMLElementCollection);
  1217. LONG nCount;
  1218. HRESULT hr = pIXMLElementCollection->get_length(&nCount);
  1219. ASSERT(SUCCEEDED(hr) || (FAILED(hr) && 0 == nCount));
  1220. if (nCount >= 1)
  1221. {
  1222. IXMLElement* pChildIXMLElement;
  1223. if (SUCCEEDED(XML_GetElementByIndex(pIXMLElementCollection, 0,
  1224. &pChildIXMLElement)))
  1225. {
  1226. ASSERT(pChildIXMLElement);
  1227. if (FAILED(pChildIXMLElement->get_text(&bstrRet)))
  1228. {
  1229. bstrRet = NULL;
  1230. }
  1231. pChildIXMLElement->Release();
  1232. }
  1233. }
  1234. pIXMLElementCollection->Release();
  1235. }
  1236. return bstrRet;
  1237. }
  1238. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  1239. //
  1240. // *** XML_GetGrandChildContent ***
  1241. //
  1242. // Description:
  1243. // Returns a bstr value from the requested child of the given element.
  1244. //
  1245. // Parameters:
  1246. // [In] pIXMLElement - A pointer to the element.
  1247. // [In] szChildW - The name of the child element.
  1248. // The caller is responsible for freeing the returned bstr.
  1249. //
  1250. // Comments:
  1251. // If pIElement represents
  1252. //
  1253. // <Channel>
  1254. // <Title>Harvey is a Cool Cat</Title>
  1255. // </Channel>
  1256. //
  1257. // Then this function will return
  1258. //
  1259. // "Harvey is a Cool Cat" for "TITLE",
  1260. //
  1261. ////////////////////////////////////////////////////////////////////////////////
  1262. BSTR
  1263. XML_GetGrandChildContent(
  1264. IXMLElement* pIXMLElement,
  1265. LPWSTR szChildW
  1266. )
  1267. {
  1268. ASSERT(pIXMLElement);
  1269. ASSERT(szChildW);
  1270. BSTR bstrRet = NULL;
  1271. IXMLElementCollection* pIXMLElementCollection;
  1272. if ((SUCCEEDED(pIXMLElement->get_children(&pIXMLElementCollection)))
  1273. && pIXMLElementCollection)
  1274. {
  1275. ASSERT(pIXMLElementCollection);
  1276. LONG nCount;
  1277. HRESULT hr = pIXMLElementCollection->get_length(&nCount);
  1278. ASSERT(SUCCEEDED(hr) || (FAILED(hr) && 0 == nCount));
  1279. for (int i = 0; (i < nCount) && !bstrRet; i++)
  1280. {
  1281. IXMLElement* pChildIXMLElement;
  1282. if (SUCCEEDED(XML_GetElementByIndex(pIXMLElementCollection, i,
  1283. &pChildIXMLElement)))
  1284. {
  1285. ASSERT(pChildIXMLElement);
  1286. BSTR bstrTagName;
  1287. if (SUCCEEDED(pChildIXMLElement->get_tagName(&bstrTagName)) && bstrTagName)
  1288. {
  1289. ASSERT(bstrTagName);
  1290. if (StrEqlW(bstrTagName, szChildW))
  1291. {
  1292. bstrRet = XML_GetFirstChildContent(pChildIXMLElement);
  1293. //
  1294. // If the tag exists, but it is empty, return the empty
  1295. // string.
  1296. //
  1297. if (NULL == bstrRet)
  1298. bstrRet = SysAllocString(L"");
  1299. }
  1300. SysFreeString(bstrTagName);
  1301. }
  1302. pChildIXMLElement->Release();
  1303. }
  1304. }
  1305. pIXMLElementCollection->Release();
  1306. }
  1307. return bstrRet;
  1308. }
  1309. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  1310. //
  1311. // *** XML_GetChildAttribute ***
  1312. //
  1313. //
  1314. // Description:
  1315. // Returns a bstr value from the requested child of the given element.
  1316. //
  1317. // Parameters:
  1318. // [In] pIXMLElement - A pointer to the element.
  1319. // [In] szChildW - The name of the child element.
  1320. // [In] szAttributeW - The name of the attribute.
  1321. // [In] szQualifierW - The name of the attribute qualifier.
  1322. // [In] szQualifierValueW - The required value of the qaulifier.
  1323. //
  1324. // Return:
  1325. // A bstr of the value contained in the child element if it is found.
  1326. // NULL if the child element or its value isn't found.
  1327. //
  1328. // Comments:
  1329. // This function will return atributes found in the child elements of the
  1330. // given element. For example:
  1331. //
  1332. // If pIElement represents
  1333. //
  1334. // <Channel>
  1335. // <Title VALUE="foo">
  1336. // <Author VALUE="bar">
  1337. // <Logo HRREF="url" TYPE="ICON">
  1338. // </Channel>
  1339. //
  1340. // Then this function will return
  1341. //
  1342. // "foo" for "TITLE", "VALUE", "", ""
  1343. // "bar" for "AUTHOR", "VALUE", "", ""
  1344. // "url" for "LOGO", "HREF", "TYPE", "ICON"
  1345. //
  1346. // NULL when the names have any other values.
  1347. //
  1348. // The caller is responsible for freeing the returned bstr.
  1349. //
  1350. ////////////////////////////////////////////////////////////////////////////////
  1351. BSTR
  1352. XML_GetChildAttribute(
  1353. IXMLElement* pIXMLElement,
  1354. LPWSTR szChildW,
  1355. LPWSTR szAttributeW,
  1356. LPWSTR szQualifierW,
  1357. LPWSTR szQualifierValueW
  1358. )
  1359. {
  1360. ASSERT(pIXMLElement);
  1361. ASSERT(szChildW);
  1362. ASSERT(szAttributeW);
  1363. BSTR bstrRet = NULL;
  1364. IXMLElementCollection* pIXMLElementCollection;
  1365. if ((SUCCEEDED(pIXMLElement->get_children(&pIXMLElementCollection)))
  1366. && pIXMLElementCollection)
  1367. {
  1368. ASSERT(pIXMLElementCollection);
  1369. LONG nCount;
  1370. //
  1371. // REVIEW: hr only used in debug builds.
  1372. //
  1373. HRESULT hr = pIXMLElementCollection->get_length(&nCount);
  1374. ASSERT(SUCCEEDED(hr) || (FAILED(hr) && 0 == nCount));
  1375. for (int i = 0; (i < nCount) && !bstrRet; i++)
  1376. {
  1377. IXMLElement* pChildIXMLElement;
  1378. if (SUCCEEDED(XML_GetElementByIndex(pIXMLElementCollection, i,
  1379. &pChildIXMLElement)))
  1380. {
  1381. ASSERT(pChildIXMLElement);
  1382. BSTR bstrTagName;
  1383. if (SUCCEEDED(pChildIXMLElement->get_tagName(&bstrTagName)) && bstrTagName)
  1384. {
  1385. ASSERT(bstrTagName);
  1386. if (StrEqlW(bstrTagName, szChildW))
  1387. {
  1388. bstrRet = XML_GetElementAttribute(pChildIXMLElement,
  1389. szAttributeW,
  1390. szQualifierW,
  1391. szQualifierValueW);
  1392. }
  1393. SysFreeString(bstrTagName);
  1394. }
  1395. pChildIXMLElement->Release();
  1396. }
  1397. }
  1398. pIXMLElementCollection->Release();
  1399. }
  1400. return bstrRet;
  1401. }
  1402. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  1403. //
  1404. // *** XML_GetElementAttribute ***
  1405. //
  1406. //
  1407. // Description:
  1408. // Returns the bstr value of of the requested attribute if it is found.
  1409. //
  1410. // Parameters:
  1411. // [In] pIXMLElement - The element that contains the attribute.
  1412. // [In] szAttributeW - The name of the attribute.
  1413. // [In] szQualifierW - The type qualifier for the atribute.
  1414. // [In] szQualifierValueW - The required value of the qaulifier.
  1415. //
  1416. // Return:
  1417. // A bstr containig the attributes value if it was found.
  1418. // NULL if the attribute wasn't found.
  1419. //
  1420. // Comments:
  1421. // The function will return attributes found inside of tags. For
  1422. // example:
  1423. //
  1424. // If pIXMLElement represents
  1425. //
  1426. // <Channel HREF="foo" Cloneable="NO">
  1427. // <USAGE VALUE="Channel">
  1428. // <USAGE VALUE="Screen Saver">
  1429. //
  1430. // Then this function will return
  1431. //
  1432. // "foo" for "HREF", "", ""
  1433. // "NO" for "Cloneable", "", ""
  1434. // "CHANNEL" for "VALUE", "VALUE", "CHANNEL"
  1435. // NULL for "VALUE", "VALUE", "NONE"
  1436. // "foo" for "HREF", "CLONEABLE", "NO"
  1437. //
  1438. // The caller is responsible for freeing the returned bstr.
  1439. //
  1440. ////////////////////////////////////////////////////////////////////////////////
  1441. BSTR
  1442. XML_GetElementAttribute(
  1443. IXMLElement* pIXMLElement,
  1444. LPWSTR szAttributeW,
  1445. LPWSTR szQualifierW,
  1446. LPWSTR szQualifierValueW
  1447. )
  1448. {
  1449. ASSERT(pIXMLElement);
  1450. ASSERT(szAttributeW);
  1451. ASSERT((NULL == szQualifierW && NULL == szQualifierValueW) ||
  1452. (szQualifierW && szQualifierValueW));
  1453. BSTR bstrRet = NULL;
  1454. VARIANT var;
  1455. VariantInit(&var);
  1456. if (NULL == szQualifierW)
  1457. {
  1458. if (SUCCEEDED(pIXMLElement->getAttribute(szAttributeW, &var)))
  1459. {
  1460. ASSERT(var.vt == VT_BSTR || NULL == var.bstrVal);
  1461. bstrRet = var.bstrVal;
  1462. }
  1463. }
  1464. else
  1465. {
  1466. if (SUCCEEDED(pIXMLElement->getAttribute(szQualifierW, &var)))
  1467. {
  1468. ASSERT(var.vt == VT_BSTR || NULL == var.bstrVal);
  1469. if(var.bstrVal)
  1470. {
  1471. if (0 == StrCmpIW(var.bstrVal, szQualifierValueW))
  1472. {
  1473. bstrRet = XML_GetElementAttribute(pIXMLElement, szAttributeW,
  1474. NULL, NULL);
  1475. }
  1476. }
  1477. VariantClear(&var);
  1478. }
  1479. }
  1480. return bstrRet;
  1481. }
  1482. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  1483. //
  1484. // *** XML_GetScreenSaverURL ***
  1485. //
  1486. //
  1487. // Description:
  1488. // Returns the screen saver URL of the first screen saver component in the channel.
  1489. //
  1490. // Parameters:
  1491. // [In] pXMLDocument - An XML document
  1492. // [Out] pbstrSSURL - The pointer that receives the screen saver URL.
  1493. //
  1494. // Return:
  1495. // S_OK if the screen saver URL was returned.
  1496. // E_FAIL if the screen saver URL couldn't be returned.
  1497. //
  1498. // Comments:
  1499. // This function gets the first screen saver element and then looks
  1500. // for the first top-level ITEM with a usage of ScreenSaver.
  1501. //
  1502. ////////////////////////////////////////////////////////////////////////////////
  1503. HRESULT
  1504. XML_GetScreenSaverURL(
  1505. IXMLDocument * pXMLDocument,
  1506. BSTR * pbstrSSURL)
  1507. {
  1508. HRESULT hr;
  1509. ASSERT(pXMLDocument);
  1510. ASSERT(pbstrSSURL);
  1511. IXMLElement* pIXMLElement;
  1512. LONG lDontCare;
  1513. hr = XML_GetFirstChannelElement(pXMLDocument, &pIXMLElement, &lDontCare);
  1514. if (SUCCEEDED(hr))
  1515. {
  1516. IXMLElement* pSSElement;
  1517. ASSERT(pIXMLElement);
  1518. hr = XML_GetScreenSaverElement(pIXMLElement, &pSSElement);
  1519. if (SUCCEEDED(hr))
  1520. {
  1521. ASSERT(pSSElement);
  1522. *pbstrSSURL = XML_GetAttribute(pSSElement, XML_HREF);
  1523. hr = *pbstrSSURL ? S_OK : E_FAIL;
  1524. pSSElement->Release();
  1525. }
  1526. pIXMLElement->Release();
  1527. }
  1528. return hr;
  1529. }
  1530. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  1531. //
  1532. // *** XML_GetScreenSaverElement ***
  1533. //
  1534. //
  1535. // Description:
  1536. // Returns the IXMLElement of the first screen saver component in the channel.
  1537. //
  1538. // Parameters:
  1539. // [In] pXMLElemet - An XML element
  1540. // [Out] ppIXMLElement - The pointer that receives the screen saver element.
  1541. //
  1542. // Return:
  1543. // S_OK if the first screen saver element was returned.
  1544. // E_FAIL if the element couldn't be returned.
  1545. //
  1546. // Comments:
  1547. // This function gets the first screen saver element and then looks
  1548. // for the first top-level ITEM with a usage of ScreenSaver.
  1549. //
  1550. ////////////////////////////////////////////////////////////////////////////////
  1551. HRESULT
  1552. XML_GetScreenSaverElement(
  1553. IXMLElement * pXMLElement,
  1554. IXMLElement ** ppScreenSaverElement)
  1555. {
  1556. ASSERT(pXMLElement);
  1557. ASSERT(ppScreenSaverElement);
  1558. IXMLElementCollection * pIXMLElementCollection;
  1559. HRESULT hr;
  1560. hr = pXMLElement->get_children(&pIXMLElementCollection);
  1561. if (SUCCEEDED(hr) && pIXMLElementCollection)
  1562. {
  1563. LONG nCount;
  1564. hr = pIXMLElementCollection->get_length(&nCount);
  1565. ASSERT(SUCCEEDED(hr) || (FAILED(hr) && 0 == nCount));
  1566. hr = E_FAIL;
  1567. BOOL bScreenSaver = FALSE;
  1568. for (int i = 0; (i < nCount) && !bScreenSaver; i++)
  1569. {
  1570. IXMLElement * pIXMLElement;
  1571. HRESULT hr2 = XML_GetElementByIndex(pIXMLElementCollection,
  1572. i,
  1573. &pIXMLElement);
  1574. if (SUCCEEDED(hr2))
  1575. {
  1576. ASSERT(pIXMLElement != NULL);
  1577. if (bScreenSaver = XML_IsScreenSaver(pIXMLElement))
  1578. {
  1579. pIXMLElement->AddRef();
  1580. *ppScreenSaverElement = pIXMLElement;
  1581. hr = S_OK;
  1582. }
  1583. pIXMLElement->Release();
  1584. }
  1585. hr = FAILED(hr2) ? hr2 : hr;
  1586. }
  1587. pIXMLElementCollection->Release();
  1588. }
  1589. else
  1590. hr = E_FAIL;
  1591. ASSERT((SUCCEEDED(hr) && *ppScreenSaverElement) || FAILED(hr));
  1592. return hr;
  1593. }
  1594. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  1595. //
  1596. // *** XML_GetSubscriptionInfo ***
  1597. //
  1598. //
  1599. // Description:
  1600. // Fills a structure with the subscription info for the given element.
  1601. //
  1602. // Parameters:
  1603. // [In] pIXMLElement - An xml element. The element doesn't have to be a
  1604. // subscription element.
  1605. // [Out] psi - The subscription info structure used by the
  1606. // subscription manager.
  1607. //
  1608. // Return:
  1609. // S_OK if any information was obtained.
  1610. //
  1611. // Comments:
  1612. // This function uses a webcheck API that fills a task trigger with
  1613. // subscription information.
  1614. //
  1615. // This function assumes that the psi->pTrigger points to a TASK_TRIGGER.
  1616. //
  1617. ////////////////////////////////////////////////////////////////////////////////
  1618. HRESULT
  1619. XML_GetSubscriptionInfo(
  1620. IXMLElement* pIXMLElement,
  1621. SUBSCRIPTIONINFO* psi
  1622. )
  1623. {
  1624. ASSERT(pIXMLElement);
  1625. ASSERT(psi);
  1626. ASSERT(psi->pTrigger);
  1627. HRESULT hr = E_FAIL;
  1628. #ifndef UNIX
  1629. HINSTANCE hinst = LoadLibrary(TEXT("webcheck.dll"));
  1630. if (hinst)
  1631. {
  1632. typedef (*PFTRIGGERFUNCTION)(IXMLElement* pIXMLElement,
  1633. TASK_TRIGGER* ptt);
  1634. PFTRIGGERFUNCTION XMLSheduleElementToTaskTrigger;
  1635. XMLSheduleElementToTaskTrigger = (PFTRIGGERFUNCTION)
  1636. GetProcAddress(hinst,
  1637. "XMLScheduleElementToTaskTrigger");
  1638. if (XMLSheduleElementToTaskTrigger)
  1639. {
  1640. ((TASK_TRIGGER*)(psi->pTrigger))->cbTriggerSize =
  1641. sizeof(TASK_TRIGGER);
  1642. hr = XMLSheduleElementToTaskTrigger(pIXMLElement,
  1643. (TASK_TRIGGER*)psi->pTrigger);
  1644. if (FAILED(hr))
  1645. psi->pTrigger = NULL;
  1646. }
  1647. FreeLibrary(hinst);
  1648. }
  1649. // See if there is a screen saver available.
  1650. IXMLElement * pScreenSaverElement;
  1651. if (SUCCEEDED(XML_GetScreenSaverElement( pIXMLElement,
  1652. &pScreenSaverElement)))
  1653. {
  1654. psi->fUpdateFlags |= SUBSINFO_CHANNELFLAGS;
  1655. psi->fChannelFlags |= CHANNEL_AGENT_PRECACHE_SCRNSAVER;
  1656. pScreenSaverElement->Release();
  1657. }
  1658. BSTR bstrLogin = XML_GetAttribute(pIXMLElement, XML_LOGIN);
  1659. if (bstrLogin)
  1660. {
  1661. psi->bNeedPassword = TRUE;
  1662. psi->fUpdateFlags |= SUBSINFO_NEEDPASSWORD; //this member is now valid
  1663. SysFreeString(bstrLogin);
  1664. }
  1665. #endif /* !UNIX */
  1666. return hr;
  1667. }
  1668. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  1669. //
  1670. // *** XML_GetBaseURL ***
  1671. //
  1672. //
  1673. // Description:
  1674. // Returns the base url for the given collection.
  1675. //
  1676. // Parameters:
  1677. // [In] pIXMLElement - A pointer to an XML element.
  1678. //
  1679. // Return:
  1680. // A bstr containing the base URL if there is one.
  1681. // NULL if ther isn't a base URL.
  1682. //
  1683. // Comments:
  1684. // If the current element has a BASE attribute return this attributes value.
  1685. // Else return the BASE attribute of its parent.
  1686. //
  1687. ////////////////////////////////////////////////////////////////////////////////
  1688. BSTR
  1689. XML_GetBaseURL(
  1690. IXMLElement* pIXMLElement
  1691. )
  1692. {
  1693. ASSERT(pIXMLElement);
  1694. BSTR bstrRet = XML_GetAttribute(pIXMLElement, XML_BASE);
  1695. if (NULL == bstrRet)
  1696. {
  1697. IXMLElement* pParentIXMLElement;
  1698. if (SUCCEEDED(pIXMLElement->get_parent(&pParentIXMLElement)) && pParentIXMLElement)
  1699. {
  1700. ASSERT(pParentIXMLElement);
  1701. bstrRet = XML_GetBaseURL(pParentIXMLElement);
  1702. pParentIXMLElement->Release();
  1703. }
  1704. }
  1705. return bstrRet;
  1706. }
  1707. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  1708. //
  1709. // *** XML_CombineURL ***
  1710. //
  1711. //
  1712. // Description:
  1713. // Combine the given URL with the base URL.
  1714. //
  1715. // Parameters:
  1716. // [In] bstrBaseURL - The base URL.
  1717. // [In] bstrRelURL - The relative URL.
  1718. //
  1719. // Return:
  1720. // A combination of the base and relative URL.
  1721. //
  1722. // Comments:
  1723. //
  1724. //
  1725. ////////////////////////////////////////////////////////////////////////////////
  1726. BSTR
  1727. XML_CombineURL(
  1728. BSTR bstrBaseURL,
  1729. BSTR bstrRelURL
  1730. )
  1731. {
  1732. ASSERT(bstrBaseURL);
  1733. ASSERT(bstrRelURL);
  1734. BSTR bstrRet = NULL;
  1735. WCHAR wszCombinedURL[INTERNET_MAX_URL_LENGTH];
  1736. DWORD cch = ARRAYSIZE(wszCombinedURL);
  1737. if (InternetCombineUrlW(bstrBaseURL, bstrRelURL, wszCombinedURL, &cch, 0))
  1738. bstrRet = SysAllocString(wszCombinedURL);
  1739. return bstrRet;
  1740. }
  1741. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  1742. //
  1743. // *** XML_IsCdfDisplayable ***
  1744. //
  1745. //
  1746. // Description:
  1747. // Determines if the given item should be displayed in the cdf view.
  1748. //
  1749. // Parameters:
  1750. // [In] pIXMLElement - A pointer to the IXMLElement interface of an object.
  1751. //
  1752. // Return:
  1753. // TRUE if the object should be displayed.
  1754. // FALSE otherwise.
  1755. //
  1756. // Comments:
  1757. // aCDFTypes contains the tag names of XML items that the cdf shell
  1758. // shell extension displays.
  1759. //
  1760. ////////////////////////////////////////////////////////////////////////////////
  1761. BOOL
  1762. XML_IsCdfDisplayable(
  1763. IXMLElement* pIXMLElement
  1764. )
  1765. {
  1766. #define KEYWORDS (sizeof(aCDFTypes) / sizeof(aCDFTypes[0]))
  1767. static const LPWSTR aCDFTypes[] = {
  1768. WSTR_ITEM,
  1769. WSTR_CHANNEL,
  1770. WSTR_SOFTDIST
  1771. };
  1772. ASSERT(pIXMLElement);
  1773. BOOL bRet = FALSE;
  1774. BSTR pStr;
  1775. HRESULT hr = pIXMLElement->get_tagName(&pStr);
  1776. if (SUCCEEDED(hr) && pStr)
  1777. {
  1778. ASSERT(pStr);
  1779. for(int i = 0; (i < KEYWORDS) && !bRet; i++)
  1780. bRet = StrEqlW(pStr, aCDFTypes[i]);
  1781. if (bRet)
  1782. bRet = XML_IsUsageChannel(pIXMLElement);
  1783. //
  1784. // Special processing.
  1785. //
  1786. if (bRet && StrEqlW(pStr, WSTR_SOFTDIST))
  1787. bRet = XML_IsSoftDistDisplayable(pIXMLElement);
  1788. SysFreeString(pStr);
  1789. }
  1790. return bRet;
  1791. }
  1792. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  1793. //
  1794. // *** XML_IsSoftDistDisplayable ***
  1795. //
  1796. //
  1797. // Description:
  1798. // Determins if the given software distribution element should be displayed.
  1799. //
  1800. // Parameters:
  1801. // [In] pIXMLElement - Pointer to the software distribution xml element.
  1802. //
  1803. // Return:
  1804. // TRUE if the element should be displayed.
  1805. // FALSE if the element shouldn't be displayed.
  1806. //
  1807. // Comments:
  1808. // This function asks the software disribution COM object if this software
  1809. // distribution tag should be displayed on this users machine.
  1810. //
  1811. ////////////////////////////////////////////////////////////////////////////////
  1812. BOOL
  1813. XML_IsSoftDistDisplayable(
  1814. IXMLElement* pIXMLElement
  1815. )
  1816. {
  1817. ASSERT(pIXMLElement);
  1818. ISoftDistExt* pISoftDistExt;
  1819. HRESULT hr = CoCreateInstance(CLSID_SoftDistExt, NULL, CLSCTX_INPROC_SERVER,
  1820. IID_ISoftDistExt, (void**)&pISoftDistExt);
  1821. if (SUCCEEDED(hr))
  1822. {
  1823. ASSERT(pISoftDistExt);
  1824. hr = pISoftDistExt->ProcessSoftDist(NULL, pIXMLElement, 0);
  1825. pISoftDistExt->Release();
  1826. }
  1827. return SUCCEEDED(hr) ? TRUE : FALSE;
  1828. }
  1829. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  1830. //
  1831. // *** XML_IsUsageChannel ***
  1832. //
  1833. //
  1834. // Description:
  1835. // Determines if this item should be displayed in channel view based on its
  1836. // usage tag.
  1837. //
  1838. // Parameters:
  1839. // [In] pIXMLelement - A pointer to the element.
  1840. //
  1841. // Return:
  1842. // TRUE if the item should be displayed in the channel view.
  1843. // FALSE otherwise.
  1844. //
  1845. // Comments:
  1846. // If an element doesn't have a USAGE tag then it gets displayed. If an
  1847. // element has any numberf of usage tags one of them must have a value of
  1848. // CHANNEL or will not get displayed.
  1849. //
  1850. ////////////////////////////////////////////////////////////////////////////////
  1851. BOOL
  1852. XML_IsUsageChannel(
  1853. IXMLElement* pIXMLElement
  1854. )
  1855. {
  1856. ASSERT(pIXMLElement);
  1857. BOOL bRet;
  1858. //
  1859. // First check if there are any USAGE elements.
  1860. //
  1861. BSTR bstrUsage = XML_GetAttribute(pIXMLElement, XML_USAGE);
  1862. if (bstrUsage)
  1863. {
  1864. //
  1865. // See if USAGE is CHANNEL.
  1866. //
  1867. if (StrEqlW(bstrUsage, WSTR_CHANNEL))
  1868. {
  1869. bRet = TRUE;
  1870. }
  1871. else
  1872. {
  1873. //
  1874. // Check if there are any other USAGE tags with value CHANNEL.
  1875. //
  1876. BSTR bstrChannel = XML_GetAttribute(pIXMLElement,
  1877. XML_USAGE_CHANNEL);
  1878. if (bstrChannel)
  1879. {
  1880. SysFreeString(bstrChannel);
  1881. bRet = TRUE;
  1882. }
  1883. else
  1884. {
  1885. bRet = FALSE;
  1886. }
  1887. }
  1888. SysFreeString(bstrUsage);
  1889. }
  1890. else
  1891. {
  1892. bRet = TRUE; // No USAGE tag defaults channel usage.
  1893. }
  1894. return bRet;
  1895. }
  1896. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  1897. //
  1898. // *** XML_IsChannel ***
  1899. //
  1900. //
  1901. // Description:
  1902. // Determines if the given XML item is a channel.
  1903. //
  1904. // Parameters:
  1905. // [In] pIXMLElement - A pointer to the IXMLElement interface of an object.
  1906. //
  1907. // Return:
  1908. // TRUE if the object is a channel.
  1909. // FALSE otherwise.
  1910. //
  1911. // Comments:
  1912. //
  1913. //
  1914. ////////////////////////////////////////////////////////////////////////////////
  1915. BOOL
  1916. XML_IsChannel(
  1917. IXMLElement* pIXMLElement
  1918. )
  1919. {
  1920. ASSERT(pIXMLElement);
  1921. BOOL bRet = FALSE;
  1922. BSTR pStr;
  1923. HRESULT hr = pIXMLElement->get_tagName(&pStr);
  1924. if (SUCCEEDED(hr) && pStr)
  1925. {
  1926. ASSERT(pStr);
  1927. bRet = StrEqlW(pStr, WSTR_CHANNEL);
  1928. SysFreeString(pStr);
  1929. }
  1930. return bRet;
  1931. }
  1932. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  1933. //
  1934. // *** XML_IsDesktopComponent ***
  1935. //
  1936. //
  1937. // Description:
  1938. // Determines if the given XML item is a desktop component.
  1939. //
  1940. // Parameters:
  1941. // [In] pIXMLElement - A pointer to the IXMLElement interface of an object.
  1942. //
  1943. // Return:
  1944. // TRUE if the object is a desktop component.
  1945. // FALSE otherwise.
  1946. //
  1947. // Comments:
  1948. //
  1949. //
  1950. ////////////////////////////////////////////////////////////////////////////////
  1951. BOOL
  1952. XML_IsDesktopComponent(
  1953. IXMLElement* pIXMLElement
  1954. )
  1955. {
  1956. ASSERT(pIXMLElement);
  1957. BOOL bRet;
  1958. BSTR bstr = XML_GetAttribute(pIXMLElement, XML_USAGE_DSKCMP);
  1959. if (bstr)
  1960. {
  1961. SysFreeString(bstr);
  1962. bRet = TRUE;
  1963. }
  1964. else
  1965. {
  1966. bRet = FALSE;
  1967. }
  1968. return bRet;
  1969. }
  1970. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  1971. //
  1972. // *** XML_IsScreenSaver ***
  1973. //
  1974. //
  1975. // Description:
  1976. // Determines if the given XML item is a screen saver.
  1977. //
  1978. // Parameters:
  1979. // [In] pIXMLElement - A pointer to the IXMLElement interface of an object.
  1980. //
  1981. // Return:
  1982. // TRUE if the object is a screen saver
  1983. // FALSE otherwise.
  1984. //
  1985. // Comments:
  1986. //
  1987. //
  1988. ////////////////////////////////////////////////////////////////////////////////
  1989. BOOL
  1990. XML_IsScreenSaver(
  1991. IXMLElement* pIXMLElement
  1992. )
  1993. {
  1994. ASSERT(pIXMLElement);
  1995. BOOL bRet;
  1996. BSTR bstrUsage = XML_GetAttribute(pIXMLElement, XML_USAGE);
  1997. if (bstrUsage)
  1998. {
  1999. bRet = (
  2000. (StrCmpIW(bstrUsage, WSTR_SCRNSAVE) == 0)
  2001. ||
  2002. (StrCmpIW(bstrUsage, WSTR_SMARTSCRN) == 0)
  2003. );
  2004. SysFreeString(bstrUsage);
  2005. }
  2006. else
  2007. {
  2008. bRet = FALSE;
  2009. }
  2010. return bRet;
  2011. }
  2012. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  2013. //
  2014. // *** XML_IsDesktopComponentUsage ***
  2015. //
  2016. //
  2017. // Description:
  2018. // Determines if the given XML item is a desktop component usage element.
  2019. //
  2020. // Parameters:
  2021. // [In] pIXMLElement - A pointer to the IXMLElement interface of an object.
  2022. //
  2023. // Return:
  2024. // TRUE if the object is a desktop component usage element.
  2025. // FALSE otherwise.
  2026. //
  2027. // Comments:
  2028. //
  2029. //
  2030. ////////////////////////////////////////////////////////////////////////////////
  2031. BOOL
  2032. XML_IsDesktopComponentUsage(
  2033. IXMLElement* pIXMLElement
  2034. )
  2035. {
  2036. ASSERT(pIXMLElement);
  2037. BOOL bRet = FALSE;
  2038. BSTR bstrName;
  2039. if (SUCCEEDED(pIXMLElement->get_tagName(&bstrName)) && bstrName)
  2040. {
  2041. ASSERT(bstrName);
  2042. if (StrEqlW(bstrName, WSTR_USAGE))
  2043. {
  2044. BSTR bstrValue = XML_GetElementAttribute(pIXMLElement, WSTR_VALUE, NULL,
  2045. NULL);
  2046. if (bstrValue)
  2047. {
  2048. bRet = (0 == StrCmpIW(bstrValue, WSTR_DSKCMP));
  2049. SysFreeString(bstrValue);
  2050. }
  2051. }
  2052. SysFreeString(bstrName);
  2053. }
  2054. return bRet;
  2055. }
  2056. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  2057. //
  2058. // *** XML_IsFolder ***
  2059. //
  2060. //
  2061. // Description:
  2062. // Determines if the given item is a folder.
  2063. //
  2064. // Parameters:
  2065. // [In] pIXMLElement - A pointer to the IXMLElement interface of an object.
  2066. //
  2067. // Return:
  2068. // TRUE if the object contains other cdf displayable objects.
  2069. // FALSE otherwise.
  2070. //
  2071. // Comments:
  2072. // An item is a folder if at least one of its children is displayable as a
  2073. // cdf item.
  2074. //
  2075. ////////////////////////////////////////////////////////////////////////////////
  2076. BOOL
  2077. XML_IsFolder(
  2078. IXMLElement* pIXMLElement
  2079. )
  2080. {
  2081. ASSERT(pIXMLElement);
  2082. BOOL bRet = FALSE;
  2083. IXMLElementCollection* pIXMLElementCollection;
  2084. HRESULT hr = pIXMLElement->get_children(&pIXMLElementCollection);
  2085. if (SUCCEEDED(hr) && pIXMLElementCollection)
  2086. {
  2087. ASSERT(pIXMLElementCollection);
  2088. LONG nCount;
  2089. hr = pIXMLElementCollection->get_length(&nCount);
  2090. ASSERT(SUCCEEDED(hr) || (FAILED(hr) && 0 == nCount));
  2091. for (int i = 0; (i < nCount) && !bRet; i++)
  2092. {
  2093. IXMLElement* pIXMLElementTemp;
  2094. hr = XML_GetElementByIndex(pIXMLElementCollection, i, &pIXMLElementTemp);
  2095. if (SUCCEEDED(hr))
  2096. {
  2097. ASSERT(pIXMLElementTemp);
  2098. if (XML_IsCdfDisplayable(pIXMLElementTemp))
  2099. bRet = TRUE;
  2100. pIXMLElementTemp->Release();
  2101. }
  2102. }
  2103. pIXMLElementCollection->Release();
  2104. }
  2105. return bRet;
  2106. }
  2107. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  2108. //
  2109. // *** XML_ContainsFolder ***
  2110. //
  2111. //
  2112. // Description:
  2113. // Determines if there are any cdf folders in the given collection.
  2114. //
  2115. // Parameters:
  2116. // [In] pIXMLElementCollection - A pointer to the collection.
  2117. //
  2118. // Return:
  2119. // TRUE if the collection contains a cf folder.
  2120. // FALSE otherwise.
  2121. //
  2122. // Comments:
  2123. //
  2124. //
  2125. ////////////////////////////////////////////////////////////////////////////////
  2126. BOOL
  2127. XML_ContainsFolder(
  2128. IXMLElementCollection* pIXMLElementCollection
  2129. )
  2130. {
  2131. ASSERT(pIXMLElementCollection);
  2132. BOOL bContainsFolder = FALSE;
  2133. LONG nCount;
  2134. HRESULT hr = pIXMLElementCollection->get_length(&nCount);
  2135. ASSERT(SUCCEEDED(hr) || (FAILED(hr) && 0 == nCount));
  2136. for (int i = 0; (i < nCount) && !bContainsFolder; i++)
  2137. {
  2138. IXMLElement* pIXMLElement;
  2139. hr = XML_GetElementByIndex(pIXMLElementCollection, i, &pIXMLElement);
  2140. if (SUCCEEDED(hr))
  2141. {
  2142. ASSERT(pIXMLElement);
  2143. bContainsFolder = XML_IsFolder(pIXMLElement);
  2144. pIXMLElement->Release();
  2145. }
  2146. }
  2147. return bContainsFolder;
  2148. }
  2149. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  2150. //
  2151. // *** XML_ChildContainsFolder ***
  2152. //
  2153. //
  2154. // Description:
  2155. //
  2156. //
  2157. // Parameters:
  2158. //
  2159. //
  2160. // Return:
  2161. //
  2162. //
  2163. // Comments:
  2164. //
  2165. //
  2166. ////////////////////////////////////////////////////////////////////////////////
  2167. BOOL
  2168. XML_ChildContainsFolder(
  2169. IXMLElementCollection *pIXMLElementCollectionParent,
  2170. ULONG nIndexChild
  2171. )
  2172. {
  2173. BOOL bRet = FALSE;
  2174. IXMLElement* pIXMLElement;
  2175. HRESULT hr = XML_GetElementByIndex(pIXMLElementCollectionParent,
  2176. nIndexChild, &pIXMLElement);
  2177. if (SUCCEEDED(hr))
  2178. {
  2179. ASSERT(pIXMLElement);
  2180. IXMLElementCollection* pIXMLElementCollection;
  2181. hr = pIXMLElement->get_children(&pIXMLElementCollection);
  2182. if (SUCCEEDED(hr) && pIXMLElementCollection)
  2183. {
  2184. ASSERT(pIXMLElementCollection);
  2185. bRet = XML_ContainsFolder(pIXMLElementCollection);
  2186. pIXMLElementCollection->Release();
  2187. }
  2188. pIXMLElement->Release();
  2189. }
  2190. return bRet;
  2191. }
  2192. #ifdef DEBUG
  2193. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  2194. //
  2195. // *** XML_IsCdfidlMemberOf ***
  2196. //
  2197. //
  2198. // Description:
  2199. // Checks if the cdf item id list is associated with a member of the given
  2200. // element collection.
  2201. //
  2202. // Parameters:
  2203. // [In] pIXMLElementCollection - The element collection to check.
  2204. // [In] pcdfidl - A pointer to cdf item id list
  2205. //
  2206. // Return:
  2207. // TRUE if the given id list can be associated with an elemnt of the given
  2208. // collection.
  2209. // FALSE otherwise.
  2210. //
  2211. // Comments:
  2212. // This function checks if the last id in the list could have been
  2213. // generated from its corresponding element in the element collection.
  2214. //
  2215. ////////////////////////////////////////////////////////////////////////////////
  2216. BOOL
  2217. XML_IsCdfidlMemberOf(
  2218. IXMLElementCollection* pIXMLElementCollection,
  2219. PCDFITEMIDLIST pcdfidl
  2220. )
  2221. {
  2222. ASSERT(CDFIDL_IsValid(pcdfidl));
  2223. BOOL bRet = FALSE;
  2224. //
  2225. // pIXMLElementCollection is NULL when a Folder hasn't been initialized.
  2226. // It isn't always neccessary to parse the cdf to get pidl info from
  2227. // the pidl. pIXMLElement collection will be NULL in low memory situations
  2228. // also. Don't return FALSE for these cases. Also check for special
  2229. // pidls that aren't in element collections.
  2230. //
  2231. if (pIXMLElementCollection &&
  2232. CDFIDL_GetIndexId(&pcdfidl->mkid) != INDEX_CHANNEL_LINK)
  2233. {
  2234. IXMLElement* pIXMLElement;
  2235. HRESULT hr = XML_GetElementByIndex(pIXMLElementCollection,
  2236. CDFIDL_GetIndexId(&pcdfidl->mkid),
  2237. &pIXMLElement);
  2238. if (SUCCEEDED(hr))
  2239. {
  2240. ASSERT(pIXMLElement);
  2241. PCDFITEMIDLIST pcdfidlElement;
  2242. pcdfidlElement = CDFIDL_CreateFromXMLElement(pIXMLElement,
  2243. CDFIDL_GetIndexId(&pcdfidl->mkid));
  2244. if (pcdfidlElement)
  2245. {
  2246. ASSERT(CDFIDL_IsValid(pcdfidlElement));
  2247. bRet = (0 == CDFIDL_CompareId(&pcdfidl->mkid,
  2248. &pcdfidlElement->mkid));
  2249. CDFIDL_Free(pcdfidlElement);
  2250. }
  2251. pIXMLElement->Release();
  2252. }
  2253. }
  2254. else
  2255. {
  2256. bRet = TRUE;
  2257. }
  2258. return bRet;
  2259. }
  2260. #endif //DEBUG
  2261. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  2262. //
  2263. // *** XML_IsStrEqualW ***
  2264. //
  2265. //
  2266. // Description:
  2267. // Determines if two WCHAR strings are equal.
  2268. //
  2269. // Parameters:
  2270. // [In] p1 - The first string to compare.
  2271. // [In] p2 - The second string to compare.
  2272. //
  2273. // Return:
  2274. // TRUE if the strings are equal.
  2275. // FALSE otherwise.
  2276. //
  2277. // Comments:
  2278. // lstrcmpW doesn't work on W95 so this function has its own strcmp logic.
  2279. //
  2280. ////////////////////////////////////////////////////////////////////////////////
  2281. #if 0
  2282. inline
  2283. BOOL
  2284. XML_IsStrEqualW(
  2285. LPWSTR p1,
  2286. LPWSTR p2
  2287. )
  2288. {
  2289. ASSERT(p1);
  2290. ASSERT(p2);
  2291. while ((*p1 == *p2) && *p1 && *p2)
  2292. {
  2293. p1++; p2++;
  2294. }
  2295. return (*p1 == *p2);
  2296. }
  2297. #endif