1 /* 2 * PROJECT: ReactOS Applications 3 * LICENSE: LGPL - See COPYING in the top level directory 4 * FILE: base/applications/msconfig_new/xmldomparser.cpp 5 * PURPOSE: XML DOM Parser 6 * COPYRIGHT: Copyright 2011-2012 Hermes BELUSCA - MAITO <hermes.belusca@sfr.fr> 7 */ 8 9 #include "precomp.h" 10 #include "xmldomparser.hpp" 11 #include "utils.h" 12 #include "stringutils.h" 13 14 // UTF8 adapted version of ConvertStringToBSTR (see lib/sdk/comsupp/comsupp.c) 15 static BSTR 16 ConvertUTF8StringToBSTR(const char *pSrc) 17 { 18 DWORD cwch; 19 BSTR wsOut(NULL); 20 21 if (!pSrc) return NULL; 22 23 /* Compute the needed size with the NULL terminator */ 24 cwch = MultiByteToWideChar(CP_UTF8, 0, pSrc, -1, NULL, 0); 25 if (cwch == 0) return NULL; 26 27 /* Allocate the BSTR (without the NULL terminator) */ 28 wsOut = SysAllocStringLen(NULL, cwch - 1); 29 if (!wsOut) 30 { 31 _com_issue_error(HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY)); 32 return NULL; 33 } 34 35 /* Convert the string */ 36 if (MultiByteToWideChar(CP_UTF8, 0, pSrc, -1, wsOut, cwch) == 0) 37 { 38 /* We failed, clean everything up */ 39 cwch = GetLastError(); 40 41 SysFreeString(wsOut); 42 wsOut = NULL; 43 44 _com_issue_error(!IS_ERROR(cwch) ? HRESULT_FROM_WIN32(cwch) : cwch); 45 } 46 47 return wsOut; 48 } 49 50 HRESULT 51 InitXMLDOMParser(VOID) 52 { 53 return CoInitialize(NULL); 54 } 55 56 VOID 57 UninitXMLDOMParser(VOID) 58 { 59 CoUninitialize(); 60 return; 61 } 62 63 HRESULT 64 CreateAndInitXMLDOMDocument(IXMLDOMDocument** ppDoc) 65 { 66 HRESULT hr = CoCreateInstance(CLSID_DOMDocument30, // __uuidof(DOMDocument30), // NOTE: Do not use DOMDocument60 if you want MSConfig working by default on XP. 67 NULL, 68 CLSCTX_INPROC_SERVER, 69 IID_PPV_ARG(IXMLDOMDocument, ppDoc) /* IID_PPV_ARGS(ppDoc) */); 70 if (!SUCCEEDED(hr)) 71 return hr; 72 73 /* These methods should not fail so don't inspect result */ 74 (*ppDoc)->put_async(VARIANT_FALSE); 75 (*ppDoc)->put_validateOnParse(VARIANT_FALSE); 76 (*ppDoc)->put_resolveExternals(VARIANT_FALSE); 77 78 return hr; 79 } 80 81 BOOL 82 LoadXMLDocumentFromResource(IXMLDOMDocument* pDoc, 83 LPCWSTR lpszXMLResName) 84 { 85 VARIANT_BOOL Success = VARIANT_FALSE; 86 HRSRC hRes; 87 HGLOBAL handle; 88 LPVOID lpXMLRes; 89 _bstr_t bstrXMLRes; 90 91 if (!pDoc) 92 return FALSE; 93 94 // hRes = FindResourceExW(NULL, RT_HTML, lpszXMLResName, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)); 95 hRes = FindResourceW(NULL, lpszXMLResName, RT_HTML); 96 if (hRes == NULL) 97 return FALSE; 98 99 handle = LoadResource(NULL, hRes); 100 if (handle == NULL) 101 return FALSE; 102 103 lpXMLRes = LockResource(handle); 104 if (lpXMLRes == NULL) 105 goto Cleanup; 106 107 /* Convert the resource to UNICODE if needed */ 108 if (!IsTextUnicode(lpXMLRes, SizeofResource(NULL, hRes), NULL)) 109 bstrXMLRes.Attach(ConvertUTF8StringToBSTR((LPCSTR)lpXMLRes)); 110 else 111 bstrXMLRes = (LPCWSTR)lpXMLRes; 112 113 if (SUCCEEDED(pDoc->loadXML(bstrXMLRes, &Success)) && (Success != VARIANT_TRUE)) 114 { 115 IXMLDOMParseError* pXMLErr = NULL; 116 _bstr_t bstrErr; 117 118 if (SUCCEEDED(pDoc->get_parseError(&pXMLErr)) && 119 SUCCEEDED(pXMLErr->get_reason(&bstrErr.GetBSTR()))) 120 { 121 LPWSTR lpszStr = NULL; 122 123 if (IS_INTRESOURCE((ULONG_PTR)lpszXMLResName)) 124 lpszStr = FormatString(L"Failed to load DOM from resource '#%u': %wS", lpszXMLResName, (wchar_t*)bstrErr); 125 else 126 lpszStr = FormatString(L"Failed to load DOM from resource '%wS': %wS", lpszXMLResName, (wchar_t*)bstrErr); 127 128 MessageBoxW(NULL, lpszStr, L"Error", MB_ICONERROR | MB_OK); 129 130 MemFree(lpszStr); 131 } 132 133 SAFE_RELEASE(pXMLErr); 134 } 135 136 Cleanup: 137 FreeResource(handle); 138 139 return (Success == VARIANT_TRUE); 140 } 141 142 BOOL 143 LoadXMLDocumentFromFile(IXMLDOMDocument* pDoc, 144 LPCWSTR lpszFilename, 145 BOOL bIgnoreErrorsIfNonExistingFile) 146 { 147 VARIANT_BOOL Success = VARIANT_FALSE; 148 _variant_t varFileName(lpszFilename); 149 150 if (!pDoc) 151 return FALSE; 152 153 if (SUCCEEDED(pDoc->load(varFileName, &Success)) && (Success != VARIANT_TRUE)) 154 { 155 IXMLDOMParseError* pXMLErr = NULL; 156 LONG lErrorCode = 0L; 157 158 if (SUCCEEDED(pDoc->get_parseError(&pXMLErr)) && 159 SUCCEEDED(pXMLErr->get_errorCode(&lErrorCode))) 160 { 161 if ( !bIgnoreErrorsIfNonExistingFile || 162 ((lErrorCode != _HRESULT_TYPEDEF_(0x800C0006) /* INET_E_OBJECT_NOT_FOUND */) && 163 (lErrorCode != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))) ) 164 { 165 _bstr_t bstrErr; 166 167 if (SUCCEEDED(pXMLErr->get_reason(&bstrErr.GetBSTR()))) 168 { 169 LPWSTR lpszStr = FormatString(L"Failed to load DOM from '%wS': %wS", lpszFilename, (wchar_t*)bstrErr); 170 MessageBoxW(NULL, lpszStr, L"Error", MB_ICONERROR | MB_OK); 171 MemFree(lpszStr); 172 } 173 } 174 } 175 176 SAFE_RELEASE(pXMLErr); 177 } 178 179 return (Success == VARIANT_TRUE); 180 } 181