[MSCOREE]

* Sync to Wine 1.3.37.

svn path=/trunk/; revision=55276
This commit is contained in:
Amine Khaldi 2012-01-28 17:34:24 +00:00
parent 5f4ae9949c
commit 53d0c6b010
15 changed files with 4287 additions and 285 deletions

View file

@ -2,11 +2,18 @@
add_definitions(-D__WINESRC__) add_definitions(-D__WINESRC__)
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
set_rc_compiler()
spec2def(mscoree.dll mscoree.spec) spec2def(mscoree.dll mscoree.spec)
list(APPEND SOURCE list(APPEND SOURCE
assembly.c
config.c
cordebug.c
corruntimehost.c corruntimehost.c
metadata.c
metahost.c
mscoree_main.c mscoree_main.c
mscoree.rc
${CMAKE_CURRENT_BINARY_DIR}/mscoree_stubs.c ${CMAKE_CURRENT_BINARY_DIR}/mscoree_stubs.c
${CMAKE_CURRENT_BINARY_DIR}/mscoree.def) ${CMAKE_CURRENT_BINARY_DIR}/mscoree.def)
@ -14,5 +21,10 @@ add_library(mscoree SHARED ${SOURCE})
set_module_type(mscoree win32dll) set_module_type(mscoree win32dll)
target_link_libraries(mscoree wine uuid) target_link_libraries(mscoree wine uuid)
add_importlibs(mscoree advapi32 shell32 msvcrt kernel32 ntdll)
if(MSVC)
target_link_libraries(mscoree xml_uuids)
endif()
add_importlibs(mscoree dbghelp advapi32 shell32 ole32 shlwapi msvcrt kernel32 ntdll)
add_cd_file(TARGET mscoree DESTINATION reactos/system32 FOR all) add_cd_file(TARGET mscoree DESTINATION reactos/system32 FOR all)

View file

@ -0,0 +1,250 @@
/*
* assembly parser
*
* Copyright 2008 James Hawkins
*
* 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
*/
#include <stdarg.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winver.h"
#include "dbghelp.h"
#include "ole2.h"
#include "mscoree.h"
#include "corhdr.h"
#include "metahost.h"
#include "cordebug.h"
#include "wine/list.h"
#include "mscoree_private.h"
#include "wine/debug.h"
#include "wine/unicode.h"
typedef struct
{
ULONG Signature;
USHORT MajorVersion;
USHORT MinorVersion;
ULONG Reserved;
ULONG VersionLength;
LPSTR Version;
BYTE Flags;
WORD Streams;
} METADATAHDR;
typedef struct
{
DWORD Offset;
DWORD Size;
} METADATASTREAMHDR;
typedef struct tagCLRTABLE
{
INT rows;
DWORD offset;
} CLRTABLE;
struct tagASSEMBLY
{
LPWSTR path;
HANDLE hfile;
HANDLE hmap;
BYTE *data;
IMAGE_NT_HEADERS *nthdr;
IMAGE_COR20_HEADER *corhdr;
METADATAHDR *metadatahdr;
};
static inline LPWSTR strdupW(LPCWSTR src)
{
LPWSTR dest;
if (!src)
return NULL;
dest = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(src) + 1) * sizeof(WCHAR));
if (dest)
lstrcpyW(dest, src);
return dest;
}
static HRESULT parse_metadata_header(ASSEMBLY *assembly, DWORD *hdrsz)
{
METADATAHDR *metadatahdr;
BYTE *ptr, *dest;
DWORD size, ofs;
ULONG rva;
rva = assembly->corhdr->MetaData.VirtualAddress;
ptr = ImageRvaToVa(assembly->nthdr, assembly->data, rva, NULL);
if (!ptr)
return E_FAIL;
metadatahdr = (METADATAHDR *)ptr;
assembly->metadatahdr = HeapAlloc(GetProcessHeap(), 0, sizeof(METADATAHDR));
if (!assembly->metadatahdr)
return E_OUTOFMEMORY;
size = FIELD_OFFSET(METADATAHDR, Version);
memcpy(assembly->metadatahdr, metadatahdr, size);
assembly->metadatahdr->Version = (LPSTR)&metadatahdr->Version;
ofs = FIELD_OFFSET(METADATAHDR, Flags);
ptr += FIELD_OFFSET(METADATAHDR, Version) + metadatahdr->VersionLength + 1;
dest = (BYTE *)assembly->metadatahdr + ofs;
memcpy(dest, ptr, sizeof(METADATAHDR) - ofs);
*hdrsz = sizeof(METADATAHDR) - sizeof(LPSTR) + metadatahdr->VersionLength + 1;
return S_OK;
}
static HRESULT parse_clr_metadata(ASSEMBLY *assembly)
{
HRESULT hr;
DWORD hdrsz;
hr = parse_metadata_header(assembly, &hdrsz);
if (FAILED(hr))
return hr;
return S_OK;
}
static HRESULT parse_pe_header(ASSEMBLY *assembly)
{
IMAGE_DATA_DIRECTORY *datadirs;
assembly->nthdr = ImageNtHeader(assembly->data);
if (!assembly->nthdr)
return E_FAIL;
if (assembly->nthdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
{
IMAGE_OPTIONAL_HEADER64 *opthdr =
(IMAGE_OPTIONAL_HEADER64 *)&assembly->nthdr->OptionalHeader;
datadirs = opthdr->DataDirectory;
}
else
{
IMAGE_OPTIONAL_HEADER32 *opthdr =
(IMAGE_OPTIONAL_HEADER32 *)&assembly->nthdr->OptionalHeader;
datadirs = opthdr->DataDirectory;
}
if (!datadirs)
return E_FAIL;
if (!datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress ||
!datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size)
{
return E_FAIL;
}
assembly->corhdr = ImageRvaToVa(assembly->nthdr, assembly->data,
datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress, NULL);
if (!assembly->corhdr)
return E_FAIL;
return S_OK;
}
HRESULT assembly_create(ASSEMBLY **out, LPCWSTR file)
{
ASSEMBLY *assembly;
HRESULT hr;
*out = NULL;
assembly = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ASSEMBLY));
if (!assembly)
return E_OUTOFMEMORY;
assembly->path = strdupW(file);
if (!assembly->path)
{
hr = E_OUTOFMEMORY;
goto failed;
}
assembly->hfile = CreateFileW(file, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (assembly->hfile == INVALID_HANDLE_VALUE)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto failed;
}
assembly->hmap = CreateFileMappingW(assembly->hfile, NULL, PAGE_READONLY,
0, 0, NULL);
if (!assembly->hmap)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto failed;
}
assembly->data = MapViewOfFile(assembly->hmap, FILE_MAP_READ, 0, 0, 0);
if (!assembly->data)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto failed;
}
hr = parse_pe_header(assembly);
if (FAILED(hr)) goto failed;
hr = parse_clr_metadata(assembly);
if (FAILED(hr)) goto failed;
*out = assembly;
return S_OK;
failed:
assembly_release(assembly);
return hr;
}
HRESULT assembly_release(ASSEMBLY *assembly)
{
if (!assembly)
return S_OK;
HeapFree(GetProcessHeap(), 0, assembly->metadatahdr);
HeapFree(GetProcessHeap(), 0, assembly->path);
UnmapViewOfFile(assembly->data);
CloseHandle(assembly->hmap);
CloseHandle(assembly->hfile);
HeapFree(GetProcessHeap(), 0, assembly);
return S_OK;
}
HRESULT assembly_get_runtime_version(ASSEMBLY *assembly, LPSTR *version)
{
*version = assembly->metadatahdr->Version;
return S_OK;
}

View file

