ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

config.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.