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.
281 lines
7.9 KiB
281 lines
7.9 KiB
//*******************************
|
|
// XML OM test code
|
|
//
|
|
// *******************************
|
|
|
|
#include <windows.h>
|
|
#include <windowsx.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <crtdbg.h>
|
|
#include <io.h>
|
|
#include <urlmon.h>
|
|
#include <hlink.h>
|
|
#include <dispex.h>
|
|
#include <shlobj.h>
|
|
#include "mshtml.h"
|
|
#include "msxml.h"
|
|
#include "Utility.h"
|
|
#include "EnumIDL.h"
|
|
#include "ParseXML.h"
|
|
|
|
|
|
//
|
|
// Dump an element attribute member if present.
|
|
//
|
|
void DumpAttrib(IXMLElement *pElem, BSTR bstrAttribName)
|
|
{
|
|
VARIANT vProp;
|
|
|
|
VariantInit(&vProp);
|
|
|
|
if (SUCCEEDED(pElem->getAttribute(bstrAttribName, &vProp)))
|
|
{
|
|
if (vProp.vt == VT_BSTR)
|
|
{
|
|
printf(" %S=\"%S\"", bstrAttribName, vProp.bstrVal);
|
|
}
|
|
VariantClear(&vProp);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Helper routine to quickly find out if this is a named element
|
|
// currently only used to improve the format of the output.
|
|
//
|
|
BOOL IsNamedElement(IXMLElement *pElem)
|
|
{
|
|
BSTR bstrName;
|
|
|
|
if (SUCCEEDED(pElem->get_tagName(&bstrName)))
|
|
{
|
|
if (bstrName)
|
|
{
|
|
SysFreeString(bstrName);
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
void DumpElement
|
|
(
|
|
LPITEMIDLIST pidl,
|
|
CPidlMgr *pCPidlMgr,
|
|
CEnumIDList *pCEnumIDList,
|
|
IXMLElement * pElem,
|
|
XMLTAG tag
|
|
)
|
|
{
|
|
BSTR bstrTagName = NULL;
|
|
BSTR bstrContent = NULL;
|
|
IXMLElementCollection * pChildren;
|
|
BSTR bstrITEM = L"ITEM";
|
|
BSTR bstrNAME = L"NAME";
|
|
BSTR bstrTYPE = L"TYPE";
|
|
BSTR bstrFOLDER = L"Folder";
|
|
BSTR bstrICON = L"ICON";
|
|
BSTR bstrBASE_URL = L"BASE-URL";
|
|
|
|
//
|
|
// Dump the NODE.
|
|
//
|
|
pElem->get_tagName(&bstrTagName);
|
|
if (bstrTagName)
|
|
{
|
|
if (!_wcsicmp(bstrTagName, bstrITEM))
|
|
{
|
|
if (tag == T_ITEM)
|
|
{
|
|
// Skip internal ITEMs
|
|
SysFreeString(bstrTagName);
|
|
return;
|
|
}
|
|
else if (tag == T_ROOT)
|
|
{
|
|
// We are at the root
|
|
// Drill down and look for ITEMs
|
|
tag = T_NONE;
|
|
}
|
|
else
|
|
{
|
|
// Drill down
|
|
tag = T_ITEM;
|
|
// Create new PIDL
|
|
pidl = pCPidlMgr->Create();
|
|
if(pidl)
|
|
pCEnumIDList->AddToEnumList(pidl);
|
|
}
|
|
}
|
|
else if (!_wcsicmp(bstrTagName, bstrNAME))
|
|
// Drill down
|
|
tag = T_NAME;
|
|
else if (!_wcsicmp(bstrTagName, bstrTYPE))
|
|
// Drill down
|
|
tag =T_TYPE;
|
|
else if (!_wcsicmp(bstrTagName, bstrICON))
|
|
// Drill down
|
|
tag = T_ICON;
|
|
else if (!_wcsicmp(bstrTagName, bstrBASE_URL))
|
|
// Drill down
|
|
tag = T_BASE_URL;
|
|
else
|
|
{
|
|
// We are not interested
|
|
SysFreeString(bstrTagName);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Build PIDL
|
|
XMLELEM_TYPE xmlElemType;
|
|
PIDLDATA pidldata;
|
|
if (SUCCEEDED(pElem->get_type((long *)&xmlElemType)))
|
|
{
|
|
if (xmlElemType == XMLELEMTYPE_TEXT)
|
|
{
|
|
if (SUCCEEDED(pElem->get_text(&bstrContent)))
|
|
{
|
|
if (bstrContent)
|
|
{
|
|
if (tag == T_TYPE)
|
|
{
|
|
if ( !_wcsicmp(bstrContent, bstrFOLDER)) // Later check on SHCONTF_FOLDERS
|
|
pidldata.fFolder = TRUE;
|
|
else
|
|
pidldata.fFolder = FALSE;
|
|
|
|
pidl = pCPidlMgr->SetDataPidl(pidl, &pidldata, FOLDER);
|
|
}
|
|
else if (tag == T_NAME)
|
|
{
|
|
WideCharToLocal(pidldata.szName, bstrContent, MAX_NAME);
|
|
pidl = pCPidlMgr->SetDataPidl(pidl, &pidldata, NAME);
|
|
}
|
|
else if (tag == T_ICON)
|
|
{
|
|
TCHAR szIcon[MAX_NAME];
|
|
WideCharToLocal(szIcon, bstrContent, MAX_NAME);
|
|
int index = AddIconImageList(g_himlLarge, szIcon);
|
|
AddIconImageList(g_himlSmall, szIcon);
|
|
pidldata.iIcon = index;
|
|
pidl = pCPidlMgr->SetDataPidl(pidl, &pidldata, ICON);
|
|
}
|
|
else if (tag == T_BASE_URL)
|
|
{
|
|
WideCharToLocal(pidldata.szUrl, bstrContent, MAX_NAME);
|
|
pidl = pCPidlMgr->SetDataPidl(pidl, &pidldata, URL);
|
|
}
|
|
}
|
|
SysFreeString(bstrContent);
|
|
}
|
|
}
|
|
}
|
|
return; // no need to free bstrTagName
|
|
}
|
|
//
|
|
// Find the children if they exist.
|
|
//
|
|
if (SUCCEEDED(pElem->get_children(&pChildren)) && pChildren)
|
|
{
|
|
WALK_ELEMENT_COLLECTION(pChildren, pDisp)
|
|
{
|
|
//
|
|
// pDisp will iterate over an IDispatch for each item in the collection.
|
|
//
|
|
IXMLElement * pChild;
|
|
if (SUCCEEDED(pDisp->QueryInterface(IID_IXMLElement, (void **)&pChild)))
|
|
{
|
|
DumpElement(pidl, pCPidlMgr, pCEnumIDList, pChild, tag );
|
|
pChild->Release();
|
|
}
|
|
}
|
|
END_WALK_ELEMENT_COLLECTION(pDisp);
|
|
pChildren->Release();
|
|
}
|
|
|
|
if (bstrTagName)
|
|
SysFreeString(bstrTagName);
|
|
}
|
|
|
|
int MyStrToOleStrN(LPOLESTR pwsz, int cchWideChar, LPCTSTR psz)
|
|
{
|
|
int i;
|
|
i=MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, cchWideChar);
|
|
if (!i)
|
|
{
|
|
//DBG_WARN("MyStrToOleStrN string too long; truncated");
|
|
pwsz[cchWideChar-1]=0;
|
|
}
|
|
else
|
|
ZeroMemory(pwsz+i, sizeof(OLECHAR)*(cchWideChar-i));
|
|
|
|
return i;
|
|
}
|
|
|
|
|
|
HRESULT GetSourceXML(IXMLDocument **ppDoc, TCHAR *pszURL)
|
|
{
|
|
PSTR pszErr = NULL;
|
|
IStream *pStm = NULL;
|
|
IPersistStreamInit *pPSI = NULL;
|
|
IXMLElement *pElem = NULL;
|
|
WCHAR *pwszURL=NULL;
|
|
BSTR pBURL=NULL;
|
|
HRESULT hr;
|
|
int cszURL = 0;
|
|
|
|
//
|
|
// Create an empty XML document.
|
|
//
|
|
hr = CoCreateInstance(CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
|
|
IID_IXMLDocument, (void**)ppDoc);
|
|
|
|
CHECK_ERROR (*ppDoc, "CoCreateInstance Failed");
|
|
|
|
pwszURL = (WCHAR *)LocalAlloc(LMEM_FIXED, ((sizeof(WCHAR))*(strlen(pszURL) + 2)));
|
|
CHECK_ERROR(pwszURL, "Mem Alloc Failure");
|
|
|
|
cszURL = MyStrToOleStrN(pwszURL, (strlen(pszURL) + 1), pszURL);
|
|
CHECK_ERROR(cszURL, "Failed to convert to UNICODE");
|
|
pBURL = SysAllocString(pwszURL);
|
|
CHECK_ERROR(pBURL, "Mem Alloc Failure");
|
|
LocalFree(pwszURL);
|
|
|
|
hr = (*ppDoc)->put_URL(pBURL);
|
|
|
|
if (! SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// Failed to parse stream, output error information.
|
|
//
|
|
IXMLError *pXMLError = NULL ;
|
|
XML_ERROR xmle;
|
|
|
|
hr = (*ppDoc)->QueryInterface(IID_IXMLError, (void **)&pXMLError);
|
|
CHECK_ERROR(SUCCEEDED(hr), "Couldn't get IXMLError");
|
|
|
|
// ASSERT(pXMLError);
|
|
|
|
hr = pXMLError->GetErrorInfo(&xmle);
|
|
SAFERELEASE(pXMLError);
|
|
CHECK_ERROR(SUCCEEDED(hr), "GetErrorInfo Failed");
|
|
|
|
SysFreeString(xmle._pszFound);
|
|
SysFreeString(xmle._pszExpected);
|
|
SysFreeString(xmle._pchBuf);
|
|
}
|
|
|
|
done: // Clean up.
|
|
//
|
|
// Release any used interfaces.
|
|
//
|
|
SAFERELEASE(pPSI);
|
|
SAFERELEASE(pStm);
|
|
// SAFERELEASE(*ppDoc); Do it in the caller!!!!!!!!!!!!!!!!!!
|
|
SysFreeString(pBURL);
|
|
return hr;
|
|
}
|
|
|