ReactOS 0.4.16-dev-319-g6cf4263
config.c
Go to the documentation of this file.
1/*
2 * Configuration file parsing
3 *
4 * Copyright 2010 Vincent Povirk
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include "mscoree_private.h"
22
23#include <ole2.h>
24#include <shlwapi.h>
25#include <initguid.h>
26#include <msxml2.h>
27
29{
34};
35
36typedef struct ConfigFileHandler
37{
38 ISAXContentHandler ISAXContentHandler_iface;
39 ISAXErrorHandler ISAXErrorHandler_iface;
45
46static inline ConfigFileHandler *impl_from_ISAXContentHandler(ISAXContentHandler *iface)
47{
48 return CONTAINING_RECORD(iface, ConfigFileHandler, ISAXContentHandler_iface);
49}
50
51static inline ConfigFileHandler *impl_from_ISAXErrorHandler(ISAXErrorHandler *iface)
52{
53 return CONTAINING_RECORD(iface, ConfigFileHandler, ISAXErrorHandler_iface);
54}
55
56static HRESULT WINAPI ConfigFileHandler_QueryInterface(ISAXContentHandler *iface,
57 REFIID riid, void **ppvObject)
58{
59 if (IsEqualGUID(riid, &IID_ISAXContentHandler) ||
61 {
62 *ppvObject = iface;
63 }
64 else
65 {
66 WARN("Unsupported interface %s\n", debugstr_guid(riid));
67 return E_NOINTERFACE;
68 }
69
70 ISAXContentHandler_AddRef(iface);
71
72 return S_OK;
73}
74
75static ULONG WINAPI ConfigFileHandler_AddRef(ISAXContentHandler *iface)
76{
78 return InterlockedIncrement(&This->ref);
79}
80
81static ULONG WINAPI ConfigFileHandler_Release(ISAXContentHandler *iface)
82{
85
86 if (ref == 0)
88
89 return ref;
90}
91
92static HRESULT WINAPI ConfigFileHandler_putDocumentLocator(ISAXContentHandler *iface,
93 ISAXLocator *pLocator)
94{
95 return S_OK;
96}
97
98static HRESULT WINAPI ConfigFileHandler_startDocument(ISAXContentHandler *iface)
99{
100 return S_OK;
101}
102
103static HRESULT WINAPI ConfigFileHandler_endDocument(ISAXContentHandler *iface)
104{
105 return S_OK;
106}
107
108static HRESULT WINAPI ConfigFileHandler_startPrefixMapping(ISAXContentHandler *iface,
109 const WCHAR *pPrefix, int nPrefix, const WCHAR *pUri, int nUri)
110{
111 return S_OK;
112}
113
114static HRESULT WINAPI ConfigFileHandler_endPrefixMapping(ISAXContentHandler *iface,
115 const WCHAR *pPrefix, int nPrefix)
116{
117 return S_OK;
118}
119
120static HRESULT parse_startup(ConfigFileHandler *This, ISAXAttributes *pAttr)
121{
122 static const WCHAR legacy[] = {'u','s','e','L','e','g','a','c','y','V','2','R','u','n','t','i','m','e','A','c','t','i','v','a','t','i','o','n','P','o','l','i','c','y',0};
123 static const WCHAR empty[] = {0};
125 int value_size;
126 HRESULT hr;
127
128 hr = ISAXAttributes_getValueFromName(pAttr, empty, 0, legacy, lstrlenW(legacy), &value, &value_size);
129 if (SUCCEEDED(hr))
130 FIXME("useLegacyV2RuntimeActivationPolicy=%s not implemented\n", debugstr_wn(value, value_size));
131 hr = S_OK;
132
133 return hr;
134}
135
137{
138 static const WCHAR version[] = {'v','e','r','s','i','o','n',0};
139 static const WCHAR sku[] = {'s','k','u',0};
140 static const WCHAR empty[] = {0};
142 int value_size;
143 HRESULT hr;
145
146 hr = ISAXAttributes_getValueFromName(pAttr, empty, 0, version, lstrlenW(version), &value, &value_size);
147 if (SUCCEEDED(hr))
148 {
149 TRACE("%s\n", debugstr_wn(value, value_size));
151 if (entry)
152 {
153 entry->version = HeapAlloc(GetProcessHeap(), 0, (value_size + 1) * sizeof(WCHAR));
154 if (entry->version)
155 {
156 lstrcpyW(entry->version, value);
157 list_add_tail(&This->result->supported_runtimes, &entry->entry);
158 }
159 else
160 {
163 }
164 }
165 else
167 }
168 else
169 WARN("Missing version attribute\n");
170
171 if (SUCCEEDED(hr))
172 {
173 hr = ISAXAttributes_getValueFromName(pAttr, empty, 0, sku, lstrlenW(sku), &value, &value_size);
174 if (SUCCEEDED(hr))
175 FIXME("sku=%s not implemented\n", debugstr_wn(value, value_size));
176 hr = S_OK;
177 }
178
179 return hr;
180}
181
182static HRESULT WINAPI ConfigFileHandler_startElement(ISAXContentHandler *iface,
183 const WCHAR *pNamespaceUri, int nNamespaceUri, const WCHAR *pLocalName,
184 int nLocalName, const WCHAR *pQName, int nQName, ISAXAttributes *pAttr)
185{
187 static const WCHAR configuration[] = {'c','o','n','f','i','g','u','r','a','t','i','o','n',0};
188 static const WCHAR startup[] = {'s','t','a','r','t','u','p',0};
189 static const WCHAR supportedRuntime[] = {'s','u','p','p','o','r','t','e','d','R','u','n','t','i','m','e',0};
190 HRESULT hr = S_OK;
191
192 TRACE("%s %s %s\n", debugstr_wn(pNamespaceUri,nNamespaceUri),
193 debugstr_wn(pLocalName,nLocalName), debugstr_wn(pQName,nQName));
194
195 if (This->statenum == sizeof(This->states) / sizeof(This->states[0]) - 1)
196 {
197 ERR("file has too much nesting\n");
198 return E_FAIL;
199 }
200
201 switch (This->states[This->statenum])
202 {
203 case STATE_ROOT:
204 if (nLocalName == sizeof(configuration)/sizeof(WCHAR)-1 &&
205 lstrcmpW(pLocalName, configuration) == 0)
206 {
207 This->states[++This->statenum] = STATE_CONFIGURATION;
208 break;
209 }
210 else
211 goto unknown;
213 if (nLocalName == sizeof(startup)/sizeof(WCHAR)-1 &&
214 lstrcmpW(pLocalName, startup) == 0)
215 {
216 hr = parse_startup(This, pAttr);
217 This->states[++This->statenum] = STATE_STARTUP;
218 break;
219 }
220 else
221 goto unknown;
222 case STATE_STARTUP:
223 if (nLocalName == sizeof(supportedRuntime)/sizeof(WCHAR)-1 &&
224 lstrcmpW(pLocalName, supportedRuntime) == 0)
225 {
227 This->states[++This->statenum] = STATE_UNKNOWN;
228 break;
229 }
230 else
231 goto unknown;
232 default:
233 goto unknown;
234 }
235
236 return hr;
237
238unknown:
239 FIXME("Unknown element %s in state %u\n", debugstr_wn(pLocalName,nLocalName),
240 This->states[This->statenum]);
241
242 This->states[++This->statenum] = STATE_UNKNOWN;
243
244 return S_OK;
245}
246
247static HRESULT WINAPI ConfigFileHandler_endElement(ISAXContentHandler *iface,
248 const WCHAR *pNamespaceUri, int nNamespaceUri, const WCHAR *pLocalName,
249 int nLocalName, const WCHAR *pQName, int nQName)
250{
252
253 TRACE("%s %s %s\n", debugstr_wn(pNamespaceUri,nNamespaceUri),
254 debugstr_wn(pLocalName,nLocalName), debugstr_wn(pQName,nQName));
255
256 if (This->statenum > 0)
257 {
258 This->statenum--;
259 }
260 else
261 {
262 ERR("element end does not match a start\n");
263 return E_FAIL;
264 }
265
266 return S_OK;
267}
268
269static HRESULT WINAPI ConfigFileHandler_characters(ISAXContentHandler *iface,
270 const WCHAR *pChars, int nChars)
271{
272 TRACE("%s\n", debugstr_wn(pChars,nChars));
273
274 return S_OK;
275}
276
277static HRESULT WINAPI ConfigFileHandler_ignorableWhitespace(ISAXContentHandler *iface,
278 const WCHAR *pChars, int nChars)
279{
280 return S_OK;
281}
282
284 const WCHAR *pTarget, int nTarget, const WCHAR *pData, int nData)
285{
286 return S_OK;
287}
288
289static HRESULT WINAPI ConfigFileHandler_skippedEntity(ISAXContentHandler *iface,
290 const WCHAR * pName, int nName)
291{
292 TRACE("%s\n", debugstr_wn(pName,nName));
293 return S_OK;
294}
295
296static const struct ISAXContentHandlerVtbl ConfigFileHandlerVtbl =
297{
312};
313
315 REFIID riid, void **ppvObject)
316{
317 if (IsEqualGUID(riid, &IID_ISAXErrorHandler) ||
319 {
320 *ppvObject = iface;
321 }
322 else
323 {
324 WARN("Unsupported interface %s\n", debugstr_guid(riid));
325 return E_NOINTERFACE;
326 }
327
328 ISAXErrorHandler_AddRef(iface);
329
330 return S_OK;
331}
332
333static ULONG WINAPI ConfigFileHandler_Error_AddRef(ISAXErrorHandler *iface)
334{
336 return IUnknown_AddRef((IUnknown*)This);
337}
338
339static ULONG WINAPI ConfigFileHandler_Error_Release(ISAXErrorHandler *iface)
340{
342 return IUnknown_Release((IUnknown*)This);
343}
344
345static HRESULT WINAPI ConfigFileHandler_error(ISAXErrorHandler *iface,
346 ISAXLocator * pLocator, const WCHAR * pErrorMessage, HRESULT hrErrorCode)
347{
348 WARN("%s,%x\n", debugstr_w(pErrorMessage), hrErrorCode);
349 return S_OK;
350}
351
352static HRESULT WINAPI ConfigFileHandler_fatalError(ISAXErrorHandler *iface,
353 ISAXLocator * pLocator, const WCHAR * pErrorMessage, HRESULT hrErrorCode)
354{
355 WARN("%s,%x\n", debugstr_w(pErrorMessage), hrErrorCode);
356 return S_OK;
357}
358
359static HRESULT WINAPI ConfigFileHandler_ignorableWarning(ISAXErrorHandler *iface,
360 ISAXLocator * pLocator, const WCHAR * pErrorMessage, HRESULT hrErrorCode)
361{
362 WARN("%s,%x\n", debugstr_w(pErrorMessage), hrErrorCode);
363 return S_OK;
364}
365
366static const struct ISAXErrorHandlerVtbl ConfigFileHandlerErrorVtbl =
367{
374};
375
377{
378 list_init(&config->supported_runtimes);
379}
380
382{
383 ISAXXMLReader *reader;
385 HRESULT hr;
386
388 if (!handler)
389 return E_OUTOFMEMORY;
390
391 handler->ISAXContentHandler_iface.lpVtbl = &ConfigFileHandlerVtbl;
392 handler->ISAXErrorHandler_iface.lpVtbl = &ConfigFileHandlerErrorVtbl;
393 handler->ref = 1;
394 handler->states[0] = STATE_ROOT;
395 handler->statenum = 0;
396 handler->result = result;
397
398 hr = CoCreateInstance(&CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER,
399 &IID_ISAXXMLReader, (LPVOID*)&reader);
400
401 if (SUCCEEDED(hr))
402 {
403 hr = ISAXXMLReader_putContentHandler(reader, &handler->ISAXContentHandler_iface);
404
405 if (SUCCEEDED(hr))
406 hr = ISAXXMLReader_putErrorHandler(reader, &handler->ISAXErrorHandler_iface);
407
408 if (SUCCEEDED(hr))
409 hr = ISAXXMLReader_parse(reader, input);
410
411 ISAXXMLReader_Release(reader);
412 }
413
414 ISAXContentHandler_Release(&handler->ISAXContentHandler_iface);
415
416 return S_OK;
417}
418
420{
422 VARIANT var;
423 HRESULT hr;
424 HRESULT initresult;
425
427
429
431
432 if (SUCCEEDED(hr))
433 {
434 V_VT(&var) = VT_UNKNOWN;
436
438
439 IStream_Release(stream);
440 }
441
442 if (SUCCEEDED(initresult))
444
445 return hr;
446}
447
449{
450 supported_runtime *cursor, *cursor2;
451
452 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &file->supported_runtimes, supported_runtime, entry)
453 {
454 HeapFree(GetProcessHeap(), 0, cursor->version);
455 list_remove(&cursor->entry);
457 }
458}
static void startup(void)
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1605
static const WCHAR empty[]
Definition: main.c:47
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define lstrcpyW
Definition: compat.h:749
@ VT_UNKNOWN
Definition: compat.h:2308
#define lstrlenW
Definition: compat.h:750
static const WCHAR version[]
Definition: asmname.c:66
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4243
static HRESULT WINAPI ConfigFileHandler_skippedEntity(ISAXContentHandler *iface, const WCHAR *pName, int nName)
Definition: config.c:289
static HRESULT WINAPI ConfigFileHandler_processingInstruction(ISAXContentHandler *iface, const WCHAR *pTarget, int nTarget, const WCHAR *pData, int nData)
Definition: config.c:283
static HRESULT WINAPI ConfigFileHandler_ignorableWarning(ISAXErrorHandler *iface, ISAXLocator *pLocator, const WCHAR *pErrorMessage, HRESULT hrErrorCode)
Definition: config.c:359
static ConfigFileHandler * impl_from_ISAXContentHandler(ISAXContentHandler *iface)
Definition: config.c:46
static HRESULT WINAPI ConfigFileHandler_endDocument(ISAXContentHandler *iface)
Definition: config.c:103
static HRESULT WINAPI ConfigFileHandler_endPrefixMapping(ISAXContentHandler *iface, const WCHAR *pPrefix, int nPrefix)
Definition: config.c:114
static const struct ISAXErrorHandlerVtbl ConfigFileHandlerErrorVtbl
Definition: config.c:366
static HRESULT WINAPI ConfigFileHandler_QueryInterface(ISAXContentHandler *iface, REFIID riid, void **ppvObject)
Definition: config.c:56
static HRESULT WINAPI ConfigFileHandler_ignorableWhitespace(ISAXContentHandler *iface, const WCHAR *pChars, int nChars)
Definition: config.c:277
static const struct ISAXContentHandlerVtbl ConfigFileHandlerVtbl
Definition: config.c:296
HRESULT parse_config_file(LPCWSTR filename, parsed_config_file *result)
Definition: config.c:419
static ULONG WINAPI ConfigFileHandler_AddRef(ISAXContentHandler *iface)
Definition: config.c:75
static HRESULT WINAPI ConfigFileHandler_startDocument(ISAXContentHandler *iface)
Definition: config.c:98
parse_state
Definition: config.c:29
@ STATE_CONFIGURATION
Definition: config.c:31
@ STATE_STARTUP
Definition: config.c:32
@ STATE_UNKNOWN
Definition: config.c:33
@ STATE_ROOT
Definition: config.c:30
static HRESULT parse_startup(ConfigFileHandler *This, ISAXAttributes *pAttr)
Definition: config.c:120
static ULONG WINAPI ConfigFileHandler_Error_Release(ISAXErrorHandler *iface)
Definition: config.c:339
static HRESULT WINAPI ConfigFileHandler_putDocumentLocator(ISAXContentHandler *iface, ISAXLocator *pLocator)
Definition: config.c:92
static HRESULT WINAPI ConfigFileHandler_startElement(ISAXContentHandler *iface, const WCHAR *pNamespaceUri, int nNamespaceUri, const WCHAR *pLocalName, int nLocalName, const WCHAR *pQName, int nQName, ISAXAttributes *pAttr)
Definition: config.c:182
static void init_config(parsed_config_file *config)
Definition: config.c:376
static ULONG WINAPI ConfigFileHandler_Error_AddRef(ISAXErrorHandler *iface)
Definition: config.c:333
static HRESULT parse_supported_runtime(ConfigFileHandler *This, ISAXAttributes *pAttr)
Definition: config.c:136
static HRESULT WINAPI ConfigFileHandler_endElement(ISAXContentHandler *iface, const WCHAR *pNamespaceUri, int nNamespaceUri, const WCHAR *pLocalName, int nLocalName, const WCHAR *pQName, int nQName)
Definition: config.c:247
static ULONG WINAPI ConfigFileHandler_Release(ISAXContentHandler *iface)
Definition: config.c:81
static HRESULT WINAPI ConfigFileHandler_Error_QueryInterface(ISAXErrorHandler *iface, REFIID riid, void **ppvObject)
Definition: config.c:314
static HRESULT WINAPI ConfigFileHandler_startPrefixMapping(ISAXContentHandler *iface, const WCHAR *pPrefix, int nPrefix, const WCHAR *pUri, int nUri)
Definition: config.c:108
static ConfigFileHandler * impl_from_ISAXErrorHandler(ISAXErrorHandler *iface)
Definition: config.c:51
static HRESULT WINAPI ConfigFileHandler_characters(ISAXContentHandler *iface, const WCHAR *pChars, int nChars)
Definition: config.c:269
void free_parsed_config_file(parsed_config_file *file)
Definition: config.c:448
static HRESULT WINAPI ConfigFileHandler_fatalError(ISAXErrorHandler *iface, ISAXLocator *pLocator, const WCHAR *pErrorMessage, HRESULT hrErrorCode)
Definition: config.c:352
static HRESULT parse_config(VARIANT input, parsed_config_file *result)
Definition: config.c:381
static HRESULT WINAPI ConfigFileHandler_error(ISAXErrorHandler *iface, ISAXLocator *pLocator, const WCHAR *pErrorMessage, HRESULT hrErrorCode)
Definition: config.c:345
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7512
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT WINAPI SHCreateStreamOnFileW(LPCWSTR lpszPath, DWORD dwMode, IStream **lppStream)
Definition: istream.c:484
FxIoTarget * pTarget
Definition: fxdeviceapi.cpp:97
GLenum GLenum GLenum input
Definition: glext.h:9031
GLuint64EXT * result
Definition: glext.h:11304
const char cursor[]
Definition: icontest.c:13
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
const char * filename
Definition: ioapi.h:137
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
BOOL legacy
Definition: mkisofs.c:131
static LPSTR pName
Definition: security.c:75
const char * var
Definition: shader.c:5666
#define STGM_FAILIFTHERE
Definition: objbase.h:928
#define STGM_SHARE_DENY_WRITE
Definition: objbase.h:922
@ COINIT_APARTMENTTHREADED
Definition: objbase.h:278
#define STGM_READ
Definition: objbase.h:917
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define V_VT(A)
Definition: oleauto.h:211
long LONG
Definition: pedump.c:60
parse_state
Definition: pop3transport.c:40
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
parsed_config_file * result
Definition: config.c:43
ISAXContentHandler ISAXContentHandler_iface
Definition: config.c:38
enum parse_state states[16]
Definition: config.c:41
ISAXErrorHandler ISAXErrorHandler_iface
Definition: config.c:39
Definition: fci.c:127
Definition: reader.h:84
Definition: send.c:48
Definition: parse.h:23
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:94
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185