mscoree: Implement config file parsing.
This commit is contained in:
parent
4b3f302193
commit
4ce33c6960
@ -1,8 +1,9 @@
|
|||||||
MODULE = mscoree.dll
|
MODULE = mscoree.dll
|
||||||
IMPORTS = dbghelp uuid shell32 advapi32
|
IMPORTS = dbghelp uuid shell32 advapi32 ole32 oleaut32 shlwapi
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
assembly.c \
|
assembly.c \
|
||||||
|
config.c \
|
||||||
corruntimehost.c \
|
corruntimehost.c \
|
||||||
metahost.c \
|
metahost.c \
|
||||||
mscoree_main.c
|
mscoree_main.c
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "ole2.h"
|
#include "ole2.h"
|
||||||
#include "corhdr.h"
|
#include "corhdr.h"
|
||||||
#include "metahost.h"
|
#include "metahost.h"
|
||||||
|
#include "wine/list.h"
|
||||||
#include "mscoree_private.h"
|
#include "mscoree_private.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
469
dlls/mscoree/config.c
Normal file
469
dlls/mscoree/config.c
Normal file
@ -0,0 +1,469 @@
|
|||||||
|
/*
|
||||||
|
* Configuration file parsing
|
||||||
|
*
|
||||||
|
* Copyright 2010 Vincent Povirk
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define COBJMACROS
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "windef.h"
|
||||||
|
#include "winbase.h"
|
||||||
|
#include "winreg.h"
|
||||||
|
#include "ole2.h"
|
||||||
|
#include "msxml2.h"
|
||||||
|
#include "metahost.h"
|
||||||
|
#include "wine/list.h"
|
||||||
|
#include "mscoree_private.h"
|
||||||
|
#include "shlwapi.h"
|
||||||
|
|
||||||
|
#include "wine/debug.h"
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL( mscoree );
|
||||||
|
|
||||||
|
enum parse_state
|
||||||
|
{
|
||||||
|
STATE_ROOT,
|
||||||
|
STATE_CONFIGURATION,
|
||||||
|
STATE_STARTUP,
|
||||||
|
STATE_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct ConfigFileHandler
|
||||||
|
{
|
||||||
|
const struct ISAXContentHandlerVtbl *lpVtbl;
|
||||||
|
const struct ISAXErrorHandlerVtbl *lpErrorVtbl;
|
||||||
|
LONG ref;
|
||||||
|
enum parse_state states[16];
|
||||||
|
int statenum;
|
||||||
|
parsed_config_file *result;
|
||||||
|
} ConfigFileHandler;
|
||||||
|
|
||||||
|
static inline ConfigFileHandler *impl_from_ISAXContentHandler(ISAXContentHandler *iface)
|
||||||
|
{
|
||||||
|
return (ConfigFileHandler *)((char*)iface - FIELD_OFFSET(ConfigFileHandler, lpVtbl));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline ConfigFileHandler *impl_from_ISAXErrorHandler(ISAXErrorHandler *iface)
|
||||||
|
{
|
||||||
|
return (ConfigFileHandler *)((char*)iface - FIELD_OFFSET(ConfigFileHandler, lpErrorVtbl));
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConfigFileHandler_QueryInterface(ISAXContentHandler *iface,
|
||||||
|
REFIID riid, void **ppvObject)
|
||||||
|
{
|
||||||
|
if (IsEqualGUID(riid, &IID_ISAXContentHandler) ||
|
||||||
|
IsEqualGUID(riid, &IID_IUnknown))
|
||||||
|
{
|
||||||
|
*ppvObject = iface;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARN("Unsupported interface %s\n", debugstr_guid(riid));
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ISAXContentHandler_AddRef(iface);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI ConfigFileHandler_AddRef(ISAXContentHandler *iface)
|
||||||
|
{
|
||||||
|
ConfigFileHandler *This = impl_from_ISAXContentHandler(iface);
|
||||||
|
return InterlockedIncrement(&This->ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI ConfigFileHandler_Release(ISAXContentHandler *iface)
|
||||||
|
{
|
||||||
|
ConfigFileHandler *This = impl_from_ISAXContentHandler(iface);
|
||||||
|
ULONG ref = InterlockedDecrement(&This->ref);
|
||||||
|
|
||||||
|
if (ref == 0)
|
||||||
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConfigFileHandler_putDocumentLocator(ISAXContentHandler *iface,
|
||||||
|
ISAXLocator *pLocator)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConfigFileHandler_startDocument(ISAXContentHandler *iface)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConfigFileHandler_endDocument(ISAXContentHandler *iface)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConfigFileHandler_startPrefixMapping(ISAXContentHandler *iface,
|
||||||
|
const WCHAR *pPrefix, int nPrefix, const WCHAR *pUri, int nUri)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConfigFileHandler_endPrefixMapping(ISAXContentHandler *iface,
|
||||||
|
const WCHAR *pPrefix, int nPrefix)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT parse_startup(ConfigFileHandler *This, ISAXAttributes *pAttr)
|
||||||
|
{
|
||||||
|
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};
|
||||||
|
static const WCHAR empty[] = {0};
|
||||||
|
LPCWSTR value;
|
||||||
|
int value_size;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = ISAXAttributes_getValueFromName(pAttr, empty, 0, legacy, lstrlenW(legacy), &value, &value_size);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
FIXME("useLegacyV2RuntimeActivationPolicy=%s not implemented\n", debugstr_wn(value, value_size));
|
||||||
|
hr = S_OK;
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT parse_supported_runtime(ConfigFileHandler *This, ISAXAttributes *pAttr)
|
||||||
|
{
|
||||||
|
static const WCHAR version[] = {'v','e','r','s','i','o','n',0};
|
||||||
|
static const WCHAR sku[] = {'s','k','u',0};
|
||||||
|
static const WCHAR empty[] = {0};
|
||||||
|
LPCWSTR value;
|
||||||
|
int value_size;
|
||||||
|
HRESULT hr;
|
||||||
|
supported_runtime *entry;
|
||||||
|
|
||||||
|
hr = ISAXAttributes_getValueFromName(pAttr, empty, 0, version, lstrlenW(version), &value, &value_size);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
TRACE("%s\n", debugstr_wn(value, value_size));
|
||||||
|
entry = HeapAlloc(GetProcessHeap(), 0, sizeof(supported_runtime));
|
||||||
|
if (entry)
|
||||||
|
{
|
||||||
|
entry->version = HeapAlloc(GetProcessHeap(), 0, (value_size + 1) * sizeof(WCHAR));
|
||||||
|
if (entry->version)
|
||||||
|
{
|
||||||
|
lstrcpyW(entry->version, value);
|
||||||
|
list_add_tail(&This->result->supported_runtimes, &entry->entry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, entry);
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
WARN("Missing version attribute\n");
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
hr = ISAXAttributes_getValueFromName(pAttr, empty, 0, sku, lstrlenW(sku), &value, &value_size);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
FIXME("sku=%s not implemented\n", debugstr_wn(value, value_size));
|
||||||
|
hr = S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConfigFileHandler_startElement(ISAXContentHandler *iface,
|
||||||
|
const WCHAR *pNamespaceUri, int nNamespaceUri, const WCHAR *pLocalName,
|
||||||
|
int nLocalName, const WCHAR *pQName, int nQName, ISAXAttributes *pAttr)
|
||||||
|
{
|
||||||
|
ConfigFileHandler *This = impl_from_ISAXContentHandler(iface);
|
||||||
|
static const WCHAR configuration[] = {'c','o','n','f','i','g','u','r','a','t','i','o','n',0};
|
||||||
|
static const WCHAR startup[] = {'s','t','a','r','t','u','p',0};
|
||||||
|
static const WCHAR supportedRuntime[] = {'s','u','p','p','o','r','t','e','d','R','u','n','t','i','m','e',0};
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
TRACE("%s %s %s\n", debugstr_wn(pNamespaceUri,nNamespaceUri),
|
||||||
|
debugstr_wn(pLocalName,nLocalName), debugstr_wn(pQName,nQName));
|
||||||
|
|
||||||
|
if (This->statenum == sizeof(This->states) / sizeof(This->states[0]) - 1)
|
||||||
|
{
|
||||||
|
ERR("file has too much nesting\n");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (This->states[This->statenum])
|
||||||
|
{
|
||||||
|
case STATE_ROOT:
|
||||||
|
if (nLocalName == sizeof(configuration)/sizeof(WCHAR)-1 &&
|
||||||
|
lstrcmpW(pLocalName, configuration) == 0)
|
||||||
|
{
|
||||||
|
This->states[++This->statenum] = STATE_CONFIGURATION;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto unknown;
|
||||||
|
case STATE_CONFIGURATION:
|
||||||
|
if (nLocalName == sizeof(startup)/sizeof(WCHAR)-1 &&
|
||||||
|
lstrcmpW(pLocalName, startup) == 0)
|
||||||
|
{
|
||||||
|
hr = parse_startup(This, pAttr);
|
||||||
|
This->states[++This->statenum] = STATE_STARTUP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto unknown;
|
||||||
|
case STATE_STARTUP:
|
||||||
|
if (nLocalName == sizeof(supportedRuntime)/sizeof(WCHAR)-1 &&
|
||||||
|
lstrcmpW(pLocalName, supportedRuntime) == 0)
|
||||||
|
{
|
||||||
|
hr = parse_supported_runtime(This, pAttr);
|
||||||
|
This->states[++This->statenum] = STATE_UNKNOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto unknown;
|
||||||
|
default:
|
||||||
|
goto unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
unknown:
|
||||||
|
FIXME("Unknown element %s in state %u\n", debugstr_wn(pLocalName,nLocalName),
|
||||||
|
This->states[This->statenum]);
|
||||||
|
|
||||||
|
This->states[++This->statenum] = STATE_UNKNOWN;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConfigFileHandler_endElement(ISAXContentHandler *iface,
|
||||||
|
const WCHAR *pNamespaceUri, int nNamespaceUri, const WCHAR *pLocalName,
|
||||||
|
int nLocalName, const WCHAR *pQName, int nQName)
|
||||||
|
{
|
||||||
|
ConfigFileHandler *This = impl_from_ISAXContentHandler(iface);
|
||||||
|
|
||||||
|
TRACE("%s %s %s\n", debugstr_wn(pNamespaceUri,nNamespaceUri),
|
||||||
|
debugstr_wn(pLocalName,nLocalName), debugstr_wn(pQName,nQName));
|
||||||
|
|
||||||
|
if (This->statenum > 0)
|
||||||
|
{
|
||||||
|
This->statenum--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERR("element end does not match a start\n");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConfigFileHandler_characters(ISAXContentHandler *iface,
|
||||||
|
const WCHAR *pChars, int nChars)
|
||||||
|
{
|
||||||
|
TRACE("%s\n", debugstr_wn(pChars,nChars));
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConfigFileHandler_ignorableWhitespace(ISAXContentHandler *iface,
|
||||||
|
const WCHAR *pChars, int nChars)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConfigFileHandler_processingInstruction(ISAXContentHandler *iface,
|
||||||
|
const WCHAR *pTarget, int nTarget, const WCHAR *pData, int nData)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConfigFileHandler_skippedEntity(ISAXContentHandler *iface,
|
||||||
|
const WCHAR * pName, int nName)
|
||||||
|
{
|
||||||
|
TRACE("%s\n", debugstr_wn(pName,nName));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct ISAXContentHandlerVtbl ConfigFileHandlerVtbl =
|
||||||
|
{
|
||||||
|
ConfigFileHandler_QueryInterface,
|
||||||
|
ConfigFileHandler_AddRef,
|
||||||
|
ConfigFileHandler_Release,
|
||||||
|
ConfigFileHandler_putDocumentLocator,
|
||||||
|
ConfigFileHandler_startDocument,
|
||||||
|
ConfigFileHandler_endDocument,
|
||||||
|
ConfigFileHandler_startPrefixMapping,
|
||||||
|
ConfigFileHandler_endPrefixMapping,
|
||||||
|
ConfigFileHandler_startElement,
|
||||||
|
ConfigFileHandler_endElement,
|
||||||
|
ConfigFileHandler_characters,
|
||||||
|
ConfigFileHandler_ignorableWhitespace,
|
||||||
|
ConfigFileHandler_processingInstruction,
|
||||||
|
ConfigFileHandler_skippedEntity
|
||||||
|
};
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConfigFileHandler_Error_QueryInterface(ISAXErrorHandler *iface,
|
||||||
|
REFIID riid, void **ppvObject)
|
||||||
|
{
|
||||||
|
if (IsEqualGUID(riid, &IID_ISAXErrorHandler) ||
|
||||||
|
IsEqualGUID(riid, &IID_IUnknown))
|
||||||
|
{
|
||||||
|
*ppvObject = iface;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARN("Unsupported interface %s\n", debugstr_guid(riid));
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ISAXErrorHandler_AddRef(iface);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI ConfigFileHandler_Error_AddRef(ISAXErrorHandler *iface)
|
||||||
|
{
|
||||||
|
ConfigFileHandler *This = impl_from_ISAXErrorHandler(iface);
|
||||||
|
return IUnknown_AddRef((IUnknown*)This);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI ConfigFileHandler_Error_Release(ISAXErrorHandler *iface)
|
||||||
|
{
|
||||||
|
ConfigFileHandler *This = impl_from_ISAXErrorHandler(iface);
|
||||||
|
return IUnknown_Release((IUnknown*)This);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConfigFileHandler_error(ISAXErrorHandler *iface,
|
||||||
|
ISAXLocator * pLocator, const WCHAR * pErrorMessage, HRESULT hrErrorCode)
|
||||||
|
{
|
||||||
|
WARN("%s,%x\n", debugstr_w(pErrorMessage), hrErrorCode);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConfigFileHandler_fatalError(ISAXErrorHandler *iface,
|
||||||
|
ISAXLocator * pLocator, const WCHAR * pErrorMessage, HRESULT hrErrorCode)
|
||||||
|
{
|
||||||
|
WARN("%s,%x\n", debugstr_w(pErrorMessage), hrErrorCode);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConfigFileHandler_ignorableWarning(ISAXErrorHandler *iface,
|
||||||
|
ISAXLocator * pLocator, const WCHAR * pErrorMessage, HRESULT hrErrorCode)
|
||||||
|
{
|
||||||
|
WARN("%s,%x\n", debugstr_w(pErrorMessage), hrErrorCode);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct ISAXErrorHandlerVtbl ConfigFileHandlerErrorVtbl =
|
||||||
|
{
|
||||||
|
ConfigFileHandler_Error_QueryInterface,
|
||||||
|
ConfigFileHandler_Error_AddRef,
|
||||||
|
ConfigFileHandler_Error_Release,
|
||||||
|
ConfigFileHandler_error,
|
||||||
|
ConfigFileHandler_fatalError,
|
||||||
|
ConfigFileHandler_ignorableWarning
|
||||||
|
};
|
||||||
|
|
||||||
|
static void init_config(parsed_config_file *config)
|
||||||
|
{
|
||||||
|
list_init(&config->supported_runtimes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT parse_config(VARIANT input, parsed_config_file *result)
|
||||||
|
{
|
||||||
|
ISAXXMLReader *reader;
|
||||||
|
ConfigFileHandler *handler;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
handler = HeapAlloc(GetProcessHeap(), 0, sizeof(ConfigFileHandler));
|
||||||
|
if (!handler)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
handler->lpVtbl = &ConfigFileHandlerVtbl;
|
||||||
|
handler->lpErrorVtbl = &ConfigFileHandlerErrorVtbl;
|
||||||
|
handler->ref = 1;
|
||||||
|
handler->states[0] = STATE_ROOT;
|
||||||
|
handler->statenum = 0;
|
||||||
|
handler->result = result;
|
||||||
|
|
||||||
|
hr = CoCreateInstance(&CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER,
|
||||||
|
&IID_ISAXXMLReader, (LPVOID*)&reader);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
hr = ISAXXMLReader_putContentHandler(reader, (ISAXContentHandler*)&handler->lpVtbl);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
hr = ISAXXMLReader_putErrorHandler(reader, (ISAXErrorHandler*)&handler->lpErrorVtbl);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
hr = ISAXXMLReader_parse(reader, input);
|
||||||
|
|
||||||
|
ISAXXMLReader_Release(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
IUnknown_Release((IUnknown*)handler);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern HRESULT parse_config_file(LPCWSTR filename, parsed_config_file *result)
|
||||||
|
{
|
||||||
|
IStream *stream;
|
||||||
|
VARIANT var;
|
||||||
|
HRESULT hr;
|
||||||
|
HRESULT initresult;
|
||||||
|
|
||||||
|
init_config(result);
|
||||||
|
|
||||||
|
initresult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||||
|
|
||||||
|
hr = SHCreateStreamOnFileW(filename, STGM_SHARE_DENY_WRITE | STGM_READ | STGM_FAILIFTHERE, &stream);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
V_VT(&var) = VT_UNKNOWN|VT_DISPATCH;
|
||||||
|
V_UNKNOWN(&var) = (IUnknown*)stream;
|
||||||
|
|
||||||
|
hr = parse_config(var, result);
|
||||||
|
|
||||||
|
IStream_Release(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(initresult))
|
||||||
|
CoUninitialize();
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_parsed_config_file(parsed_config_file *file)
|
||||||
|
{
|
||||||
|
supported_runtime *cursor, *cursor2;
|
||||||
|
|
||||||
|
LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &file->supported_runtimes, supported_runtime, entry)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, cursor->version);
|
||||||
|
list_remove(&cursor->entry);
|
||||||
|
HeapFree(GetProcessHeap(), 0, cursor);
|
||||||
|
}
|
||||||
|
}
|
@ -32,10 +32,10 @@
|
|||||||
#include "cor.h"
|
#include "cor.h"
|
||||||
#include "mscoree.h"
|
#include "mscoree.h"
|
||||||
#include "metahost.h"
|
#include "metahost.h"
|
||||||
|
#include "wine/list.h"
|
||||||
#include "mscoree_private.h"
|
#include "mscoree_private.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "wine/list.h"
|
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL( mscoree );
|
WINE_DEFAULT_DEBUG_CHANNEL( mscoree );
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "corerror.h"
|
#include "corerror.h"
|
||||||
#include "mscoree.h"
|
#include "mscoree.h"
|
||||||
#include "metahost.h"
|
#include "metahost.h"
|
||||||
|
#include "wine/list.h"
|
||||||
#include "mscoree_private.h"
|
#include "mscoree_private.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
@ -1041,15 +1042,15 @@ extern HRESULT CLRMetaHost_CreateInstance(REFIID riid, void **ppobj)
|
|||||||
HRESULT get_runtime_info(LPCWSTR exefile, LPCWSTR version, LPCWSTR config_file,
|
HRESULT get_runtime_info(LPCWSTR exefile, LPCWSTR version, LPCWSTR config_file,
|
||||||
DWORD startup_flags, DWORD runtimeinfo_flags, BOOL legacy, ICLRRuntimeInfo **result)
|
DWORD startup_flags, DWORD runtimeinfo_flags, BOOL legacy, ICLRRuntimeInfo **result)
|
||||||
{
|
{
|
||||||
|
static const WCHAR dotconfig[] = {'.','c','o','n','f','i','g',0};
|
||||||
static const DWORD supported_startup_flags = 0;
|
static const DWORD supported_startup_flags = 0;
|
||||||
static const DWORD supported_runtime_flags = RUNTIME_INFO_UPGRADE_VERSION;
|
static const DWORD supported_runtime_flags = RUNTIME_INFO_UPGRADE_VERSION;
|
||||||
int i;
|
int i;
|
||||||
WCHAR local_version[MAX_PATH];
|
WCHAR local_version[MAX_PATH];
|
||||||
ULONG local_version_size = MAX_PATH;
|
ULONG local_version_size = MAX_PATH;
|
||||||
|
WCHAR local_config_file[MAX_PATH];
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
parsed_config_file parsed_config;
|
||||||
if (config_file)
|
|
||||||
FIXME("ignoring config filename %s\n", debugstr_w(config_file));
|
|
||||||
|
|
||||||
if (startup_flags & ~supported_startup_flags)
|
if (startup_flags & ~supported_startup_flags)
|
||||||
FIXME("unsupported startup flags %x\n", startup_flags & ~supported_startup_flags);
|
FIXME("unsupported startup flags %x\n", startup_flags & ~supported_startup_flags);
|
||||||
@ -1057,6 +1058,43 @@ HRESULT get_runtime_info(LPCWSTR exefile, LPCWSTR version, LPCWSTR config_file,
|
|||||||
if (runtimeinfo_flags & ~supported_runtime_flags)
|
if (runtimeinfo_flags & ~supported_runtime_flags)
|
||||||
FIXME("unsupported runtimeinfo flags %x\n", runtimeinfo_flags & ~supported_runtime_flags);
|
FIXME("unsupported runtimeinfo flags %x\n", runtimeinfo_flags & ~supported_runtime_flags);
|
||||||
|
|
||||||
|
if (exefile && !config_file)
|
||||||
|
{
|
||||||
|
strcpyW(local_config_file, exefile);
|
||||||
|
strcatW(local_config_file, dotconfig);
|
||||||
|
|
||||||
|
config_file = local_config_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config_file)
|
||||||
|
{
|
||||||
|
int found=0;
|
||||||
|
hr = parse_config_file(config_file, &parsed_config);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
supported_runtime *entry;
|
||||||
|
LIST_FOR_EACH_ENTRY(entry, &parsed_config.supported_runtimes, supported_runtime, entry)
|
||||||
|
{
|
||||||
|
hr = CLRMetaHost_GetRuntime(0, entry->version, &IID_ICLRRuntimeInfo, (void**)result);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARN("failed to parse config file %s, hr=%x\n", debugstr_w(config_file), hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_parsed_config_file(&parsed_config);
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (exefile && !version)
|
if (exefile && !version)
|
||||||
{
|
{
|
||||||
hr = CLRMetaHost_GetVersionFromFile(0, exefile, local_version, &local_version_size);
|
hr = CLRMetaHost_GetVersionFromFile(0, exefile, local_version, &local_version_size);
|
||||||
|
@ -32,12 +32,16 @@
|
|||||||
#include "ole2.h"
|
#include "ole2.h"
|
||||||
#include "ocidl.h"
|
#include "ocidl.h"
|
||||||
#include "shellapi.h"
|
#include "shellapi.h"
|
||||||
|
#include "xmldom.h"
|
||||||
|
#include "xmldso.h"
|
||||||
|
|
||||||
#include "initguid.h"
|
#include "initguid.h"
|
||||||
|
#include "msxml2.h"
|
||||||
#include "cor.h"
|
#include "cor.h"
|
||||||
#include "corerror.h"
|
#include "corerror.h"
|
||||||
#include "mscoree.h"
|
#include "mscoree.h"
|
||||||
#include "metahost.h"
|
#include "metahost.h"
|
||||||
|
#include "wine/list.h"
|
||||||
#include "mscoree_private.h"
|
#include "mscoree_private.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
@ -54,6 +54,21 @@ extern HRESULT force_get_runtime_info(ICLRRuntimeInfo **result);
|
|||||||
|
|
||||||
extern HRESULT ICLRRuntimeInfo_GetRuntimeHost(ICLRRuntimeInfo *iface, RuntimeHost **result);
|
extern HRESULT ICLRRuntimeInfo_GetRuntimeHost(ICLRRuntimeInfo *iface, RuntimeHost **result);
|
||||||
|
|
||||||
|
typedef struct parsed_config_file
|
||||||
|
{
|
||||||
|
struct list supported_runtimes;
|
||||||
|
} parsed_config_file;
|
||||||
|
|
||||||
|
typedef struct supported_runtime
|
||||||
|
{
|
||||||
|
struct list entry;
|
||||||
|
LPWSTR version;
|
||||||
|
} supported_runtime;
|
||||||
|
|
||||||
|
extern HRESULT parse_config_file(LPCWSTR filename, parsed_config_file *result);
|
||||||
|
|
||||||
|
extern void free_parsed_config_file(parsed_config_file *file);
|
||||||
|
|
||||||
/* Mono 2.6 embedding */
|
/* Mono 2.6 embedding */
|
||||||
typedef struct _MonoDomain MonoDomain;
|
typedef struct _MonoDomain MonoDomain;
|
||||||
typedef struct _MonoAssembly MonoAssembly;
|
typedef struct _MonoAssembly MonoAssembly;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user