Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenconfig.c
Go to the documentation of this file.
00001 /* 00002 * Configuration file parsing 00003 * 00004 * Copyright 2010 Vincent Povirk 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #define COBJMACROS 00022 00023 #include <stdarg.h> 00024 00025 #include "windef.h" 00026 #include "winbase.h" 00027 #include "winreg.h" 00028 #include "ole2.h" 00029 #include "msxml2.h" 00030 #include "mscoree.h" 00031 #include "corhdr.h" 00032 #include "metahost.h" 00033 #include "cordebug.h" 00034 #include "wine/list.h" 00035 #include "mscoree_private.h" 00036 #include "shlwapi.h" 00037 00038 #include "wine/debug.h" 00039 00040 WINE_DEFAULT_DEBUG_CHANNEL( mscoree ); 00041 00042 enum parse_state 00043 { 00044 STATE_ROOT, 00045 STATE_CONFIGURATION, 00046 STATE_STARTUP, 00047 STATE_UNKNOWN 00048 }; 00049 00050 typedef struct ConfigFileHandler 00051 { 00052 ISAXContentHandler ISAXContentHandler_iface; 00053 ISAXErrorHandler ISAXErrorHandler_iface; 00054 LONG ref; 00055 enum parse_state states[16]; 00056 int statenum; 00057 parsed_config_file *result; 00058 } ConfigFileHandler; 00059 00060 static inline ConfigFileHandler *impl_from_ISAXContentHandler(ISAXContentHandler *iface) 00061 { 00062 return CONTAINING_RECORD(iface, ConfigFileHandler, ISAXContentHandler_iface); 00063 } 00064 00065 static inline ConfigFileHandler *impl_from_ISAXErrorHandler(ISAXErrorHandler *iface) 00066 { 00067 return CONTAINING_RECORD(iface, ConfigFileHandler, ISAXErrorHandler_iface); 00068 } 00069 00070 static HRESULT WINAPI ConfigFileHandler_QueryInterface(ISAXContentHandler *iface, 00071 REFIID riid, void **ppvObject) 00072 { 00073 if (IsEqualGUID(riid, &IID_ISAXContentHandler) || 00074 IsEqualGUID(riid, &IID_IUnknown)) 00075 { 00076 *ppvObject = iface; 00077 } 00078 else 00079 { 00080 WARN("Unsupported interface %s\n", debugstr_guid(riid)); 00081 return E_NOINTERFACE; 00082 } 00083 00084 ISAXContentHandler_AddRef(iface); 00085 00086 return S_OK; 00087 } 00088 00089 static ULONG WINAPI ConfigFileHandler_AddRef(ISAXContentHandler *iface) 00090 { 00091 ConfigFileHandler *This = impl_from_ISAXContentHandler(iface); 00092 return InterlockedIncrement(&This->ref); 00093 } 00094 00095 static ULONG WINAPI ConfigFileHandler_Release(ISAXContentHandler *iface) 00096 { 00097 ConfigFileHandler *This = impl_from_ISAXContentHandler(iface); 00098 ULONG ref = InterlockedDecrement(&This->ref); 00099 00100 if (ref == 0) 00101 HeapFree(GetProcessHeap(), 0, This); 00102 00103 return ref; 00104 } 00105 00106 static HRESULT WINAPI ConfigFileHandler_putDocumentLocator(ISAXContentHandler *iface, 00107 ISAXLocator *pLocator) 00108 { 00109 return S_OK; 00110 } 00111 00112 static HRESULT WINAPI ConfigFileHandler_startDocument(ISAXContentHandler *iface) 00113 { 00114 return S_OK; 00115 } 00116 00117 static HRESULT WINAPI ConfigFileHandler_endDocument(ISAXContentHandler *iface) 00118 { 00119 return S_OK; 00120 } 00121 00122 static HRESULT WINAPI ConfigFileHandler_startPrefixMapping(ISAXContentHandler *iface, 00123 const WCHAR *pPrefix, int nPrefix, const WCHAR *pUri, int nUri) 00124 { 00125 return S_OK; 00126 } 00127 00128 static HRESULT WINAPI ConfigFileHandler_endPrefixMapping(ISAXContentHandler *iface, 00129 const WCHAR *pPrefix, int nPrefix) 00130 { 00131 return S_OK; 00132 } 00133 00134 static HRESULT parse_startup(ConfigFileHandler *This, ISAXAttributes *pAttr) 00135 { 00136 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}; 00137 static const WCHAR empty[] = {0}; 00138 LPCWSTR value; 00139 int value_size; 00140 HRESULT hr; 00141 00142 hr = ISAXAttributes_getValueFromName(pAttr, empty, 0, legacy, lstrlenW(legacy), &value, &value_size); 00143 if (SUCCEEDED(hr)) 00144 FIXME("useLegacyV2RuntimeActivationPolicy=%s not implemented\n", debugstr_wn(value, value_size)); 00145 hr = S_OK; 00146 00147 return hr; 00148 } 00149 00150 static HRESULT parse_supported_runtime(ConfigFileHandler *This, ISAXAttributes *pAttr) 00151 { 00152 static const WCHAR version[] = {'v','e','r','s','i','o','n',0}; 00153 static const WCHAR sku[] = {'s','k','u',0}; 00154 static const WCHAR empty[] = {0}; 00155 LPCWSTR value; 00156 int value_size; 00157 HRESULT hr; 00158 supported_runtime *entry; 00159 00160 hr = ISAXAttributes_getValueFromName(pAttr, empty, 0, version, lstrlenW(version), &value, &value_size); 00161 if (SUCCEEDED(hr)) 00162 { 00163 TRACE("%s\n", debugstr_wn(value, value_size)); 00164 entry = HeapAlloc(GetProcessHeap(), 0, sizeof(supported_runtime)); 00165 if (entry) 00166 { 00167 entry->version = HeapAlloc(GetProcessHeap(), 0, (value_size + 1) * sizeof(WCHAR)); 00168 if (entry->version) 00169 { 00170 lstrcpyW(entry->version, value); 00171 list_add_tail(&This->result->supported_runtimes, &entry->entry); 00172 } 00173 else 00174 { 00175 HeapFree(GetProcessHeap(), 0, entry); 00176 hr = E_OUTOFMEMORY; 00177 } 00178 } 00179 else 00180 hr = E_OUTOFMEMORY; 00181 } 00182 else 00183 WARN("Missing version attribute\n"); 00184 00185 if (SUCCEEDED(hr)) 00186 { 00187 hr = ISAXAttributes_getValueFromName(pAttr, empty, 0, sku, lstrlenW(sku), &value, &value_size); 00188 if (SUCCEEDED(hr)) 00189 FIXME("sku=%s not implemented\n", debugstr_wn(value, value_size)); 00190 hr = S_OK; 00191 } 00192 00193 return hr; 00194 } 00195 00196 static HRESULT WINAPI ConfigFileHandler_startElement(ISAXContentHandler *iface, 00197 const WCHAR *pNamespaceUri, int nNamespaceUri, const WCHAR *pLocalName, 00198 int nLocalName, const WCHAR *pQName, int nQName, ISAXAttributes *pAttr) 00199 { 00200 ConfigFileHandler *This = impl_from_ISAXContentHandler(iface); 00201 static const WCHAR configuration[] = {'c','o','n','f','i','g','u','r','a','t','i','o','n',0}; 00202 static const WCHAR startup[] = {'s','t','a','r','t','u','p',0}; 00203 static const WCHAR supportedRuntime[] = {'s','u','p','p','o','r','t','e','d','R','u','n','t','i','m','e',0}; 00204 HRESULT hr = S_OK; 00205 00206 TRACE("%s %s %s\n", debugstr_wn(pNamespaceUri,nNamespaceUri), 00207 debugstr_wn(pLocalName,nLocalName), debugstr_wn(pQName,nQName)); 00208 00209 if (This->statenum == sizeof(This->states) / sizeof(This->states[0]) - 1) 00210 { 00211 ERR("file has too much nesting\n"); 00212 return E_FAIL; 00213 } 00214 00215 switch (This->states[This->statenum]) 00216 { 00217 case STATE_ROOT: 00218 if (nLocalName == sizeof(configuration)/sizeof(WCHAR)-1 && 00219 lstrcmpW(pLocalName, configuration) == 0) 00220 { 00221 This->states[++This->statenum] = STATE_CONFIGURATION; 00222 break; 00223 } 00224 else 00225 goto unknown; 00226 case STATE_CONFIGURATION: 00227 if (nLocalName == sizeof(startup)/sizeof(WCHAR)-1 && 00228 lstrcmpW(pLocalName, startup) == 0) 00229 { 00230 hr = parse_startup(This, pAttr); 00231 This->states[++This->statenum] = STATE_STARTUP; 00232 break; 00233 } 00234 else 00235 goto unknown; 00236 case STATE_STARTUP: 00237 if (nLocalName == sizeof(supportedRuntime)/sizeof(WCHAR)-1 && 00238 lstrcmpW(pLocalName, supportedRuntime) == 0) 00239 { 00240 hr = parse_supported_runtime(This, pAttr); 00241 This->states[++This->statenum] = STATE_UNKNOWN; 00242 break; 00243 } 00244 else 00245 goto unknown; 00246 default: 00247 goto unknown; 00248 } 00249 00250 return hr; 00251 00252 unknown: 00253 FIXME("Unknown element %s in state %u\n", debugstr_wn(pLocalName,nLocalName), 00254 This->states[This->statenum]); 00255 00256 This->states[++This->statenum] = STATE_UNKNOWN; 00257 00258 return S_OK; 00259 } 00260 00261 static HRESULT WINAPI ConfigFileHandler_endElement(ISAXContentHandler *iface, 00262 const WCHAR *pNamespaceUri, int nNamespaceUri, const WCHAR *pLocalName, 00263 int nLocalName, const WCHAR *pQName, int nQName) 00264 { 00265 ConfigFileHandler *This = impl_from_ISAXContentHandler(iface); 00266 00267 TRACE("%s %s %s\n", debugstr_wn(pNamespaceUri,nNamespaceUri), 00268 debugstr_wn(pLocalName,nLocalName), debugstr_wn(pQName,nQName)); 00269 00270 if (This->statenum > 0) 00271 { 00272 This->statenum--; 00273 } 00274 else 00275 { 00276 ERR("element end does not match a start\n"); 00277 return E_FAIL; 00278 } 00279 00280 return S_OK; 00281 } 00282 00283 static HRESULT WINAPI ConfigFileHandler_characters(ISAXContentHandler *iface, 00284 const WCHAR *pChars, int nChars) 00285 { 00286 TRACE("%s\n", debugstr_wn(pChars,nChars)); 00287 00288 return S_OK; 00289 } 00290 00291 static HRESULT WINAPI ConfigFileHandler_ignorableWhitespace(ISAXContentHandler *iface, 00292 const WCHAR *pChars, int nChars) 00293 { 00294 return S_OK; 00295 } 00296 00297 static HRESULT WINAPI ConfigFileHandler_processingInstruction(ISAXContentHandler *iface, 00298 const WCHAR *pTarget, int nTarget, const WCHAR *pData, int nData) 00299 { 00300 return S_OK; 00301 } 00302 00303 static HRESULT WINAPI ConfigFileHandler_skippedEntity(ISAXContentHandler *iface, 00304 const WCHAR * pName, int nName) 00305 { 00306 TRACE("%s\n", debugstr_wn(pName,nName)); 00307 return S_OK; 00308 } 00309 00310 static const struct ISAXContentHandlerVtbl ConfigFileHandlerVtbl = 00311 { 00312 ConfigFileHandler_QueryInterface, 00313 ConfigFileHandler_AddRef, 00314 ConfigFileHandler_Release, 00315 ConfigFileHandler_putDocumentLocator, 00316 ConfigFileHandler_startDocument, 00317 ConfigFileHandler_endDocument, 00318 ConfigFileHandler_startPrefixMapping, 00319 ConfigFileHandler_endPrefixMapping, 00320 ConfigFileHandler_startElement, 00321 ConfigFileHandler_endElement, 00322 ConfigFileHandler_characters, 00323 ConfigFileHandler_ignorableWhitespace, 00324 ConfigFileHandler_processingInstruction, 00325 ConfigFileHandler_skippedEntity 00326 }; 00327 00328 static HRESULT WINAPI ConfigFileHandler_Error_QueryInterface(ISAXErrorHandler *iface, 00329 REFIID riid, void **ppvObject) 00330 { 00331 if (IsEqualGUID(riid, &IID_ISAXErrorHandler) || 00332 IsEqualGUID(riid, &IID_IUnknown)) 00333 { 00334 *ppvObject = iface; 00335 } 00336 else 00337 { 00338 WARN("Unsupported interface %s\n", debugstr_guid(riid)); 00339 return E_NOINTERFACE; 00340 } 00341 00342 ISAXErrorHandler_AddRef(iface); 00343 00344 return S_OK; 00345 } 00346 00347 static ULONG WINAPI ConfigFileHandler_Error_AddRef(ISAXErrorHandler *iface) 00348 { 00349 ConfigFileHandler *This = impl_from_ISAXErrorHandler(iface); 00350 return IUnknown_AddRef((IUnknown*)This); 00351 } 00352 00353 static ULONG WINAPI ConfigFileHandler_Error_Release(ISAXErrorHandler *iface) 00354 { 00355 ConfigFileHandler *This = impl_from_ISAXErrorHandler(iface); 00356 return IUnknown_Release((IUnknown*)This); 00357 } 00358 00359 static HRESULT WINAPI ConfigFileHandler_error(ISAXErrorHandler *iface, 00360 ISAXLocator * pLocator, const WCHAR * pErrorMessage, HRESULT hrErrorCode) 00361 { 00362 WARN("%s,%x\n", debugstr_w(pErrorMessage), hrErrorCode); 00363 return S_OK; 00364 } 00365 00366 static HRESULT WINAPI ConfigFileHandler_fatalError(ISAXErrorHandler *iface, 00367 ISAXLocator * pLocator, const WCHAR * pErrorMessage, HRESULT hrErrorCode) 00368 { 00369 WARN("%s,%x\n", debugstr_w(pErrorMessage), hrErrorCode); 00370 return S_OK; 00371 } 00372 00373 static HRESULT WINAPI ConfigFileHandler_ignorableWarning(ISAXErrorHandler *iface, 00374 ISAXLocator * pLocator, const WCHAR * pErrorMessage, HRESULT hrErrorCode) 00375 { 00376 WARN("%s,%x\n", debugstr_w(pErrorMessage), hrErrorCode); 00377 return S_OK; 00378 } 00379 00380 static const struct ISAXErrorHandlerVtbl ConfigFileHandlerErrorVtbl = 00381 { 00382 ConfigFileHandler_Error_QueryInterface, 00383 ConfigFileHandler_Error_AddRef, 00384 ConfigFileHandler_Error_Release, 00385 ConfigFileHandler_error, 00386 ConfigFileHandler_fatalError, 00387 ConfigFileHandler_ignorableWarning 00388 }; 00389 00390 static void init_config(parsed_config_file *config) 00391 { 00392 list_init(&config->supported_runtimes); 00393 } 00394 00395 static HRESULT parse_config(VARIANT input, parsed_config_file *result) 00396 { 00397 ISAXXMLReader *reader; 00398 ConfigFileHandler *handler; 00399 HRESULT hr; 00400 00401 handler = HeapAlloc(GetProcessHeap(), 0, sizeof(ConfigFileHandler)); 00402 if (!handler) 00403 return E_OUTOFMEMORY; 00404 00405 handler->ISAXContentHandler_iface.lpVtbl = &ConfigFileHandlerVtbl; 00406 handler->ISAXErrorHandler_iface.lpVtbl = &ConfigFileHandlerErrorVtbl; 00407 handler->ref = 1; 00408 handler->states[0] = STATE_ROOT; 00409 handler->statenum = 0; 00410 handler->result = result; 00411 00412 hr = CoCreateInstance(&CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER, 00413 &IID_ISAXXMLReader, (LPVOID*)&reader); 00414 00415 if (SUCCEEDED(hr)) 00416 { 00417 hr = ISAXXMLReader_putContentHandler(reader, &handler->ISAXContentHandler_iface); 00418 00419 if (SUCCEEDED(hr)) 00420 hr = ISAXXMLReader_putErrorHandler(reader, &handler->ISAXErrorHandler_iface); 00421 00422 if (SUCCEEDED(hr)) 00423 hr = ISAXXMLReader_parse(reader, input); 00424 00425 ISAXXMLReader_Release(reader); 00426 } 00427 00428 IUnknown_Release((IUnknown*)handler); 00429 00430 return S_OK; 00431 } 00432 00433 HRESULT parse_config_file(LPCWSTR filename, parsed_config_file *result) 00434 { 00435 IStream *stream; 00436 VARIANT var; 00437 HRESULT hr; 00438 HRESULT initresult; 00439 00440 init_config(result); 00441 00442 initresult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); 00443 00444 hr = SHCreateStreamOnFileW(filename, STGM_SHARE_DENY_WRITE | STGM_READ | STGM_FAILIFTHERE, &stream); 00445 00446 if (SUCCEEDED(hr)) 00447 { 00448 V_VT(&var) = VT_UNKNOWN|VT_DISPATCH; 00449 V_UNKNOWN(&var) = (IUnknown*)stream; 00450 00451 hr = parse_config(var, result); 00452 00453 IStream_Release(stream); 00454 } 00455 00456 if (SUCCEEDED(initresult)) 00457 CoUninitialize(); 00458 00459 return hr; 00460 } 00461 00462 void free_parsed_config_file(parsed_config_file *file) 00463 { 00464 supported_runtime *cursor, *cursor2; 00465 00466 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &file->supported_runtimes, supported_runtime, entry) 00467 { 00468 HeapFree(GetProcessHeap(), 0, cursor->version); 00469 list_remove(&cursor->entry); 00470 HeapFree(GetProcessHeap(), 0, cursor); 00471 } 00472 } Generated on Sat May 26 2012 04:17:41 for ReactOS by
1.7.6.1
|