mirror of
https://github.com/reactos/reactos.git
synced 2024-11-25 20:43:31 +08:00
181 lines
5.1 KiB
C++
181 lines
5.1 KiB
C++
/*
|
|
* PROJECT: ReactOS Applications
|
|
* LICENSE: LGPL - See COPYING in the top level directory
|
|
* FILE: base/applications/msconfig_new/xmldomparser.cpp
|
|
* PURPOSE: XML DOM Parser
|
|
* COPYRIGHT: Copyright 2011-2012 Hermes BELUSCA - MAITO <hermes.belusca@sfr.fr>
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
#include "xmldomparser.hpp"
|
|
#include "utils.h"
|
|
#include "stringutils.h"
|
|
|
|
// UTF8 adapted version of ConvertStringToBSTR (see lib/sdk/comsupp/comsupp.c)
|
|
static BSTR
|
|
ConvertUTF8StringToBSTR(const char *pSrc)
|
|
{
|
|
DWORD cwch;
|
|
BSTR wsOut(NULL);
|
|
|
|
if (!pSrc) return NULL;
|
|
|
|
/* Compute the needed size with the NULL terminator */
|
|
cwch = MultiByteToWideChar(CP_UTF8, 0, pSrc, -1, NULL, 0);
|
|
if (cwch == 0) return NULL;
|
|
|
|
/* Allocate the BSTR (without the NULL terminator) */
|
|
wsOut = SysAllocStringLen(NULL, cwch - 1);
|
|
if (!wsOut)
|
|
{
|
|
_com_issue_error(HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY));
|
|
return NULL;
|
|
}
|
|
|
|
/* Convert the string */
|
|
if (MultiByteToWideChar(CP_UTF8, 0, pSrc, -1, wsOut, cwch) == 0)
|
|
{
|
|
/* We failed, clean everything up */
|
|
cwch = GetLastError();
|
|
|
|
SysFreeString(wsOut);
|
|
wsOut = NULL;
|
|
|
|
_com_issue_error(!IS_ERROR(cwch) ? HRESULT_FROM_WIN32(cwch) : cwch);
|
|
}
|
|
|
|
return wsOut;
|
|
}
|
|
|
|
HRESULT
|
|
InitXMLDOMParser(VOID)
|
|
{
|
|
return CoInitialize(NULL);
|
|
}
|
|
|
|
VOID
|
|
UninitXMLDOMParser(VOID)
|
|
{
|
|
CoUninitialize();
|
|
return;
|
|
}
|
|
|
|
HRESULT
|
|
CreateAndInitXMLDOMDocument(IXMLDOMDocument** ppDoc)
|
|
{
|
|
HRESULT hr = CoCreateInstance(CLSID_DOMDocument30, // __uuidof(DOMDocument30), // NOTE: Do not use DOMDocument60 if you want MSConfig working by default on XP.
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_PPV_ARG(IXMLDOMDocument, ppDoc) /* IID_PPV_ARGS(ppDoc) */);
|
|
if (!SUCCEEDED(hr))
|
|
return hr;
|
|
|
|
/* These methods should not fail so don't inspect result */
|
|
(*ppDoc)->put_async(VARIANT_FALSE);
|
|
(*ppDoc)->put_validateOnParse(VARIANT_FALSE);
|
|
(*ppDoc)->put_resolveExternals(VARIANT_FALSE);
|
|
|
|
return hr;
|
|
}
|
|
|
|
BOOL
|
|
LoadXMLDocumentFromResource(IXMLDOMDocument* pDoc,
|
|
LPCWSTR lpszXMLResName)
|
|
{
|
|
VARIANT_BOOL Success = VARIANT_FALSE;
|
|
HRSRC hRes;
|
|
HGLOBAL handle;
|
|
LPVOID lpXMLRes;
|
|
_bstr_t bstrXMLRes;
|
|
|
|
if (!pDoc)
|
|
return FALSE;
|
|
|
|
// hRes = FindResourceExW(NULL, RT_HTML, lpszXMLResName, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
|
|
hRes = FindResourceW(NULL, lpszXMLResName, RT_HTML);
|
|
if (hRes == NULL)
|
|
return FALSE;
|
|
|
|
handle = LoadResource(NULL, hRes);
|
|
if (handle == NULL)
|
|
return FALSE;
|
|
|
|
lpXMLRes = LockResource(handle);
|
|
if (lpXMLRes == NULL)
|
|
goto Cleanup;
|
|
|
|
/* Convert the resource to UNICODE if needed */
|
|
if (!IsTextUnicode(lpXMLRes, SizeofResource(NULL, hRes), NULL))
|
|
bstrXMLRes.Attach(ConvertUTF8StringToBSTR((LPCSTR)lpXMLRes));
|
|
else
|
|
bstrXMLRes = (LPCWSTR)lpXMLRes;
|
|
|
|
if (SUCCEEDED(pDoc->loadXML(bstrXMLRes, &Success)) && (Success != VARIANT_TRUE))
|
|
{
|
|
IXMLDOMParseError* pXMLErr = NULL;
|
|
_bstr_t bstrErr;
|
|
|
|
if (SUCCEEDED(pDoc->get_parseError(&pXMLErr)) &&
|
|
SUCCEEDED(pXMLErr->get_reason(&bstrErr.GetBSTR())))
|
|
{
|
|
LPWSTR lpszStr = NULL;
|
|
|
|
if (IS_INTRESOURCE((ULONG_PTR)lpszXMLResName))
|
|
lpszStr = FormatString(L"Failed to load DOM from resource '#%u': %wS", lpszXMLResName, (wchar_t*)bstrErr);
|
|
else
|
|
lpszStr = FormatString(L"Failed to load DOM from resource '%wS': %wS", lpszXMLResName, (wchar_t*)bstrErr);
|
|
|
|
MessageBoxW(NULL, lpszStr, L"Error", MB_ICONERROR | MB_OK);
|
|
|
|
MemFree(lpszStr);
|
|
}
|
|
|
|
SAFE_RELEASE(pXMLErr);
|
|
}
|
|
|
|
Cleanup:
|
|
FreeResource(handle);
|
|
|
|
return (Success == VARIANT_TRUE);
|
|
}
|
|
|
|
BOOL
|
|
LoadXMLDocumentFromFile(IXMLDOMDocument* pDoc,
|
|
LPCWSTR lpszFilename,
|
|
BOOL bIgnoreErrorsIfNonExistingFile)
|
|
{
|
|
VARIANT_BOOL Success = VARIANT_FALSE;
|
|
_variant_t varFileName(lpszFilename);
|
|
|
|
if (!pDoc)
|
|
return FALSE;
|
|
|
|
if (SUCCEEDED(pDoc->load(varFileName, &Success)) && (Success != VARIANT_TRUE))
|
|
{
|
|
IXMLDOMParseError* pXMLErr = NULL;
|
|
LONG lErrorCode = 0L;
|
|
|
|
if (SUCCEEDED(pDoc->get_parseError(&pXMLErr)) &&
|
|
SUCCEEDED(pXMLErr->get_errorCode(&lErrorCode)))
|
|
{
|
|
if ( !bIgnoreErrorsIfNonExistingFile ||
|
|
((lErrorCode != _HRESULT_TYPEDEF_(0x800C0006) /* INET_E_OBJECT_NOT_FOUND */) &&
|
|
(lErrorCode != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))) )
|
|
{
|
|
_bstr_t bstrErr;
|
|
|
|
if (SUCCEEDED(pXMLErr->get_reason(&bstrErr.GetBSTR())))
|
|
{
|
|
LPWSTR lpszStr = FormatString(L"Failed to load DOM from '%wS': %wS", lpszFilename, (wchar_t*)bstrErr);
|
|
MessageBoxW(NULL, lpszStr, L"Error", MB_ICONERROR | MB_OK);
|
|
MemFree(lpszStr);
|
|
}
|
|
}
|
|
}
|
|
|
|
SAFE_RELEASE(pXMLErr);
|
|
}
|
|
|
|
return (Success == VARIANT_TRUE);
|
|
}
|