ReactOS  0.4.15-dev-1201-gb2cf5a4
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 
36 typedef struct ConfigFileHandler
37 {
38  ISAXContentHandler ISAXContentHandler_iface;
39  ISAXErrorHandler ISAXErrorHandler_iface;
41  enum parse_state states[16];
42  int statenum;
45 
46 static inline ConfigFileHandler *impl_from_ISAXContentHandler(ISAXContentHandler *iface)
47 {
48  return CONTAINING_RECORD(iface, ConfigFileHandler, ISAXContentHandler_iface);
49 }
50 
51 static inline ConfigFileHandler *impl_from_ISAXErrorHandler(ISAXErrorHandler *iface)
52 {
53  return CONTAINING_RECORD(iface, ConfigFileHandler, ISAXErrorHandler_iface);
54 }
55 
56 static 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 
75 static ULONG WINAPI ConfigFileHandler_AddRef(ISAXContentHandler *iface)
76 {
78  return InterlockedIncrement(&This->ref);
79 }
80 
81 static ULONG WINAPI ConfigFileHandler_Release(ISAXContentHandler *iface)
82 {
85 
86  if (ref == 0)
88 
89  return ref;
90 }
91 
92 static HRESULT WINAPI ConfigFileHandler_putDocumentLocator(ISAXContentHandler *iface,
93  ISAXLocator *pLocator)
94 {
95  return S_OK;
96 }
97 
98 static HRESULT WINAPI ConfigFileHandler_startDocument(ISAXContentHandler *iface)
99 {
100  return S_OK;
101 }
102 
103 static HRESULT WINAPI ConfigFileHandler_endDocument(ISAXContentHandler *iface)
104 {
105  return S_OK;
106 }
107 
108 static HRESULT WINAPI ConfigFileHandler_startPrefixMapping(ISAXContentHandler *iface,
109  const WCHAR *pPrefix, int nPrefix, const WCHAR *pUri, int nUri)
110 {
111  return S_OK;
112 }
113 
114 static HRESULT WINAPI ConfigFileHandler_endPrefixMapping(ISAXContentHandler *iface,
115  const WCHAR *pPrefix, int nPrefix)
116 {
117  return S_OK;
118 }
119 
120 static 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};
124  LPCWSTR value;
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 
136 static HRESULT parse_supported_runtime(ConfigFileHandler *This, ISAXAttributes *pAttr)
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};
141  LPCWSTR value;
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  {
162  hr = E_OUTOFMEMORY;
163  }
164  }
165  else
166  hr = E_OUTOFMEMORY;
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 
182 static 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;
212  case STATE_CONFIGURATION:
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  {
226  hr = parse_supported_runtime(This, pAttr);
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 
238 unknown:
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 
247 static 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 
269 static 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 
277 static HRESULT WINAPI ConfigFileHandler_ignorableWhitespace(ISAXContentHandler *iface,
278  const WCHAR *pChars, int nChars)
279 {
280  return S_OK;
281 }
282 
283 static HRESULT WINAPI ConfigFileHandler_processingInstruction(ISAXContentHandler *iface,
284  const WCHAR *pTarget, int nTarget, const WCHAR *pData, int nData)
285 {
286  return S_OK;
287 }
288 
289 static 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 
296 static 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 
333 static ULONG WINAPI ConfigFileHandler_Error_AddRef(ISAXErrorHandler *iface)
334 {
336  return IUnknown_AddRef((IUnknown*)This);
337 }
338 
339 static ULONG WINAPI ConfigFileHandler_Error_Release(ISAXErrorHandler *iface)
340 {
342  return IUnknown_Release((IUnknown*)This);
343 }
344 
345 static 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 
352 static 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 
359 static 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 
366 static 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 {
421  IStream *stream;
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))
443  CoUninitialize();
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 HRESULT parse_config(VARIANT input, parsed_config_file *result)
Definition: config.c:381
const char * var
Definition: shader.c:5666
static const struct ISAXErrorHandlerVtbl ConfigFileHandlerErrorVtbl
Definition: config.c:366
#define REFIID
Definition: guiddef.h:118
#define E_NOINTERFACE
Definition: winerror.h:2364
static HRESULT WINAPI ConfigFileHandler_endDocument(ISAXContentHandler *iface)
Definition: config.c:103
struct ConfigFileHandler ConfigFileHandler
HRESULT hr
Definition: shlfolder.c:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
REFIID riid
Definition: precomp.h:44
enum parse_state states[16]
Definition: config.c:41
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define STGM_FAILIFTHERE
Definition: objbase.h:927
#define WARN(fmt,...)
Definition: debug.h:112
int startup(int argc, const char *argv[])
Definition: startup.c:430
static HRESULT WINAPI ConfigFileHandler_startPrefixMapping(ISAXContentHandler *iface, const WCHAR *pPrefix, int nPrefix, const WCHAR *pUri, int nUri)
Definition: config.c:108
const char * filename
Definition: ioapi.h:135
#define lstrlenW
Definition: compat.h:609
#define E_FAIL
Definition: ddrawi.h:102
Definition: send.c:48
static const struct ISAXContentHandlerVtbl ConfigFileHandlerVtbl
Definition: config.c:296
static HRESULT WINAPI ConfigFileHandler_fatalError(ISAXErrorHandler *iface, ISAXLocator *pLocator, const WCHAR *pErrorMessage, HRESULT hrErrorCode)
Definition: config.c:352
static ULONG WINAPI ConfigFileHandler_Error_AddRef(ISAXErrorHandler *iface)
Definition: config.c:333
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
static HRESULT WINAPI ConfigFileHandler_skippedEntity(ISAXContentHandler *iface, const WCHAR *pName, int nName)
Definition: config.c:289
long LONG
Definition: pedump.c:60
static HRESULT WINAPI ConfigFileHandler_QueryInterface(ISAXContentHandler *iface, REFIID riid, void **ppvObject)
Definition: config.c:56
#define debugstr_w
Definition: kernel32.h:32
static ConfigFileHandler * impl_from_ISAXContentHandler(ISAXContentHandler *iface)
Definition: config.c:46
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:111
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_endPrefixMapping(ISAXContentHandler *iface, const WCHAR *pPrefix, int nPrefix)
Definition: config.c:114
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR version[]
Definition: asmname.c:66
#define debugstr_guid
Definition: kernel32.h:35
static HRESULT WINAPI ConfigFileHandler_ignorableWarning(ISAXErrorHandler *iface, ISAXLocator *pLocator, const WCHAR *pErrorMessage, HRESULT hrErrorCode)
Definition: config.c:359
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define STGM_READ
Definition: objbase.h:916
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
static HRESULT parse_supported_runtime(ConfigFileHandler *This, ISAXAttributes *pAttr)
Definition: config.c:136
static HRESULT WINAPI ConfigFileHandler_startDocument(ISAXContentHandler *iface)
Definition: config.c:98
#define TRACE(s)
Definition: solgame.cpp:4
static LPSTR pName
Definition: security.c:75
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
void free_parsed_config_file(parsed_config_file *file)
Definition: config.c:448
parsed_config_file * result
Definition: config.c:43
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
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:79
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
const GUID IID_IUnknown
#define WINAPI
Definition: msvc.h:6
Definition: id3.c:95
static HRESULT WINAPI ConfigFileHandler_putDocumentLocator(ISAXContentHandler *iface, ISAXLocator *pLocator)
Definition: config.c:92
#define InterlockedDecrement
Definition: armddk.h:52
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
#define V_VT(A)
Definition: oleauto.h:211
HRESULT parse_config_file(LPCWSTR filename, parsed_config_file *result)
Definition: config.c:419
uint32_t entry
Definition: isohybrid.c:63
REFIID LPVOID * ppvObject
Definition: precomp.h:44
#define V_UNKNOWN(A)
Definition: oleauto.h:281
GLsizei const GLfloat * value
Definition: glext.h:6069
#define debugstr_wn
Definition: kernel32.h:33
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
#define ERR(fmt,...)
Definition: debug.h:110
static ConfigFileHandler * impl_from_ISAXErrorHandler(ISAXErrorHandler *iface)
Definition: config.c:51
static ULONG WINAPI ConfigFileHandler_AddRef(ISAXContentHandler *iface)
Definition: config.c:75
static HRESULT parse_startup(ConfigFileHandler *This, ISAXAttributes *pAttr)
Definition: config.c:120
#define S_OK
Definition: intsafe.h:51
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
#define InterlockedIncrement
Definition: armddk.h:53
GLenum GLenum GLenum input
Definition: glext.h:9031
const char cursor[]
Definition: icontest.c:13
#define lstrcpyW
Definition: compat.h:608
static HRESULT WINAPI ConfigFileHandler_ignorableWhitespace(ISAXContentHandler *iface, const WCHAR *pChars, int nChars)
Definition: config.c:277
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
BOOL empty
Definition: button.c:170
ISAXErrorHandler ISAXErrorHandler_iface
Definition: config.c:39
ISAXContentHandler ISAXContentHandler_iface
Definition: config.c:38
Definition: reader.h:83
static ULONG WINAPI ConfigFileHandler_Release(ISAXContentHandler *iface)
Definition: config.c:81
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
unsigned int ULONG
Definition: retypes.h:1
HRESULT WINAPI SHCreateStreamOnFileW(LPCWSTR lpszPath, DWORD dwMode, IStream **lppStream)
Definition: istream.c:484
static ULONG WINAPI ConfigFileHandler_Error_Release(ISAXErrorHandler *iface)
Definition: config.c:339
parse_state
Definition: pop3transport.c:39
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7786
#define STGM_SHARE_DENY_WRITE
Definition: objbase.h:921
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1827
static void init_config(parsed_config_file *config)
Definition: config.c:376
GLuint64EXT * result
Definition: glext.h:11304
BOOL legacy
Definition: mkisofs.c:131
static HRESULT WINAPI ConfigFileHandler_Error_QueryInterface(ISAXErrorHandler *iface, REFIID riid, void **ppvObject)
Definition: config.c:314
static HRESULT WINAPI ConfigFileHandler_error(ISAXErrorHandler *iface, ISAXLocator *pLocator, const WCHAR *pErrorMessage, HRESULT hrErrorCode)
Definition: config.c:345
#define HeapFree(x, y, z)
Definition: compat.h:594
#define SUCCEEDED(hr)
Definition: intsafe.h:49
static HRESULT WINAPI ConfigFileHandler_characters(ISAXContentHandler *iface, const WCHAR *pChars, int nChars)
Definition: config.c:269
Definition: fci.c:126