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.
375 lines
9.0 KiB
375 lines
9.0 KiB
// ===========================================================================
|
|
// File: DUMAN.CXX
|
|
// Distribution Unit Manager
|
|
//
|
|
|
|
#include <cdlpch.h>
|
|
#include <dispex.h>
|
|
#include <delaydll.h>
|
|
|
|
#define ERROR_EXIT(cond) if (!(cond)) { \
|
|
goto Exit;}
|
|
|
|
HRESULT DupAttributeA(IXMLElement *pElem, LPWSTR szAttribName, LPSTR *ppszRet)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"DupAttributeA",
|
|
"%#x, %.80wq, %#x",
|
|
pElem, szAttribName, ppszRet
|
|
));
|
|
|
|
VARIANT vProp;
|
|
LPSTR pVal = NULL;
|
|
|
|
HRESULT hr = GetAttribute(pElem, szAttribName, &vProp);
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
DWORD len;
|
|
// compute length
|
|
if (!(len = WideCharToMultiByte(CP_ACP, 0, vProp.bstrVal , -1, pVal,
|
|
0, NULL, NULL))) {
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
goto Exit;
|
|
}
|
|
pVal = new char[len+1];
|
|
if (!pVal) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
if (!WideCharToMultiByte(CP_ACP, 0, vProp.bstrVal , -1, pVal,
|
|
len, NULL, NULL)) {
|
|
|
|
SAFEDELETE(pVal);
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
|
|
VariantClear(&vProp);
|
|
|
|
if (pVal) {
|
|
SAFEDELETE((*ppszRet));
|
|
*ppszRet = pVal;
|
|
}
|
|
|
|
DEBUG_LEAVE(hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT DupAttribute(IXMLElement *pElem, LPWSTR szAttribName, LPWSTR *ppszRet)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"DupAttribute",
|
|
"%#x, %.80wq, %#x",
|
|
pElem, szAttribName, ppszRet
|
|
));
|
|
|
|
VARIANT vProp;
|
|
LPWSTR pVal = NULL;
|
|
|
|
HRESULT hr = GetAttribute(pElem, szAttribName, &vProp);
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
Assert(vProp.vt == VT_BSTR);
|
|
Assert(vProp.bstrVal);
|
|
|
|
if (vProp.bstrVal) {
|
|
hr = CDLDupWStr( &pVal, vProp.bstrVal);
|
|
} else {
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
|
|
VariantClear(&vProp);
|
|
|
|
if (pVal) {
|
|
SAFEDELETE((*ppszRet));
|
|
*ppszRet = pVal;
|
|
}
|
|
|
|
DEBUG_LEAVE(hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT GetAttributeA(IXMLElement *pElem, LPWSTR szAttribName, LPSTR pAttribValue, DWORD dwBufferLen)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"GetAttributeA",
|
|
"%#x, %.80wq, %.80q, %#x",
|
|
pElem, szAttribName, pAttribValue, dwBufferLen
|
|
));
|
|
|
|
VARIANT vProp;
|
|
|
|
HRESULT hr = GetAttribute(pElem, szAttribName, &vProp);
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
|
|
if (!WideCharToMultiByte(CP_ACP, 0, vProp.bstrVal , -1, pAttribValue,
|
|
dwBufferLen, NULL, NULL)) {
|
|
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
VariantClear(&vProp);
|
|
}
|
|
|
|
DEBUG_LEAVE(hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT GetAttribute(IXMLElement *pElem, LPWSTR szAttribName, VARIANT *pvProp)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"GetAttribute",
|
|
"%#x, %.80wq, %#x",
|
|
pElem, szAttribName, pvProp
|
|
));
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
VariantInit(pvProp);
|
|
|
|
if ((hr = pElem->getAttribute(szAttribName, pvProp)) == S_OK )
|
|
{
|
|
Assert(pvProp->vt == VT_BSTR);
|
|
// caller needs to VariantClear(pvProp);
|
|
}
|
|
|
|
if (hr == S_FALSE) {
|
|
|
|
hr = REGDB_E_KEYMISSING;
|
|
}
|
|
|
|
DEBUG_LEAVE(hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT GetNextChildTag(IXMLElement *pRoot, LPCWSTR szTag, IXMLElement **ppChildReq, int &nLastChild)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"GetNextChildTag",
|
|
"%#x, %.80wq, %#x, %#x",
|
|
pRoot, szTag, ppChildReq, &nLastChild
|
|
));
|
|
|
|
BSTR bstrTag = NULL;
|
|
IXMLElementCollection * pChildren = NULL;
|
|
HRESULT hr = S_FALSE; // assume not found.
|
|
IXMLElement * pChild = NULL;
|
|
|
|
//
|
|
// Find the children if they exist
|
|
//
|
|
if (SUCCEEDED(pRoot->get_children(&pChildren)) && pChildren)
|
|
{
|
|
long length = 0;
|
|
|
|
if (SUCCEEDED(pChildren->get_length(&length)) && length > 0)
|
|
{
|
|
VARIANT vIndex, vEmpty;
|
|
vIndex.vt = VT_I4;
|
|
vEmpty.vt = VT_EMPTY;
|
|
|
|
nLastChild++;
|
|
|
|
for (long i=nLastChild; i<length; i++)
|
|
{
|
|
vIndex.lVal = i;
|
|
IDispatch *pDispItem = NULL;
|
|
if (SUCCEEDED(pChildren->item(vIndex, vEmpty, &pDispItem)))
|
|
{
|
|
|
|
if (SUCCEEDED(pDispItem->QueryInterface(IID_IXMLElement, (void **)&pChild)))
|
|
{
|
|
// look for first SoftDist tag
|
|
|
|
pChild->get_tagName(&bstrTag);
|
|
|
|
// we may get a NULL bstrTag, possibly from a comment TAG, hence check returned bstrTag
|
|
if (bstrTag && (StrCmpIW(bstrTag, szTag) == 0))
|
|
{
|
|
nLastChild = i;
|
|
SAFERELEASE(pDispItem);
|
|
hr = S_OK;
|
|
goto Exit;
|
|
}
|
|
|
|
SAFESYSFREESTRING(bstrTag);
|
|
|
|
SAFERELEASE(pChild);
|
|
}
|
|
|
|
SAFERELEASE(pDispItem);
|
|
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
|
|
Exit:
|
|
|
|
*ppChildReq = pChild;
|
|
|
|
if (pChildren)
|
|
SAFERELEASE(pChildren);
|
|
|
|
SAFESYSFREESTRING(bstrTag);
|
|
|
|
DEBUG_LEAVE(hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT GetFirstChildTag(IXMLElement *pRoot, LPCWSTR szTag, IXMLElement **ppChildReq)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"GetFirstChildTag",
|
|
"%#x, %.80wq, %#x",
|
|
pRoot, szTag, ppChildReq
|
|
));
|
|
|
|
int nLastChild = -1; // first child, never seen any before this one
|
|
|
|
HRESULT hr = GetNextChildTag(pRoot, szTag, ppChildReq, nLastChild);
|
|
|
|
DEBUG_LEAVE(hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
GetTextContent(IXMLElement *pRoot, LPCWSTR szTag, LPWSTR *ppszContent)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"GetTextContent",
|
|
"%#x, %.80wq, %#x",
|
|
pRoot, szTag, ppszContent
|
|
));
|
|
|
|
IXMLElement *pChild = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
if (GetFirstChildTag(pRoot, szTag, &pChild) == S_OK) {
|
|
|
|
BSTR bstrText = NULL;
|
|
hr = pChild->get_text(&bstrText);
|
|
if (FAILED(hr)) {
|
|
goto Exit;
|
|
}
|
|
if (bstrText) {
|
|
hr = CDLDupWStr( ppszContent, bstrText);
|
|
} else {
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
SAFESYSFREESTRING(bstrText);
|
|
}
|
|
|
|
Exit:
|
|
|
|
SAFERELEASE(pChild);
|
|
|
|
DEBUG_LEAVE(hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT GetSoftDistFromOSD(LPCSTR szFile, IXMLElement **ppSoftDist)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"GetSoftDistFromOSD",
|
|
"%.80q, %#x",
|
|
szFile, ppSoftDist
|
|
));
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
IXMLDocument *pDoc = NULL;
|
|
IStream *pStm = NULL;
|
|
IPersistStreamInit *pPSI = NULL;
|
|
IXMLElement *pRoot = NULL;
|
|
BSTR bStrName;
|
|
|
|
|
|
// BUGBUG: optimize here to keep the xml parser up beyond the current code
|
|
// download?
|
|
|
|
//
|
|
// Create an empty XML document
|
|
//
|
|
hr = CoCreateInstance(CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
|
|
IID_IXMLDocument, (void**)&pDoc);
|
|
|
|
ERROR_EXIT (pDoc);
|
|
|
|
//
|
|
// Synchronously create a stream on an URL
|
|
//
|
|
hr = URLOpenBlockingStream(0, szFile, &pStm, 0,0);
|
|
ERROR_EXIT(SUCCEEDED(hr) && pStm);
|
|
|
|
//
|
|
// Get the IPersistStreamInit interface to the XML doc
|
|
//
|
|
hr = pDoc->QueryInterface(IID_IPersistStreamInit, (void **)&pPSI);
|
|
ERROR_EXIT(SUCCEEDED(hr));
|
|
|
|
//
|
|
// Init the XML doc from the stream
|
|
//
|
|
hr = pPSI->Load(pStm);
|
|
ERROR_EXIT(SUCCEEDED(hr));
|
|
|
|
//
|
|
// Now walk the OM and look at interesting things:
|
|
//
|
|
hr = pDoc->get_root(&pRoot);
|
|
ERROR_EXIT(SUCCEEDED(hr));
|
|
hr = pRoot->get_tagName(&bStrName);
|
|
|
|
if (StrCmpIW(bStrName, DU_TAG_SOFTDIST) == 0)
|
|
{
|
|
*ppSoftDist = pRoot;
|
|
(*ppSoftDist)->AddRef();
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
*ppSoftDist = NULL;
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
|
|
SAFESYSFREESTRING(bStrName);
|
|
|
|
|
|
|
|
Exit:
|
|
|
|
SAFERELEASE(pDoc);
|
|
SAFERELEASE(pPSI);
|
|
SAFERELEASE(pStm);
|
|
SAFERELEASE(pRoot);
|
|
|
|
DEBUG_LEAVE(hr);
|
|
return hr;
|
|
}
|