2775 lines
71 KiB
C++
2775 lines
71 KiB
C++
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// xmlutil.cpp
|
||
|
//
|
||
|
// XML item helper functions.
|
||
|
//
|
||
|
// History:
|
||
|
//
|
||
|
// 4/1/97 edwardp Created.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
//
|
||
|
// Includes
|
||
|
//
|
||
|
|
||
|
#include "stdinc.h"
|
||
|
#include "cdfidl.h"
|
||
|
#include "xmlutil.h"
|
||
|
#include "winineti.h"
|
||
|
#include <ocidl.h> // IPersistStreamInit.
|
||
|
|
||
|
//
|
||
|
// Function prototypes.
|
||
|
//
|
||
|
|
||
|
|
||
|
//
|
||
|
// XML helper functions.
|
||
|
//
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// *** XML_MarkCacheEntrySticky ***
|
||
|
//
|
||
|
// Description:
|
||
|
// Marks the cache entry for the given URL as sticky by setting its
|
||
|
// expiration delta to be very high
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] lpszUrl - url for cache entry to make sticky
|
||
|
//
|
||
|
// Return:
|
||
|
// S_OK if the url entry was successfully marked sticky
|
||
|
// E_FAIL otherwise.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT XML_MarkCacheEntrySticky(LPTSTR lpszURL)
|
||
|
{
|
||
|
char chBuf[MAX_CACHE_ENTRY_INFO_SIZE];
|
||
|
LPINTERNET_CACHE_ENTRY_INFO lpInfo = (LPINTERNET_CACHE_ENTRY_INFO) chBuf;
|
||
|
|
||
|
DWORD dwSize = sizeof(chBuf);
|
||
|
lpInfo->dwStructSize = dwSize;
|
||
|
|
||
|
if (GetUrlCacheEntryInfo(lpszURL, lpInfo, &dwSize))
|
||
|
{
|
||
|
lpInfo->dwExemptDelta = 0xFFFFFFFF; // make VERY sticky
|
||
|
if (SetUrlCacheEntryInfo(lpszURL, lpInfo, CACHE_ENTRY_EXEMPT_DELTA_FC))
|
||
|
{
|
||
|
return S_OK;
|
||
|
}
|
||
|
}
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_SynchronousParse ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Synchronously parses the given URL.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLDocument - An interface pointer to an XML document object.
|
||
|
// [In] pidl - The pidl of the cdf file (contains the full path).
|
||
|
//
|
||
|
// Return:
|
||
|
// S_OK if the object was parsed successfully.
|
||
|
// E_FAIL otherwise.
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
XML_SynchronousParse(
|
||
|
IXMLDocument* pIXMLDocument,
|
||
|
LPTSTR szPath
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLDocument);
|
||
|
ASSERT(szPath);
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
IPersistStreamInit* pIPersistStreamInit;
|
||
|
|
||
|
hr = pIXMLDocument->QueryInterface(IID_IPersistStreamInit,
|
||
|
(void**)&pIPersistStreamInit);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pIPersistStreamInit);
|
||
|
|
||
|
IStream* pIStream;
|
||
|
|
||
|
//
|
||
|
// URLOpenBlockingStream pumps window messages! Don't use it!
|
||
|
//
|
||
|
|
||
|
//hr = URLOpenBlockingStream(NULL, szPath, &pIStream, 0, NULL);
|
||
|
|
||
|
hr = SHCreateStreamOnFile(szPath, STGM_READ, &pIStream);
|
||
|
|
||
|
TraceMsg(TF_CDFPARSE, "[%s SHCreateStreamOnFileW %s %s %s]",
|
||
|
PathIsURL(szPath) ? TEXT("*** ") : TEXT(""), szPath,
|
||
|
SUCCEEDED(hr) ? TEXT("SUCCEEDED") : TEXT("FAILED"),
|
||
|
PathIsURL(szPath) ? TEXT("***") : TEXT(""));
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pIStream);
|
||
|
|
||
|
//
|
||
|
// Load loads and parses the file. If this call succeeds the cdf
|
||
|
// will be displayed. If it fails none of the cdf is displayed.
|
||
|
//
|
||
|
|
||
|
hr = pIPersistStreamInit->Load(pIStream);
|
||
|
|
||
|
TraceMsg(TF_CDFPARSE, "[XML Parser %s]",
|
||
|
SUCCEEDED(hr) ? TEXT("SUCCEEDED") : TEXT("FAILED"));
|
||
|
|
||
|
pIStream->Release();
|
||
|
|
||
|
//
|
||
|
// If CDFVIEW is downloading a CDF from the net mark it as sticky
|
||
|
// in the cache
|
||
|
//
|
||
|
if (PathIsURL(szPath))
|
||
|
{
|
||
|
XML_MarkCacheEntrySticky(szPath);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pIPersistStreamInit->Release();
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_DownloadImages ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
//
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
//
|
||
|
// Return:
|
||
|
//
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
XML_DownloadLogo(
|
||
|
IXMLDocument *pIXMLDocument
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLDocument);
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
IXMLElement* pIXMLElement;
|
||
|
LONG nIndex;
|
||
|
|
||
|
hr = XML_GetFirstChannelElement(pIXMLDocument, &pIXMLElement, &nIndex);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
BSTR bstrURL = XML_GetAttribute(pIXMLElement, XML_LOGO);
|
||
|
|
||
|
if (bstrURL)
|
||
|
{
|
||
|
hr = XML_DownloadImage(bstrURL);
|
||
|
|
||
|
SysFreeString(bstrURL);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Download the wide logo also.
|
||
|
//
|
||
|
|
||
|
bstrURL = XML_GetAttribute(pIXMLElement, XML_LOGO_WIDE);
|
||
|
|
||
|
if (bstrURL)
|
||
|
{
|
||
|
hr = XML_DownloadImage(bstrURL);
|
||
|
|
||
|
SysFreeString(bstrURL);
|
||
|
}
|
||
|
|
||
|
|
||
|
pIXMLElement->Release();
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_DownloadImages ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
//
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
//
|
||
|
// Return:
|
||
|
//
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
XML_DownloadImages(
|
||
|
IXMLDocument *pIXMLDocument
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLDocument);
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
IXMLElement* pIXMLElement;
|
||
|
LONG nIndex;
|
||
|
|
||
|
hr = XML_GetFirstChannelElement(pIXMLDocument, &pIXMLElement, &nIndex);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
hr = XML_RecursiveImageDownload(pIXMLElement);
|
||
|
|
||
|
pIXMLElement->Release();
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_RecuriveImageDownload ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
//
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
//
|
||
|
// Return:
|
||
|
//
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
XML_RecursiveImageDownload(
|
||
|
IXMLElement* pIXMLElement
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
BSTR bstrTagName;
|
||
|
|
||
|
HRESULT hr2 = pIXMLElement->get_tagName(&bstrTagName);
|
||
|
|
||
|
if (SUCCEEDED(hr2) && bstrTagName)
|
||
|
{
|
||
|
if (StrEqlW(bstrTagName, WSTR_LOGO))
|
||
|
{
|
||
|
BSTR bstrURL = XML_GetAttribute(pIXMLElement, XML_HREF);
|
||
|
|
||
|
if (bstrURL && *bstrURL != 0)
|
||
|
{
|
||
|
hr = XML_DownloadImage(bstrURL);
|
||
|
|
||
|
SysFreeString(bstrURL);
|
||
|
}
|
||
|
}
|
||
|
else if (XML_IsCdfDisplayable(pIXMLElement))
|
||
|
{
|
||
|
IXMLElementCollection* pIXMLElementCollection;
|
||
|
|
||
|
hr2 = pIXMLElement->get_children(&pIXMLElementCollection);
|
||
|
|
||
|
if (SUCCEEDED(hr2) && pIXMLElementCollection)
|
||
|
{
|
||
|
ASSERT(pIXMLElementCollection);
|
||
|
|
||
|
LONG nCount;
|
||
|
|
||
|
hr2 = pIXMLElementCollection->get_length(&nCount);
|
||
|
|
||
|
ASSERT(SUCCEEDED(hr2) || (FAILED(hr2) && 0 == nCount));
|
||
|
|
||
|
for (int i = 0; i < nCount; i++)
|
||
|
{
|
||
|
IXMLElement* pIXMLElementChild;
|
||
|
|
||
|
hr2 = XML_GetElementByIndex(pIXMLElementCollection, i,
|
||
|
&pIXMLElementChild);
|
||
|
|
||
|
if (SUCCEEDED(hr2))
|
||
|
{
|
||
|
ASSERT (pIXMLElementChild);
|
||
|
|
||
|
XML_RecursiveImageDownload(pIXMLElementChild);
|
||
|
|
||
|
pIXMLElementChild->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pIXMLElementCollection->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SysFreeString(bstrTagName);
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_DownloadImage ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
//
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
//
|
||
|
// Return:
|
||
|
//
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
XML_DownloadImage(
|
||
|
LPCWSTR pwszURL
|
||
|
)
|
||
|
{
|
||
|
ASSERT (pwszURL);
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
WCHAR szFileW[MAX_PATH];
|
||
|
|
||
|
hr = URLDownloadToCacheFileW(NULL, pwszURL, szFileW,
|
||
|
ARRAYSIZE(szFileW), 0, NULL);
|
||
|
|
||
|
//
|
||
|
// Mark the logo in the cache as sticky
|
||
|
//
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
TCHAR szURL[INTERNET_MAX_URL_LENGTH];
|
||
|
SHUnicodeToTChar(pwszURL, szURL, ARRAYSIZE(szURL));
|
||
|
|
||
|
XML_MarkCacheEntrySticky(szURL);
|
||
|
}
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
|
||
|
TCHAR szURL[INTERNET_MAX_URL_LENGTH];
|
||
|
SHUnicodeToTChar(pwszURL, szURL, ARRAYSIZE(szURL));
|
||
|
|
||
|
TraceMsg(TF_CDFPARSE,
|
||
|
"[*** Image URLDownloadToCacheFileW %s %s ***]",
|
||
|
szURL, SUCCEEDED(hr) ? TEXT("SUCCEEDED") :
|
||
|
TEXT("FAILED"));
|
||
|
|
||
|
#endif // DEBUG
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetDocType ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the type of the given xml document.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLDocument - A pointer to the xml document.
|
||
|
//
|
||
|
// Return:
|
||
|
// DOC_CHANNEL, DOC_DESKTOPCOMPONENT, DOC_SOFTWAREUPDATE, or DOC_UNKNOWN.
|
||
|
//
|
||
|
// Comments:
|
||
|
// If at the root level of a channel an ITEM contains a USAGE type of
|
||
|
// DesktopComponent then the document is a Desktop Component otherwise
|
||
|
// it is a channel.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
XMLDOCTYPE
|
||
|
XML_GetDocType(IXMLDocument* pIXMLDocument)
|
||
|
{
|
||
|
ASSERT(pIXMLDocument);
|
||
|
|
||
|
XMLDOCTYPE xdtRet;
|
||
|
|
||
|
IXMLElement* pIXMLElement;
|
||
|
LONG nIndex;
|
||
|
|
||
|
HRESULT hr = XML_GetFirstDesktopComponentElement(pIXMLDocument,
|
||
|
&pIXMLElement,
|
||
|
&nIndex);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
xdtRet = DOC_DESKTOPCOMPONENT;
|
||
|
|
||
|
pIXMLElement->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = XML_GetFirstChannelElement(pIXMLDocument, &pIXMLElement,
|
||
|
&nIndex);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
BSTR bstr = XML_GetAttribute( pIXMLElement, XML_USAGE_SOFTWAREUPDATE );
|
||
|
|
||
|
if (bstr)
|
||
|
{
|
||
|
SysFreeString(bstr);
|
||
|
xdtRet = DOC_SOFTWAREUPDATE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
xdtRet = DOC_CHANNEL;
|
||
|
}
|
||
|
|
||
|
|
||
|
pIXMLElement->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
xdtRet = DOC_UNKNOWN;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return xdtRet;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetChildElementCollection ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns an element collection given the parent collection and an index.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pParentIXMLElementCollection - The parent collection.
|
||
|
// [In] nIndex - Index to the requested collection.
|
||
|
// [Out] ppIXMLElementCollection - A pointer that receives the
|
||
|
// requested collection.
|
||
|
//
|
||
|
// Return:
|
||
|
// S_OK if the collection is returned.
|
||
|
// E_FAIL otherwise.
|
||
|
//
|
||
|
// Comments:
|
||
|
// The caller is responsible for calling Release() on the returned interface
|
||
|
// pointer.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
XML_GetChildElementCollection(
|
||
|
IXMLElementCollection *pParentIXMLElementCollection,
|
||
|
LONG nIndex,
|
||
|
IXMLElementCollection** ppIXMLElementCollection
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pParentIXMLElementCollection);
|
||
|
ASSERT(ppIXMLElementCollection);
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
IXMLElement* pIXMLElement;
|
||
|
|
||
|
hr = XML_GetElementByIndex(pParentIXMLElementCollection, nIndex,
|
||
|
&pIXMLElement);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
hr = pIXMLElement->get_children(ppIXMLElementCollection);
|
||
|
if(SUCCEEDED(hr) && !(*ppIXMLElementCollection))
|
||
|
hr = E_FAIL;
|
||
|
|
||
|
pIXMLElement->Release();
|
||
|
}
|
||
|
|
||
|
ASSERT((SUCCEEDED(hr) && (*ppIXMLElementCollection)) || FAILED(hr));
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetElementByIndex ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the nIndex'th element of the given collection.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElementCollection - A pointer to the collection.
|
||
|
// [In] nIndex - The index of the item to retrieve.
|
||
|
// [Out] ppIXMLElement - A pointer that receives the item.
|
||
|
//
|
||
|
// Return:
|
||
|
// S_OK if the item was retrieved.
|
||
|
// E_FAIL otherwise.
|
||
|
//
|
||
|
// Comments:
|
||
|
// The caller is responsible for calling Release() on the returned interface
|
||
|
// pointer.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
XML_GetElementByIndex(
|
||
|
IXMLElementCollection* pIXMLElementCollection,
|
||
|
LONG nIndex,
|
||
|
IXMLElement** ppIXMLElement
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElementCollection);
|
||
|
ASSERT(ppIXMLElement);
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
VARIANT var1, var2;
|
||
|
|
||
|
VariantInit(&var1);
|
||
|
VariantInit(&var2);
|
||
|
|
||
|
var1.vt = VT_I4;
|
||
|
var1.lVal = nIndex;
|
||
|
|
||
|
IDispatch* pIDispatch;
|
||
|
|
||
|
hr = pIXMLElementCollection->item(var1, var2, &pIDispatch);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pIDispatch);
|
||
|
|
||
|
hr = pIDispatch->QueryInterface(IID_IXMLElement, (void**)ppIXMLElement);
|
||
|
|
||
|
pIDispatch->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*ppIXMLElement = NULL;
|
||
|
}
|
||
|
|
||
|
ASSERT((SUCCEEDED(hr) && *ppIXMLElement) ||
|
||
|
(FAILED(hr) && NULL == *ppIXMLElement));
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetElementByName ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the first element with the given tag name.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElementCollection - A pointer to the collection.
|
||
|
// [In] nszNameW - The tag name of the item to retrieve.
|
||
|
// [Out] ppIXMLElement - A pointer that receives the item.
|
||
|
//
|
||
|
// Return:
|
||
|
// S_OK if the item was retrieved.
|
||
|
// E_OUTOFMEMORY if a sys string could not be allocated.
|
||
|
// E_FAIL otherwise.
|
||
|
//
|
||
|
// Comments:
|
||
|
// The caller is responsible for calling Release() on the returned interface
|
||
|
// pointer.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
XML_GetElementByName(
|
||
|
IXMLElementCollection* pIXMLElementCollection,
|
||
|
LPWSTR szNameW,
|
||
|
IXMLElement** ppIXMLElement
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElementCollection);
|
||
|
ASSERT(ppIXMLElement);
|
||
|
|
||
|
HRESULT hr = E_FAIL;
|
||
|
|
||
|
LONG nCount;
|
||
|
|
||
|
HRESULT hr2 = pIXMLElementCollection->get_length(&nCount);
|
||
|
|
||
|
ASSERT(SUCCEEDED(hr2) || (FAILED(hr2) && 0 == nCount));
|
||
|
|
||
|
for (int i = 0, bElement = FALSE; (i < nCount) && !bElement; i++)
|
||
|
{
|
||
|
IXMLElement* pIXMLElement;
|
||
|
|
||
|
hr2 = XML_GetElementByIndex(pIXMLElementCollection, i, &pIXMLElement);
|
||
|
|
||
|
if (SUCCEEDED(hr2))
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
BSTR pStr;
|
||
|
|
||
|
hr2 = pIXMLElement->get_tagName(&pStr);
|
||
|
|
||
|
if (SUCCEEDED(hr2) && pStr)
|
||
|
{
|
||
|
ASSERT(pStr);
|
||
|
|
||
|
if (bElement = StrEqlW(pStr, szNameW))
|
||
|
{
|
||
|
pIXMLElement->AddRef();
|
||
|
*ppIXMLElement = pIXMLElement;
|
||
|
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
|
||
|
SysFreeString(pStr);
|
||
|
}
|
||
|
|
||
|
pIXMLElement->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
hr = FAILED(hr2) ? hr2 : hr;
|
||
|
|
||
|
/* Enable this when pIXMLElementCollection->item works with VT_BSTR
|
||
|
|
||
|
VARIANT var1, var2;
|
||
|
|
||
|
VariantInit(&var1);
|
||
|
VariantInit(&var2);
|
||
|
|
||
|
var1.vt = VT_BSTR;
|
||
|
var1.bstrVal = SysAllocString(szNameW);
|
||
|
|
||
|
var2.vt = VT_I4
|
||
|
var2.lVal = 1;
|
||
|
|
||
|
if (var1.bstrVal)
|
||
|
{
|
||
|
|
||
|
IDispatch* pIDispatch;
|
||
|
|
||
|
hr = pIXMLElementCollection->item(var1, var2, &pIDispatch);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pIDispatch);
|
||
|
|
||
|
hr = pIDispatch->QueryInterface(IID_IXMLElement,
|
||
|
(void**)ppIXMLElement);
|
||
|
|
||
|
pIDispatch->Release();
|
||
|
}
|
||
|
|
||
|
SysFreeString(var1.bstrVal);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
}
|
||
|
|
||
|
*/
|
||
|
|
||
|
ASSERT((SUCCEEDED(hr) && ppIXMLElement) || FAILED(hr));
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetFirstChannelElement ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the IXMLElement of the first channel in the XML document.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLDocument - A pointer to the XML document object.
|
||
|
// [Out] ppIXMLElement - The pointer that receives the element.
|
||
|
// [Out] pnIndex - The index of the element.
|
||
|
//
|
||
|
// Return:
|
||
|
// S_OK if the first channel element was returned.
|
||
|
// E_FAIL if the element couldn't be returned.
|
||
|
//
|
||
|
// Comments:
|
||
|
// This function can't call XML_GetElementByName to find the first channel.
|
||
|
// XML channels can have a tag name of "Channel" or "CHAN".
|
||
|
// XML_GetElementByName wouldn't be able to determine which of the items
|
||
|
// came first if both where present in the XML doc.
|
||
|
//
|
||
|
// The caller is responsible for calling Release() on the returned interface
|
||
|
// pointer. The return pointer is not NULL'ed out on error.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
XML_GetFirstChannelElement(
|
||
|
IXMLDocument* pIXMLDocument,
|
||
|
IXMLElement** ppIXMLElement,
|
||
|
PLONG pnIndex)
|
||
|
{
|
||
|
ASSERT(pIXMLDocument);
|
||
|
ASSERT(ppIXMLElement);
|
||
|
ASSERT(pnIndex);
|
||
|
IXMLElement *pRootElem = NULL;
|
||
|
HRESULT hr = E_FAIL;
|
||
|
|
||
|
*pnIndex = 0;
|
||
|
hr = pIXMLDocument->get_root(&pRootElem);
|
||
|
|
||
|
if (SUCCEEDED(hr) && pRootElem)
|
||
|
{
|
||
|
ASSERT(pRootElem);
|
||
|
|
||
|
if (XML_IsChannel(pRootElem))
|
||
|
{
|
||
|
*ppIXMLElement = pRootElem;
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pRootElem->Release();
|
||
|
hr = E_FAIL;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_FAIL;
|
||
|
}
|
||
|
|
||
|
ASSERT((SUCCEEDED(hr) && (*ppIXMLElement)) || FAILED(hr));
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetDesktopElementFromChannelElement ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the IXMLElement of the first dekstop component in the channel.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pChannelIXMLElement - A pointer to the XML channel element.
|
||
|
// [Out] ppIXMLElement - The pointer that receives the element.
|
||
|
// [Out] pnIndex - The index of the element.
|
||
|
//
|
||
|
// Return:
|
||
|
// S_OK if the first desktop element was returned.
|
||
|
// E_FAIL if the element couldn't be returned.
|
||
|
//
|
||
|
// Comments:
|
||
|
// This looks for the first ITEM with a usage of DesktopComponent.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
HRESULT
|
||
|
XML_GetDesktopElementFromChannelElement(
|
||
|
IXMLElement* pChannelIXMLElement,
|
||
|
IXMLElement** ppIXMLElement,
|
||
|
PLONG pnIndex)
|
||
|
{
|
||
|
ASSERT(pChannelIXMLElement);
|
||
|
ASSERT(ppIXMLElement);
|
||
|
ASSERT(pnIndex);
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
IXMLElementCollection* pIXMLElementCollection;
|
||
|
|
||
|
hr = pChannelIXMLElement->get_children(&pIXMLElementCollection);
|
||
|
|
||
|
if (SUCCEEDED(hr) && pIXMLElementCollection)
|
||
|
{
|
||
|
ASSERT(pIXMLElementCollection);
|
||
|
|
||
|
LONG nCount;
|
||
|
|
||
|
hr = pIXMLElementCollection->get_length(&nCount);
|
||
|
|
||
|
ASSERT(SUCCEEDED(hr) || (FAILED(hr) && 0 == nCount));
|
||
|
|
||
|
hr = E_FAIL;
|
||
|
|
||
|
for (int i = 0, bComponent = FALSE; (i < nCount) && !bComponent;
|
||
|
i++)
|
||
|
{
|
||
|
IXMLElement* pIXMLElement;
|
||
|
|
||
|
HRESULT hr2 = XML_GetElementByIndex(pIXMLElementCollection, i,
|
||
|
&pIXMLElement);
|
||
|
|
||
|
if (SUCCEEDED(hr2))
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
if (bComponent = XML_IsDesktopComponent(pIXMLElement))
|
||
|
{
|
||
|
pIXMLElement->AddRef();
|
||
|
*ppIXMLElement = pIXMLElement;
|
||
|
*pnIndex = i;
|
||
|
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
|
||
|
pIXMLElement->Release();
|
||
|
}
|
||
|
|
||
|
hr = FAILED(hr2) ? hr2 : hr;
|
||
|
}
|
||
|
|
||
|
pIXMLElementCollection->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_FAIL;
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetFirstDesktopComponentElement ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the IXMLElement of the first dekstop component in the channel.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLDocument - A pointer to the XML document object.
|
||
|
// [Out] ppIXMLElement - The pointer that receives the element.
|
||
|
// [Out] pnIndex - The index of the element.
|
||
|
//
|
||
|
// Return:
|
||
|
// S_OK if the first channel element was returned.
|
||
|
// E_FAIL if the element couldn't be returned.
|
||
|
//
|
||
|
// Comments:
|
||
|
// This function gets the first channel and then looks for the first
|
||
|
// top-level ITEM with a usage of DesktopComponent.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
XML_GetFirstDesktopComponentElement(
|
||
|
IXMLDocument* pIXMLDocument,
|
||
|
IXMLElement** ppIXMLElement,
|
||
|
PLONG pnIndex)
|
||
|
{
|
||
|
ASSERT(pIXMLDocument);
|
||
|
ASSERT(ppIXMLElement);
|
||
|
ASSERT(pnIndex);
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
IXMLElement* pChannelIXMLElement;
|
||
|
LONG nIndex;
|
||
|
|
||
|
hr = XML_GetFirstChannelElement(pIXMLDocument, &pChannelIXMLElement,
|
||
|
&nIndex);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pChannelIXMLElement);
|
||
|
|
||
|
hr = XML_GetDesktopElementFromChannelElement(pChannelIXMLElement,
|
||
|
ppIXMLElement,
|
||
|
pnIndex);
|
||
|
|
||
|
pChannelIXMLElement->Release();
|
||
|
}
|
||
|
|
||
|
ASSERT((SUCCEEDED(hr) && *ppIXMLElement) || FAILED(hr));
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetFirstDesktopComponentUsageElement ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the first USAGE VALUE="DesktopComponent" element of the first
|
||
|
// desktop component.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLDocument - A pointer to the the document.
|
||
|
// [Out] pIXMLElement - A pointer the receives the element.
|
||
|
//
|
||
|
// Return:
|
||
|
// S_OK if the element was found.
|
||
|
// E_FAIL if the element wasn't found.
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
XML_GetFirstDesktopComponentUsageElement(
|
||
|
IXMLDocument* pIXMLDocument,
|
||
|
IXMLElement** ppIXMLElement
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLDocument);
|
||
|
ASSERT(ppIXMLElement);
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
IXMLElement* pParentIXMLElement;
|
||
|
LONG nIndex;
|
||
|
|
||
|
hr = XML_GetFirstDesktopComponentElement(pIXMLDocument, &pParentIXMLElement,
|
||
|
&nIndex);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
IXMLElementCollection* pIXMLElementCollection;
|
||
|
|
||
|
hr = pParentIXMLElement->get_children(&pIXMLElementCollection);
|
||
|
|
||
|
if (SUCCEEDED(hr) && pIXMLElementCollection)
|
||
|
{
|
||
|
ASSERT(pIXMLElementCollection);
|
||
|
|
||
|
LONG nCount;
|
||
|
|
||
|
hr = pIXMLElementCollection->get_length(&nCount);
|
||
|
|
||
|
ASSERT(SUCCEEDED(hr) || (FAILED(hr) && 0 == nCount));
|
||
|
|
||
|
hr = E_FAIL;
|
||
|
|
||
|
for (int i = 0, bUsage = FALSE; (i < nCount) && !bUsage; i++)
|
||
|
{
|
||
|
IXMLElement* pIXMLElement;
|
||
|
|
||
|
HRESULT hr2 = XML_GetElementByIndex(pIXMLElementCollection, i,
|
||
|
&pIXMLElement);
|
||
|
|
||
|
if (SUCCEEDED(hr2))
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
if (bUsage = XML_IsDesktopComponentUsage(pIXMLElement))
|
||
|
{
|
||
|
pIXMLElement->AddRef();
|
||
|
*ppIXMLElement = pIXMLElement;
|
||
|
//*pnIndex = i;
|
||
|
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
|
||
|
pIXMLElement->Release();
|
||
|
}
|
||
|
|
||
|
hr = FAILED(hr2) ? hr2 : hr;
|
||
|
}
|
||
|
|
||
|
pIXMLElementCollection->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_FAIL;
|
||
|
}
|
||
|
|
||
|
pParentIXMLElement->Release();
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetDesktopComponentInfo ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Fills in the desktop component information structure.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLDocument - A ponter to the document.
|
||
|
// [Out] pInfo - A desktop component information structure.
|
||
|
//
|
||
|
// Return:
|
||
|
// S_OK if the given document is desktop component document.
|
||
|
// E_FAIL otherwise.
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
XML_GetDesktopComponentInfo(
|
||
|
IXMLDocument* pIXMLDocument,
|
||
|
COMPONENT* pInfo
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLDocument);
|
||
|
ASSERT(pInfo);
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
IXMLElement* pIXMLElement;
|
||
|
|
||
|
hr = XML_GetFirstDesktopComponentUsageElement(pIXMLDocument, &pIXMLElement);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
memset(pInfo, 0, sizeof(COMPONENT));
|
||
|
|
||
|
pInfo->dwSize = sizeof(COMPONENT);
|
||
|
pInfo->fChecked = TRUE;
|
||
|
pInfo->fDirty = TRUE;
|
||
|
pInfo->fNoScroll = FALSE;
|
||
|
pInfo->cpPos.dwSize = sizeof(COMPPOS);
|
||
|
pInfo->cpPos.izIndex = COMPONENT_TOP;
|
||
|
pInfo->dwCurItemState = IS_NORMAL;
|
||
|
|
||
|
BSTR bstrValue;
|
||
|
|
||
|
if (bstrValue = XML_GetAttribute(pIXMLElement, XML_OPENAS))
|
||
|
{
|
||
|
if (!(0 == StrCmpIW(bstrValue, WSTR_IMAGE)))
|
||
|
{
|
||
|
pInfo->iComponentType = COMP_TYPE_WEBSITE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pInfo->iComponentType = COMP_TYPE_PICTURE;
|
||
|
}
|
||
|
|
||
|
SysFreeString(bstrValue);
|
||
|
}
|
||
|
|
||
|
if (bstrValue = XML_GetAttribute(pIXMLElement, XML_WIDTH))
|
||
|
{
|
||
|
pInfo->cpPos.dwWidth = StrToIntW(bstrValue);
|
||
|
SysFreeString(bstrValue);
|
||
|
}
|
||
|
|
||
|
if (bstrValue = XML_GetAttribute(pIXMLElement, XML_HEIGHT))
|
||
|
{
|
||
|
pInfo->cpPos.dwHeight = StrToIntW(bstrValue);
|
||
|
SysFreeString(bstrValue);
|
||
|
}
|
||
|
|
||
|
if (bstrValue = XML_GetAttribute(pIXMLElement, XML_ITEMSTATE))
|
||
|
{
|
||
|
if(!StrCmpIW(bstrValue, WSTR_NORMAL))
|
||
|
pInfo->dwCurItemState = IS_NORMAL;
|
||
|
else
|
||
|
{
|
||
|
if(!StrCmpIW(bstrValue, WSTR_FULLSCREEN))
|
||
|
pInfo->dwCurItemState = IS_FULLSCREEN;
|
||
|
else
|
||
|
pInfo->dwCurItemState = IS_SPLIT;
|
||
|
}
|
||
|
SysFreeString(bstrValue);
|
||
|
}
|
||
|
|
||
|
if (bstrValue = XML_GetAttribute(pIXMLElement, XML_CANRESIZE))
|
||
|
{
|
||
|
pInfo->cpPos.fCanResize = StrEqlW(bstrValue, WSTR_YES);
|
||
|
SysFreeString(bstrValue);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (bstrValue = XML_GetAttribute(pIXMLElement, XML_CANRESIZEX))
|
||
|
{
|
||
|
pInfo->cpPos.fCanResizeX = StrEqlW(bstrValue, WSTR_YES);
|
||
|
SysFreeString(bstrValue);
|
||
|
}
|
||
|
|
||
|
if (bstrValue = XML_GetAttribute(pIXMLElement, XML_CANRESIZEY))
|
||
|
{
|
||
|
pInfo->cpPos.fCanResizeY = StrEqlW(bstrValue, WSTR_YES);
|
||
|
SysFreeString(bstrValue);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bstrValue = XML_GetAttribute(pIXMLElement, XML_PREFERREDLEFT))
|
||
|
{
|
||
|
if (StrChrW(bstrValue, L'%'))
|
||
|
{
|
||
|
pInfo->cpPos.iPreferredLeftPercent = StrToIntW(bstrValue);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pInfo->cpPos.iLeft = StrToIntW(bstrValue);
|
||
|
}
|
||
|
|
||
|
SysFreeString(bstrValue);
|
||
|
}
|
||
|
|
||
|
if (bstrValue = XML_GetAttribute(pIXMLElement, XML_PREFERREDTOP))
|
||
|
{
|
||
|
if (StrChrW(bstrValue, L'%'))
|
||
|
{
|
||
|
pInfo->cpPos.iPreferredTopPercent = StrToIntW(bstrValue);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pInfo->cpPos.iTop = StrToIntW(bstrValue);
|
||
|
}
|
||
|
|
||
|
SysFreeString(bstrValue);
|
||
|
}
|
||
|
|
||
|
IXMLElement *pIXMLElementParent;
|
||
|
|
||
|
hr = pIXMLElement->get_parent(&pIXMLElementParent);
|
||
|
if(!pIXMLElementParent)
|
||
|
hr = E_FAIL;
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pIXMLElementParent);
|
||
|
|
||
|
if (bstrValue = XML_GetAttribute(pIXMLElementParent, XML_TITLE))
|
||
|
{
|
||
|
StrCpyNW(pInfo->wszFriendlyName, bstrValue,
|
||
|
ARRAYSIZE(pInfo->wszFriendlyName));
|
||
|
SysFreeString(bstrValue);
|
||
|
}
|
||
|
|
||
|
if (bstrValue = XML_GetAttribute(pIXMLElementParent, XML_HREF))
|
||
|
{
|
||
|
if (*bstrValue)
|
||
|
{
|
||
|
StrCpyNW(pInfo->wszSource, bstrValue,
|
||
|
ARRAYSIZE(pInfo->wszSource));
|
||
|
SysFreeString(bstrValue);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_FAIL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
IXMLElement *pIXMLChannel;
|
||
|
LONG nIndex;
|
||
|
|
||
|
hr = XML_GetFirstChannelElement(pIXMLDocument, &pIXMLChannel,
|
||
|
&nIndex);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pIXMLChannel);
|
||
|
if (bstrValue = XML_GetAttribute(pIXMLChannel, XML_SELF))
|
||
|
{
|
||
|
StrCpyNW(pInfo->wszSubscribedURL, bstrValue,
|
||
|
ARRAYSIZE(pInfo->wszSubscribedURL));
|
||
|
SysFreeString(bstrValue);
|
||
|
}
|
||
|
|
||
|
pIXMLChannel->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pIXMLElementParent->Release();
|
||
|
}
|
||
|
|
||
|
pIXMLElement->Release();
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetAttribute ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns a bstr representing the requested attribute of the given element.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElement - A pointer to the XML element.
|
||
|
// [In] attribute - The requested attribute.
|
||
|
//
|
||
|
// Return:
|
||
|
// A bstr with the attribute value.
|
||
|
// NULL if there wasn't enough memory to allocated the bstr.
|
||
|
//
|
||
|
// Comments:
|
||
|
// This function keeps a table of attributes and their properties. It bases
|
||
|
// attribute look up on this table.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BSTR
|
||
|
XML_GetAttribute(
|
||
|
IXMLElement* pIXMLElement,
|
||
|
XML_ATTRIBUTE attrIndex
|
||
|
)
|
||
|
{
|
||
|
//
|
||
|
// A table is used to read values associated with a given xml element. The
|
||
|
// xml element can have attributes (values inside the elements tag) or child
|
||
|
// elements (elements between tags).
|
||
|
//
|
||
|
// Rules:
|
||
|
// 1) If child is NULL. Read the Attribute from the current item.
|
||
|
// 2) If child is not NULL, read the Attribute from the child
|
||
|
// item.
|
||
|
// 3) If AttributeType is NULL, use the Attribute value to read the
|
||
|
// attribute.
|
||
|
// 4) If AttributeType is not NULL, verify that the item contains
|
||
|
// the AttributeType attribute before using Attribute to read
|
||
|
// the value.
|
||
|
// 5) If the value is not found use Default as the return value.
|
||
|
//
|
||
|
|
||
|
static const struct _tagXML_ATTRIBUTE_ARRAY
|
||
|
{
|
||
|
LPWSTR szChildW;
|
||
|
LPWSTR szAttributeW;
|
||
|
LPWSTR szQualifierW;
|
||
|
LPWSTR szQualifierValueW;
|
||
|
XML_ATTRIBUTE attrSecondary;
|
||
|
LPWSTR szDefaultW;
|
||
|
BOOL fUseBaseURL;
|
||
|
XML_ATTRIBUTE attribute; // Only used in ASSERT.
|
||
|
}
|
||
|
aAttribTable[] =
|
||
|
{
|
||
|
/*
|
||
|
Child Attribute Qualifier Qual. Value Secondary Lookup Default Base URL Enum Check
|
||
|
-------------- -------------- ----------- ------------ ----------------- ---------- -------- -----------------*/
|
||
|
{WSTR_TITLE, NULL, NULL, NULL, XML_TITLE_ATTR, WSTR_EMPTY, FALSE, XML_TITLE },
|
||
|
{NULL, WSTR_TITLE, NULL, NULL, XML_HREF, WSTR_EMPTY, FALSE, XML_TITLE_ATTR },
|
||
|
{NULL, WSTR_HREF, NULL, NULL, XML_A_HREF, WSTR_EMPTY, TRUE, XML_HREF },
|
||
|
{WSTR_ABSTRACT, NULL, NULL, NULL, XML_ABSTRACT_ATTR, WSTR_EMPTY, FALSE, XML_ABSTRACT },
|
||
|
{NULL, WSTR_ABSTRACT, NULL, NULL, XML_HREF, WSTR_EMPTY, FALSE, XML_ABSTRACT_ATTR},
|
||
|
{WSTR_LOGO, WSTR_HREF, WSTR_STYLE, WSTR_ICON, XML_NULL, NULL, TRUE, XML_ICON },
|
||
|
{WSTR_LOGO, WSTR_HREF, WSTR_STYLE, WSTR_IMAGE, XML_LOGO_DEFAULT, NULL, TRUE, XML_LOGO },
|
||
|
{WSTR_LOGO, WSTR_HREF, NULL, NULL, XML_NULL, NULL, TRUE, XML_LOGO_DEFAULT },
|
||
|
{NULL, WSTR_SELF, NULL, NULL, XML_SELF_OLD, NULL, TRUE, XML_SELF },
|
||
|
{WSTR_SELF, WSTR_HREF, NULL, NULL, XML_NULL, NULL, TRUE, XML_SELF_OLD },
|
||
|
{NULL, WSTR_BASE, NULL, NULL, XML_NULL, NULL, FALSE, XML_BASE },
|
||
|
{WSTR_USAGE, WSTR_VALUE, NULL, NULL, XML_SHOW, NULL, FALSE, XML_USAGE },
|
||
|
{WSTR_USAGE, WSTR_VALUE, WSTR_VALUE, WSTR_CHANNEL, XML_SHOW_CHANNEL, NULL, FALSE, XML_USAGE_CHANNEL},
|
||
|
{WSTR_USAGE, WSTR_VALUE, WSTR_VALUE, WSTR_DSKCMP, XML_SHOW_DSKCMP, NULL, FALSE, XML_USAGE_DSKCMP },
|
||
|
{WSTR_WIDTH, WSTR_VALUE, NULL, NULL, XML_NULL, WSTR_ZERO, FALSE, XML_WIDTH },
|
||
|
{WSTR_HEIGHT, WSTR_VALUE, NULL, NULL, XML_NULL, WSTR_ZERO, FALSE, XML_HEIGHT },
|
||
|
{WSTR_RESIZE, WSTR_VALUE, NULL, NULL, XML_NULL, NULL, FALSE, XML_CANRESIZE },
|
||
|
{WSTR_RESIZEX, WSTR_VALUE, NULL, NULL, XML_NULL, WSTR_YES, FALSE, XML_CANRESIZEX },
|
||
|
{WSTR_RESIZEY, WSTR_VALUE, NULL, NULL, XML_NULL, WSTR_YES, FALSE, XML_CANRESIZEY },
|
||
|
{WSTR_PREFLEFT, WSTR_VALUE, NULL, NULL, XML_NULL, NULL, FALSE, XML_PREFERREDLEFT},
|
||
|
{WSTR_PREFTOP, WSTR_VALUE, NULL, NULL, XML_NULL, NULL, FALSE, XML_PREFERREDTOP },
|
||
|
{WSTR_OPENAS, WSTR_VALUE, NULL, NULL, XML_NULL, WSTR_HTML, FALSE, XML_OPENAS },
|
||
|
{NULL, WSTR_SHOW, NULL, NULL, XML_NULL, NULL, FALSE, XML_SHOW },
|
||
|
{NULL, WSTR_SHOW, WSTR_SHOW, WSTR_CHANNEL, XML_NULL, NULL, FALSE, XML_SHOW_CHANNEL },
|
||
|
{NULL, WSTR_SHOW, WSTR_SHOW, WSTR_DSKCMP, XML_NULL, NULL, FALSE, XML_SHOW_DSKCMP },
|
||
|
{WSTR_A, WSTR_HREF, NULL, NULL, XML_INFOURI, WSTR_EMPTY, TRUE, XML_A_HREF },
|
||
|
{NULL, WSTR_INFOURI, NULL, NULL, XML_NULL, WSTR_EMPTY, TRUE, XML_INFOURI },
|
||
|
{WSTR_LOGO, WSTR_HREF, WSTR_STYLE, WSTR_IMAGEW, XML_NULL, NULL, TRUE, XML_LOGO_WIDE },
|
||
|
{WSTR_LOGIN, NULL, NULL, NULL, XML_NULL, NULL, FALSE, XML_LOGIN },
|
||
|
|
||
|
{WSTR_USAGE, WSTR_VALUE, WSTR_VALUE, WSTR_SOFTWAREUPDATE, XML_SHOW_SOFTWAREUPDATE, NULL, FALSE, XML_USAGE_SOFTWAREUPDATE},
|
||
|
{NULL, WSTR_SHOW, WSTR_SHOW, WSTR_SOFTWAREUPDATE, XML_NULL, NULL, FALSE, XML_SHOW_SOFTWAREUPDATE },
|
||
|
{WSTR_ITEMSTATE,WSTR_VALUE, NULL, NULL, XML_NULL, WSTR_NORMAL,FALSE, XML_ITEMSTATE },
|
||
|
};
|
||
|
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
//
|
||
|
// REVIEW: aAttribTable attribute field only used in debug builds.
|
||
|
//
|
||
|
|
||
|
ASSERT(attrIndex == aAttribTable[attrIndex].attribute);
|
||
|
|
||
|
BSTR bstrRet = NULL;
|
||
|
|
||
|
if (NULL == aAttribTable[attrIndex].szAttributeW)
|
||
|
{
|
||
|
bstrRet = XML_GetGrandChildContent(pIXMLElement,
|
||
|
aAttribTable[attrIndex].szChildW);
|
||
|
|
||
|
}
|
||
|
else if (NULL != aAttribTable[attrIndex].szChildW)
|
||
|
{
|
||
|
bstrRet = XML_GetChildAttribute(pIXMLElement,
|
||
|
aAttribTable[attrIndex].szChildW,
|
||
|
aAttribTable[attrIndex].szAttributeW,
|
||
|
aAttribTable[attrIndex].szQualifierW,
|
||
|
aAttribTable[attrIndex].szQualifierValueW);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bstrRet = XML_GetElementAttribute(pIXMLElement,
|
||
|
aAttribTable[attrIndex].szAttributeW,
|
||
|
aAttribTable[attrIndex].szQualifierW,
|
||
|
aAttribTable[attrIndex].szQualifierValueW);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If the title or tooltip aren't displayable on the local system use the
|
||
|
// URL in their place.
|
||
|
//
|
||
|
|
||
|
if (bstrRet && (XML_TITLE == attrIndex || XML_TITLE_ATTR == attrIndex ||
|
||
|
XML_ABSTRACT == attrIndex))
|
||
|
{
|
||
|
if (!StrLocallyDisplayable(bstrRet))
|
||
|
{
|
||
|
SysFreeString(bstrRet);
|
||
|
bstrRet = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Special cases:
|
||
|
// TITLE can also be an attribute.
|
||
|
// ABSTRACT can also be an attribute.
|
||
|
// LOGO elements don't have to have the TYPE="IMAGE"
|
||
|
// SELF is now an attribute SELF_OLD can be removed in the future.
|
||
|
// USAGE can also be specified via the SHOW attribute.
|
||
|
// USAGE_CHANNEL should also check for SHOW="Channel".
|
||
|
// USAGE_DSKCMP should also check for SHOW="DesktopComponent"
|
||
|
//
|
||
|
|
||
|
if (NULL == bstrRet && XML_NULL != aAttribTable[attrIndex].attrSecondary)
|
||
|
{
|
||
|
bstrRet = XML_GetAttribute(pIXMLElement,
|
||
|
aAttribTable[attrIndex].attrSecondary);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Combine URL if required.
|
||
|
//
|
||
|
|
||
|
if (bstrRet && aAttribTable[attrIndex].fUseBaseURL)
|
||
|
{
|
||
|
BSTR bstrBaseURL = XML_GetBaseURL(pIXMLElement);
|
||
|
|
||
|
if (bstrBaseURL)
|
||
|
{
|
||
|
|
||
|
BSTR bstrCombinedURL = XML_CombineURL(bstrBaseURL, bstrRet);
|
||
|
|
||
|
if (bstrCombinedURL)
|
||
|
{
|
||
|
SysFreeString(bstrRet);
|
||
|
bstrRet = bstrCombinedURL;
|
||
|
}
|
||
|
|
||
|
SysFreeString(bstrBaseURL);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* The following prevent long urls from over-running the pidl buffer */
|
||
|
|
||
|
if (bstrRet &&
|
||
|
(attrIndex == XML_HREF) &&
|
||
|
(SysStringLen(bstrRet) > INTERNET_MAX_URL_LENGTH))
|
||
|
{
|
||
|
SysReAllocStringLen(&bstrRet, bstrRet, INTERNET_MAX_URL_LENGTH-1);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Set default return value.
|
||
|
//
|
||
|
|
||
|
if (NULL == bstrRet && aAttribTable[attrIndex].szDefaultW)
|
||
|
bstrRet = SysAllocString(aAttribTable[attrIndex].szDefaultW);
|
||
|
|
||
|
|
||
|
return bstrRet;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetFirstChildContent ***
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns a bstr value from first child of the given element.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElement - A pointer to the element.
|
||
|
// The caller is responsible for freeing the returned bstr.
|
||
|
//
|
||
|
// Comments:
|
||
|
// If pIElement represents
|
||
|
//
|
||
|
// <Title>Harvey is a Cool Cat<B>this will be ignored</B></Title>
|
||
|
//
|
||
|
// Then this function will return
|
||
|
//
|
||
|
// "Harvey is a Cool Cat"
|
||
|
//
|
||
|
// REVIEW THIS IS A TEMPORARY ROUTINE UNTIL THE XML PARSER SUPPORTS THIS DIRECTLY
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BSTR
|
||
|
XML_GetFirstChildContent(
|
||
|
IXMLElement* pIXMLElement
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
BSTR bstrRet = NULL;
|
||
|
|
||
|
IXMLElementCollection* pIXMLElementCollection;
|
||
|
|
||
|
if ((SUCCEEDED(pIXMLElement->get_children(&pIXMLElementCollection)))
|
||
|
&& pIXMLElementCollection)
|
||
|
{
|
||
|
ASSERT(pIXMLElementCollection);
|
||
|
|
||
|
LONG nCount;
|
||
|
|
||
|
HRESULT hr = pIXMLElementCollection->get_length(&nCount);
|
||
|
|
||
|
ASSERT(SUCCEEDED(hr) || (FAILED(hr) && 0 == nCount));
|
||
|
|
||
|
if (nCount >= 1)
|
||
|
{
|
||
|
IXMLElement* pChildIXMLElement;
|
||
|
|
||
|
if (SUCCEEDED(XML_GetElementByIndex(pIXMLElementCollection, 0,
|
||
|
&pChildIXMLElement)))
|
||
|
{
|
||
|
ASSERT(pChildIXMLElement);
|
||
|
|
||
|
if (FAILED(pChildIXMLElement->get_text(&bstrRet)))
|
||
|
{
|
||
|
bstrRet = NULL;
|
||
|
}
|
||
|
|
||
|
pChildIXMLElement->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pIXMLElementCollection->Release();
|
||
|
}
|
||
|
|
||
|
return bstrRet;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetGrandChildContent ***
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns a bstr value from the requested child of the given element.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElement - A pointer to the element.
|
||
|
// [In] szChildW - The name of the child element.
|
||
|
// The caller is responsible for freeing the returned bstr.
|
||
|
//
|
||
|
// Comments:
|
||
|
// If pIElement represents
|
||
|
//
|
||
|
// <Channel>
|
||
|
// <Title>Harvey is a Cool Cat</Title>
|
||
|
// </Channel>
|
||
|
//
|
||
|
// Then this function will return
|
||
|
//
|
||
|
// "Harvey is a Cool Cat" for "TITLE",
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
BSTR
|
||
|
XML_GetGrandChildContent(
|
||
|
IXMLElement* pIXMLElement,
|
||
|
LPWSTR szChildW
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
ASSERT(szChildW);
|
||
|
|
||
|
BSTR bstrRet = NULL;
|
||
|
|
||
|
IXMLElementCollection* pIXMLElementCollection;
|
||
|
|
||
|
if ((SUCCEEDED(pIXMLElement->get_children(&pIXMLElementCollection)))
|
||
|
&& pIXMLElementCollection)
|
||
|
{
|
||
|
ASSERT(pIXMLElementCollection);
|
||
|
|
||
|
LONG nCount;
|
||
|
|
||
|
HRESULT hr = pIXMLElementCollection->get_length(&nCount);
|
||
|
|
||
|
ASSERT(SUCCEEDED(hr) || (FAILED(hr) && 0 == nCount));
|
||
|
|
||
|
for (int i = 0; (i < nCount) && !bstrRet; i++)
|
||
|
{
|
||
|
IXMLElement* pChildIXMLElement;
|
||
|
|
||
|
if (SUCCEEDED(XML_GetElementByIndex(pIXMLElementCollection, i,
|
||
|
&pChildIXMLElement)))
|
||
|
{
|
||
|
ASSERT(pChildIXMLElement);
|
||
|
|
||
|
BSTR bstrTagName;
|
||
|
|
||
|
if (SUCCEEDED(pChildIXMLElement->get_tagName(&bstrTagName)) && bstrTagName)
|
||
|
{
|
||
|
ASSERT(bstrTagName);
|
||
|
|
||
|
if (StrEqlW(bstrTagName, szChildW))
|
||
|
{
|
||
|
bstrRet = XML_GetFirstChildContent(pChildIXMLElement);
|
||
|
|
||
|
//
|
||
|
// If the tag exists, but it is empty, return the empty
|
||
|
// string.
|
||
|
//
|
||
|
|
||
|
if (NULL == bstrRet)
|
||
|
bstrRet = SysAllocString(L"");
|
||
|
}
|
||
|
|
||
|
SysFreeString(bstrTagName);
|
||
|
}
|
||
|
|
||
|
|
||
|
pChildIXMLElement->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pIXMLElementCollection->Release();
|
||
|
}
|
||
|
|
||
|
return bstrRet;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetChildAttribute ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns a bstr value from the requested child of the given element.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElement - A pointer to the element.
|
||
|
// [In] szChildW - The name of the child element.
|
||
|
// [In] szAttributeW - The name of the attribute.
|
||
|
// [In] szQualifierW - The name of the attribute qualifier.
|
||
|
// [In] szQualifierValueW - The required value of the qaulifier.
|
||
|
//
|
||
|
// Return:
|
||
|
// A bstr of the value contained in the child element if it is found.
|
||
|
// NULL if the child element or its value isn't found.
|
||
|
//
|
||
|
// Comments:
|
||
|
// This function will return atributes found in the child elements of the
|
||
|
// given element. For example:
|
||
|
//
|
||
|
// If pIElement represents
|
||
|
//
|
||
|
// <Channel>
|
||
|
// <Title VALUE="foo">
|
||
|
// <Author VALUE="bar">
|
||
|
// <Logo HRREF="url" TYPE="ICON">
|
||
|
// </Channel>
|
||
|
//
|
||
|
// Then this function will return
|
||
|
//
|
||
|
// "foo" for "TITLE", "VALUE", "", ""
|
||
|
// "bar" for "AUTHOR", "VALUE", "", ""
|
||
|
// "url" for "LOGO", "HREF", "TYPE", "ICON"
|
||
|
//
|
||
|
// NULL when the names have any other values.
|
||
|
//
|
||
|
// The caller is responsible for freeing the returned bstr.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BSTR
|
||
|
XML_GetChildAttribute(
|
||
|
IXMLElement* pIXMLElement,
|
||
|
LPWSTR szChildW,
|
||
|
LPWSTR szAttributeW,
|
||
|
LPWSTR szQualifierW,
|
||
|
LPWSTR szQualifierValueW
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
ASSERT(szChildW);
|
||
|
ASSERT(szAttributeW);
|
||
|
|
||
|
BSTR bstrRet = NULL;
|
||
|
|
||
|
IXMLElementCollection* pIXMLElementCollection;
|
||
|
|
||
|
if ((SUCCEEDED(pIXMLElement->get_children(&pIXMLElementCollection)))
|
||
|
&& pIXMLElementCollection)
|
||
|
{
|
||
|
ASSERT(pIXMLElementCollection);
|
||
|
|
||
|
LONG nCount;
|
||
|
|
||
|
//
|
||
|
// REVIEW: hr only used in debug builds.
|
||
|
//
|
||
|
|
||
|
HRESULT hr = pIXMLElementCollection->get_length(&nCount);
|
||
|
|
||
|
ASSERT(SUCCEEDED(hr) || (FAILED(hr) && 0 == nCount));
|
||
|
|
||
|
for (int i = 0; (i < nCount) && !bstrRet; i++)
|
||
|
{
|
||
|
IXMLElement* pChildIXMLElement;
|
||
|
|
||
|
if (SUCCEEDED(XML_GetElementByIndex(pIXMLElementCollection, i,
|
||
|
&pChildIXMLElement)))
|
||
|
{
|
||
|
ASSERT(pChildIXMLElement);
|
||
|
|
||
|
BSTR bstrTagName;
|
||
|
|
||
|
if (SUCCEEDED(pChildIXMLElement->get_tagName(&bstrTagName)) && bstrTagName)
|
||
|
{
|
||
|
ASSERT(bstrTagName);
|
||
|
|
||
|
if (StrEqlW(bstrTagName, szChildW))
|
||
|
{
|
||
|
bstrRet = XML_GetElementAttribute(pChildIXMLElement,
|
||
|
szAttributeW,
|
||
|
szQualifierW,
|
||
|
szQualifierValueW);
|
||
|
}
|
||
|
|
||
|
SysFreeString(bstrTagName);
|
||
|
}
|
||
|
|
||
|
|
||
|
pChildIXMLElement->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pIXMLElementCollection->Release();
|
||
|
}
|
||
|
|
||
|
return bstrRet;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetElementAttribute ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the bstr value of of the requested attribute if it is found.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElement - The element that contains the attribute.
|
||
|
// [In] szAttributeW - The name of the attribute.
|
||
|
// [In] szQualifierW - The type qualifier for the atribute.
|
||
|
// [In] szQualifierValueW - The required value of the qaulifier.
|
||
|
//
|
||
|
// Return:
|
||
|
// A bstr containig the attributes value if it was found.
|
||
|
// NULL if the attribute wasn't found.
|
||
|
//
|
||
|
// Comments:
|
||
|
// The function will return attributes found inside of tags. For
|
||
|
// example:
|
||
|
//
|
||
|
// If pIXMLElement represents
|
||
|
//
|
||
|
// <Channel HREF="foo" Cloneable="NO">
|
||
|
// <USAGE VALUE="Channel">
|
||
|
// <USAGE VALUE="Screen Saver">
|
||
|
//
|
||
|
// Then this function will return
|
||
|
//
|
||
|
// "foo" for "HREF", "", ""
|
||
|
// "NO" for "Cloneable", "", ""
|
||
|
// "CHANNEL" for "VALUE", "VALUE", "CHANNEL"
|
||
|
// NULL for "VALUE", "VALUE", "NONE"
|
||
|
// "foo" for "HREF", "CLONEABLE", "NO"
|
||
|
//
|
||
|
// The caller is responsible for freeing the returned bstr.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BSTR
|
||
|
XML_GetElementAttribute(
|
||
|
IXMLElement* pIXMLElement,
|
||
|
LPWSTR szAttributeW,
|
||
|
LPWSTR szQualifierW,
|
||
|
LPWSTR szQualifierValueW
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
ASSERT(szAttributeW);
|
||
|
ASSERT((NULL == szQualifierW && NULL == szQualifierValueW) ||
|
||
|
(szQualifierW && szQualifierValueW));
|
||
|
|
||
|
BSTR bstrRet = NULL;
|
||
|
|
||
|
VARIANT var;
|
||
|
|
||
|
VariantInit(&var);
|
||
|
|
||
|
if (NULL == szQualifierW)
|
||
|
{
|
||
|
if (SUCCEEDED(pIXMLElement->getAttribute(szAttributeW, &var)))
|
||
|
{
|
||
|
ASSERT(var.vt == VT_BSTR || NULL == var.bstrVal);
|
||
|
|
||
|
bstrRet = var.bstrVal;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (SUCCEEDED(pIXMLElement->getAttribute(szQualifierW, &var)))
|
||
|
{
|
||
|
ASSERT(var.vt == VT_BSTR || NULL == var.bstrVal);
|
||
|
|
||
|
if(var.bstrVal)
|
||
|
{
|
||
|
if (0 == StrCmpIW(var.bstrVal, szQualifierValueW))
|
||
|
{
|
||
|
bstrRet = XML_GetElementAttribute(pIXMLElement, szAttributeW,
|
||
|
NULL, NULL);
|
||
|
}
|
||
|
}
|
||
|
VariantClear(&var);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bstrRet;
|
||
|
}
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetScreenSaverURL ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the screen saver URL of the first screen saver component in the channel.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pXMLDocument - An XML document
|
||
|
// [Out] pbstrSSURL - The pointer that receives the screen saver URL.
|
||
|
//
|
||
|
// Return:
|
||
|
// S_OK if the screen saver URL was returned.
|
||
|
// E_FAIL if the screen saver URL couldn't be returned.
|
||
|
//
|
||
|
// Comments:
|
||
|
// This function gets the first screen saver element and then looks
|
||
|
// for the first top-level ITEM with a usage of ScreenSaver.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
XML_GetScreenSaverURL(
|
||
|
IXMLDocument * pXMLDocument,
|
||
|
BSTR * pbstrSSURL)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
ASSERT(pXMLDocument);
|
||
|
ASSERT(pbstrSSURL);
|
||
|
|
||
|
IXMLElement* pIXMLElement;
|
||
|
LONG lDontCare;
|
||
|
|
||
|
hr = XML_GetFirstChannelElement(pXMLDocument, &pIXMLElement, &lDontCare);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
IXMLElement* pSSElement;
|
||
|
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
hr = XML_GetScreenSaverElement(pIXMLElement, &pSSElement);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pSSElement);
|
||
|
|
||
|
*pbstrSSURL = XML_GetAttribute(pSSElement, XML_HREF);
|
||
|
|
||
|
hr = *pbstrSSURL ? S_OK : E_FAIL;
|
||
|
|
||
|
pSSElement->Release();
|
||
|
}
|
||
|
pIXMLElement->Release();
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetScreenSaverElement ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the IXMLElement of the first screen saver component in the channel.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pXMLElemet - An XML element
|
||
|
// [Out] ppIXMLElement - The pointer that receives the screen saver element.
|
||
|
//
|
||
|
// Return:
|
||
|
// S_OK if the first screen saver element was returned.
|
||
|
// E_FAIL if the element couldn't be returned.
|
||
|
//
|
||
|
// Comments:
|
||
|
// This function gets the first screen saver element and then looks
|
||
|
// for the first top-level ITEM with a usage of ScreenSaver.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
XML_GetScreenSaverElement(
|
||
|
IXMLElement * pXMLElement,
|
||
|
IXMLElement ** ppScreenSaverElement)
|
||
|
{
|
||
|
ASSERT(pXMLElement);
|
||
|
ASSERT(ppScreenSaverElement);
|
||
|
|
||
|
IXMLElementCollection * pIXMLElementCollection;
|
||
|
HRESULT hr;
|
||
|
|
||
|
hr = pXMLElement->get_children(&pIXMLElementCollection);
|
||
|
if (SUCCEEDED(hr) && pIXMLElementCollection)
|
||
|
{
|
||
|
LONG nCount;
|
||
|
|
||
|
hr = pIXMLElementCollection->get_length(&nCount);
|
||
|
|
||
|
ASSERT(SUCCEEDED(hr) || (FAILED(hr) && 0 == nCount));
|
||
|
|
||
|
hr = E_FAIL;
|
||
|
|
||
|
BOOL bScreenSaver = FALSE;
|
||
|
for (int i = 0; (i < nCount) && !bScreenSaver; i++)
|
||
|
{
|
||
|
IXMLElement * pIXMLElement;
|
||
|
|
||
|
HRESULT hr2 = XML_GetElementByIndex(pIXMLElementCollection,
|
||
|
i,
|
||
|
&pIXMLElement);
|
||
|
|
||
|
if (SUCCEEDED(hr2))
|
||
|
{
|
||
|
ASSERT(pIXMLElement != NULL);
|
||
|
|
||
|
if (bScreenSaver = XML_IsScreenSaver(pIXMLElement))
|
||
|
{
|
||
|
pIXMLElement->AddRef();
|
||
|
*ppScreenSaverElement = pIXMLElement;
|
||
|
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
|
||
|
pIXMLElement->Release();
|
||
|
}
|
||
|
|
||
|
hr = FAILED(hr2) ? hr2 : hr;
|
||
|
}
|
||
|
|
||
|
pIXMLElementCollection->Release();
|
||
|
}
|
||
|
else
|
||
|
hr = E_FAIL;
|
||
|
|
||
|
ASSERT((SUCCEEDED(hr) && *ppScreenSaverElement) || FAILED(hr));
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetSubscriptionInfo ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Fills a structure with the subscription info for the given element.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElement - An xml element. The element doesn't have to be a
|
||
|
// subscription element.
|
||
|
// [Out] psi - The subscription info structure used by the
|
||
|
// subscription manager.
|
||
|
//
|
||
|
// Return:
|
||
|
// S_OK if any information was obtained.
|
||
|
//
|
||
|
// Comments:
|
||
|
// This function uses a webcheck API that fills a task trigger with
|
||
|
// subscription information.
|
||
|
//
|
||
|
// This function assumes that the psi->pTrigger points to a TASK_TRIGGER.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
XML_GetSubscriptionInfo(
|
||
|
IXMLElement* pIXMLElement,
|
||
|
SUBSCRIPTIONINFO* psi
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
ASSERT(psi);
|
||
|
ASSERT(psi->pTrigger);
|
||
|
|
||
|
HRESULT hr = E_FAIL;
|
||
|
|
||
|
#ifndef UNIX
|
||
|
HINSTANCE hinst = LoadLibrary(TEXT("webcheck.dll"));
|
||
|
|
||
|
if (hinst)
|
||
|
{
|
||
|
typedef (*PFTRIGGERFUNCTION)(IXMLElement* pIXMLElement,
|
||
|
TASK_TRIGGER* ptt);
|
||
|
|
||
|
PFTRIGGERFUNCTION XMLSheduleElementToTaskTrigger;
|
||
|
|
||
|
XMLSheduleElementToTaskTrigger = (PFTRIGGERFUNCTION)
|
||
|
GetProcAddress(hinst,
|
||
|
"XMLScheduleElementToTaskTrigger");
|
||
|
|
||
|
if (XMLSheduleElementToTaskTrigger)
|
||
|
{
|
||
|
((TASK_TRIGGER*)(psi->pTrigger))->cbTriggerSize =
|
||
|
sizeof(TASK_TRIGGER);
|
||
|
|
||
|
hr = XMLSheduleElementToTaskTrigger(pIXMLElement,
|
||
|
(TASK_TRIGGER*)psi->pTrigger);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
psi->pTrigger = NULL;
|
||
|
}
|
||
|
|
||
|
FreeLibrary(hinst);
|
||
|
}
|
||
|
|
||
|
// See if there is a screen saver available.
|
||
|
IXMLElement * pScreenSaverElement;
|
||
|
if (SUCCEEDED(XML_GetScreenSaverElement( pIXMLElement,
|
||
|
&pScreenSaverElement)))
|
||
|
{
|
||
|
psi->fUpdateFlags |= SUBSINFO_CHANNELFLAGS;
|
||
|
psi->fChannelFlags |= CHANNEL_AGENT_PRECACHE_SCRNSAVER;
|
||
|
pScreenSaverElement->Release();
|
||
|
}
|
||
|
|
||
|
BSTR bstrLogin = XML_GetAttribute(pIXMLElement, XML_LOGIN);
|
||
|
|
||
|
if (bstrLogin)
|
||
|
{
|
||
|
psi->bNeedPassword = TRUE;
|
||
|
psi->fUpdateFlags |= SUBSINFO_NEEDPASSWORD; //this member is now valid
|
||
|
SysFreeString(bstrLogin);
|
||
|
}
|
||
|
|
||
|
#endif /* !UNIX */
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_GetBaseURL ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the base url for the given collection.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElement - A pointer to an XML element.
|
||
|
//
|
||
|
// Return:
|
||
|
// A bstr containing the base URL if there is one.
|
||
|
// NULL if ther isn't a base URL.
|
||
|
//
|
||
|
// Comments:
|
||
|
// If the current element has a BASE attribute return this attributes value.
|
||
|
// Else return the BASE attribute of its parent.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BSTR
|
||
|
XML_GetBaseURL(
|
||
|
IXMLElement* pIXMLElement
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
BSTR bstrRet = XML_GetAttribute(pIXMLElement, XML_BASE);
|
||
|
|
||
|
if (NULL == bstrRet)
|
||
|
{
|
||
|
IXMLElement* pParentIXMLElement;
|
||
|
|
||
|
if (SUCCEEDED(pIXMLElement->get_parent(&pParentIXMLElement)) && pParentIXMLElement)
|
||
|
{
|
||
|
ASSERT(pParentIXMLElement);
|
||
|
|
||
|
bstrRet = XML_GetBaseURL(pParentIXMLElement);
|
||
|
|
||
|
pParentIXMLElement->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bstrRet;
|
||
|
}
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_CombineURL ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Combine the given URL with the base URL.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] bstrBaseURL - The base URL.
|
||
|
// [In] bstrRelURL - The relative URL.
|
||
|
//
|
||
|
// Return:
|
||
|
// A combination of the base and relative URL.
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BSTR
|
||
|
XML_CombineURL(
|
||
|
BSTR bstrBaseURL,
|
||
|
BSTR bstrRelURL
|
||
|
)
|
||
|
{
|
||
|
ASSERT(bstrBaseURL);
|
||
|
ASSERT(bstrRelURL);
|
||
|
|
||
|
BSTR bstrRet = NULL;
|
||
|
|
||
|
WCHAR wszCombinedURL[INTERNET_MAX_URL_LENGTH];
|
||
|
DWORD cch = ARRAYSIZE(wszCombinedURL);
|
||
|
|
||
|
if (InternetCombineUrlW(bstrBaseURL, bstrRelURL, wszCombinedURL, &cch, 0))
|
||
|
bstrRet = SysAllocString(wszCombinedURL);
|
||
|
|
||
|
return bstrRet;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_IsCdfDisplayable ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Determines if the given item should be displayed in the cdf view.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElement - A pointer to the IXMLElement interface of an object.
|
||
|
//
|
||
|
// Return:
|
||
|
// TRUE if the object should be displayed.
|
||
|
// FALSE otherwise.
|
||
|
//
|
||
|
// Comments:
|
||
|
// aCDFTypes contains the tag names of XML items that the cdf shell
|
||
|
// shell extension displays.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL
|
||
|
XML_IsCdfDisplayable(
|
||
|
IXMLElement* pIXMLElement
|
||
|
)
|
||
|
{
|
||
|
#define KEYWORDS (sizeof(aCDFTypes) / sizeof(aCDFTypes[0]))
|
||
|
|
||
|
static const LPWSTR aCDFTypes[] = {
|
||
|
WSTR_ITEM,
|
||
|
WSTR_CHANNEL,
|
||
|
WSTR_SOFTDIST
|
||
|
};
|
||
|
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
BOOL bRet = FALSE;
|
||
|
|
||
|
BSTR pStr;
|
||
|
|
||
|
HRESULT hr = pIXMLElement->get_tagName(&pStr);
|
||
|
|
||
|
if (SUCCEEDED(hr) && pStr)
|
||
|
{
|
||
|
ASSERT(pStr);
|
||
|
|
||
|
for(int i = 0; (i < KEYWORDS) && !bRet; i++)
|
||
|
bRet = StrEqlW(pStr, aCDFTypes[i]);
|
||
|
|
||
|
if (bRet)
|
||
|
bRet = XML_IsUsageChannel(pIXMLElement);
|
||
|
|
||
|
//
|
||
|
// Special processing.
|
||
|
//
|
||
|
|
||
|
if (bRet && StrEqlW(pStr, WSTR_SOFTDIST))
|
||
|
bRet = XML_IsSoftDistDisplayable(pIXMLElement);
|
||
|
|
||
|
SysFreeString(pStr);
|
||
|
}
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_IsSoftDistDisplayable ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Determins if the given software distribution element should be displayed.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElement - Pointer to the software distribution xml element.
|
||
|
//
|
||
|
// Return:
|
||
|
// TRUE if the element should be displayed.
|
||
|
// FALSE if the element shouldn't be displayed.
|
||
|
//
|
||
|
// Comments:
|
||
|
// This function asks the software disribution COM object if this software
|
||
|
// distribution tag should be displayed on this users machine.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL
|
||
|
XML_IsSoftDistDisplayable(
|
||
|
IXMLElement* pIXMLElement
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
ISoftDistExt* pISoftDistExt;
|
||
|
|
||
|
HRESULT hr = CoCreateInstance(CLSID_SoftDistExt, NULL, CLSCTX_INPROC_SERVER,
|
||
|
IID_ISoftDistExt, (void**)&pISoftDistExt);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pISoftDistExt);
|
||
|
|
||
|
hr = pISoftDistExt->ProcessSoftDist(NULL, pIXMLElement, 0);
|
||
|
|
||
|
pISoftDistExt->Release();
|
||
|
}
|
||
|
|
||
|
return SUCCEEDED(hr) ? TRUE : FALSE;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_IsUsageChannel ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Determines if this item should be displayed in channel view based on its
|
||
|
// usage tag.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLelement - A pointer to the element.
|
||
|
//
|
||
|
// Return:
|
||
|
// TRUE if the item should be displayed in the channel view.
|
||
|
// FALSE otherwise.
|
||
|
//
|
||
|
// Comments:
|
||
|
// If an element doesn't have a USAGE tag then it gets displayed. If an
|
||
|
// element has any numberf of usage tags one of them must have a value of
|
||
|
// CHANNEL or will not get displayed.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL
|
||
|
XML_IsUsageChannel(
|
||
|
IXMLElement* pIXMLElement
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
BOOL bRet;
|
||
|
|
||
|
//
|
||
|
// First check if there are any USAGE elements.
|
||
|
//
|
||
|
|
||
|
BSTR bstrUsage = XML_GetAttribute(pIXMLElement, XML_USAGE);
|
||
|
|
||
|
if (bstrUsage)
|
||
|
{
|
||
|
//
|
||
|
// See if USAGE is CHANNEL.
|
||
|
//
|
||
|
|
||
|
if (StrEqlW(bstrUsage, WSTR_CHANNEL))
|
||
|
{
|
||
|
bRet = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// Check if there are any other USAGE tags with value CHANNEL.
|
||
|
//
|
||
|
|
||
|
BSTR bstrChannel = XML_GetAttribute(pIXMLElement,
|
||
|
XML_USAGE_CHANNEL);
|
||
|
|
||
|
if (bstrChannel)
|
||
|
{
|
||
|
SysFreeString(bstrChannel);
|
||
|
bRet = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bRet = FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SysFreeString(bstrUsage);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bRet = TRUE; // No USAGE tag defaults channel usage.
|
||
|
}
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_IsChannel ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Determines if the given XML item is a channel.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElement - A pointer to the IXMLElement interface of an object.
|
||
|
//
|
||
|
// Return:
|
||
|
// TRUE if the object is a channel.
|
||
|
// FALSE otherwise.
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL
|
||
|
XML_IsChannel(
|
||
|
IXMLElement* pIXMLElement
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
BOOL bRet = FALSE;
|
||
|
|
||
|
BSTR pStr;
|
||
|
|
||
|
HRESULT hr = pIXMLElement->get_tagName(&pStr);
|
||
|
|
||
|
if (SUCCEEDED(hr) && pStr)
|
||
|
{
|
||
|
ASSERT(pStr);
|
||
|
|
||
|
bRet = StrEqlW(pStr, WSTR_CHANNEL);
|
||
|
|
||
|
SysFreeString(pStr);
|
||
|
}
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_IsDesktopComponent ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Determines if the given XML item is a desktop component.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElement - A pointer to the IXMLElement interface of an object.
|
||
|
//
|
||
|
// Return:
|
||
|
// TRUE if the object is a desktop component.
|
||
|
// FALSE otherwise.
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL
|
||
|
XML_IsDesktopComponent(
|
||
|
IXMLElement* pIXMLElement
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
BOOL bRet;
|
||
|
|
||
|
BSTR bstr = XML_GetAttribute(pIXMLElement, XML_USAGE_DSKCMP);
|
||
|
|
||
|
if (bstr)
|
||
|
{
|
||
|
SysFreeString(bstr);
|
||
|
bRet = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bRet = FALSE;
|
||
|
}
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_IsScreenSaver ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Determines if the given XML item is a screen saver.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElement - A pointer to the IXMLElement interface of an object.
|
||
|
//
|
||
|
// Return:
|
||
|
// TRUE if the object is a screen saver
|
||
|
// FALSE otherwise.
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL
|
||
|
XML_IsScreenSaver(
|
||
|
IXMLElement* pIXMLElement
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
BOOL bRet;
|
||
|
|
||
|
BSTR bstrUsage = XML_GetAttribute(pIXMLElement, XML_USAGE);
|
||
|
|
||
|
if (bstrUsage)
|
||
|
{
|
||
|
bRet = (
|
||
|
(StrCmpIW(bstrUsage, WSTR_SCRNSAVE) == 0)
|
||
|
||
|
||
|
(StrCmpIW(bstrUsage, WSTR_SMARTSCRN) == 0)
|
||
|
);
|
||
|
|
||
|
SysFreeString(bstrUsage);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bRet = FALSE;
|
||
|
}
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_IsDesktopComponentUsage ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Determines if the given XML item is a desktop component usage element.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElement - A pointer to the IXMLElement interface of an object.
|
||
|
//
|
||
|
// Return:
|
||
|
// TRUE if the object is a desktop component usage element.
|
||
|
// FALSE otherwise.
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL
|
||
|
XML_IsDesktopComponentUsage(
|
||
|
IXMLElement* pIXMLElement
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
BOOL bRet = FALSE;
|
||
|
|
||
|
BSTR bstrName;
|
||
|
|
||
|
if (SUCCEEDED(pIXMLElement->get_tagName(&bstrName)) && bstrName)
|
||
|
{
|
||
|
ASSERT(bstrName);
|
||
|
|
||
|
if (StrEqlW(bstrName, WSTR_USAGE))
|
||
|
{
|
||
|
BSTR bstrValue = XML_GetElementAttribute(pIXMLElement, WSTR_VALUE, NULL,
|
||
|
NULL);
|
||
|
|
||
|
if (bstrValue)
|
||
|
{
|
||
|
bRet = (0 == StrCmpIW(bstrValue, WSTR_DSKCMP));
|
||
|
|
||
|
SysFreeString(bstrValue);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SysFreeString(bstrName);
|
||
|
}
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_IsFolder ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Determines if the given item is a folder.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElement - A pointer to the IXMLElement interface of an object.
|
||
|
//
|
||
|
// Return:
|
||
|
// TRUE if the object contains other cdf displayable objects.
|
||
|
// FALSE otherwise.
|
||
|
//
|
||
|
// Comments:
|
||
|
// An item is a folder if at least one of its children is displayable as a
|
||
|
// cdf item.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL
|
||
|
XML_IsFolder(
|
||
|
IXMLElement* pIXMLElement
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
BOOL bRet = FALSE;
|
||
|
|
||
|
IXMLElementCollection* pIXMLElementCollection;
|
||
|
|
||
|
HRESULT hr = pIXMLElement->get_children(&pIXMLElementCollection);
|
||
|
|
||
|
if (SUCCEEDED(hr) && pIXMLElementCollection)
|
||
|
{
|
||
|
ASSERT(pIXMLElementCollection);
|
||
|
|
||
|
LONG nCount;
|
||
|
|
||
|
hr = pIXMLElementCollection->get_length(&nCount);
|
||
|
|
||
|
ASSERT(SUCCEEDED(hr) || (FAILED(hr) && 0 == nCount));
|
||
|
|
||
|
for (int i = 0; (i < nCount) && !bRet; i++)
|
||
|
{
|
||
|
IXMLElement* pIXMLElementTemp;
|
||
|
|
||
|
hr = XML_GetElementByIndex(pIXMLElementCollection, i, &pIXMLElementTemp);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pIXMLElementTemp);
|
||
|
|
||
|
if (XML_IsCdfDisplayable(pIXMLElementTemp))
|
||
|
bRet = TRUE;
|
||
|
|
||
|
pIXMLElementTemp->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pIXMLElementCollection->Release();
|
||
|
}
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_ContainsFolder ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Determines if there are any cdf folders in the given collection.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElementCollection - A pointer to the collection.
|
||
|
//
|
||
|
// Return:
|
||
|
// TRUE if the collection contains a cf folder.
|
||
|
// FALSE otherwise.
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL
|
||
|
XML_ContainsFolder(
|
||
|
IXMLElementCollection* pIXMLElementCollection
|
||
|
)
|
||
|
{
|
||
|
ASSERT(pIXMLElementCollection);
|
||
|
|
||
|
BOOL bContainsFolder = FALSE;
|
||
|
|
||
|
LONG nCount;
|
||
|
|
||
|
HRESULT hr = pIXMLElementCollection->get_length(&nCount);
|
||
|
|
||
|
ASSERT(SUCCEEDED(hr) || (FAILED(hr) && 0 == nCount));
|
||
|
|
||
|
for (int i = 0; (i < nCount) && !bContainsFolder; i++)
|
||
|
{
|
||
|
IXMLElement* pIXMLElement;
|
||
|
|
||
|
hr = XML_GetElementByIndex(pIXMLElementCollection, i, &pIXMLElement);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
bContainsFolder = XML_IsFolder(pIXMLElement);
|
||
|
|
||
|
pIXMLElement->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bContainsFolder;
|
||
|
}
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_ChildContainsFolder ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
//
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
//
|
||
|
// Return:
|
||
|
//
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL
|
||
|
XML_ChildContainsFolder(
|
||
|
IXMLElementCollection *pIXMLElementCollectionParent,
|
||
|
ULONG nIndexChild
|
||
|
)
|
||
|
{
|
||
|
BOOL bRet = FALSE;
|
||
|
|
||
|
IXMLElement* pIXMLElement;
|
||
|
|
||
|
HRESULT hr = XML_GetElementByIndex(pIXMLElementCollectionParent,
|
||
|
nIndexChild, &pIXMLElement);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
IXMLElementCollection* pIXMLElementCollection;
|
||
|
|
||
|
hr = pIXMLElement->get_children(&pIXMLElementCollection);
|
||
|
|
||
|
if (SUCCEEDED(hr) && pIXMLElementCollection)
|
||
|
{
|
||
|
ASSERT(pIXMLElementCollection);
|
||
|
|
||
|
bRet = XML_ContainsFolder(pIXMLElementCollection);
|
||
|
|
||
|
pIXMLElementCollection->Release();
|
||
|
}
|
||
|
|
||
|
pIXMLElement->Release();
|
||
|
}
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_IsCdfidlMemberOf ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Checks if the cdf item id list is associated with a member of the given
|
||
|
// element collection.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] pIXMLElementCollection - The element collection to check.
|
||
|
// [In] pcdfidl - A pointer to cdf item id list
|
||
|
//
|
||
|
// Return:
|
||
|
// TRUE if the given id list can be associated with an elemnt of the given
|
||
|
// collection.
|
||
|
// FALSE otherwise.
|
||
|
//
|
||
|
// Comments:
|
||
|
// This function checks if the last id in the list could have been
|
||
|
// generated from its corresponding element in the element collection.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL
|
||
|
XML_IsCdfidlMemberOf(
|
||
|
IXMLElementCollection* pIXMLElementCollection,
|
||
|
PCDFITEMIDLIST pcdfidl
|
||
|
)
|
||
|
{
|
||
|
ASSERT(CDFIDL_IsValid(pcdfidl));
|
||
|
|
||
|
BOOL bRet = FALSE;
|
||
|
|
||
|
//
|
||
|
// pIXMLElementCollection is NULL when a Folder hasn't been initialized.
|
||
|
// It isn't always neccessary to parse the cdf to get pidl info from
|
||
|
// the pidl. pIXMLElement collection will be NULL in low memory situations
|
||
|
// also. Don't return FALSE for these cases. Also check for special
|
||
|
// pidls that aren't in element collections.
|
||
|
//
|
||
|
|
||
|
if (pIXMLElementCollection &&
|
||
|
CDFIDL_GetIndexId(&pcdfidl->mkid) != INDEX_CHANNEL_LINK)
|
||
|
{
|
||
|
IXMLElement* pIXMLElement;
|
||
|
|
||
|
HRESULT hr = XML_GetElementByIndex(pIXMLElementCollection,
|
||
|
CDFIDL_GetIndexId(&pcdfidl->mkid),
|
||
|
&pIXMLElement);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ASSERT(pIXMLElement);
|
||
|
|
||
|
PCDFITEMIDLIST pcdfidlElement;
|
||
|
|
||
|
pcdfidlElement = CDFIDL_CreateFromXMLElement(pIXMLElement,
|
||
|
CDFIDL_GetIndexId(&pcdfidl->mkid));
|
||
|
|
||
|
if (pcdfidlElement)
|
||
|
{
|
||
|
ASSERT(CDFIDL_IsValid(pcdfidlElement));
|
||
|
|
||
|
bRet = (0 == CDFIDL_CompareId(&pcdfidl->mkid,
|
||
|
&pcdfidlElement->mkid));
|
||
|
|
||
|
CDFIDL_Free(pcdfidlElement);
|
||
|
}
|
||
|
|
||
|
pIXMLElement->Release();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bRet = TRUE;
|
||
|
}
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
#endif //DEBUG
|
||
|
|
||
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
||
|
//
|
||
|
// *** XML_IsStrEqualW ***
|
||
|
//
|
||
|
//
|
||
|
// Description:
|
||
|
// Determines if two WCHAR strings are equal.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// [In] p1 - The first string to compare.
|
||
|
// [In] p2 - The second string to compare.
|
||
|
//
|
||
|
// Return:
|
||
|
// TRUE if the strings are equal.
|
||
|
// FALSE otherwise.
|
||
|
//
|
||
|
// Comments:
|
||
|
// lstrcmpW doesn't work on W95 so this function has its own strcmp logic.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
#if 0
|
||
|
inline
|
||
|
BOOL
|
||
|
XML_IsStrEqualW(
|
||
|
LPWSTR p1,
|
||
|
LPWSTR p2
|
||
|
)
|
||
|
{
|
||
|
ASSERT(p1);
|
||
|
ASSERT(p2);
|
||
|
|
||
|
while ((*p1 == *p2) && *p1 && *p2)
|
||
|
{
|
||
|
p1++; p2++;
|
||
|
}
|
||
|
|
||
|
return (*p1 == *p2);
|
||
|
}
|
||
|
#endif
|
||
|
|