@ -0,0 +1,472 @@
/*
* 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 "mscoree.h"
#include "corhdr.h"
#include "metahost.h"
#include "cordebug.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
{
ISAXContentHandler ISAXContentHandler_iface;
ISAXErrorHandler ISAXErrorHandler_iface;
LONG ref;
enum parse_state states[16];
int statenum;
parsed_config_file *result;
} ConfigFileHandler;
static inline ConfigFileHandler *impl_from_ISAXContentHandler(ISAXContentHandler *iface)
{
return CONTAINING_RECORD(iface, ConfigFileHandler, ISAXContentHandler_iface);
}
static inline ConfigFileHandler *impl_from_ISAXErrorHandler(ISAXErrorHandler *iface)
{
return CONTAINING_RECORD(iface, ConfigFileHandler, ISAXErrorHandler_iface);
}
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->ISAXContentHandler_iface.lpVtbl = &ConfigFileHandlerVtbl;
handler->ISAXErrorHandler_iface.lpVtbl = &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, &handler->ISAXContentHandler_iface);
if (SUCCEEDED(hr))
hr = ISAXXMLReader_putErrorHandler(reader, &handler->ISAXErrorHandler_iface);
if (SUCCEEDED(hr))
hr = ISAXXMLReader_parse(reader, input);
ISAXXMLReader_Release(reader);
}
IUnknown_Release((IUnknown*)handler);
return S_OK;
}
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);
}
}

View file

@ -0,0 +1,786 @@
/*
*
* Copyright 2011 Alistair Leslie-Hughes
*
* 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 "winuser.h"
#include "winnls.h"
#include "winreg.h"
#include "ole2.h"
#include "shellapi.h"
#include "mscoree.h"
#include "corhdr.h"
#include "metahost.h"
#include "cordebug.h"
#include "wine/list.h"
#include "mscoree_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL( mscoree );
typedef struct DebugProcess
{
ICorDebugProcess ICorDebugProcess_iface;
CorDebug *cordebug;
DWORD dwProcessID;
HANDLE handle;
HANDLE thread;
LONG ref;
} DebugProcess;
static inline CorDebug *impl_from_ICorDebug( ICorDebug *iface )
{
return CONTAINING_RECORD(iface, CorDebug, ICorDebug_iface);
}
static inline CorDebug *impl_from_ICorDebugProcessEnum( ICorDebugProcessEnum *iface )
{
return CONTAINING_RECORD(iface, CorDebug, ICorDebugProcessEnum_iface);
}
static inline DebugProcess *impl_from_ICorDebugProcess( ICorDebugProcess *iface )
{
return CONTAINING_RECORD(iface, DebugProcess, ICorDebugProcess_iface);
}
/* ICorDebugProcess Interface */
static HRESULT WINAPI cordebugprocess_QueryInterface(ICorDebugProcess *iface,
REFIID riid, void **ppvObject)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
if ( IsEqualGUID( riid, &IID_ICorDebugProcess ) ||
IsEqualGUID( riid, &IID_ICorDebugController ) ||
IsEqualGUID( riid, &IID_IUnknown ) )
{
*ppvObject = &This->ICorDebugProcess_iface;
}
else
{
FIXME("Unsupported interface %s\n", debugstr_guid(riid));
return E_NOINTERFACE;
}
ICorDebug_AddRef(iface);
return S_OK;
}
static ULONG WINAPI cordebugprocess_AddRef(ICorDebugProcess *iface)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("%p ref=%u\n", This, ref);
return ref;
}
static ULONG WINAPI cordebugprocess_Release(ICorDebugProcess *iface)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("%p ref=%u\n", This, ref);
if (ref == 0)
{
if(This->handle)
CloseHandle(This->handle);
if(This->thread)
CloseHandle(This->thread);
if(This->cordebug)
ICorDebug_Release(&This->cordebug->ICorDebug_iface);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI cordebugprocess_Stop(ICorDebugProcess *iface, DWORD dwTimeoutIgnored)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_Continue(ICorDebugProcess *iface, BOOL fIsOutOfBand)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
TRACE("%p\n", This);
if(This->thread)
ResumeThread(This->thread);
return S_OK;
}
static HRESULT WINAPI cordebugprocess_IsRunning(ICorDebugProcess *iface, BOOL *pbRunning)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_HasQueuedCallbacks(ICorDebugProcess *iface,
ICorDebugThread *pThread, BOOL *pbQueued)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_EnumerateThreads(ICorDebugProcess *iface,
ICorDebugThreadEnum **ppThreads)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_SetAllThreadsDebugState(ICorDebugProcess *iface,
CorDebugThreadState state, ICorDebugThread *pExceptThisThread)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_Detach(ICorDebugProcess *iface)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_Terminate(ICorDebugProcess *iface, UINT exitCode)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
BOOL ret = TRUE;
TRACE("%p\n", This);
if(This->handle)
{
ret = TerminateProcess(This->handle, exitCode);
CloseHandle(This->handle);
This->handle = NULL;
}
return ret ? S_OK : E_FAIL;
}
static HRESULT WINAPI cordebugprocess_CanCommitChanges(ICorDebugProcess *iface,
ULONG cSnapshots, ICorDebugEditAndContinueSnapshot * pSnapshots[],
ICorDebugErrorInfoEnum **pError)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_CommitChanges(ICorDebugProcess *iface,
ULONG cSnapshots, ICorDebugEditAndContinueSnapshot * pSnapshots[],
ICorDebugErrorInfoEnum **pError)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_GetID(ICorDebugProcess *iface, DWORD *pdwProcessId)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
TRACE("%p\n", This);
if(!pdwProcessId)
return E_INVALIDARG;
*pdwProcessId = This->dwProcessID;
return S_OK;
}
static HRESULT WINAPI cordebugprocess_GetHandle(ICorDebugProcess *iface, HPROCESS *phProcessHandle)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
TRACE("%p\n", This);
if(!phProcessHandle)
return E_INVALIDARG;
*phProcessHandle = This->handle;
return S_OK;
}
static HRESULT WINAPI cordebugprocess_GetThread(ICorDebugProcess *iface, DWORD dwThreadId,
ICorDebugThread **ppThread)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_EnumerateObjects(ICorDebugProcess *iface,
ICorDebugObjectEnum **ppObjects)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_IsTransitionStub(ICorDebugProcess *iface,
CORDB_ADDRESS address, BOOL *pbTransitionStub)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_IsOSSuspended(ICorDebugProcess *iface,
DWORD threadID, BOOL *pbSuspended)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_GetThreadContext(ICorDebugProcess *iface,
DWORD threadID, ULONG32 contextSize, BYTE context[])
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_SetThreadContext(ICorDebugProcess *iface,
DWORD threadID, ULONG32 contextSize, BYTE context[])
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_ReadMemory(ICorDebugProcess *iface,
CORDB_ADDRESS address, DWORD size, BYTE buffer[],
SIZE_T *read)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_WriteMemory(ICorDebugProcess *iface,
CORDB_ADDRESS address, DWORD size, BYTE buffer[],
SIZE_T *written)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_ClearCurrentException(ICorDebugProcess *iface,
DWORD threadID)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_EnableLogMessages(ICorDebugProcess *iface,
BOOL fOnOff)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_ModifyLogSwitch(ICorDebugProcess *iface,
WCHAR *pLogSwitchName, LONG lLevel)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_EnumerateAppDomains(ICorDebugProcess *iface,
ICorDebugAppDomainEnum **ppAppDomains)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_GetObject(ICorDebugProcess *iface,
ICorDebugValue **ppObject)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_ThreadForFiberCookie(ICorDebugProcess *iface,
DWORD fiberCookie, ICorDebugThread **ppThread)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI cordebugprocess_GetHelperThreadID(ICorDebugProcess *iface,
DWORD *pThreadID)
{
DebugProcess *This = impl_from_ICorDebugProcess(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
/***************************************/
static const ICorDebugProcessVtbl cordebugprocessVtbl = {
cordebugprocess_QueryInterface,
cordebugprocess_AddRef,
cordebugprocess_Release,
cordebugprocess_Stop,
cordebugprocess_Continue,
cordebugprocess_IsRunning,
cordebugprocess_HasQueuedCallbacks,
cordebugprocess_EnumerateThreads,
cordebugprocess_SetAllThreadsDebugState,
cordebugprocess_Detach,
cordebugprocess_Terminate,
cordebugprocess_CanCommitChanges,
cordebugprocess_CommitChanges,
cordebugprocess_GetID,
cordebugprocess_GetHandle,
cordebugprocess_GetThread,
cordebugprocess_EnumerateObjects,
cordebugprocess_IsTransitionStub,
cordebugprocess_IsOSSuspended,
cordebugprocess_GetThreadContext,
cordebugprocess_SetThreadContext,
cordebugprocess_ReadMemory,
cordebugprocess_WriteMemory,
cordebugprocess_ClearCurrentException,
cordebugprocess_EnableLogMessages,
cordebugprocess_ModifyLogSwitch,
cordebugprocess_EnumerateAppDomains,
cordebugprocess_GetObject,
cordebugprocess_ThreadForFiberCookie,
cordebugprocess_GetHelperThreadID
};
static HRESULT CorDebugProcess_Create(CorDebug *cordebug, IUnknown** ppUnk, LPPROCESS_INFORMATION lpProcessInformation)
{
DebugProcess *This;
This = HeapAlloc( GetProcessHeap(), 0, sizeof *This );
if ( !This )
return E_OUTOFMEMORY;
if(!DuplicateHandle(GetCurrentProcess(), lpProcessInformation->hProcess,
GetCurrentProcess(), &This->handle, 0, FALSE, DUPLICATE_SAME_ACCESS))
{
ERR("Failed to duplicate process handle\n");
HeapFree(GetProcessHeap(), 0, This);
return E_FAIL;
}
if(!DuplicateHandle(GetCurrentProcess(), lpProcessInformation->hThread,
GetCurrentProcess(), &This->thread, 0, FALSE, DUPLICATE_SAME_ACCESS))
{
CloseHandle(This->handle);
ERR("Failed to duplicate thread handle\n");
HeapFree(GetProcessHeap(), 0, This);
return E_FAIL;
}
This->ICorDebugProcess_iface.lpVtbl = &cordebugprocessVtbl;
This->ref = 1;
This->cordebug = cordebug;
This->dwProcessID = lpProcessInformation->dwProcessId;
if(This->cordebug)
ICorDebug_AddRef(&This->cordebug->ICorDebug_iface);
*ppUnk = (IUnknown*)This;
return S_OK;
}
/* ICorDebugProcessEnum Interface */
static HRESULT WINAPI process_enum_QueryInterface(ICorDebugProcessEnum *iface, REFIID riid, void **ppvObject)
{
CorDebug *This = impl_from_ICorDebugProcessEnum(iface);
TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
if ( IsEqualGUID( riid, &IID_ICorDebugProcessEnum ) ||
IsEqualGUID( riid, &IID_ICorDebugEnum ) ||
IsEqualGUID( riid, &IID_IUnknown ) )
{
*ppvObject = &This->ICorDebugProcessEnum_iface;
}
else
{
FIXME("Unsupported interface %s\n", debugstr_guid(riid));
return E_NOINTERFACE;
}
ICorDebug_AddRef(iface);
return S_OK;
}
static ULONG WINAPI process_enum_AddRef(ICorDebugProcessEnum *iface)
{
CorDebug *This = impl_from_ICorDebugProcessEnum(iface);
TRACE("%p ref=%u\n", This, This->ref);
return ICorDebug_AddRef(&This->ICorDebug_iface);
}
static ULONG WINAPI process_enum_Release(ICorDebugProcessEnum *iface)
{
CorDebug *This = impl_from_ICorDebugProcessEnum(iface);
TRACE("%p ref=%u\n", This, This->ref);
return ICorDebug_Release(&This->ICorDebug_iface);
}
static HRESULT WINAPI process_enum_Skip(ICorDebugProcessEnum *iface, ULONG celt)
{
CorDebug *This = impl_from_ICorDebugProcessEnum(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI process_enum_Reset(ICorDebugProcessEnum *iface)
{
CorDebug *This = impl_from_ICorDebugProcessEnum(iface);
FIXME("stub %p\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI process_enum_Clone(ICorDebugProcessEnum *iface, ICorDebugEnum **ppEnum)
{
CorDebug *This = impl_from_ICorDebugProcessEnum(iface);
FIXME("stub %p %p\n", This, ppEnum);
return E_NOTIMPL;
}
static HRESULT WINAPI process_enum_GetCount(ICorDebugProcessEnum *iface, ULONG *pcelt)
{
CorDebug *This = impl_from_ICorDebugProcessEnum(iface);
TRACE("stub %p %p\n", This, pcelt);
if(!pcelt)
return E_INVALIDARG;
*pcelt = list_count(&This->processes);
return S_OK;
}
static HRESULT WINAPI process_enum_Next(ICorDebugProcessEnum *iface, ULONG celt,
ICorDebugProcess * processes[], ULONG *pceltFetched)
{
CorDebug *This = impl_from_ICorDebugProcessEnum(iface);
FIXME("stub %p %d %p %p\n", This, celt, processes, pceltFetched);
return E_NOTIMPL;
}
static const struct ICorDebugProcessEnumVtbl processenum_vtbl =
{
process_enum_QueryInterface,
process_enum_AddRef,
process_enum_Release,
process_enum_Skip,
process_enum_Reset,
process_enum_Clone,
process_enum_GetCount,
process_enum_Next
};
/*** IUnknown methods ***/
static HRESULT WINAPI CorDebug_QueryInterface(ICorDebug *iface, REFIID riid, void **ppvObject)
{
CorDebug *This = impl_from_ICorDebug( iface );
TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
if ( IsEqualGUID( riid, &IID_ICorDebug ) ||
IsEqualGUID( riid, &IID_IUnknown ) )
{
*ppvObject = &This->ICorDebug_iface;
}
else
{
FIXME("Unsupported interface %s\n", debugstr_guid(riid));
return E_NOINTERFACE;
}
ICorDebug_AddRef( iface );
return S_OK;
}
static ULONG WINAPI CorDebug_AddRef(ICorDebug *iface)
{
CorDebug *This = impl_from_ICorDebug( iface );
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("%p ref=%u\n", This, ref);
return ref;
}
static ULONG WINAPI CorDebug_Release(ICorDebug *iface)
{
CorDebug *This = impl_from_ICorDebug( iface );
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("%p ref=%u\n", This, ref);
if (ref == 0)
{
if(!list_empty(&This->processes))
ERR("Processes haven't been removed Correctly\n");
if(This->runtimehost)
ICLRRuntimeHost_Release(This->runtimehost);
if(This->pCallback)
ICorDebugManagedCallback2_Release(This->pCallback2);
if(This->pCallback)
ICorDebugManagedCallback_Release(This->pCallback);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
/*** ICorDebug methods ***/
static HRESULT WINAPI CorDebug_Initialize(ICorDebug *iface)
{
CorDebug *This = impl_from_ICorDebug( iface );
FIXME("stub %p\n", This);
return S_OK;
}
static HRESULT WINAPI CorDebug_Terminate(ICorDebug *iface)
{
struct CorProcess *cursor, *cursor2;
CorDebug *This = impl_from_ICorDebug( iface );
TRACE("stub %p\n", This);
LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->processes, struct CorProcess, entry)
{
if(cursor->pProcess)
{
ICorDebugProcess_Terminate(cursor->pProcess, 0);
ICorDebugProcess_Release(cursor->pProcess);
}
list_remove(&cursor->entry);
HeapFree(GetProcessHeap(), 0, cursor);
}
return S_OK;
}
static HRESULT WINAPI CorDebug_SetManagedHandler(ICorDebug *iface, ICorDebugManagedCallback *pCallback)
{
CorDebug *This = impl_from_ICorDebug( iface );
HRESULT hr;
ICorDebugManagedCallback2 *pCallback2;
TRACE("%p (%p)\n", This, pCallback);
if(!pCallback)
return E_INVALIDARG;
hr = ICorDebugManagedCallback_QueryInterface(pCallback, &IID_ICorDebugManagedCallback2, (void**)&pCallback2);
if(hr == S_OK)
{
if(This->pCallback2)
ICorDebugManagedCallback2_Release(This->pCallback2);
if(This->pCallback)
ICorDebugManagedCallback_Release(This->pCallback);
This->pCallback = pCallback;
This->pCallback2 = pCallback2;
ICorDebugManagedCallback_AddRef(This->pCallback);
}
else
{
WARN("Debugging without interface ICorDebugManagedCallback2 is currently not supported.\n");
}
return hr;
}
static HRESULT WINAPI CorDebug_SetUnmanagedHandler(ICorDebug *iface, ICorDebugUnmanagedCallback *pCallback)
{
CorDebug *This = impl_from_ICorDebug( iface );
FIXME("stub %p %p\n", This, pCallback);
return E_NOTIMPL;
}
static HRESULT WINAPI CorDebug_CreateProcess(ICorDebug *iface, LPCWSTR lpApplicationName,
LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles,
DWORD dwCreationFlags, PVOID lpEnvironment,LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation,
CorDebugCreateProcessFlags debuggingFlags, ICorDebugProcess **ppProcess)
{
CorDebug *This = impl_from_ICorDebug( iface );
ICorDebugProcess *pDebugProcess;
HRESULT hr;
TRACE("stub %p %s %s %p %p %d %d %p %s %p %p %d %p\n", This, debugstr_w(lpApplicationName),
debugstr_w(lpCommandLine), lpProcessAttributes, lpThreadAttributes,
bInheritHandles, dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
lpStartupInfo, lpProcessInformation, debuggingFlags, ppProcess);
if(CreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes,
bInheritHandles, dwCreationFlags | CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory,
lpStartupInfo, lpProcessInformation))
{
hr = CorDebugProcess_Create(This, (IUnknown**)&pDebugProcess, lpProcessInformation);
if(hr == S_OK)
{
struct CorProcess *new_process = HeapAlloc( GetProcessHeap(), 0, sizeof(CorProcess) );
new_process->pProcess = pDebugProcess;
list_add_tail(&This->processes, &new_process->entry);
ICorDebugProcess_AddRef(pDebugProcess);
*ppProcess = pDebugProcess;
if(This->pCallback)
ICorDebugManagedCallback_CreateProcess(This->pCallback, pDebugProcess);
}
else
{
TerminateProcess(lpProcessInformation->hProcess, 0);
}
}
else
hr = E_FAIL;
return hr;
}
static HRESULT WINAPI CorDebug_DebugActiveProcess(ICorDebug *iface, DWORD id, BOOL win32Attach,
ICorDebugProcess **ppProcess)
{
CorDebug *This = impl_from_ICorDebug( iface );
FIXME("stub %p %d %d %p\n", This, id, win32Attach, ppProcess);
return E_NOTIMPL;
}
static HRESULT WINAPI CorDebug_EnumerateProcesses( ICorDebug *iface, ICorDebugProcessEnum **ppProcess)
{
CorDebug *This = impl_from_ICorDebug( iface );
TRACE("stub %p %p\n", This, ppProcess);
if(!ppProcess)
return E_INVALIDARG;
*ppProcess = &This->ICorDebugProcessEnum_iface;
ICorDebugProcessEnum_AddRef(*ppProcess);
return S_OK;
}
static HRESULT WINAPI CorDebug_GetProcess(ICorDebug *iface, DWORD dwProcessId, ICorDebugProcess **ppProcess)
{
CorDebug *This = impl_from_ICorDebug( iface );
FIXME("stub %p %d %p\n", This, dwProcessId, ppProcess);
return E_NOTIMPL;
}
static HRESULT WINAPI CorDebug_CanLaunchOrAttach(ICorDebug *iface, DWORD dwProcessId,
BOOL win32DebuggingEnabled)
{
CorDebug *This = impl_from_ICorDebug( iface );
FIXME("stub %p %d %d\n", This, dwProcessId, win32DebuggingEnabled);
return S_OK;
}
static const struct ICorDebugVtbl cordebug_vtbl =
{
CorDebug_QueryInterface,
CorDebug_AddRef,
CorDebug_Release,
CorDebug_Initialize,
CorDebug_Terminate,
CorDebug_SetManagedHandler,
CorDebug_SetUnmanagedHandler,
CorDebug_CreateProcess,
CorDebug_DebugActiveProcess,
CorDebug_EnumerateProcesses,
CorDebug_GetProcess,
CorDebug_CanLaunchOrAttach
};
HRESULT CorDebug_Create(ICLRRuntimeHost *runtimehost, IUnknown** ppUnk)
{
CorDebug *This;
This = HeapAlloc( GetProcessHeap(), 0, sizeof *This );
if ( !This )
return E_OUTOFMEMORY;
This->ICorDebug_iface.lpVtbl = &cordebug_vtbl;
This->ICorDebugProcessEnum_iface.lpVtbl = &processenum_vtbl;
This->ref = 1;
This->pCallback = NULL;
This->pCallback2 = NULL;
This->runtimehost = runtimehost;
list_init(&This->processes);
if(This->runtimehost)
ICLRRuntimeHost_AddRef(This->runtimehost);
*ppUnk = (IUnknown*)This;
return S_OK;
}

View file

@ -24,25 +24,185 @@
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "winuser.h" #include "winuser.h"
#include "winnls.h"
#include "winreg.h" #include "winreg.h"
#include "ole2.h" #include "ole2.h"
#include "shellapi.h"
#include "cor.h" #include "cor.h"
#include "mscoree.h" #include "mscoree.h"
#include "metahost.h"
#include "corhdr.h"
#include "cordebug.h"
#include "wine/list.h"
#include "mscoree_private.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL( mscoree ); WINE_DEFAULT_DEBUG_CHANNEL( mscoree );
typedef struct _corruntimehost #include "initguid.h"
{
const struct ICorRuntimeHostVtbl *lpVtbl;
LONG ref;
} corruntimehost;
static inline corruntimehost *impl_from_ICorRuntimeHost( ICorRuntimeHost *iface ) DEFINE_GUID(IID__AppDomain, 0x05f696dc,0x2b29,0x3663,0xad,0x8b,0xc4,0x38,0x9c,0xf2,0xa7,0x13);
struct DomainEntry
{ {
return (corruntimehost *)((char*)iface - FIELD_OFFSET(corruntimehost, lpVtbl)); struct list entry;
MonoDomain *domain;
};
static HRESULT RuntimeHost_AddDomain(RuntimeHost *This, MonoDomain **result)
{
struct DomainEntry *entry;
char *mscorlib_path;
HRESULT res=S_OK;
EnterCriticalSection(&This->lock);
entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
if (!entry)
{
res = E_OUTOFMEMORY;
goto end;
}
mscorlib_path = WtoA(This->version->mscorlib_path);
if (!mscorlib_path)
{
HeapFree(GetProcessHeap(), 0, entry);
res = E_OUTOFMEMORY;
goto end;
}
entry->domain = This->mono->mono_jit_init(mscorlib_path);
HeapFree(GetProcessHeap(), 0, mscorlib_path);
if (!entry->domain)
{
HeapFree(GetProcessHeap(), 0, entry);
res = E_FAIL;
goto end;
}
This->mono->is_started = TRUE;
list_add_tail(&This->domains, &entry->entry);
*result = entry->domain;
end:
LeaveCriticalSection(&This->lock);
return res;
}
static HRESULT RuntimeHost_GetDefaultDomain(RuntimeHost *This, MonoDomain **result)
{
HRESULT res=S_OK;
EnterCriticalSection(&This->lock);
if (This->default_domain) goto end;
res = RuntimeHost_AddDomain(This, &This->default_domain);
end:
*result = This->default_domain;
LeaveCriticalSection(&This->lock);
return res;
}
static void RuntimeHost_DeleteDomain(RuntimeHost *This, MonoDomain *domain)
{
struct DomainEntry *entry;
EnterCriticalSection(&This->lock);
LIST_FOR_EACH_ENTRY(entry, &This->domains, struct DomainEntry, entry)
{
if (entry->domain == domain)
{
list_remove(&entry->entry);
if (This->default_domain == domain)
This->default_domain = NULL;
HeapFree(GetProcessHeap(), 0, entry);
break;
}
}
LeaveCriticalSection(&This->lock);
}
static HRESULT RuntimeHost_GetIUnknownForDomain(RuntimeHost *This, MonoDomain *domain, IUnknown **punk)
{
HRESULT hr;
void *args[1];
MonoAssembly *assembly;
MonoImage *image;
MonoClass *klass;
MonoMethod *method;
MonoObject *appdomain_object;
IUnknown *unk;
assembly = This->mono->mono_domain_assembly_open(domain, "mscorlib");
if (!assembly)
{
ERR("Cannot load mscorlib\n");
return E_FAIL;
}
image = This->mono->mono_assembly_get_image(assembly);
if (!image)
{
ERR("Couldn't get assembly image\n");
return E_FAIL;
}
klass = This->mono->mono_class_from_name(image, "System", "AppDomain");
if (!klass)
{
ERR("Couldn't get class from image\n");
return E_FAIL;
}
method = This->mono->mono_class_get_method_from_name(klass, "get_CurrentDomain", 0);
if (!method)
{
ERR("Couldn't get method from class\n");
return E_FAIL;
}
args[0] = NULL;
appdomain_object = This->mono->mono_runtime_invoke(method, NULL, args, NULL);
if (!appdomain_object)
{
ERR("Couldn't get result pointer\n");
return E_FAIL;
}
hr = RuntimeHost_GetIUnknownForObject(This, appdomain_object, &unk);
if (SUCCEEDED(hr))
{
hr = IUnknown_QueryInterface(unk, &IID__AppDomain, (void**)punk);
IUnknown_Release(unk);
}
return hr;
}
static inline RuntimeHost *impl_from_ICLRRuntimeHost( ICLRRuntimeHost *iface )
{
return CONTAINING_RECORD(iface, RuntimeHost, ICLRRuntimeHost_iface);
}
static inline RuntimeHost *impl_from_ICorRuntimeHost( ICorRuntimeHost *iface )
{
return CONTAINING_RECORD(iface, RuntimeHost, ICorRuntimeHost_iface);
} }
/*** IUnknown methods ***/ /*** IUnknown methods ***/
@ -50,7 +210,7 @@ static HRESULT WINAPI corruntimehost_QueryInterface(ICorRuntimeHost* iface,
REFIID riid, REFIID riid,
void **ppvObject) void **ppvObject)
{ {
corruntimehost *This = impl_from_ICorRuntimeHost( iface ); RuntimeHost *This = impl_from_ICorRuntimeHost( iface );
TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
if ( IsEqualGUID( riid, &IID_ICorRuntimeHost ) || if ( IsEqualGUID( riid, &IID_ICorRuntimeHost ) ||
@ -71,20 +231,17 @@ static HRESULT WINAPI corruntimehost_QueryInterface(ICorRuntimeHost* iface,
static ULONG WINAPI corruntimehost_AddRef(ICorRuntimeHost* iface) static ULONG WINAPI corruntimehost_AddRef(ICorRuntimeHost* iface)
{ {
corruntimehost *This = impl_from_ICorRuntimeHost( iface ); RuntimeHost *This = impl_from_ICorRuntimeHost( iface );
return InterlockedIncrement( &This->ref ); return InterlockedIncrement( &This->ref );
} }
static ULONG WINAPI corruntimehost_Release(ICorRuntimeHost* iface) static ULONG WINAPI corruntimehost_Release(ICorRuntimeHost* iface)
{ {
corruntimehost *This = impl_from_ICorRuntimeHost( iface ); RuntimeHost *This = impl_from_ICorRuntimeHost( iface );
ULONG ref; ULONG ref;
ref = InterlockedDecrement( &This->ref ); ref = InterlockedDecrement( &This->ref );
if ( ref == 0 )
{
HeapFree( GetProcessHeap(), 0, This );
}
return ref; return ref;
} }
@ -149,7 +306,7 @@ static HRESULT WINAPI corruntimehost_Start(
ICorRuntimeHost* iface) ICorRuntimeHost* iface)
{ {
FIXME("stub %p\n", iface); FIXME("stub %p\n", iface);
return E_NOTIMPL; return S_OK;
} }
static HRESULT WINAPI corruntimehost_Stop( static HRESULT WINAPI corruntimehost_Stop(
@ -173,8 +330,20 @@ static HRESULT WINAPI corruntimehost_GetDefaultDomain(
ICorRuntimeHost* iface, ICorRuntimeHost* iface,
IUnknown **pAppDomain) IUnknown **pAppDomain)
{ {
FIXME("stub %p\n", iface); RuntimeHost *This = impl_from_ICorRuntimeHost( iface );
return E_NOTIMPL; HRESULT hr;
MonoDomain *domain;
TRACE("(%p)\n", iface);
hr = RuntimeHost_GetDefaultDomain(This, &domain);
if (SUCCEEDED(hr))
{
hr = RuntimeHost_GetIUnknownForDomain(This, domain, pAppDomain);
}
return hr;
} }
static HRESULT WINAPI corruntimehost_EnumDomains( static HRESULT WINAPI corruntimehost_EnumDomains(
@ -271,18 +440,506 @@ static const struct ICorRuntimeHostVtbl corruntimehost_vtbl =
corruntimehost_CurrentDomain corruntimehost_CurrentDomain
}; };
IUnknown* create_corruntimehost(void) static HRESULT WINAPI CLRRuntimeHost_QueryInterface(ICLRRuntimeHost* iface,
REFIID riid,
void **ppvObject)
{ {
corruntimehost *This; RuntimeHost *This = impl_from_ICLRRuntimeHost( iface );
TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
if ( IsEqualGUID( riid, &IID_ICLRRuntimeHost ) ||
IsEqualGUID( riid, &IID_IUnknown ) )
{
*ppvObject = iface;
}
else
{
FIXME("Unsupported interface %s\n", debugstr_guid(riid));
return E_NOINTERFACE;
}
ICLRRuntimeHost_AddRef( iface );
return S_OK;
}
static ULONG WINAPI CLRRuntimeHost_AddRef(ICLRRuntimeHost* iface)
{
RuntimeHost *This = impl_from_ICLRRuntimeHost( iface );
return ICorRuntimeHost_AddRef(&This->ICorRuntimeHost_iface);
}
static ULONG WINAPI CLRRuntimeHost_Release(ICLRRuntimeHost* iface)
{
RuntimeHost *This = impl_from_ICLRRuntimeHost( iface );
return ICorRuntimeHost_Release(&This->ICorRuntimeHost_iface);
}
static HRESULT WINAPI CLRRuntimeHost_Start(ICLRRuntimeHost* iface)
{
FIXME("(%p)\n", iface);
return E_NOTIMPL;
}
static HRESULT WINAPI CLRRuntimeHost_Stop(ICLRRuntimeHost* iface)
{
FIXME("(%p)\n", iface);
return E_NOTIMPL;
}
static HRESULT WINAPI CLRRuntimeHost_SetHostControl(ICLRRuntimeHost* iface,
IHostControl *pHostControl)
{
FIXME("(%p,%p)\n", iface, pHostControl);
return E_NOTIMPL;
}
static HRESULT WINAPI CLRRuntimeHost_GetCLRControl(ICLRRuntimeHost* iface,
ICLRControl **pCLRControl)
{
FIXME("(%p,%p)\n", iface, pCLRControl);
return E_NOTIMPL;
}
static HRESULT WINAPI CLRRuntimeHost_UnloadAppDomain(ICLRRuntimeHost* iface,
DWORD dwAppDomainId, BOOL fWaitUntilDone)
{
FIXME("(%p,%u,%i)\n", iface, dwAppDomainId, fWaitUntilDone);
return E_NOTIMPL;
}
static HRESULT WINAPI CLRRuntimeHost_ExecuteInAppDomain(ICLRRuntimeHost* iface,
DWORD dwAppDomainId, FExecuteInAppDomainCallback pCallback, void *cookie)
{
FIXME("(%p,%u,%p,%p)\n", iface, dwAppDomainId, pCallback, cookie);
return E_NOTIMPL;
}
static HRESULT WINAPI CLRRuntimeHost_GetCurrentAppDomainId(ICLRRuntimeHost* iface,
DWORD *pdwAppDomainId)
{
FIXME("(%p,%p)\n", iface, pdwAppDomainId);
return E_NOTIMPL;
}
static HRESULT WINAPI CLRRuntimeHost_ExecuteApplication(ICLRRuntimeHost* iface,
LPCWSTR pwzAppFullName, DWORD dwManifestPaths, LPCWSTR *ppwzManifestPaths,
DWORD dwActivationData, LPCWSTR *ppwzActivationData, int *pReturnValue)
{
FIXME("(%p,%s,%u,%u)\n", iface, debugstr_w(pwzAppFullName), dwManifestPaths, dwActivationData);
return E_NOTIMPL;
}
static HRESULT WINAPI CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost* iface,
LPCWSTR pwzAssemblyPath, LPCWSTR pwzTypeName, LPCWSTR pwzMethodName,
LPCWSTR pwzArgument, DWORD *pReturnValue)
{
RuntimeHost *This = impl_from_ICLRRuntimeHost( iface );
HRESULT hr;
MonoDomain *domain;
MonoAssembly *assembly;
MonoImage *image;
MonoClass *klass;
MonoMethod *method;
MonoObject *result;
MonoString *str;
void *args[2];
char *filenameA = NULL, *classA = NULL, *methodA = NULL;
char *argsA = NULL, *ns;
TRACE("(%p,%s,%s,%s,%s)\n", iface, debugstr_w(pwzAssemblyPath),
debugstr_w(pwzTypeName), debugstr_w(pwzMethodName), debugstr_w(pwzArgument));
hr = RuntimeHost_GetDefaultDomain(This, &domain);
if(hr != S_OK)
{
ERR("Couldn't get Default Domain\n");
return hr;
}
hr = E_FAIL;
filenameA = WtoA(pwzAssemblyPath);
assembly = This->mono->mono_domain_assembly_open(domain, filenameA);
if (!assembly)
{
ERR("Cannot open assembly %s\n", filenameA);
goto cleanup;
}
image = This->mono->mono_assembly_get_image(assembly);
if (!image)
{
ERR("Couldn't get assembly image\n");
goto cleanup;
}
classA = WtoA(pwzTypeName);
ns = strrchr(classA, '.');
*ns = '\0';
klass = This->mono->mono_class_from_name(image, classA, ns+1);
if (!klass)
{
ERR("Couldn't get class from image\n");
goto cleanup;
}
methodA = WtoA(pwzMethodName);
method = This->mono->mono_class_get_method_from_name(klass, methodA, 1);
if (!method)
{
ERR("Couldn't get method from class\n");
goto cleanup;
}
/* The .NET function we are calling has the following declaration
* public static int functionName(String param)
*/
argsA = WtoA(pwzArgument);
str = This->mono->mono_string_new(domain, argsA);
args[0] = str;
args[1] = NULL;
result = This->mono->mono_runtime_invoke(method, NULL, args, NULL);
if (!result)
ERR("Couldn't get result pointer\n");
else
{
*pReturnValue = *(DWORD*)This->mono->mono_object_unbox(result);
hr = S_OK;
}
cleanup:
if(filenameA)
HeapFree(GetProcessHeap(), 0, filenameA);
if(classA)
HeapFree(GetProcessHeap(), 0, classA);
if(argsA)
HeapFree(GetProcessHeap(), 0, argsA);
if(methodA)
HeapFree(GetProcessHeap(), 0, methodA);
return hr;
}
static const struct ICLRRuntimeHostVtbl CLRHostVtbl =
{
CLRRuntimeHost_QueryInterface,
CLRRuntimeHost_AddRef,
CLRRuntimeHost_Release,
CLRRuntimeHost_Start,
CLRRuntimeHost_Stop,
CLRRuntimeHost_SetHostControl,
CLRRuntimeHost_GetCLRControl,
CLRRuntimeHost_UnloadAppDomain,
CLRRuntimeHost_ExecuteInAppDomain,
CLRRuntimeHost_GetCurrentAppDomainId,
CLRRuntimeHost_ExecuteApplication,
CLRRuntimeHost_ExecuteInDefaultAppDomain
};
/* Create an instance of a type given its name, by calling its constructor with
* no arguments. Note that result MUST be in the stack, or the garbage
* collector may free it prematurely. */
HRESULT RuntimeHost_CreateManagedInstance(RuntimeHost *This, LPCWSTR name,
MonoDomain *domain, MonoObject **result)
{
HRESULT hr=S_OK;
char *nameA=NULL;
MonoType *type;
MonoClass *klass;
MonoObject *obj;
if (!domain)
hr = RuntimeHost_GetDefaultDomain(This, &domain);
if (SUCCEEDED(hr))
{
nameA = WtoA(name);
if (!nameA)
hr = E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
{
type = This->mono->mono_reflection_type_from_name(nameA, NULL);
if (!type)
{
ERR("Cannot find type %s\n", debugstr_w(name));
hr = E_FAIL;
}
}
if (SUCCEEDED(hr))
{
klass = This->mono->mono_class_from_mono_type(type);
if (!klass)
{
ERR("Cannot convert type %s to a class\n", debugstr_w(name));
hr = E_FAIL;
}
}
if (SUCCEEDED(hr))
{
obj = This->mono->mono_object_new(domain, klass);
if (!obj)
{
ERR("Cannot allocate object of type %s\n", debugstr_w(name));
hr = E_FAIL;
}
}
if (SUCCEEDED(hr))
{
/* FIXME: Detect exceptions from the constructor? */
This->mono->mono_runtime_object_init(obj);
*result = obj;
}
HeapFree(GetProcessHeap(), 0, nameA);
return hr;
}
/* Get an IUnknown pointer for a Mono object.
*
* This is just a "light" wrapper around
* System.Runtime.InteropServices.Marshal:GetIUnknownForObject
*
* NOTE: The IUnknown* is created with a reference to the object.
* Until they have a reference, objects must be in the stack to prevent the
* garbage collector from freeing them. */
HRESULT RuntimeHost_GetIUnknownForObject(RuntimeHost *This, MonoObject *obj,
IUnknown **ppUnk)
{
MonoDomain *domain;
MonoAssembly *assembly;
MonoImage *image;
MonoClass *klass;
MonoMethod *method;
MonoObject *result;
void *args[2];
domain = This->mono->mono_object_get_domain(obj);
assembly = This->mono->mono_domain_assembly_open(domain, "mscorlib");
if (!assembly)
{
ERR("Cannot load mscorlib\n");
return E_FAIL;
}
image = This->mono->mono_assembly_get_image(assembly);
if (!image)
{
ERR("Couldn't get assembly image\n");
return E_FAIL;
}
klass = This->mono->mono_class_from_name(image, "System.Runtime.InteropServices", "Marshal");
if (!klass)
{
ERR("Couldn't get class from image\n");
return E_FAIL;
}
method = This->mono->mono_class_get_method_from_name(klass, "GetIUnknownForObject", 1);
if (!method)
{
ERR("Couldn't get method from class\n");
return E_FAIL;
}
args[0] = obj;
args[1] = NULL;
result = This->mono->mono_runtime_invoke(method, NULL, args, NULL);
if (!result)
{
ERR("Couldn't get result pointer\n");
return E_FAIL;
}
*ppUnk = *(IUnknown**)This->mono->mono_object_unbox(result);
if (!*ppUnk)
{
ERR("GetIUnknownForObject returned 0\n");
return E_FAIL;
}
return S_OK;
}
static void get_utf8_args(int *argc, char ***argv)
{
WCHAR **argvw;
int size=0, i;
char *current_arg;
argvw = CommandLineToArgvW(GetCommandLineW(), argc);
for (i=0; i<*argc; i++)
{
size += sizeof(char*);
size += WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, NULL, 0, NULL, NULL);
}
size += sizeof(char*);
*argv = HeapAlloc(GetProcessHeap(), 0, size);
current_arg = (char*)(*argv + *argc + 1);
for (i=0; i<*argc; i++)
{
(*argv)[i] = current_arg;
current_arg += WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, current_arg, size, NULL, NULL);
}
(*argv)[*argc] = NULL;
HeapFree(GetProcessHeap(), 0, argvw);
}
__int32 WINAPI _CorExeMain(void)
{
int exit_code;
int argc;
char **argv;
MonoDomain *domain;
MonoAssembly *assembly;
WCHAR filename[MAX_PATH];
char *filenameA;
ICLRRuntimeInfo *info;
RuntimeHost *host;
HRESULT hr;
int i;
get_utf8_args(&argc, &argv);
GetModuleFileNameW(NULL, filename, MAX_PATH);
TRACE("%s", debugstr_w(filename));
for (i=0; i<argc; i++)
TRACE(" %s", debugstr_a(argv[i]));
TRACE("\n");
filenameA = WtoA(filename);
if (!filenameA)
return -1;
hr = get_runtime_info(filename, NULL, NULL, 0, 0, FALSE, &info);
if (SUCCEEDED(hr))
{
hr = ICLRRuntimeInfo_GetRuntimeHost(info, &host);
if (SUCCEEDED(hr))
hr = RuntimeHost_GetDefaultDomain(host, &domain);
if (SUCCEEDED(hr))
{
assembly = host->mono->mono_domain_assembly_open(domain, filenameA);
exit_code = host->mono->mono_jit_exec(domain, assembly, argc, argv);
RuntimeHost_DeleteDomain(host, domain);
}
else
exit_code = -1;
ICLRRuntimeInfo_Release(info);
}
else
exit_code = -1;
HeapFree(GetProcessHeap(), 0, argv);
unload_all_runtimes();
return exit_code;
}
HRESULT RuntimeHost_Construct(const CLRRuntimeInfo *runtime_version,
loaded_mono *loaded_mono, RuntimeHost** result)
{
RuntimeHost *This;
This = HeapAlloc( GetProcessHeap(), 0, sizeof *This ); This = HeapAlloc( GetProcessHeap(), 0, sizeof *This );
if ( !This ) if ( !This )
return NULL; return E_OUTOFMEMORY;
This->ICorRuntimeHost_iface.lpVtbl = &corruntimehost_vtbl;
This->ICLRRuntimeHost_iface.lpVtbl = &CLRHostVtbl;
This->lpVtbl = &corruntimehost_vtbl;
This->ref = 1; This->ref = 1;
This->version = runtime_version;
This->mono = loaded_mono;
list_init(&This->domains);
This->default_domain = NULL;
InitializeCriticalSection(&This->lock);
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": RuntimeHost.lock");
FIXME("return iface %p\n", This); *result = This;
return (IUnknown*) &This->lpVtbl; return S_OK;
}
HRESULT RuntimeHost_GetInterface(RuntimeHost *This, REFCLSID clsid, REFIID riid, void **ppv)
{
IUnknown *unk;
HRESULT hr;
if (IsEqualGUID(clsid, &CLSID_CorRuntimeHost))
{
unk = (IUnknown*)&This->ICorRuntimeHost_iface;
IUnknown_AddRef(unk);
}
else if (IsEqualGUID(clsid, &CLSID_CLRRuntimeHost))
{
unk = (IUnknown*)&This->ICLRRuntimeHost_iface;
IUnknown_AddRef(unk);
}
else if (IsEqualGUID(clsid, &CLSID_CorMetaDataDispenser) ||
IsEqualGUID(clsid, &CLSID_CorMetaDataDispenserRuntime))
{
hr = MetaDataDispenser_CreateInstance(&unk);
if (FAILED(hr))
return hr;
}
else if (IsEqualGUID(clsid, &CLSID_CLRDebuggingLegacy))
{
hr = CorDebug_Create(&This->ICLRRuntimeHost_iface, &unk);
if (FAILED(hr))
return hr;
}
else
unk = NULL;
if (unk)
{
hr = IUnknown_QueryInterface(unk, riid, ppv);
IUnknown_Release(unk);
return hr;
}
else
FIXME("not implemented for class %s\n", debugstr_guid(clsid));
return CLASS_E_CLASSNOTAVAILABLE;
}
HRESULT RuntimeHost_Destroy(RuntimeHost *This)
{
struct DomainEntry *cursor, *cursor2;
This->lock.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->lock);
LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->domains, struct DomainEntry, entry)
{
list_remove(&cursor->entry);
HeapFree(GetProcessHeap(), 0, cursor);
}
HeapFree( GetProcessHeap(), 0, This );
return S_OK;
} }

View file

@ -0,0 +1,205 @@
/*
* IMetaDataDispenserEx - dynamic creation/editing of assemblies
*
* Copyright 2010 Vincent Povirk for CodeWeavers
*
* 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
*/
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#define COBJMACROS
#include "wine/library.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "ole2.h"
#include "cor.h"
#include "mscoree.h"
#include "corhdr.h"
#include "cordebug.h"
#include "metahost.h"
#include "wine/list.h"
#include "mscoree_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL( mscoree );
typedef struct MetaDataDispenser
{
IMetaDataDispenserEx IMetaDataDispenserEx_iface;
LONG ref;
} MetaDataDispenser;
static inline MetaDataDispenser *impl_from_IMetaDataDispenserEx(IMetaDataDispenserEx *iface)
{
return CONTAINING_RECORD(iface, MetaDataDispenser, IMetaDataDispenserEx_iface);
}
static HRESULT WINAPI MetaDataDispenser_QueryInterface(IMetaDataDispenserEx* iface,
REFIID riid, void **ppvObject)
{
TRACE("%p %s %p\n", iface, debugstr_guid(riid), ppvObject);
if (IsEqualGUID(riid, &IID_IMetaDataDispenserEx) ||
IsEqualGUID(riid, &IID_IMetaDataDispenser) ||
IsEqualGUID(riid, &IID_IUnknown))
{
*ppvObject = iface;
}
else
{
FIXME("Unsupported interface %s\n", debugstr_guid(riid));
return E_NOINTERFACE;
}
IMetaDataDispenserEx_AddRef( iface );
return S_OK;
}
static ULONG WINAPI MetaDataDispenser_AddRef(IMetaDataDispenserEx* iface)
{
MetaDataDispenser *This = impl_from_IMetaDataDispenserEx(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("%p ref=%u\n", This, ref);
return ref;
}
static ULONG WINAPI MetaDataDispenser_Release(IMetaDataDispenserEx* iface)
{
MetaDataDispenser *This = impl_from_IMetaDataDispenserEx(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("%p ref=%u\n", This, ref);
if (ref == 0)
{
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI MetaDataDispenser_DefineScope(IMetaDataDispenserEx* iface,
REFCLSID rclsid, DWORD dwCreateFlags, REFIID riid, IUnknown **ppIUnk)
{
FIXME("%p %s %x %s %p\n", iface, debugstr_guid(rclsid), dwCreateFlags,
debugstr_guid(riid), ppIUnk);
return E_NOTIMPL;
}
static HRESULT WINAPI MetaDataDispenser_OpenScope(IMetaDataDispenserEx* iface,
LPCWSTR szScope, DWORD dwOpenFlags, REFIID riid, IUnknown **ppIUnk)
{
FIXME("%p %s %x %s %p\n", iface, debugstr_w(szScope), dwOpenFlags,
debugstr_guid(riid), ppIUnk);
return E_NOTIMPL;
}
static HRESULT WINAPI MetaDataDispenser_OpenScopeOnMemory(IMetaDataDispenserEx* iface,
const void *pData, ULONG cbData, DWORD dwOpenFlags, REFIID riid, IUnknown **ppIUnk)
{
FIXME("%p %p %u %x %s %p\n", iface, pData, cbData, dwOpenFlags,
debugstr_guid(riid), ppIUnk);
return E_NOTIMPL;
}
static HRESULT WINAPI MetaDataDispenser_SetOption(IMetaDataDispenserEx* iface,
REFGUID optionid, const VARIANT *value)
{
FIXME("%p %s\n", iface, debugstr_guid(optionid));
return E_NOTIMPL;
}
static HRESULT WINAPI MetaDataDispenser_GetOption(IMetaDataDispenserEx* iface,
REFGUID optionid, VARIANT *pvalue)
{
FIXME("%p %s\n", iface, debugstr_guid(optionid));
return E_NOTIMPL;
}
static HRESULT WINAPI MetaDataDispenser_OpenScopeOnITypeInfo(IMetaDataDispenserEx* iface,
ITypeInfo *pITI, DWORD dwOpenFlags, REFIID riid, IUnknown **ppIUnk)
{
FIXME("%p %p %u %s %p\n", iface, pITI, dwOpenFlags, debugstr_guid(riid), ppIUnk);
return E_NOTIMPL;
}
static HRESULT WINAPI MetaDataDispenser_GetCORSystemDirectory(IMetaDataDispenserEx* iface,
LPWSTR szBuffer, DWORD cchBuffer, DWORD *pchBuffer)
{
FIXME("%p %p %u %p\n", iface, szBuffer, cchBuffer, pchBuffer);
return E_NOTIMPL;
}
static HRESULT WINAPI MetaDataDispenser_FindAssembly(IMetaDataDispenserEx* iface,
LPCWSTR szAppBase, LPCWSTR szPrivateBin, LPCWSTR szGlobalBin, LPCWSTR szAssemblyName,
LPWSTR szName, ULONG cchName, ULONG *pcName)
{
FIXME("%p %s %s %s %s %p %u %p\n", iface, debugstr_w(szAppBase),
debugstr_w(szPrivateBin), debugstr_w(szGlobalBin),
debugstr_w(szAssemblyName), szName, cchName, pcName);
return E_NOTIMPL;
}
static HRESULT WINAPI MetaDataDispenser_FindAssemblyModule(IMetaDataDispenserEx* iface,
LPCWSTR szAppBase, LPCWSTR szPrivateBin, LPCWSTR szGlobalBin, LPCWSTR szAssemblyName,
LPCWSTR szModuleName, LPWSTR szName, ULONG cchName, ULONG *pcName)
{
FIXME("%p %s %s %s %s %s %p %u %p\n", iface, debugstr_w(szAppBase),
debugstr_w(szPrivateBin), debugstr_w(szGlobalBin), debugstr_w(szAssemblyName),
debugstr_w(szModuleName), szName, cchName, pcName);
return E_NOTIMPL;
}
static const struct IMetaDataDispenserExVtbl MetaDataDispenserVtbl =
{
MetaDataDispenser_QueryInterface,
MetaDataDispenser_AddRef,
MetaDataDispenser_Release,
MetaDataDispenser_DefineScope,
MetaDataDispenser_OpenScope,
MetaDataDispenser_OpenScopeOnMemory,
MetaDataDispenser_SetOption,
MetaDataDispenser_GetOption,
MetaDataDispenser_OpenScopeOnITypeInfo,
MetaDataDispenser_GetCORSystemDirectory,
MetaDataDispenser_FindAssembly,
MetaDataDispenser_FindAssemblyModule
};
HRESULT MetaDataDispenser_CreateInstance(IUnknown **ppUnk)
{
MetaDataDispenser *This;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(MetaDataDispenser));
if (!This)
return E_OUTOFMEMORY;
This->IMetaDataDispenserEx_iface.lpVtbl = &MetaDataDispenserVtbl;
This->ref = 1;
*ppUnk = (IUnknown*)This;
return S_OK;
}

File diff suppressed because it is too large Load diff

View file

@ -4,9 +4,18 @@
<include base="ReactOS">include/reactos/wine</include> <include base="ReactOS">include/reactos/wine</include>
<define name="__WINESRC__" /> <define name="__WINESRC__" />
<library>wine</library> <library>wine</library>
<library>dbghelp</library>
<library>advapi32</library> <library>advapi32</library>
<library>shell32</library> <library>shell32</library>
<library>ole32</library>
<library>shlwapi</library>
<library>uuid</library> <library>uuid</library>
<file>assembly.c</file>
<file>config.c</file>
<file>cordebug.c</file>
<file>corruntimehost.c</file> <file>corruntimehost.c</file>
<file>metadata.c</file>
<file>metahost.c</file>
<file>mscoree_main.c</file> <file>mscoree_main.c</file>
<file>mscoree.rc</file>
</module> </module>

View file

@ -0,0 +1 @@
1 WINE_REGISTRY mscoree.rgs

View file

@ -0,0 +1,84 @@
HKCR
{
NoRemove Interface
{
}
NoRemove CLSID
{
'{90F1A06E-7712-4762-86B5-7A5EBA6BDB01}' = s 'Microsoft Common Language Runtime Host V2'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
ProgId = s 'CLRMetaData.CLRRuntimeHost.1'
VersionIndependentProgId = s 'CLRMetaData.CLRRuntimeHost'
}
'{90F1A06E-7712-4762-86B5-7A5EBA6BDB02}' = s 'Microsoft Common Language Runtime Host V2'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
ProgId = s 'CLRMetaData.CLRRuntimeHost.2'
VersionIndependentProgId = s 'CLRMetaData.CLRRuntimeHost'
}
'{E5CB7A31-7512-11D2-89CE-0080C792E5D8}' = s 'Microsoft Common Language Runtime Meta Data'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
ProgId = s 'CLRMetaData.CorMetaDataDispenser.2'
VersionIndependentProgId = s 'CLRMetaData.CorMetaDataDispenser'
}
'{1EC2DE53-75CC-11D2-9775-00A0C9B4D50C}' = s 'Microsoft Common Language Runtime Meta Data'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
ProgId = s 'CLRMetaData.CorMetaDataDispenserRuntime.2'
VersionIndependentProgId = s 'CLRMetaData.CorMetaDataDispenserRuntime'
}
'{CB2F6723-AB3A-11D2-9C40-00C04FA30A3E}' = s 'Microsoft Common Language Runtime Host'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
ProgId = s 'CLRMetaData.CorRuntimeHost.2'
VersionIndependentProgId = s 'CLRMetaData.CorRuntimeHost'
}
}
'CLRMetaData.CLRRuntimeHost.1' = s 'Microsoft Common Language Runtime Host V2'
{
CLSID = s '{90F1A06E-7712-4762-86B5-7A5EBA6BDB01}'
}
'CLRMetaData.CLRRuntimeHost' = s 'Microsoft Common Language Runtime Host V2'
{
CLSID = s '{90F1A06E-7712-4762-86B5-7A5EBA6BDB01}'
CurVer = s 'CLRMetaData.CLRRuntimeHost.1'
}
'CLRMetaData.CLRRuntimeHost.2' = s 'Microsoft Common Language Runtime Host V2'
{
CLSID = s '{90F1A06E-7712-4762-86B5-7A5EBA6BDB02}'
}
'CLRMetaData.CLRRuntimeHost' = s 'Microsoft Common Language Runtime Host V2'
{
CLSID = s '{90F1A06E-7712-4762-86B5-7A5EBA6BDB02}'
CurVer = s 'CLRMetaData.CLRRuntimeHost.2'
}
'CLRMetaData.CorMetaDataDispenser.2' = s 'Microsoft Common Language Runtime Meta Data'
{
CLSID = s '{E5CB7A31-7512-11D2-89CE-0080C792E5D8}'
}
'CLRMetaData.CorMetaDataDispenser' = s 'Microsoft Common Language Runtime Meta Data'
{
CLSID = s '{E5CB7A31-7512-11D2-89CE-0080C792E5D8}'
CurVer = s 'CLRMetaData.CorMetaDataDispenser.2'
}
'CLRMetaData.CorMetaDataDispenserRuntime.2' = s 'Microsoft Common Language Runtime Meta Data'
{
CLSID = s '{1EC2DE53-75CC-11D2-9775-00A0C9B4D50C}'
}
'CLRMetaData.CorMetaDataDispenserRuntime' = s 'Microsoft Common Language Runtime Meta Data'
{
CLSID = s '{1EC2DE53-75CC-11D2-9775-00A0C9B4D50C}'
CurVer = s 'CLRMetaData.CorMetaDataDispenserRuntime.2'
}
'CLRMetaData.CorRuntimeHost.2' = s 'Microsoft Common Language Runtime Host'
{
CLSID = s '{CB2F6723-AB3A-11D2-9C40-00C04FA30A3E}'
}
'CLRMetaData.CorRuntimeHost' = s 'Microsoft Common Language Runtime Host'
{
CLSID = s '{CB2F6723-AB3A-11D2-9C40-00C04FA30A3E}'
CurVer = s 'CLRMetaData.CorRuntimeHost.2'
}
}

View file

@ -7,6 +7,7 @@
@ stub CallFunctionShim @ stub CallFunctionShim
@ stub CloseCtrs @ stub CloseCtrs
@ stdcall CLRCreateInstance(ptr ptr ptr)
@ stdcall ClrCreateManagedInstance(wstr ptr ptr) @ stdcall ClrCreateManagedInstance(wstr ptr ptr)
@ stub CoEEShutDownCOM @ stub CoEEShutDownCOM
@ stdcall CoInitializeCor(long) @ stdcall CoInitializeCor(long)
@ -27,8 +28,8 @@
@ stub CorIsLatestSvc @ stub CorIsLatestSvc
@ stub CorMarkThreadInThreadPool @ stub CorMarkThreadInThreadPool
@ stub CorTickleSvc @ stub CorTickleSvc
@ stub CreateConfigStream @ stdcall CreateConfigStream(wstr ptr)
@ stub CreateDebuggingInterfaceFromVersion @ stdcall CreateDebuggingInterfaceFromVersion(long wstr ptr)
@ stdcall -private DllCanUnloadNow() @ stdcall -private DllCanUnloadNow()
@ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllGetClassObject(ptr ptr ptr)
@ stdcall -private DllRegisterServer() @ stdcall -private DllRegisterServer()
@ -42,7 +43,7 @@
@ stdcall GetCORSystemDirectory(ptr long ptr) @ stdcall GetCORSystemDirectory(ptr long ptr)
@ stdcall GetCORVersion(ptr long ptr) @ stdcall GetCORVersion(ptr long ptr)
@ stub GetCompileInfo @ stub GetCompileInfo
@ stub GetFileVersion @ stdcall GetFileVersion(wstr ptr long ptr)
@ stub GetHashFromAssemblyFile @ stub GetHashFromAssemblyFile
@ stub GetHashFromAssemblyFileW @ stub GetHashFromAssemblyFileW
@ stub GetHashFromBlob @ stub GetHashFromBlob
@ -56,9 +57,9 @@
@ stub GetPermissionRequests @ stub GetPermissionRequests
@ stub GetPrivateContextsPerfCounters @ stub GetPrivateContextsPerfCounters
@ stub GetProcessExecutableHeap @ stub GetProcessExecutableHeap
@ stub GetRealProcAddress @ stdcall GetRealProcAddress(str ptr)
@ stdcall GetRequestedRuntimeInfo(wstr wstr wstr long long ptr long ptr ptr long ptr) @ stdcall GetRequestedRuntimeInfo(wstr wstr wstr long long ptr long ptr ptr long ptr)
@ stub GetRequestedRuntimeVersion @ stdcall GetRequestedRuntimeVersion(wstr ptr long ptr)
@ stub GetRequestedRuntimeVersionForCLSID @ stub GetRequestedRuntimeVersionForCLSID
@ stub GetStartupFlags @ stub GetStartupFlags
@ stub GetTargetForVTableEntry @ stub GetTargetForVTableEntry

View file

@ -21,55 +21,65 @@
#include <stdarg.h> #include <stdarg.h>
#define COBJMACROS
#include "wine/unicode.h" #include "wine/unicode.h"
#include "wine/library.h"
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "winuser.h" #include "winuser.h"
#include "winnls.h" #include "winnls.h"
#include "winreg.h" #include "winreg.h"
#include "ole2.h" #include "ole2.h"
#include "ocidl.h"
#include "shellapi.h" #include "shellapi.h"
#include "initguid.h" #include "initguid.h"
#include "msxml2.h"
#include "corerror.h"
#include "cor.h" #include "cor.h"
#include "mscoree.h" #include "mscoree.h"
#include "corhdr.h"
#include "cordebug.h"
#include "metahost.h"
#include "fusion.h"
#include "wine/list.h"
#include "mscoree_private.h" #include "mscoree_private.h"
#include "rpcproxy.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL( mscoree ); WINE_DEFAULT_DEBUG_CHANNEL( mscoree );
static BOOL get_mono_path(LPWSTR path) static HINSTANCE MSCOREE_hInstance;
{
static const WCHAR mono_key[] = {'S','o','f','t','w','a','r','e','\\','N','o','v','e','l','l','\\','M','o','n','o',0}; char *WtoA(LPCWSTR wstr)
static const WCHAR defaul_clr[] = {'D','e','f','a','u','l','t','C','L','R',0}; {
static const WCHAR install_root[] = {'S','d','k','I','n','s','t','a','l','l','R','o','o','t',0}; int length;
static const WCHAR slash[] = {'\\',0}; char *result;
length = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
result = HeapAlloc(GetProcessHeap(), 0, length);
if (result)
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, result, length, NULL, NULL);
return result;
}
static BOOL get_install_root(LPWSTR install_dir)
{
const WCHAR dotnet_key[] = {'S','O','F','T','W','A','R','E','\\','M','i','c','r','o','s','o','f','t','\\','.','N','E','T','F','r','a','m','e','w','o','r','k','\\',0};
const WCHAR install_root[] = {'I','n','s','t','a','l','l','R','o','o','t',0};
WCHAR version[64], version_key[MAX_PATH];
DWORD len; DWORD len;
HKEY key; HKEY key;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, mono_key, 0, KEY_READ, &key)) if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, dotnet_key, 0, KEY_READ, &key))
return FALSE; return FALSE;
len = sizeof(version); len = MAX_PATH;
if (RegQueryValueExW(key, defaul_clr, 0, NULL, (LPBYTE)version, &len)) if (RegQueryValueExW(key, install_root, 0, NULL, (LPBYTE)install_dir, &len))
{
RegCloseKey(key);
return FALSE;
}
RegCloseKey(key);
lstrcpyW(version_key, mono_key);
lstrcatW(version_key, slash);
lstrcatW(version_key, version);
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, version_key, 0, KEY_READ, &key))
return FALSE;
len = sizeof(WCHAR) * MAX_PATH;
if (RegQueryValueExW(key, install_root, 0, NULL, (LPBYTE)path, &len))
{ {
RegCloseKey(key); RegCloseKey(key);
return FALSE; return FALSE;
@ -79,140 +89,38 @@ static BOOL get_mono_path(LPWSTR path)
return TRUE; return TRUE;
} }
static CRITICAL_SECTION mono_lib_cs;
static CRITICAL_SECTION_DEBUG mono_lib_cs_debug =
{
0, 0, &mono_lib_cs,
{ &mono_lib_cs_debug.ProcessLocksList,
&mono_lib_cs_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": mono_lib_cs") }
};
static CRITICAL_SECTION mono_lib_cs = { &mono_lib_cs_debug, -1, 0, 0, 0, 0 };
HMODULE mono_handle;
void (*mono_config_parse)(const char *filename);
MonoAssembly* (*mono_domain_assembly_open) (MonoDomain *domain, const char *name);
void (*mono_jit_cleanup)(MonoDomain *domain);
int (*mono_jit_exec)(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]);
MonoDomain* (*mono_jit_init)(const char *file);
int (*mono_jit_set_trace_options)(const char* options);
void (*mono_set_dirs)(const char *assembly_dir, const char *config_dir);
static void set_environment(LPCWSTR bin_path)
{
WCHAR path_env[MAX_PATH];
int len;
static const WCHAR pathW[] = {'P','A','T','H',0};
/* We have to modify PATH as Mono loads other DLLs from this directory. */
GetEnvironmentVariableW(pathW, path_env, sizeof(path_env)/sizeof(WCHAR));
len = strlenW(path_env);
path_env[len++] = ';';
strcpyW(path_env+len, bin_path);
SetEnvironmentVariableW(pathW, path_env);
}
static HMODULE load_mono(void)
{
static const WCHAR mono_dll[] = {'\\','b','i','n','\\','m','o','n','o','.','d','l','l',0};
static const WCHAR libmono_dll[] = {'\\','b','i','n','\\','l','i','b','m','o','n','o','.','d','l','l',0};
static const WCHAR bin[] = {'\\','b','i','n',0};
static const WCHAR lib[] = {'\\','l','i','b',0};
static const WCHAR etc[] = {'\\','e','t','c',0};
HMODULE result;
WCHAR mono_path[MAX_PATH], mono_dll_path[MAX_PATH+16], mono_bin_path[MAX_PATH+4];
WCHAR mono_lib_path[MAX_PATH+4], mono_etc_path[MAX_PATH+4];
char mono_lib_path_a[MAX_PATH], mono_etc_path_a[MAX_PATH];
EnterCriticalSection(&mono_lib_cs);
if (!mono_handle)
{
if (!get_mono_path(mono_path)) goto end;
strcpyW(mono_bin_path, mono_path);
strcatW(mono_bin_path, bin);
set_environment(mono_bin_path);
strcpyW(mono_lib_path, mono_path);
strcatW(mono_lib_path, lib);
WideCharToMultiByte(CP_UTF8, 0, mono_lib_path, -1, mono_lib_path_a, MAX_PATH, NULL, NULL);
strcpyW(mono_etc_path, mono_path);
strcatW(mono_etc_path, etc);
WideCharToMultiByte(CP_UTF8, 0, mono_etc_path, -1, mono_etc_path_a, MAX_PATH, NULL, NULL);
strcpyW(mono_dll_path, mono_path);
strcatW(mono_dll_path, mono_dll);
mono_handle = LoadLibraryW(mono_dll_path);
if (!mono_handle)
{
strcpyW(mono_dll_path, mono_path);
strcatW(mono_dll_path, libmono_dll);
mono_handle = LoadLibraryW(mono_dll_path);
}
if (!mono_handle) goto end;
#define LOAD_MONO_FUNCTION(x) do { \
x = (void*)GetProcAddress(mono_handle, #x); \
if (!x) { \
mono_handle = NULL; \
goto end; \
} \
} while (0);
LOAD_MONO_FUNCTION(mono_config_parse);
LOAD_MONO_FUNCTION(mono_domain_assembly_open);
LOAD_MONO_FUNCTION(mono_jit_cleanup);
LOAD_MONO_FUNCTION(mono_jit_exec);
LOAD_MONO_FUNCTION(mono_jit_init);
LOAD_MONO_FUNCTION(mono_jit_set_trace_options);
LOAD_MONO_FUNCTION(mono_set_dirs);
#undef LOAD_MONO_FUNCTION
mono_set_dirs(mono_lib_path_a, mono_etc_path_a);
mono_config_parse(NULL);
}
end:
result = mono_handle;
LeaveCriticalSection(&mono_lib_cs);
if (!result)
MESSAGE("wine: Install the Windows version of Mono to run .NET executables\n");
return result;
}
HRESULT WINAPI CorBindToRuntimeHost(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, HRESULT WINAPI CorBindToRuntimeHost(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor,
LPCWSTR pwszHostConfigFile, VOID *pReserved, LPCWSTR pwszHostConfigFile, VOID *pReserved,
DWORD startupFlags, REFCLSID rclsid, DWORD startupFlags, REFCLSID rclsid,
REFIID riid, LPVOID *ppv) REFIID riid, LPVOID *ppv)
{ {
FIXME("(%s, %s, %s, %p, %d, %s, %s, %p): semi-stub!\n", debugstr_w(pwszVersion), HRESULT ret;
ICLRRuntimeInfo *info;
TRACE("(%s, %s, %s, %p, %d, %s, %s, %p)\n", debugstr_w(pwszVersion),
debugstr_w(pwszBuildFlavor), debugstr_w(pwszHostConfigFile), pReserved, debugstr_w(pwszBuildFlavor), debugstr_w(pwszHostConfigFile), pReserved,
startupFlags, debugstr_guid(rclsid), debugstr_guid(riid), ppv); startupFlags, debugstr_guid(rclsid), debugstr_guid(riid), ppv);
if (!get_mono_path(NULL)) *ppv = NULL;
ret = get_runtime_info(NULL, pwszVersion, pwszHostConfigFile, startupFlags, 0, TRUE, &info);
if (SUCCEEDED(ret))
{ {
MESSAGE("wine: Install the Windows version of Mono to run .NET executables\n"); ret = ICLRRuntimeInfo_GetInterface(info, rclsid, riid, ppv);
return E_FAIL;
ICLRRuntimeInfo_Release(info);
} }
return S_OK; return ret;
} }
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{ {
TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
MSCOREE_hInstance = hinstDLL;
switch (fdwReason) switch (fdwReason)
{ {
case DLL_WINE_PREATTACH: case DLL_WINE_PREATTACH:
@ -221,6 +129,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
DisableThreadLibraryCalls(hinstDLL); DisableThreadLibraryCalls(hinstDLL);
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
expect_no_runtimes();
break; break;
} }
return TRUE; return TRUE;
@ -241,75 +150,6 @@ BOOL WINAPI _CorDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
return TRUE; return TRUE;
} }
static void get_utf8_args(int *argc, char ***argv)
{
WCHAR **argvw;
int size=0, i;
char *current_arg;
argvw = CommandLineToArgvW(GetCommandLineW(), argc);
for (i=0; i<*argc; i++)
{
size += sizeof(char*);
size += WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, NULL, 0, NULL, NULL);
}
size += sizeof(char*);
*argv = HeapAlloc(GetProcessHeap(), 0, size);
current_arg = (char*)(*argv + *argc + 1);
for (i=0; i<*argc; i++)
{
(*argv)[i] = current_arg;
current_arg += WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, current_arg, size, NULL, NULL);
}
(*argv)[*argc] = NULL;
HeapFree(GetProcessHeap(), 0, argvw);
}
__int32 WINAPI _CorExeMain(void)
{
int exit_code;
int trace_size;
char trace_setting[256];
int argc;
char **argv;
MonoDomain *domain;
MonoAssembly *assembly;
char filename[MAX_PATH];
if (!load_mono())
{
return -1;
}
get_utf8_args(&argc, &argv);
trace_size = GetEnvironmentVariableA("WINE_MONO_TRACE", trace_setting, sizeof(trace_setting));
if (trace_size)
{
mono_jit_set_trace_options(trace_setting);
}
GetModuleFileNameA(NULL, filename, MAX_PATH);
domain = mono_jit_init(filename);
assembly = mono_domain_assembly_open(domain, filename);
exit_code = mono_jit_exec(domain, assembly, argc, argv);
mono_jit_cleanup(domain);
HeapFree(GetProcessHeap(), 0, argv);
return exit_code;
}
__int32 WINAPI _CorExeMain2(PBYTE ptrMemory, DWORD cntMemory, LPWSTR imageName, LPWSTR loaderName, LPWSTR cmdLine) __int32 WINAPI _CorExeMain2(PBYTE ptrMemory, DWORD cntMemory, LPWSTR imageName, LPWSTR loaderName, LPWSTR cmdLine)
{ {
TRACE("(%p, %u, %s, %s, %s)\n", ptrMemory, cntMemory, debugstr_w(imageName), debugstr_w(loaderName), debugstr_w(cmdLine)); TRACE("(%p, %u, %s, %s, %s)\n", ptrMemory, cntMemory, debugstr_w(imageName), debugstr_w(loaderName), debugstr_w(cmdLine));
@ -319,7 +159,8 @@ __int32 WINAPI _CorExeMain2(PBYTE ptrMemory, DWORD cntMemory, LPWSTR imageName,
void WINAPI CorExitProcess(int exitCode) void WINAPI CorExitProcess(int exitCode)
{ {
FIXME("(%x) stub\n", exitCode); TRACE("(%x)\n", exitCode);
unload_all_runtimes();
ExitProcess(exitCode); ExitProcess(exitCode);
} }
@ -336,52 +177,150 @@ HRESULT WINAPI _CorValidateImage(PVOID* imageBase, LPCWSTR imageName)
HRESULT WINAPI GetCORSystemDirectory(LPWSTR pbuffer, DWORD cchBuffer, DWORD *dwLength) HRESULT WINAPI GetCORSystemDirectory(LPWSTR pbuffer, DWORD cchBuffer, DWORD *dwLength)
{ {
FIXME("(%p, %d, %p): stub!\n", pbuffer, cchBuffer, dwLength); ICLRRuntimeInfo *info;
HRESULT ret;
if (!dwLength) TRACE("(%p, %d, %p)!\n", pbuffer, cchBuffer, dwLength);
if (!dwLength || !pbuffer)
return E_POINTER; return E_POINTER;
*dwLength = 0; ret = get_runtime_info(NULL, NULL, NULL, 0, RUNTIME_INFO_UPGRADE_VERSION, TRUE, &info);
return S_OK; if (SUCCEEDED(ret))
{
*dwLength = cchBuffer;
ret = ICLRRuntimeInfo_GetRuntimeDirectory(info, pbuffer, dwLength);
ICLRRuntimeInfo_Release(info);
}
return ret;
} }
HRESULT WINAPI GetCORVersion(LPWSTR pbuffer, DWORD cchBuffer, DWORD *dwLength) HRESULT WINAPI GetCORVersion(LPWSTR pbuffer, DWORD cchBuffer, DWORD *dwLength)
{ {
static const WCHAR version[] = {'v','1','.','1','.','4','3','2','2',0}; ICLRRuntimeInfo *info;
HRESULT ret;
FIXME("(%p, %d, %p): semi-stub!\n", pbuffer, cchBuffer, dwLength); TRACE("(%p, %d, %p)!\n", pbuffer, cchBuffer, dwLength);
if (!dwLength) if (!dwLength || !pbuffer)
return E_POINTER; return E_POINTER;
*dwLength = lstrlenW(version); ret = get_runtime_info(NULL, NULL, NULL, 0, RUNTIME_INFO_UPGRADE_VERSION, TRUE, &info);
if (cchBuffer < *dwLength) if (SUCCEEDED(ret))
return ERROR_INSUFFICIENT_BUFFER; {
*dwLength = cchBuffer;
ret = ICLRRuntimeInfo_GetVersionString(info, pbuffer, dwLength);
if (pbuffer) ICLRRuntimeInfo_Release(info);
lstrcpyW(pbuffer, version); }
return S_OK; return ret;
} }
HRESULT WINAPI GetRequestedRuntimeInfo(LPCWSTR pExe, LPCWSTR pwszVersion, LPCWSTR pConfigurationFile, HRESULT WINAPI GetRequestedRuntimeInfo(LPCWSTR pExe, LPCWSTR pwszVersion, LPCWSTR pConfigurationFile,
DWORD startupFlags, DWORD runtimeInfoFlags, LPWSTR pDirectory, DWORD dwDirectory, DWORD *dwDirectoryLength, DWORD startupFlags, DWORD runtimeInfoFlags, LPWSTR pDirectory, DWORD dwDirectory, DWORD *dwDirectoryLength,
LPWSTR pVersion, DWORD cchBuffer, DWORD *dwlength) LPWSTR pVersion, DWORD cchBuffer, DWORD *dwlength)
{ {
FIXME("(%s, %s, %s, 0x%08x, 0x%08x, %p, 0x%08x, %p, %p, 0x%08x, %p) stub\n", debugstr_w(pExe), HRESULT ret;
ICLRRuntimeInfo *info;
DWORD length_dummy;
TRACE("(%s, %s, %s, 0x%08x, 0x%08x, %p, 0x%08x, %p, %p, 0x%08x, %p)\n", debugstr_w(pExe),
debugstr_w(pwszVersion), debugstr_w(pConfigurationFile), startupFlags, runtimeInfoFlags, pDirectory, debugstr_w(pwszVersion), debugstr_w(pConfigurationFile), startupFlags, runtimeInfoFlags, pDirectory,
dwDirectory, dwDirectoryLength, pVersion, cchBuffer, dwlength); dwDirectory, dwDirectoryLength, pVersion, cchBuffer, dwlength);
return GetCORVersion(pVersion, cchBuffer, dwlength);
if (!dwDirectoryLength) dwDirectoryLength = &length_dummy;
if (!dwlength) dwlength = &length_dummy;
ret = get_runtime_info(pExe, pwszVersion, pConfigurationFile, startupFlags, runtimeInfoFlags, TRUE, &info);
if (SUCCEEDED(ret))
{
*dwlength = cchBuffer;
ret = ICLRRuntimeInfo_GetVersionString(info, pVersion, dwlength);
if (SUCCEEDED(ret))
{
*dwDirectoryLength = dwDirectory;
ret = ICLRRuntimeInfo_GetRuntimeDirectory(info, pDirectory, dwDirectoryLength);
}
ICLRRuntimeInfo_Release(info);
}
return ret;
}
HRESULT WINAPI GetRequestedRuntimeVersion(LPWSTR pExe, LPWSTR pVersion, DWORD cchBuffer, DWORD *dwlength)
{
TRACE("(%s, %p, %d, %p)\n", debugstr_w(pExe), debugstr_w(pExe), cchBuffer, dwlength);
if(!dwlength)
return E_POINTER;
return GetRequestedRuntimeInfo(pExe, NULL, NULL, 0, 0, NULL, 0, NULL, pVersion, cchBuffer, dwlength);
}
HRESULT WINAPI GetRealProcAddress(LPCSTR procname, void **ppv)
{
FIXME("(%s, %p)\n", debugstr_a(procname), ppv);
return CLR_E_SHIM_RUNTIMEEXPORT;
}
HRESULT WINAPI GetFileVersion(LPCWSTR szFilename, LPWSTR szBuffer, DWORD cchBuffer, DWORD *dwLength)
{
TRACE("(%s, %p, %d, %p)\n", debugstr_w(szFilename), szBuffer, cchBuffer, dwLength);
if (!szFilename || !dwLength)
return E_POINTER;
*dwLength = cchBuffer;
return CLRMetaHost_GetVersionFromFile(0, szFilename, szBuffer, dwLength);
} }
HRESULT WINAPI LoadLibraryShim( LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE * phModDll) HRESULT WINAPI LoadLibraryShim( LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE * phModDll)
{ {
FIXME("(%p %s, %p, %p, %p): semi-stub\n", szDllName, debugstr_w(szDllName), szVersion, pvReserved, phModDll); HRESULT ret=S_OK;
WCHAR dll_filename[MAX_PATH];
WCHAR version[MAX_PATH];
static const WCHAR default_version[] = {'v','1','.','1','.','4','3','2','2',0};
static const WCHAR slash[] = {'\\',0};
DWORD dummy;
if (phModDll) *phModDll = LoadLibraryW(szDllName); TRACE("(%p %s, %p, %p, %p)\n", szDllName, debugstr_w(szDllName), szVersion, pvReserved, phModDll);
return S_OK;
if (!szDllName || !phModDll)
return E_POINTER;
if (!get_install_root(dll_filename))
{
ERR("error reading registry key for installroot\n");
dll_filename[0] = 0;
}
else
{
if (!szVersion)
{
ret = GetCORVersion(version, MAX_PATH, &dummy);
if (SUCCEEDED(ret))
szVersion = version;
else
szVersion = default_version;
}
strcatW(dll_filename, szVersion);
strcatW(dll_filename, slash);
}
strcatW(dll_filename, szDllName);
*phModDll = LoadLibraryW(dll_filename);
return *phModDll ? S_OK : E_HANDLE;
} }
HRESULT WINAPI LockClrVersion(FLockClrVersionCallback hostCallback, FLockClrVersionCallback *pBeginHostSetup, FLockClrVersionCallback *pEndHostSetup) HRESULT WINAPI LockClrVersion(FLockClrVersionCallback hostCallback, FLockClrVersionCallback *pBeginHostSetup, FLockClrVersionCallback *pEndHostSetup)
@ -433,16 +372,24 @@ HRESULT WINAPI LoadStringRC(UINT resId, LPWSTR pBuffer, int iBufLen, int bQuiet)
HRESULT WINAPI CorBindToRuntimeEx(LPWSTR szVersion, LPWSTR szBuildFlavor, DWORD nflags, REFCLSID rslsid, HRESULT WINAPI CorBindToRuntimeEx(LPWSTR szVersion, LPWSTR szBuildFlavor, DWORD nflags, REFCLSID rslsid,
REFIID riid, LPVOID *ppv) REFIID riid, LPVOID *ppv)
{ {
FIXME("%s %s %d %s %s %p\n", debugstr_w(szVersion), debugstr_w(szBuildFlavor), nflags, debugstr_guid( rslsid ), HRESULT ret;
ICLRRuntimeInfo *info;
TRACE("%s %s %d %s %s %p\n", debugstr_w(szVersion), debugstr_w(szBuildFlavor), nflags, debugstr_guid( rslsid ),
debugstr_guid( riid ), ppv); debugstr_guid( riid ), ppv);
if(IsEqualGUID( riid, &IID_ICorRuntimeHost ))
{
*ppv = create_corruntimehost();
return S_OK;
}
*ppv = NULL; *ppv = NULL;
return E_NOTIMPL;
ret = get_runtime_info(NULL, szVersion, NULL, nflags, RUNTIME_INFO_UPGRADE_VERSION, TRUE, &info);
if (SUCCEEDED(ret))
{
ret = ICLRRuntimeInfo_GetInterface(info, rslsid, riid, ppv);
ICLRRuntimeInfo_Release(info);
}
return ret;
} }
HRESULT WINAPI CorBindToCurrentRuntime(LPCWSTR filename, REFCLSID rclsid, REFIID riid, LPVOID *ppv) HRESULT WINAPI CorBindToCurrentRuntime(LPCWSTR filename, REFCLSID rclsid, REFIID riid, LPVOID *ppv)
@ -453,8 +400,37 @@ HRESULT WINAPI CorBindToCurrentRuntime(LPCWSTR filename, REFCLSID rclsid, REFIID
STDAPI ClrCreateManagedInstance(LPCWSTR pTypeName, REFIID riid, void **ppObject) STDAPI ClrCreateManagedInstance(LPCWSTR pTypeName, REFIID riid, void **ppObject)
{ {
FIXME("(%s,%s,%p)\n", debugstr_w(pTypeName), debugstr_guid(riid), ppObject); HRESULT ret;
return E_NOTIMPL; ICLRRuntimeInfo *info;
RuntimeHost *host;
MonoObject *obj;
IUnknown *unk;
TRACE("(%s,%s,%p)\n", debugstr_w(pTypeName), debugstr_guid(riid), ppObject);
/* FIXME: How to determine which runtime version to use? */
ret = get_runtime_info(NULL, NULL, NULL, 0, RUNTIME_INFO_UPGRADE_VERSION, TRUE, &info);
if (SUCCEEDED(ret))
{
ret = ICLRRuntimeInfo_GetRuntimeHost(info, &host);
ICLRRuntimeInfo_Release(info);
}
if (SUCCEEDED(ret))
ret = RuntimeHost_CreateManagedInstance(host, pTypeName, NULL, &obj);
if (SUCCEEDED(ret))
ret = RuntimeHost_GetIUnknownForObject(host, obj, &unk);
if (SUCCEEDED(ret))
{
ret = IUnknown_QueryInterface(unk, riid, ppObject);
IUnknown_Release(unk);
}
return ret;
} }
BOOL WINAPI StrongNameSignatureVerification(LPCWSTR filename, DWORD inFlags, DWORD* pOutFlags) BOOL WINAPI StrongNameSignatureVerification(LPCWSTR filename, DWORD inFlags, DWORD* pOutFlags)
@ -469,6 +445,63 @@ BOOL WINAPI StrongNameSignatureVerificationEx(LPCWSTR filename, BOOL forceVerifi
return FALSE; return FALSE;
} }
HRESULT WINAPI CreateConfigStream(LPCWSTR filename, IStream **stream)
{
FIXME("(%s, %p): stub\n", debugstr_w(filename), stream);
return E_NOTIMPL;
}
HRESULT WINAPI CreateDebuggingInterfaceFromVersion(int nDebugVersion, LPCWSTR version, IUnknown **ppv)
{
const WCHAR v2_0[] = {'v','2','.','0','.','5','0','7','2','7',0};
HRESULT hr = E_FAIL;
ICLRRuntimeInfo *runtimeinfo;
if(nDebugVersion < 1 || nDebugVersion > 4)
return E_INVALIDARG;
TRACE("(%d %s, %p): stub\n", nDebugVersion, debugstr_w(version), ppv);
if(!ppv)
return E_INVALIDARG;
*ppv = NULL;
if(strcmpW(version, v2_0) != 0)
{
FIXME("Currently .NET Version '%s' not support.\n", debugstr_w(version));
return E_INVALIDARG;
}
if(nDebugVersion != 3)
return E_INVALIDARG;
hr = CLRMetaHost_GetRuntime(0, version, &IID_ICLRRuntimeInfo, (void**)&runtimeinfo);
if(hr == S_OK)
{
hr = ICLRRuntimeInfo_GetInterface(runtimeinfo, &CLSID_CLRDebuggingLegacy, &IID_ICorDebug, (void**)ppv);
ICLRRuntimeInfo_Release(runtimeinfo);
}
if(!*ppv)
return E_FAIL;
return hr;
}
HRESULT WINAPI CLRCreateInstance(REFCLSID clsid, REFIID riid, LPVOID *ppInterface)
{
TRACE("(%s,%s,%p)\n", debugstr_guid(clsid), debugstr_guid(riid), ppInterface);
if (IsEqualGUID(clsid, &CLSID_CLRMetaHost))
return CLRMetaHost_CreateInstance(riid, ppInterface);
FIXME("not implemented for class %s\n", debugstr_guid(clsid));
return CLASS_E_CLASSNOTAVAILABLE;
}
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{ {
FIXME("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); FIXME("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
@ -480,19 +513,17 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
HRESULT WINAPI DllRegisterServer(void) HRESULT WINAPI DllRegisterServer(void)
{ {
FIXME("\n"); return __wine_register_resources( MSCOREE_hInstance );
return S_OK;
} }
HRESULT WINAPI DllUnregisterServer(void) HRESULT WINAPI DllUnregisterServer(void)
{ {
FIXME("\n"); return __wine_unregister_resources( MSCOREE_hInstance );
return S_OK;
} }
HRESULT WINAPI DllCanUnloadNow(VOID) HRESULT WINAPI DllCanUnloadNow(VOID)
{ {
return S_OK; return S_FALSE;
} }
INT WINAPI ND_RU1( const void *ptr, INT offset ) INT WINAPI ND_RU1( const void *ptr, INT offset )

View file

@ -20,20 +20,170 @@
#ifndef __MSCOREE_PRIVATE__ #ifndef __MSCOREE_PRIVATE__
#define __MSCOREE_PRIVATE__ #define __MSCOREE_PRIVATE__
extern IUnknown* create_corruntimehost(void); extern char *WtoA(LPCWSTR wstr) DECLSPEC_HIDDEN;
/* Mono 2.6 embedding */ extern HRESULT CLRMetaHost_CreateInstance(REFIID riid, void **ppobj) DECLSPEC_HIDDEN;
extern HRESULT WINAPI CLRMetaHost_GetVersionFromFile(ICLRMetaHost* iface,
LPCWSTR pwzFilePath, LPWSTR pwzBuffer, DWORD *pcchBuffer) DECLSPEC_HIDDEN;
typedef struct tagASSEMBLY ASSEMBLY;
HRESULT assembly_create(ASSEMBLY **out, LPCWSTR file) DECLSPEC_HIDDEN;
HRESULT assembly_release(ASSEMBLY *assembly) DECLSPEC_HIDDEN;
HRESULT assembly_get_runtime_version(ASSEMBLY *assembly, LPSTR *version) DECLSPEC_HIDDEN;
/* Mono embedding */
typedef struct _MonoDomain MonoDomain; typedef struct _MonoDomain MonoDomain;
typedef struct _MonoAssembly MonoAssembly; typedef struct _MonoAssembly MonoAssembly;
typedef struct _MonoAssemblyName MonoAssemblyName;
typedef struct _MonoType MonoType;
typedef struct _MonoImage MonoImage;
typedef struct _MonoClass MonoClass;
typedef struct _MonoObject MonoObject;
typedef struct _MonoString MonoString;
typedef struct _MonoMethod MonoMethod;
typedef struct _MonoProfiler MonoProfiler;
extern HMODULE mono_handle; typedef struct loaded_mono loaded_mono;
typedef struct RuntimeHost RuntimeHost;
extern void (*mono_config_parse)(const char *filename); typedef struct CLRRuntimeInfo
extern MonoAssembly* (*mono_domain_assembly_open) (MonoDomain *domain, const char *name); {
extern void (*mono_jit_cleanup)(MonoDomain *domain); ICLRRuntimeInfo ICLRRuntimeInfo_iface;
extern int (*mono_jit_exec)(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]); LPCWSTR mono_libdir;
extern MonoDomain* (*mono_jit_init)(const char *file); DWORD major;
extern int (*mono_jit_set_trace_options)(const char* options); DWORD minor;
extern void (*mono_set_dirs)(const char *assembly_dir, const char *config_dir); DWORD build;
int mono_abi_version;
WCHAR mono_path[MAX_PATH];
WCHAR mscorlib_path[MAX_PATH];
struct RuntimeHost *loaded_runtime;
} CLRRuntimeInfo;
struct RuntimeHost
{
ICorRuntimeHost ICorRuntimeHost_iface;
ICLRRuntimeHost ICLRRuntimeHost_iface;
const CLRRuntimeInfo *version;
loaded_mono *mono;
struct list domains;
MonoDomain *default_domain;
CRITICAL_SECTION lock;
LONG ref;
};
typedef struct CorProcess
{
struct list entry;
ICorDebugProcess *pProcess;
} CorProcess;
typedef struct CorDebug
{
ICorDebug ICorDebug_iface;
ICorDebugProcessEnum ICorDebugProcessEnum_iface;
LONG ref;
ICLRRuntimeHost *runtimehost;
/* ICorDebug Callback */
ICorDebugManagedCallback *pCallback;
ICorDebugManagedCallback2 *pCallback2;
/* Debug Processes */
struct list processes;
} CorDebug;
extern HRESULT get_runtime_info(LPCWSTR exefile, LPCWSTR version, LPCWSTR config_file,
DWORD startup_flags, DWORD runtimeinfo_flags, BOOL legacy, ICLRRuntimeInfo **result) DECLSPEC_HIDDEN;
extern HRESULT ICLRRuntimeInfo_GetRuntimeHost(ICLRRuntimeInfo *iface, RuntimeHost **result) DECLSPEC_HIDDEN;
extern HRESULT MetaDataDispenser_CreateInstance(IUnknown **ppUnk) DECLSPEC_HIDDEN;
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) DECLSPEC_HIDDEN;
extern void free_parsed_config_file(parsed_config_file *file) DECLSPEC_HIDDEN;
typedef enum {
MONO_IMAGE_OK,
MONO_IMAGE_ERROR_ERRNO,
MONO_IMAGE_MISSING_ASSEMBLYREF,
MONO_IMAGE_IMAGE_INVALID
} MonoImageOpenStatus;
typedef MonoAssembly* (*MonoAssemblyPreLoadFunc)(MonoAssemblyName *aname, char **assemblies_path, void *user_data);
typedef void (*MonoProfileFunc)(MonoProfiler *prof);
struct loaded_mono
{
HMODULE mono_handle;
HMODULE glib_handle;
BOOL is_started;
BOOL is_shutdown;
MonoImage* (CDECL *mono_assembly_get_image)(MonoAssembly *assembly);
MonoAssembly* (CDECL *mono_assembly_open)(const char *filename, MonoImageOpenStatus *status);
MonoClass* (CDECL *mono_class_from_mono_type)(MonoType *type);
MonoClass* (CDECL *mono_class_from_name)(MonoImage *image, const char* name_space, const char *name);
MonoMethod* (CDECL *mono_class_get_method_from_name)(MonoClass *klass, const char *name, int param_count);
void (CDECL *mono_config_parse)(const char *filename);
MonoAssembly* (CDECL *mono_domain_assembly_open) (MonoDomain *domain, const char *name);
void (CDECL *mono_free)(void *);
void (CDECL *mono_install_assembly_preload_hook)(MonoAssemblyPreLoadFunc func, void *user_data);
int (CDECL *mono_jit_exec)(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]);
MonoDomain* (CDECL *mono_jit_init)(const char *file);
int (CDECL *mono_jit_set_trace_options)(const char* options);
MonoDomain* (CDECL *mono_object_get_domain)(MonoObject *obj);
MonoObject* (CDECL *mono_object_new)(MonoDomain *domain, MonoClass *klass);
void* (CDECL *mono_object_unbox)(MonoObject *obj);
void (CDECL *mono_profiler_install)(MonoProfiler *prof, MonoProfileFunc shutdown_callback);
MonoType* (CDECL *mono_reflection_type_from_name)(char *name, MonoImage *image);
MonoObject* (CDECL *mono_runtime_invoke)(MonoMethod *method, void *obj, void **params, MonoObject **exc);
void (CDECL *mono_runtime_object_init)(MonoObject *this_obj);
void (CDECL *mono_runtime_quit)(void);
void (CDECL *mono_runtime_set_shutting_down)(void);
void (CDECL *mono_set_dirs)(const char *assembly_dir, const char *config_dir);
char* (CDECL *mono_stringify_assembly_name)(MonoAssemblyName *aname);
void (CDECL *mono_thread_pool_cleanup)(void);
void (CDECL *mono_thread_suspend_all_other_threads)(void);
void (CDECL *mono_threads_set_shutting_down)(void);
MonoString* (CDECL *mono_string_new)(MonoDomain *domain, const char *str);
};
/* loaded runtime interfaces */
extern void unload_all_runtimes(void) DECLSPEC_HIDDEN;
extern void expect_no_runtimes(void) DECLSPEC_HIDDEN;
extern HRESULT RuntimeHost_Construct(const CLRRuntimeInfo *runtime_version,
loaded_mono *loaded_mono, RuntimeHost** result) DECLSPEC_HIDDEN;
extern HRESULT RuntimeHost_GetInterface(RuntimeHost *This, REFCLSID clsid, REFIID riid, void **ppv) DECLSPEC_HIDDEN;
extern HRESULT RuntimeHost_GetIUnknownForObject(RuntimeHost *This, MonoObject *obj, IUnknown **ppUnk) DECLSPEC_HIDDEN;
extern HRESULT RuntimeHost_CreateManagedInstance(RuntimeHost *This, LPCWSTR name,
MonoDomain *domain, MonoObject **result) DECLSPEC_HIDDEN;
extern HRESULT RuntimeHost_Destroy(RuntimeHost *This) DECLSPEC_HIDDEN;
HRESULT WINAPI CLRMetaHost_GetRuntime(ICLRMetaHost* iface, LPCWSTR pwzVersion, REFIID iid, LPVOID *ppRuntime) DECLSPEC_HIDDEN;
extern HRESULT CorDebug_Create(ICLRRuntimeHost *runtimehost, IUnknown** ppUnk) DECLSPEC_HIDDEN;
#endif /* __MSCOREE_PRIVATE__ */ #endif /* __MSCOREE_PRIVATE__ */

View file

@ -176,7 +176,10 @@ list(APPEND IDL_SOURCES
if(MSVC) if(MSVC)
list(APPEND IDL_SOURCES list(APPEND IDL_SOURCES
atliface.idl) atliface.idl
cor.idl
cordebug.idl
metahost.idl)
else() else()
list(APPEND IDL_SOURCES list(APPEND IDL_SOURCES
wbemcli.idl wbemcli.idl

View file

@ -95,7 +95,7 @@ reactos/dll/win32/msacm32 # Autosync
reactos/dll/win32/msadp32.acm # Synced to Wine-1.3.37 reactos/dll/win32/msadp32.acm # Synced to Wine-1.3.37
reactos/dll/win32/mscat32 # Autosync reactos/dll/win32/mscat32 # Autosync
reactos/dll/win32/mscms # Synced to Wine-1.3.37 reactos/dll/win32/mscms # Synced to Wine-1.3.37
reactos/dll/win32/mscoree # Autosync reactos/dll/win32/mscoree # Synced to Wine-1.3.37
reactos/dll/win32/msctf # Synced to Wine-1.3.37 reactos/dll/win32/msctf # Synced to Wine-1.3.37
reactos/dll/win32/msftedit # Synced to Wine-1.3.37 reactos/dll/win32/msftedit # Synced to Wine-1.3.37
reactos/dll/win32/msg711.acm # Synced to Wine-1.3.37 reactos/dll/win32/msg711.acm # Synced to Wine-1.3.37