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.
 
 
 
 
 
 

818 lines
25 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 2000
//
// File: auxml.cpp
//
// About: source file for AU related XML and schema data structure and functions
//--------------------------------------------------------------------------
#include "auxml.h"
const LPCWSTR DEFAULT_COMPANY_NAME = L"Microsoft";
HRESULT GetCabsDownloadPath(LPTSTR lpszDir, UINT uDirSize);
void DBGDumpXMLNode(IXMLDOMNode *pNode)
{
BSTR bsNodeName;
pNode->get_nodeName(&bsNodeName);
BSTR bsNodeXML;
pNode->get_xml(&bsNodeXML);
DEBUGMSG("XML for %S is %S", bsNodeName, bsNodeXML);
SafeFreeBSTR(bsNodeName);
SafeFreeBSTR(bsNodeXML);
}
void DBGShowNodeName(IXMLDOMNode *pNode)
{
BSTR bsNodeName;
if (SUCCEEDED(pNode->get_nodeName(&bsNodeName)))
{
DEBUGMSG("node name is %S", bsNodeName);
}
else
{
DEBUGMSG("FAIL to get node name");
}
}
void DBGDumpXMLDocProperties(IXMLDOMDocument2 *pDoc)
{
BSTR bsSelectionLanguage, bsSelectionNamespaces, bsServerHTTPRequest;
VARIANT vVal;
VariantInit(&vVal);
pDoc->getProperty(L"SelectionLanguage", &vVal);
DEBUGMSG("XMLDoc selection language is %S", vVal.bstrVal);
VariantClear(&vVal);
pDoc->getProperty(L"SelectionNamespaces", &vVal);
DEBUGMSG("XMLDoc selection namespaces is %S", vVal.bstrVal);
VariantClear(&vVal);
pDoc->getProperty(L"ServerHTTPRequest", &vVal);
DEBUGMSG("XMLDoc ServerHTTPRequest is %s", vVal.boolVal ? "True" : "False");
VariantClear(&vVal);
}
BSTR DBGReadXMLFromFile(LPCWSTR wszFile)
{
BSTR bsResult = NULL;
IXMLDOMDocument2 *pSourceXML;
if (FAILED(CoCreateInstance(__uuidof( DOMDocument30), NULL, CLSCTX_INPROC_SERVER, __uuidof(IXMLDOMDocument2), (void**)&pSourceXML)))
{
DEBUGMSG("DBGReadXMLFromFile() Fail to create source XML ");
}
else
{
pSourceXML->put_async(VARIANT_FALSE);
pSourceXML->put_resolveExternals(VARIANT_TRUE);
VARIANT vSource;
vSource.vt = VT_BSTR;
vSource.bstrVal = SysAllocString(wszFile);
if (NULL == vSource.bstrVal)
{
DEBUGMSG("DBGReadXMLFromFile() fail to allocate string");
}
else
{
VARIANT_BOOL fSuccess;
if (S_OK != pSourceXML->load(vSource, &fSuccess))
{
DEBUGMSG("DBGReadXMLFromFile() fail to load XML source file");
}
else
{
pSourceXML->get_xml(&bsResult);
}
VariantClear(&vSource);
}
pSourceXML->Release();
}
return bsResult;
}
BOOL CItemDetails::Init(BSTR bsItemDetails)
{
BOOL fRet = TRUE;
if (FAILED(CoCreateInstance(__uuidof(DOMDocument30), NULL, CLSCTX_INPROC_SERVER, __uuidof( IXMLDOMDocument2), (void**)&m_pxml)))
{
DEBUGMSG("CItemDetails::Init() fail to create XML document");
fRet = FALSE;
goto end;
}
m_pxml->put_async(VARIANT_FALSE);
m_pxml->put_resolveExternals(VARIANT_TRUE);
m_pxml->put_validateOnParse(VARIANT_TRUE);
VARIANT_BOOL fOk;
if (S_OK != m_pxml->loadXML(bsItemDetails, &fOk))
{
DEBUGMSG("CItemDetails::Init() fail to load XML");
fRet = FALSE;
}
end:
if (!fRet)
{
SafeReleaseNULL(m_pxml);
}
return fRet;
}
void CItemDetails::Uninit()
{
SafeRelease(m_pxml);
}
IXMLDOMNode * CItemDetails::getIdentityNode(BSTR bsItemId)
{
IXMLDOMNode * pIdentityNode = NULL ;
CAU_BSTR aubsPattern(L"//identity[@itemID=\"");
HRESULT hr ;
// DEBUGMSG("CItemDetails::getIdentityNode() starts");
if (aubsPattern.IsNULL())
{
DEBUGMSG("failed to create pattern string");
goto done;
}
if (!aubsPattern.append(bsItemId))
{
DEBUGMSG("failed to append string");
goto done;
}
if (!aubsPattern.append(L"\"]"))
{
DEBUGMSG("failed to append string");
goto done;
}
if (FAILED(hr = m_pxml->selectSingleNode(aubsPattern, &pIdentityNode)) ||
NULL == pIdentityNode)
{
DEBUGMSG(" failed to find identityNode %#lx", hr);
}
done:
//DEBUGMSG("CItemDetails::getIdentityNode() done");
return pIdentityNode;
}
IXMLDOMNode * CItemDetails::getItemNode(BSTR bsItemId)
{
IXMLDOMNode * pIdentityNode = getIdentityNode(bsItemId);
IXMLDOMNode * pItemNode = NULL;
HRESULT hr;
// DEBUGMSG("CItemDetails::getItemNode() starts");
if (NULL == pIdentityNode)
{
goto done;
}
if (FAILED(hr = pIdentityNode->get_parentNode(&pItemNode)) || NULL == pItemNode)
{
DEBUGMSG(" fail to get item node %#lx", hr);
goto done;
}
done:
SafeRelease(pIdentityNode);
//DEBUGMSG("CItemDetails::getItemNode() ends");
return pItemNode;
}
IXMLDOMNode * CItemDetails::CloneIdentityNode(BSTR bsItemId)
{
IXMLDOMNode * pIdentityNode ;
IXMLDOMNode * pCloneIdentityNode = NULL;
HRESULT hr;
//DEBUGMSG("CItemDetails::CloneIdentityNode() starts");
if (NULL == (pIdentityNode = getIdentityNode(bsItemId)))
{
goto done;
}
if (FAILED(hr = pIdentityNode->cloneNode(VARIANT_TRUE, &pCloneIdentityNode)) ||
NULL == pCloneIdentityNode)
{
DEBUGMSG("CItemDetails::CloneIdentityNode() failed to clone identityNode %#lx", hr);
}
done:
SafeRelease(pIdentityNode);
// DEBUGMSG("CItemDetails::CloneIdentityNode() ends");
return pCloneIdentityNode;
}
IXMLDOMNode * CItemDetails::CloneDescriptionNode(BSTR bsItemId)
{
IXMLDOMNode * pItemNode = getItemNode(bsItemId);
IXMLDOMNode * pDescriptionNode = NULL;
IXMLDOMNode * pCloneDescriptionNode = NULL;
CAU_BSTR aubsDescription(L"description");
HRESULT hr;
if (NULL == pItemNode)
{
goto done;
}
if (aubsDescription.IsNULL())
{
DEBUGMSG("CItemDetails::CloneDescriptionNode() fail to create description string");
goto done;
}
if (!FindNode(pItemNode, aubsDescription, &pDescriptionNode))
{
DEBUGMSG("CItemDetails::CloneDescriptionNode() fail to get description node");
goto done;
}
if (FAILED(hr = pDescriptionNode->cloneNode(VARIANT_TRUE, &pCloneDescriptionNode)) ||
NULL == pCloneDescriptionNode)
{
DEBUGMSG("CItemDetails::CloneDescriptionNode() fail to clone node %#lx", hr);
}
done:
SafeRelease(pItemNode);
SafeRelease(pDescriptionNode);
return pCloneDescriptionNode;
}
IXMLDOMNode * CItemDetails::ClonePlatformNode(BSTR bsItemId)
{
IXMLDOMNode * pItemNode = getItemNode(bsItemId);
IXMLDOMNode * pPlatformNode = NULL;
IXMLDOMNode * pClonePlatformNode = NULL;
CAU_BSTR aubsPlatform(L"platform");
HRESULT hr ;
if (NULL == pItemNode)
{
goto done;
}
if (aubsPlatform.IsNULL())
{
DEBUGMSG("CItemDetails::ClonePlatformNode() fail to create platform string");
goto done;
}
if (!FindNode(pItemNode, aubsPlatform, &pPlatformNode))
{
DEBUGMSG("CItemDetails::ClonePlatformNode() fail to get platform node");
goto done;
}
if (FAILED(hr = pPlatformNode->cloneNode(VARIANT_TRUE, &pClonePlatformNode)))
{
DEBUGMSG("CItemDetails::ClonePlatformNode() fail to clone node %#lx", hr);
}
done:
SafeRelease(pItemNode);
SafeRelease(pPlatformNode);
return pClonePlatformNode;
}
/////////////////////////////////////////////////////////////////////////////////////////
// retrieve cab names associated with an item identified by bsitemid
// called should free ppCabNames allocated in the function
// *pCabsNum contains number of cab names returned
////////////////////////////////////////////////////////////////////////////////////////
HRESULT CItemDetails::GetCabNames(BSTR bsItemId, BSTR ** ppCabNames, UINT *pCabsNum)
{
IXMLDOMNode * pItemNode = getItemNode(bsItemId);
IXMLDOMNodeList *pCodeBaseNodes = NULL;
BSTR * pCabNames = NULL;
UINT uCabsNum;
CAU_BSTR aubsCodeBase (L"installation/codeBase");
CAU_BSTR aubsHREF(L"href");
HRESULT hr = E_FAIL;
//DEBUGMSG("CItemDetails::GetCabNames() starts");
if (aubsCodeBase.IsNULL() || aubsHREF.IsNULL())
{
DEBUGMSG("fail to create aubs");
goto done;
}
if (NULL == pItemNode)
{
goto done;
}
if (FAILED(hr = pItemNode->selectNodes(aubsCodeBase, &pCodeBaseNodes)) || NULL == pCodeBaseNodes)
{
DEBUGMSG("Fail to find codebase section");
goto done;
}
pCodeBaseNodes->get_length((long *) &uCabsNum);
pCabNames = (BSTR*) malloc(uCabsNum * sizeof(BSTR));
ZeroMemory((PVOID)pCabNames, uCabsNum * sizeof(BSTR));
if (NULL == pCabNames)
{
hr = E_OUTOFMEMORY;
goto done;
}
for (UINT i = 0; i < uCabsNum ; i++)
{
IXMLDOMNode *pCodeBaseNode;
if (FAILED(hr = pCodeBaseNodes->get_item(i, &pCodeBaseNode)))
{
DEBUGMSG("Fail to get codebase %d", i);
goto done;
}
if (FAILED(hr = GetAttribute(pCodeBaseNode, aubsHREF, &(pCabNames[i]))))
{
DEBUGMSG("Fail to get attribute href");
pCodeBaseNode->Release();
goto done;
}
pCodeBaseNode->Release();
}
*ppCabNames = pCabNames;
*pCabsNum = uCabsNum;
done:
SafeRelease(pCodeBaseNodes);
SafeRelease(pItemNode);
if (FAILED(hr))
{
if (NULL != pCabNames)
{
for (UINT j = 0; j < uCabsNum; j++)
{
SafeFreeBSTR(pCabNames[j]);
}
free(pCabNames);
}
}
// DEBUGMSG("CItemDetails::GetCabNames() ends");
return hr;
}
BSTR CItemDetails::GetItemDownloadPath(BSTR bstrItemId)
{
// USES_CONVERSION; only needed for ansi version
BSTR bstrdownloadPath;
BSTR bstrRet = NULL;
IXMLDOMNode * pIdentityNode ;
DEBUGMSG("CItemDetails::GetItemDownloadPath starts");
if (NULL == (pIdentityNode = getIdentityNode(bstrItemId)))
{
goto done;
}
if (FAILED(UtilGetUniqIdentityStr(pIdentityNode, &bstrdownloadPath, 0)))
{
DEBUGMSG("GetItemDownloadPath() fail to get unique identity string");
goto done;
}
TCHAR tszPath[MAX_PATH];
GetCabsDownloadPath(tszPath, MAX_PATH);
lstrcat(tszPath, _T("\\"));
lstrcat(tszPath, W2T(bstrdownloadPath));
bstrRet = SysAllocString(T2W(tszPath));
SysFreeString(bstrdownloadPath);
done:
SafeRelease(pIdentityNode);
DEBUGMSG("CItemDetails::GetItemDownloadPath() got %S", bstrRet);
if (NULL != bstrRet && !EnsureDirExists(W2T(bstrRet)))
{
DEBUGMSG("CItemDetails::GetItemDownloadPath() fail to create directory %S", bstrRet);
SysFreeString(bstrRet);
bstrRet = NULL;
}
return bstrRet;
}
HRESULT CItemDetails::FindNextItemId(BSTR bsPrevItemId, BSTR * pbsNextItemId)
{
return E_NOTIMPL;
}
HRESULT CItemDetails::GetTitle(BSTR bsItemId, BSTR * pbsTitle)
{
return E_NOTIMPL;
}
HRESULT CItemDetails::GetDescription(BSTR bsItemId, BSTR *pbsDescription)
{
return E_NOTIMPL;
}
HRESULT CItemDetails::GetCompanyName(BSTR bsItemId, BSTR *pbsCompanyName)
{
return E_NOTIMPL;
}
HRESULT CItemDetails::GetRTFUrl(BSTR bsItemId, BSTR *pbsRTFUrl)
{
return E_NOTIMPL;
}
HRESULT CItemDetails::GetEulaUrl(BSTR bsItemId, BSTR *pbsEulaUrl)
{
return E_NOTIMPL;
}
CItemList* ExtractDriverItemInfo(BSTR bsDetails)
{
DEBUGMSG("Extracting driver item information starts");
return ExtractNormalItemInfo(bsDetails);
DEBUGMSG("Extracting driver item information done");
}
CItemList* ExtractNormalItemInfo(BSTR bsDetails)
{
USES_CONVERSION;
IXMLDOMDocument2 *pItemDetailsXML;
IXMLDOMNodeList *pItemNodeList = NULL;
CItemList *pRet = NULL;
int i;
HRESULT hr ;
CAU_BSTR bsItemPattern(L"catalog/provider/item"); //case sensitive
CAU_BSTR bsItemIDPattern(L"identity/@itemID");
CAU_BSTR bsTitlePattern(L"description/descriptionText/title");
CAU_BSTR bsDescPattern(L"description/descriptionText/text()");
CAU_BSTR bsRTFUrlPattern(L"description/descriptionText/details/@href");
CAU_BSTR bsEulaUrlPattern(L"description/descriptionText/eula/@href");
BSTR pPatterns[] = {
bsItemIDPattern, bsTitlePattern, bsDescPattern,
bsRTFUrlPattern, bsEulaUrlPattern };
CAU_BSTR bsCompanyNamePattern(L"description/descriptionText/title");
DEBUGMSG("ExtractNormalItemInfo() starts");
// DEBUGMSG("input string is %S", bsDetails);
if (bsCompanyNamePattern.IsNULL() || bsItemPattern.IsNULL())
{
goto done;
}
for (i = 0; i < ARRAYSIZE(pPatterns); i++)
{
if (NULL == pPatterns[i])
{
goto done;
}
}
if (FAILED(CoCreateInstance(__uuidof(DOMDocument30), NULL, CLSCTX_INPROC_SERVER, __uuidof( IXMLDOMDocument2), (void**)&pItemDetailsXML)))
{
DEBUGMSG("Fail to create XML document for Item Details");
goto done;
}
hr = pItemDetailsXML->put_async(VARIANT_FALSE);
VARIANT_BOOL fOk;
hr = pItemDetailsXML->loadXML(bsDetails, &fOk);
if (S_OK != hr)
{
DEBUGMSG("ExtractNormalItemInfo(): fail to extract information");
goto done;
}
hr = pItemDetailsXML->selectNodes(bsItemPattern, &pItemNodeList);
if (FAILED(hr) || NULL == pItemNodeList)
{
DEBUGMSG("ExtractNormalItemInfo() : no item found");
goto done;
}
pRet = new CItemList();
long lNodeNum;
pItemNodeList->get_length(&lNodeNum);
for (i = 0; i < lNodeNum; i++)
{
IXMLDOMNode *pnextItem;
hr = pItemNodeList->nextNode(&pnextItem);
if (NULL == pnextItem)
{
continue;
}
//BSTR bsRegIDPattern = L""; //publishername.name to stick into registry when hidden
const char * pFields[] = {
"ItemID", "Title", "Description", "RTFUrl", "EulaUrl"};
IXMLDOMNode *pNode;
CItem *pitem = new CItem();
for (int j = 0; j < ARRAYSIZE(pPatterns); j++)
{
hr = pnextItem->selectSingleNode(pPatterns[j], &pNode);
if (NULL != pNode)
{
BSTR bsItemInfo;
pNode->get_text(&bsItemInfo);
pitem->SetField(pFields[j], bsItemInfo);
pNode->Release();
}
}
IXMLDOMNode *pProvider = NULL;
pnextItem->get_parentNode(&pProvider);
if (NULL == pProvider)
{
DEBUGMSG("ExtractNormalItemInfo() fail to get provider node");
}
else
{
BSTR bsCompanyName = NULL;
pProvider->selectSingleNode(bsCompanyNamePattern, &pNode);
if (NULL == pNode)
{
DEBUGMSG("ExtractNormalItemInfo() couldn't find company name, default to MS");
bsCompanyName = SysAllocString(DEFAULT_COMPANY_NAME);
}
else
{
pNode->get_text(&bsCompanyName);
pNode->Release();
}
if (NULL != bsCompanyName)
{
pitem->SetField("CompanyName", bsCompanyName);
SysFreeString(bsCompanyName);
}
pRet->Add(pitem);
pProvider->Release();
}
pnextItem->Release();
}
pItemDetailsXML->Release();
done:
DEBUGMSG("ExtractNormalItemInfo() ends");
return pRet;
}
///////////////////////////////////////////////////////////////////
// merge catalog 1 and catalog2 and make it destination catalog *pDesCatalog
///////////////////////////////////////////////////////////////////
HRESULT MergeCatalogs(BSTR bsCatalog1, BSTR bsCatalog2, BSTR *pbsDesCatalog )
{
IXMLDOMDocument * pCat1 = NULL;
IXMLDOMDocument * pCat2 = NULL;
IXMLDOMNodeList *pProviderNodeList = NULL;
IXMLDOMNode *pCatalogNode = NULL;
CAU_BSTR aubscatalog(L"catalog");
CAU_BSTR aubsprovider(L"catalog/provider");
HRESULT hr = E_FAIL;
DEBUGMSG("MergeCatalogs() starts");
if (aubsprovider.IsNULL() ||
aubscatalog.IsNULL() ||
FAILED(hr = LoadXMLDoc(bsCatalog1, &pCat1)) ||
FAILED(hr = LoadXMLDoc(bsCatalog2,&pCat2)))
{
DEBUGMSG("MergeCatalogs() fail to load xml or fail or allocate string (with error %#lx)", hr);
goto done;
}
if (FAILED(hr = FindSingleDOMNode(pCat1, aubscatalog, &pCatalogNode)))
{
DEBUGMSG("Fail to find provider in catalog 1");
goto done;
}
if (NULL == (pProviderNodeList = FindDOMNodeList(pCat2, aubsprovider)))
{
DEBUGMSG("Fail to find provider in catalog 2 with error %#lx", hr);
goto done;
}
long lNum;
pProviderNodeList->get_length(&lNum);
for (int i = 0; i < lNum; i++)
{
IXMLDOMNode * pProviderNode;
if (FAILED(hr = pProviderNodeList->get_item(i, &pProviderNode)))
{
DEBUGMSG("Fail to get item in Provider List with error %#lx", hr);
goto done;
}
if (FAILED(hr = InsertNode(pCatalogNode, pProviderNode)))
{
DEBUGMSG("Fail to append provider node from catalog 2 to catalog 1 with error %#lx", hr);
pProviderNode->Release();
goto done;
}
pProviderNode->Release();
}
if (FAILED(hr = pCat1->get_xml(pbsDesCatalog)))
{
DEBUGMSG("Fail to get result xml for catalog 1 with error %#lx", hr);
goto done;
}
LOGFILE(MERGED_CATALOG_FILE, *pbsDesCatalog);
done:
SafeRelease(pCat1);
SafeRelease(pCat2);
SafeRelease(pProviderNodeList);
SafeRelease(pCatalogNode);
DEBUGMSG("MergeCatalogs() ends");
return hr;
}
IXMLDOMNode * createDownloadItemStatusNode(IXMLDOMDocument * pxml, CItem * pItem, BSTR bsInstallation)
{
CAU_BSTR aubs_itemStatus(L"itemStatus");
CAU_BSTR aubs_downloadPath(L"downloadPath");
CAU_BSTR aubs_downloadStatus(L"downloadStatus");
CAU_BSTR aubs_downloadStatusValue(L"value");
IXMLDOMElement * pitemStatus = NULL;
BOOL fError = FALSE; //no error occurs
IXMLDOMNode * pIdentity = NULL;
IXMLDOMNode * pdescription = NULL;
IXMLDOMNode * pPlatform = NULL;
IXMLDOMElement *pdownloadStatus = NULL;
IXMLDOMElement *pdownloadPath = NULL;
CItemDetails itemDetails;
BSTR bsItemId = NULL, bsdownloadPath=NULL;
VARIANT vComplete;
IXMLDOMNode * pNewNode;
IXMLDOMNode ** ItemStatusChildren[] = {&pIdentity, &pdescription, &pPlatform};
DEBUGMSG("CAUCatalog::createDownloadItemStatusNode() starts");
if (!itemDetails.Init(bsInstallation))
{
DEBUGMSG("fail to init itemdetails");
fError = TRUE;
goto done;
}
if (aubs_itemStatus.IsNULL() || aubs_downloadPath.IsNULL() ||
aubs_downloadStatus.IsNULL() || aubs_downloadStatusValue.IsNULL())
{
DEBUGMSG("fail to create string");
fError = TRUE;
goto done;
}
bsItemId = pItem->GetField("ItemId");
DEBUGMSG("creating node for %S", bsItemId);
if (NULL == bsItemId)
{
DEBUGMSG("fails to get item id");
fError = TRUE;
goto done;
}
if (FAILED(pxml->createElement(aubs_itemStatus, &pitemStatus)) || NULL == pitemStatus)
{
DEBUGMSG("fail to create item status node");
fError = TRUE;
goto done;
}
pIdentity = itemDetails.CloneIdentityNode(bsItemId);
pdescription = itemDetails.CloneDescriptionNode(bsItemId);
pPlatform = itemDetails.ClonePlatformNode(bsItemId);
if (NULL == pIdentity || NULL == pdescription || NULL == pPlatform)
{
fError = TRUE;
goto done;
}
for (int i = 0; i < ARRAYSIZE(ItemStatusChildren); i++)
{
if (FAILED(pitemStatus->appendChild(*(ItemStatusChildren[i]), &pNewNode)))
{
DEBUGMSG("fail to append identy node");
fError = TRUE;
goto done;
}
}
if (FAILED(pxml->createElement(aubs_downloadPath, &pdownloadPath)) || NULL == pdownloadPath)
{
DEBUGMSG("fail to create download path node");
fError = TRUE;
goto done;
}
bsdownloadPath = itemDetails.GetItemDownloadPath(bsItemId);
if (NULL == bsdownloadPath)
{
fError = TRUE;
goto done;
}
if (FAILED(pdownloadPath->put_text(bsdownloadPath)))
{
DEBUGMSG("fail to set download path text to %S", bsdownloadPath);
fError = TRUE;
goto done;
}
if (FAILED(pitemStatus->appendChild(pdownloadPath, &pNewNode)))
{
DEBUGMSG("fail to append download path");
fError = TRUE;
goto done;
}
if (FAILED(pxml->createElement(aubs_downloadStatus, &pdownloadStatus)) || NULL == pdownloadStatus)
{
DEBUGMSG("fail to create download status node");
fError = TRUE;
goto done;
}
vComplete.vt = VT_BSTR;
vComplete.bstrVal = L"COMPLETE";
if (FAILED(SetAttribute(pdownloadStatus, aubs_downloadStatusValue, vComplete)))
{
DEBUGMSG("fail to set download status attribute");
fError = TRUE;
goto done;
}
if (FAILED(pitemStatus->appendChild(pdownloadStatus, &pNewNode)))
{
DEBUGMSG("fail to append download status node");
fError = TRUE;
goto done;
}
done:
itemDetails.Uninit();
SafeFreeBSTR(bsItemId);
SafeFreeBSTR(bsdownloadPath);
if (fError)
{
SafeRelease(pitemStatus);
pitemStatus = NULL;
}
SafeRelease(pIdentity);
SafeRelease(pPlatform);
SafeRelease(pdescription);
SafeRelease(pdownloadPath);
SafeRelease(pdownloadStatus);
DEBUGMSG("CAUCatalog::createDownloadItemStatusNode() ends");
return pitemStatus;
}
IXMLDOMDocument2 * CreateXMLDoc()
{
IXMLDOMDocument2 *pxml;
if (FAILED(CoCreateInstance(__uuidof(DOMDocument30), NULL, CLSCTX_INPROC_SERVER, __uuidof(IXMLDOMDocument2), (void**) &pxml)))
{
printf("fail to create xml document");
return NULL;
}
pxml->put_async(VARIANT_FALSE);
pxml->put_resolveExternals(VARIANT_FALSE);
pxml->put_validateOnParse(VARIANT_FALSE);
return pxml;
}
BSTR BuildDownloadResult(BSTR bsItemDetails, CItemList *pItemList)
{
BSTR bsRet = NULL;
IXMLDOMNode * pItems = NULL;
CAU_BSTR aubsItems(L"items");
HRESULT hr ;
IXMLDOMDocument *pxml;
CAU_BSTR aubsResultTemplate (L"<?xml version=\"1.0\"?><items xmlns=\"x-schema:http://schemas.windowsupdate.com/iu/resultschema.xml\"></items>");
if (aubsResultTemplate.IsNULL() || aubsItems.IsNULL())
{
DEBUGMSG("CAUCatalog::buildDownloadResult() fail to create result template string");
goto done;
}
if (FAILED(LoadXMLDoc(aubsResultTemplate, &pxml)))
{
DEBUGMSG("CAUCatalog::buildDownloadResult() fail to load download result template");
goto done;
}
if (FAILED(hr = FindSingleDOMNode(pxml, aubsItems, &pItems)) || NULL == pItems)
{
DEBUGMSG("CAUCatalog::buildDownloadResult() fail to get items with error %#lx", hr);
goto done;
}
UINT uItemCount= pItemList->Count();
DEBUGMSG("need to insert %d items in download result", uItemCount);
for (UINT i = 0; i < uItemCount; i++)
{
CItem *pItem = (*pItemList)[i];
if (pItem->IsSelected())
{
IXMLDOMNode * pItemStatus = createDownloadItemStatusNode(pxml, pItem, bsItemDetails);
if (NULL != pItemStatus)
{
IXMLDOMNode * pNewNode;
if (FAILED(pItems->appendChild(pItemStatus, &pNewNode)) || NULL == pNewNode)
{
DEBUGMSG("fail to insert item %d", i);
}
else
{
DEBUGMSG("item %d inserted", i);
}
pItemStatus->Release();
}
}
}
if (FAILED( hr = pxml->get_xml(&bsRet)))
{
DEBUGMSG("CAUCatalog::buildDownloadResult() fail to get xml for the result %#lx", hr);
}
done: SafeRelease(pItems); SafeRelease(pxml); return bsRet; }