Author: akhaldi
Date: Mon Jun 4 10:46:54 2012
New Revision: 56692
URL:
http://svn.reactos.org/svn/reactos?rev=56692&view=rev
Log:
[MSCOREE]
* Sync to Wine 1.5.4.
Modified:
trunk/reactos/dll/win32/mscoree/CMakeLists.txt
trunk/reactos/dll/win32/mscoree/assembly.c
trunk/reactos/dll/win32/mscoree/config.c
trunk/reactos/dll/win32/mscoree/corruntimehost.c
trunk/reactos/dll/win32/mscoree/metahost.c
trunk/reactos/dll/win32/mscoree/mscoree.spec
trunk/reactos/dll/win32/mscoree/mscoree_main.c
trunk/reactos/dll/win32/mscoree/mscoree_private.h
trunk/reactos/media/doc/README.WINE
Modified: trunk/reactos/dll/win32/mscoree/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mscoree/CMakeLis…
==============================================================================
--- trunk/reactos/dll/win32/mscoree/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mscoree/CMakeLists.txt [iso-8859-1] Mon Jun 4 10:46:54 2012
@@ -2,7 +2,9 @@
add_definitions(-D__WINESRC__)
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
-set_rc_compiler()
+remove_definitions(-D_WIN32_WINNT=0x502)
+add_definitions(-D_WIN32_WINNT=0x600)
+
spec2def(mscoree.dll mscoree.spec)
list(APPEND SOURCE
Modified: trunk/reactos/dll/win32/mscoree/assembly.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mscoree/assembly…
==============================================================================
--- trunk/reactos/dll/win32/mscoree/assembly.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mscoree/assembly.c [iso-8859-1] Mon Jun 4 10:46:54 2012
@@ -63,10 +63,13 @@
struct tagASSEMBLY
{
+ int is_mapped_file;
+
+ /* mapped files */
LPWSTR path;
-
HANDLE hfile;
HANDLE hmap;
+
BYTE *data;
IMAGE_NT_HEADERS *nthdr;
@@ -87,6 +90,29 @@
lstrcpyW(dest, src);
return dest;
+}
+
+static void* assembly_rva_to_va(ASSEMBLY *assembly, ULONG rva)
+{
+ if (assembly->is_mapped_file)
+ return ImageRvaToVa(assembly->nthdr, assembly->data, rva, NULL);
+ else
+ return assembly->data + rva;
+}
+
+static ULONG assembly_datadir_get_data(ASSEMBLY *assembly,
+ IMAGE_DATA_DIRECTORY *datadir, void **data)
+{
+ if (!datadir->VirtualAddress || !datadir->Size)
+ {
+ *data = NULL;
+ return 0;
+ }
+ else
+ {
+ *data = assembly_rva_to_va(assembly, datadir->VirtualAddress);
+ return datadir->Size;
+ }
}
static HRESULT parse_metadata_header(ASSEMBLY *assembly, DWORD *hdrsz)
@@ -97,7 +123,7 @@
ULONG rva;
rva = assembly->corhdr->MetaData.VirtualAddress;
- ptr = ImageRvaToVa(assembly->nthdr, assembly->data, rva, NULL);
+ ptr = assembly_rva_to_va(assembly, rva);
if (!ptr)
return E_FAIL;
@@ -158,18 +184,22 @@
if (!datadirs)
return E_FAIL;
- if (!datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress ||
- !datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size)
- {
+ if (!assembly_datadir_get_data(assembly,
&datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR], (void**)&assembly->corhdr))
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;
+
+ return S_OK;
+}
+
+static HRESULT parse_headers(ASSEMBLY *assembly)
+{
+ HRESULT hr;
+
+ hr = parse_pe_header(assembly);
+
+ if (SUCCEEDED(hr))
+ hr = parse_clr_metadata(assembly);
+
+ return hr;
}
HRESULT assembly_create(ASSEMBLY **out, LPCWSTR file)
@@ -183,6 +213,8 @@
if (!assembly)
return E_OUTOFMEMORY;
+ assembly->is_mapped_file = 1;
+
assembly->path = strdupW(file);
if (!assembly->path)
{
@@ -213,10 +245,7 @@
goto failed;
}
- hr = parse_pe_header(assembly);
- if (FAILED(hr)) goto failed;
-
- hr = parse_clr_metadata(assembly);
+ hr = parse_headers(assembly);
if (FAILED(hr)) goto failed;
*out = assembly;
@@ -227,16 +256,43 @@
return hr;
}
+HRESULT assembly_from_hmodule(ASSEMBLY **out, HMODULE hmodule)
+{
+ ASSEMBLY *assembly;
+ HRESULT hr;
+
+ *out = NULL;
+
+ assembly = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ASSEMBLY));
+ if (!assembly)
+ return E_OUTOFMEMORY;
+
+ assembly->is_mapped_file = 0;
+
+ assembly->data = (BYTE*)hmodule;
+
+ hr = parse_headers(assembly);
+ if (SUCCEEDED(hr))
+ *out = assembly;
+ else
+ assembly_release(assembly);
+
+ return hr;
+}
+
HRESULT assembly_release(ASSEMBLY *assembly)
{
if (!assembly)
return S_OK;
+ if (assembly->is_mapped_file)
+ {
+ UnmapViewOfFile(assembly->data);
+ CloseHandle(assembly->hmap);
+ CloseHandle(assembly->hfile);
+ }
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;
@@ -248,3 +304,13 @@
return S_OK;
}
+
+HRESULT assembly_get_vtable_fixups(ASSEMBLY *assembly, VTableFixup **fixups, DWORD
*count)
+{
+ ULONG size;
+
+ size = assembly_datadir_get_data(assembly, &assembly->corhdr->VTableFixups,
(void**)fixups);
+ *count = size / sizeof(VTableFixup);
+
+ return S_OK;
+}
Modified: trunk/reactos/dll/win32/mscoree/config.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mscoree/config.c…
==============================================================================
--- trunk/reactos/dll/win32/mscoree/config.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mscoree/config.c [iso-8859-1] Mon Jun 4 10:46:54 2012
@@ -425,7 +425,7 @@
ISAXXMLReader_Release(reader);
}
- IUnknown_Release((IUnknown*)handler);
+ ISAXContentHandler_Release(&handler->ISAXContentHandler_iface);
return S_OK;
}
@@ -445,7 +445,7 @@
if (SUCCEEDED(hr))
{
- V_VT(&var) = VT_UNKNOWN|VT_DISPATCH;
+ V_VT(&var) = VT_UNKNOWN;
V_UNKNOWN(&var) = (IUnknown*)stream;
hr = parse_config(var, result);
Modified: trunk/reactos/dll/win32/mscoree/corruntimehost.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mscoree/corrunti…
==============================================================================
--- trunk/reactos/dll/win32/mscoree/corruntimehost.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mscoree/corruntimehost.c [iso-8859-1] Mon Jun 4 10:46:54
2012
@@ -19,6 +19,7 @@
#define COBJMACROS
+#include <assert.h>
#include <stdarg.h>
#include "windef.h"
@@ -38,6 +39,8 @@
#include "mscoree_private.h"
#include "wine/debug.h"
+#include "wine/unicode.h"
+#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL( mscoree );
@@ -49,6 +52,21 @@
{
struct list entry;
MonoDomain *domain;
+};
+
+static HANDLE dll_fixup_heap; /* using a separate heap so we can have execute permission
*/
+
+static struct list dll_fixups;
+
+struct dll_fixup
+{
+ struct list entry;
+ int done;
+ HMODULE dll;
+ void *thunk_code; /* pointer into dll_fixup_heap */
+ VTableFixup *fixup;
+ void *vtable;
+ void *tokens; /* pointer into process heap */
};
static HRESULT RuntimeHost_AddDomain(RuntimeHost *This, MonoDomain **result)
@@ -146,6 +164,8 @@
MonoMethod *method;
MonoObject *appdomain_object;
IUnknown *unk;
+
+ This->mono->mono_thread_attach(domain);
assembly = This->mono->mono_domain_assembly_open(domain,
"mscorlib");
if (!assembly)
@@ -559,6 +579,8 @@
hr = E_FAIL;
+ This->mono->mono_thread_attach(domain);
+
filenameA = WtoA(pwzAssemblyPath);
assembly = This->mono->mono_domain_assembly_open(domain, filenameA);
if (!assembly)
@@ -609,14 +631,10 @@
}
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);
+ HeapFree(GetProcessHeap(), 0, filenameA);
+ HeapFree(GetProcessHeap(), 0, classA);
+ HeapFree(GetProcessHeap(), 0, argsA);
+ HeapFree(GetProcessHeap(), 0, methodA);
return hr;
}
@@ -661,6 +679,8 @@
if (SUCCEEDED(hr))
{
+ This->mono->mono_thread_attach(domain);
+
type = This->mono->mono_reflection_type_from_name(nameA, NULL);
if (!type)
{
@@ -708,7 +728,9 @@
*
* 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. */
+ * garbage collector from freeing them.
+ *
+ * mono_thread_attach must have already been called for this thread. */
HRESULT RuntimeHost_GetIUnknownForObject(RuntimeHost *This, MonoObject *obj,
IUnknown **ppUnk)
{
@@ -798,13 +820,223 @@
HeapFree(GetProcessHeap(), 0, argvw);
}
+#if __i386__
+
+# define CAN_FIXUP_VTABLE 1
+
+#include "pshpack1.h"
+
+struct vtable_fixup_thunk
+{
+ /* sub $0x4,%esp */
+ BYTE i1[3];
+ /* mov fixup,(%esp) */
+ BYTE i2[3];
+ struct dll_fixup *fixup;
+ /* mov function,%eax */
+ BYTE i3;
+ void (CDECL *function)(struct dll_fixup *);
+ /* call *%eax */
+ BYTE i4[2];
+ /* pop %eax */
+ BYTE i5;
+ /* jmp *vtable_entry */
+ BYTE i6[2];
+ void *vtable_entry;
+};
+
+static const struct vtable_fixup_thunk thunk_template = {
+ {0x83,0xec,0x04},
+ {0xc7,0x04,0x24},
+ NULL,
+ 0xb8,
+ NULL,
+ {0xff,0xd0},
+ 0x58,
+ {0xff,0x25},
+ NULL
+};
+
+#include "poppack.h"
+
+#else /* !defined(__i386__) */
+
+# define CAN_FIXUP_VTABLE 0
+
+struct vtable_fixup_thunk
+{
+ struct dll_fixup *fixup;
+ void (CDECL *function)(struct dll_fixup *fixup);
+ void *vtable_entry;
+};
+
+static const struct vtable_fixup_thunk thunk_template = {0};
+
+#endif
+
+static void CDECL ReallyFixupVTable(struct dll_fixup *fixup)
+{
+ HRESULT hr=S_OK;
+ WCHAR filename[MAX_PATH];
+ ICLRRuntimeInfo *info=NULL;
+ RuntimeHost *host;
+ char *filenameA;
+ MonoImage *image=NULL;
+ MonoAssembly *assembly=NULL;
+ MonoImageOpenStatus status=0;
+ MonoDomain *domain;
+
+ if (fixup->done) return;
+
+ /* It's possible we'll have two threads doing this at once. This is
+ * considered preferable to the potential deadlock if we use a mutex. */
+
+ GetModuleFileNameW(fixup->dll, filename, MAX_PATH);
+
+ TRACE("%p,%p,%s\n", fixup, fixup->dll, debugstr_w(filename));
+
+ filenameA = WtoA(filename);
+ if (!filenameA)
+ hr = E_OUTOFMEMORY;
+
+ if (SUCCEEDED(hr))
+ 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))
+ {
+ host->mono->mono_thread_attach(domain);
+
+ image = host->mono->mono_image_open_from_module_handle(fixup->dll,
+ filenameA, 1, &status);
+ }
+
+ if (image)
+ assembly = host->mono->mono_assembly_load_from(image, filenameA,
&status);
+
+ if (assembly)
+ {
+ int i;
+
+ /* Mono needs an image that belongs to an assembly. */
+ image = host->mono->mono_assembly_get_image(assembly);
+
+ if (fixup->fixup->type & COR_VTABLE_32BIT)
+ {
+ DWORD *vtable = fixup->vtable;
+ DWORD *tokens = fixup->tokens;
+ for (i=0; i<fixup->fixup->count; i++)
+ {
+ TRACE("%x\n", tokens[i]);
+ vtable[i] = PtrToUint(host->mono->mono_marshal_get_vtfixup_ftnptr(
+ image, tokens[i], fixup->fixup->type));
+ }
+ }
+
+ fixup->done = 1;
+ }
+
+ if (info != NULL)
+ ICLRRuntimeHost_Release(info);
+
+ HeapFree(GetProcessHeap(), 0, filenameA);
+
+ if (!fixup->done)
+ {
+ ERR("unable to fixup vtable, hr=%x, status=%d\n", hr, status);
+ /* If we returned now, we'd get an infinite loop. */
+ assert(0);
+ }
+}
+
+static void FixupVTableEntry(HMODULE hmodule, VTableFixup *vtable_fixup)
+{
+ /* We can't actually generate code for the functions without loading mono,
+ * and loading mono inside DllMain is a terrible idea. So we make thunks
+ * that call ReallyFixupVTable, which will load the runtime and fill in the
+ * vtable, then do an indirect jump using the (now filled in) vtable. Note
+ * that we have to keep the thunks around forever, as one of them may get
+ * called while we're filling in the table, and we can never be sure all
+ * threads are clear. */
+ struct dll_fixup *fixup;
+
+ fixup = HeapAlloc(GetProcessHeap(), 0, sizeof(*fixup));
+
+ fixup->dll = hmodule;
+ fixup->thunk_code = HeapAlloc(dll_fixup_heap, 0, sizeof(struct vtable_fixup_thunk)
* vtable_fixup->count);
+ fixup->fixup = vtable_fixup;
+ fixup->vtable = (BYTE*)hmodule + vtable_fixup->rva;
+ fixup->done = 0;
+
+ if (vtable_fixup->type & COR_VTABLE_32BIT)
+ {
+ DWORD *vtable = fixup->vtable;
+ DWORD *tokens;
+ int i;
+ struct vtable_fixup_thunk *thunks = fixup->thunk_code;
+
+ if (sizeof(void*) > 4)
+ ERR("32-bit fixup in 64-bit mode; broken image?\n");
+
+ tokens = fixup->tokens = HeapAlloc(GetProcessHeap(), 0, sizeof(*tokens) *
vtable_fixup->count);
+ memcpy(tokens, vtable, sizeof(*tokens) * vtable_fixup->count);
+ for (i=0; i<vtable_fixup->count; i++)
+ {
+ memcpy(&thunks[i], &thunk_template, sizeof(thunk_template));
+ thunks[i].fixup = fixup;
+ thunks[i].function = ReallyFixupVTable;
+ thunks[i].vtable_entry = &vtable[i];
+ vtable[i] = PtrToUint(&thunks[i]);
+ }
+ }
+ else
+ {
+ ERR("unsupported vtable fixup flags %x\n", vtable_fixup->type);
+ HeapFree(dll_fixup_heap, 0, fixup->thunk_code);
+ HeapFree(GetProcessHeap(), 0, fixup);
+ return;
+ }
+
+ list_add_tail(&dll_fixups, &fixup->entry);
+}
+
+static void FixupVTable(HMODULE hmodule)
+{
+ ASSEMBLY *assembly;
+ HRESULT hr;
+ VTableFixup *vtable_fixups;
+ ULONG vtable_fixup_count, i;
+
+ hr = assembly_from_hmodule(&assembly, hmodule);
+ if (SUCCEEDED(hr))
+ {
+ hr = assembly_get_vtable_fixups(assembly, &vtable_fixups,
&vtable_fixup_count);
+ if (CAN_FIXUP_VTABLE)
+ for (i=0; i<vtable_fixup_count; i++)
+ FixupVTableEntry(hmodule, &vtable_fixups[i]);
+ else if (vtable_fixup_count)
+ FIXME("cannot fixup vtable; expect a crash\n");
+
+ assembly_release(assembly);
+ }
+ else
+ ERR("failed to read CLR headers, hr=%x\n", hr);
+}
+
__int32 WINAPI _CorExeMain(void)
{
int exit_code;
int argc;
char **argv;
MonoDomain *domain;
- MonoAssembly *assembly;
+ MonoImage *image;
+ MonoImageOpenStatus status;
+ MonoAssembly *assembly=NULL;
WCHAR filename[MAX_PATH];
char *filenameA;
ICLRRuntimeInfo *info;
@@ -825,6 +1057,8 @@
if (!filenameA)
return -1;
+ FixupVTable(GetModuleHandleW(NULL));
+
hr = get_runtime_info(filename, NULL, NULL, 0, 0, FALSE, &info);
if (SUCCEEDED(hr))
@@ -836,9 +1070,21 @@
if (SUCCEEDED(hr))
{
- assembly = host->mono->mono_domain_assembly_open(domain, filenameA);
-
- exit_code = host->mono->mono_jit_exec(domain, assembly, argc, argv);
+ image =
host->mono->mono_image_open_from_module_handle(GetModuleHandleW(NULL),
+ filenameA, 1, &status);
+
+ if (image)
+ assembly = host->mono->mono_assembly_load_from(image, filenameA,
&status);
+
+ if (assembly)
+ {
+ exit_code = host->mono->mono_jit_exec(domain, assembly, argc,
argv);
+ }
+ else
+ {
+ ERR("couldn't load %s, status=%d\n", debugstr_w(filename),
status);
+ exit_code = -1;
+ }
RuntimeHost_DeleteDomain(host, domain);
}
@@ -855,6 +1101,43 @@
unload_all_runtimes();
return exit_code;
+}
+
+BOOL WINAPI _CorDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
+
+ switch (fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hinstDLL);
+ FixupVTable(hinstDLL);
+ break;
+ case DLL_PROCESS_DETACH:
+ /* FIXME: clean up the vtables */
+ break;
+ }
+ return TRUE;
+}
+
+/* called from DLL_PROCESS_ATTACH */
+void runtimehost_init(void)
+{
+ dll_fixup_heap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
+ list_init(&dll_fixups);
+}
+
+/* called from DLL_PROCESS_DETACH */
+void runtimehost_uninit(void)
+{
+ struct dll_fixup *fixup, *fixup2;
+
+ HeapDestroy(dll_fixup_heap);
+ LIST_FOR_EACH_ENTRY_SAFE(fixup, fixup2, &dll_fixups, struct dll_fixup, entry)
+ {
+ HeapFree(GetProcessHeap(), 0, fixup->tokens);
+ HeapFree(GetProcessHeap(), 0, fixup);
+ }
}
HRESULT RuntimeHost_Construct(const CLRRuntimeInfo *runtime_version,
@@ -943,3 +1226,148 @@
HeapFree( GetProcessHeap(), 0, This );
return S_OK;
}
+
+#define CHARS_IN_GUID 39
+#define ARRAYSIZE(array) (sizeof(array)/sizeof((array)[0]))
+
+HRESULT create_monodata(REFIID riid, LPVOID *ppObj )
+{
+ static const WCHAR wszCodebase[] =
{'C','o','d','e','B','a','s','e',0};
+ static const WCHAR wszClass[] =
{'C','l','a','s','s',0};
+ static const WCHAR wszFileSlash[] =
{'f','i','l','e',':','/','/','/',0};
+ static const WCHAR wszCLSIDSlash[] =
{'C','L','S','I','D','\\',0};
+ static const WCHAR wszInprocServer32[] =
{'\\','I','n','p','r','o','c','S','e','r','v','e','r','3','2',0};
+ WCHAR path[CHARS_IN_GUID + ARRAYSIZE(wszCLSIDSlash) + ARRAYSIZE(wszInprocServer32) -
1];
+ MonoDomain *domain;
+ MonoAssembly *assembly;
+ ICLRRuntimeInfo *info;
+ RuntimeHost *host;
+ HRESULT hr;
+ HKEY key;
+ LONG res;
+ int offset = 0;
+ WCHAR codebase[MAX_PATH + 8];
+ WCHAR classname[350];
+ WCHAR filename[MAX_PATH];
+
+ DWORD dwBufLen = 350;
+
+ lstrcpyW(path, wszCLSIDSlash);
+ StringFromGUID2(riid, path + lstrlenW(wszCLSIDSlash), CHARS_IN_GUID);
+ lstrcatW(path, wszInprocServer32);
+
+ TRACE("Registry key: %s\n", debugstr_w(path));
+
+ res = RegOpenKeyExW(HKEY_CLASSES_ROOT, path, 0, KEY_READ, &key);
+ if (res == ERROR_FILE_NOT_FOUND)
+ return CLASS_E_CLASSNOTAVAILABLE;
+
+ res = RegGetValueW( key, NULL, wszClass, RRF_RT_REG_SZ, NULL, classname,
&dwBufLen);
+ if(res != ERROR_SUCCESS)
+ {
+ WARN("Class value cannot be found.\n");
+ hr = CLASS_E_CLASSNOTAVAILABLE;
+ goto cleanup;
+ }
+
+ TRACE("classname (%s)\n", debugstr_w(classname));
+
+ dwBufLen = MAX_PATH + 8;
+ res = RegGetValueW( key, NULL, wszCodebase, RRF_RT_REG_SZ, NULL, codebase,
&dwBufLen);
+ if(res != ERROR_SUCCESS)
+ {
+ WARN("CodeBase value cannot be found.\n");
+ hr = CLASS_E_CLASSNOTAVAILABLE;
+ goto cleanup;
+ }
+
+ /* Strip file:/// */
+ if(strncmpW(codebase, wszFileSlash, strlenW(wszFileSlash)) == 0)
+ offset = strlenW(wszFileSlash);
+
+ strcpyW(filename, codebase + offset);
+
+ TRACE("codebase (%s)\n", debugstr_w(filename));
+
+ *ppObj = NULL;
+
+
+ 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))
+ {
+ MonoImage *image;
+ MonoClass *klass;
+ MonoObject *result;
+ IUnknown *unk = NULL;
+ char *filenameA, *ns;
+ char *classA;
+
+ hr = CLASS_E_CLASSNOTAVAILABLE;
+
+ host->mono->mono_thread_attach(domain);
+
+ filenameA = WtoA(filename);
+ assembly = host->mono->mono_domain_assembly_open(domain, filenameA);
+ HeapFree(GetProcessHeap(), 0, filenameA);
+ if (!assembly)
+ {
+ ERR("Cannot open assembly %s\n", filenameA);
+ goto cleanup;
+ }
+
+ image = host->mono->mono_assembly_get_image(assembly);
+ if (!image)
+ {
+ ERR("Couldn't get assembly image\n");
+ goto cleanup;
+ }
+
+ classA = WtoA(classname);
+ ns = strrchr(classA, '.');
+ *ns = '\0';
+
+ klass = host->mono->mono_class_from_name(image, classA, ns+1);
+ HeapFree(GetProcessHeap(), 0, classA);
+ if (!klass)
+ {
+ ERR("Couldn't get class from image\n");
+ goto cleanup;
+ }
+
+ /*
+ * Use the default constructor for the .NET class.
+ */
+ result = host->mono->mono_object_new(domain, klass);
+ host->mono->mono_runtime_object_init(result);
+
+ hr = RuntimeHost_GetIUnknownForObject(host, result, &unk);
+ if (SUCCEEDED(hr))
+ {
+ hr = IUnknown_QueryInterface(unk, &IID_IUnknown, ppObj);
+
+ IUnknown_Release(unk);
+ }
+ else
+ hr = CLASS_E_CLASSNOTAVAILABLE;
+ }
+ else
+ hr = CLASS_E_CLASSNOTAVAILABLE;
+ }
+ else
+ hr = CLASS_E_CLASSNOTAVAILABLE;
+
+cleanup:
+ if(info)
+ ICLRRuntimeInfo_Release(info);
+
+ RegCloseKey(key);
+
+ return hr;
+}
Modified: trunk/reactos/dll/win32/mscoree/metahost.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mscoree/metahost…
==============================================================================
--- trunk/reactos/dll/win32/mscoree/metahost.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mscoree/metahost.c [iso-8859-1] Mon Jun 4 10:46:54 2012
@@ -165,16 +165,19 @@
} while (0);
LOAD_MONO_FUNCTION(mono_assembly_get_image);
+ LOAD_MONO_FUNCTION(mono_assembly_load_from);
LOAD_MONO_FUNCTION(mono_assembly_open);
LOAD_MONO_FUNCTION(mono_config_parse);
LOAD_MONO_FUNCTION(mono_class_from_mono_type);
LOAD_MONO_FUNCTION(mono_class_from_name);
LOAD_MONO_FUNCTION(mono_class_get_method_from_name);
LOAD_MONO_FUNCTION(mono_domain_assembly_open);
+ LOAD_MONO_FUNCTION(mono_image_open_from_module_handle);
LOAD_MONO_FUNCTION(mono_install_assembly_preload_hook);
LOAD_MONO_FUNCTION(mono_jit_exec);
LOAD_MONO_FUNCTION(mono_jit_init);
LOAD_MONO_FUNCTION(mono_jit_set_trace_options);
+ LOAD_MONO_FUNCTION(mono_marshal_get_vtfixup_ftnptr);
LOAD_MONO_FUNCTION(mono_object_get_domain);
LOAD_MONO_FUNCTION(mono_object_new);
LOAD_MONO_FUNCTION(mono_object_unbox);
@@ -186,6 +189,7 @@
LOAD_MONO_FUNCTION(mono_set_dirs);
LOAD_MONO_FUNCTION(mono_stringify_assembly_name);
LOAD_MONO_FUNCTION(mono_string_new);
+ LOAD_MONO_FUNCTION(mono_thread_attach);
/* GLib imports obsoleted by the 2.0 ABI */
if (This->mono_abi_version == 1)
@@ -564,6 +568,14 @@
return CLRRuntimeInfo_GetRuntimeHost(This, result);
}
+#ifdef __i386__
+static const WCHAR libmono2_arch_dll[] =
{'\\','b','i','n','\\','l','i','b','m','o','n','o','-','2','.','0','-','x','8','6','.','d','l','l',0};
+#elif defined(__x86_64__)
+static const WCHAR libmono2_arch_dll[] =
{'\\','b','i','n','\\','l','i','b','m','o','n','o','-','2','.','0','-','x','8','6','_','6','4','.','d','l','l',0};
+#else
+static const WCHAR libmono2_arch_dll[] =
{'\\','b','i','n','\\','l','i','b','m','o','n','o','-','2','.','0','.','d','l','l',0};
+#endif
+
static BOOL find_mono_dll(LPCWSTR path, LPWSTR dll_path, int abi_version)
{
static const WCHAR mono_dll[] =
{'\\','b','i','n','\\','m','o','n','o','.','d','l','l',0};
@@ -588,8 +600,15 @@
else if (abi_version == 2)
{
strcpyW(dll_path, path);
- strcatW(dll_path, mono2_dll);
+ strcatW(dll_path, libmono2_arch_dll);
attributes = GetFileAttributesW(dll_path);
+
+ if (attributes == INVALID_FILE_ATTRIBUTES)
+ {
+ strcpyW(dll_path, path);
+ strcatW(dll_path, mono2_dll);
+ attributes = GetFileAttributesW(dll_path);
+ }
if (attributes == INVALID_FILE_ATTRIBUTES)
{
@@ -973,7 +992,7 @@
*minor = 0;
*build = 0;
- if (version[0] == 'v')
+ if (version[0] == 'v' || version[0] == 'V')
{
version++;
if (!isdigit(*version))
@@ -1310,11 +1329,21 @@
if (version)
{
- return CLRMetaHost_GetRuntime(0, version, &IID_ICLRRuntimeInfo,
(void**)result);
+ hr = CLRMetaHost_GetRuntime(0, version, &IID_ICLRRuntimeInfo,
(void**)result);
+ if(SUCCEEDED(hr))
+ return hr;
}
if (runtimeinfo_flags & RUNTIME_INFO_UPGRADE_VERSION)
{
+ DWORD major, minor, build;
+
+ if (version && !parse_runtime_version(version, &major, &minor,
&build))
+ {
+ ERR("Cannot parse %s\n", debugstr_w(version));
+ return CLR_E_SHIM_RUNTIME;
+ }
+
find_runtimes();
if (legacy)
@@ -1325,8 +1354,16 @@
while (i--)
{
if (runtimes[i].mono_abi_version)
- return
ICLRRuntimeInfo_QueryInterface(&runtimes[i].ICLRRuntimeInfo_iface,
- &IID_ICLRRuntimeInfo, (void **)result);
+ {
+ /* Must be greater or equal to the version passed in. */
+ if (!version || ((runtimes[i].major >= major &&
runtimes[i].minor >= minor && runtimes[i].build >= build) ||
+ (runtimes[i].major >= major && runtimes[i].minor >
minor) ||
+ (runtimes[i].major > major)))
+ {
+ return
ICLRRuntimeInfo_QueryInterface(&runtimes[i].ICLRRuntimeInfo_iface,
+ &IID_ICLRRuntimeInfo, (void **)result);
+ }
+ }
}
if (legacy)
Modified: trunk/reactos/dll/win32/mscoree/mscoree.spec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mscoree/mscoree.…
==============================================================================
--- trunk/reactos/dll/win32/mscoree/mscoree.spec [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mscoree/mscoree.spec [iso-8859-1] Mon Jun 4 10:46:54 2012
@@ -9,7 +9,7 @@
@ stub CloseCtrs
@ stdcall CLRCreateInstance(ptr ptr ptr)
@ stdcall ClrCreateManagedInstance(wstr ptr ptr)
-@ stub CoEEShutDownCOM
+@ stdcall CoEEShutDownCOM()
@ stdcall CoInitializeCor(long)
@ stub CoInitializeEE
@ stub CoUninitializeCor
Modified: trunk/reactos/dll/win32/mscoree/mscoree_main.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mscoree/mscoree_…
==============================================================================
--- trunk/reactos/dll/win32/mscoree/mscoree_main.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mscoree/mscoree_main.c [iso-8859-1] Mon Jun 4 10:46:54 2012
@@ -52,6 +52,8 @@
static HINSTANCE MSCOREE_hInstance;
+typedef HRESULT (*fnCreateInstance)(REFIID riid, LPVOID *ppObj);
+
char *WtoA(LPCWSTR wstr)
{
int length;
@@ -88,6 +90,105 @@
return TRUE;
}
+
+typedef struct mscorecf
+{
+ IClassFactory IClassFactory_iface;
+ LONG ref;
+
+ fnCreateInstance pfnCreateInstance;
+
+ CLSID clsid;
+} mscorecf;
+
+static inline mscorecf *impl_from_IClassFactory( IClassFactory *iface )
+{
+ return CONTAINING_RECORD(iface, mscorecf, IClassFactory_iface);
+}
+
+static HRESULT WINAPI mscorecf_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID
*ppobj )
+{
+ TRACE("%s %p\n", debugstr_guid(riid), ppobj);
+
+ if (IsEqualGUID(riid, &IID_IUnknown) ||
+ IsEqualGUID(riid, &IID_IClassFactory))
+ {
+ IClassFactory_AddRef( iface );
+ *ppobj = iface;
+ return S_OK;
+ }
+
+ ERR("interface %s not implemented\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI mscorecf_AddRef(IClassFactory *iface )
+{
+ mscorecf *This = impl_from_IClassFactory(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
+
+ TRACE("%p ref=%u\n", This, ref);
+
+ return ref;
+}
+
+static ULONG WINAPI mscorecf_Release(IClassFactory *iface )
+{
+ mscorecf *This = impl_from_IClassFactory(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 mscorecf_CreateInstance(IClassFactory *iface,LPUNKNOWN pOuter,
+ REFIID riid, LPVOID *ppobj )
+{
+ mscorecf *This = impl_from_IClassFactory( iface );
+ HRESULT hr;
+ IUnknown *punk;
+
+ TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj );
+
+ *ppobj = NULL;
+
+ if (pOuter)
+ return CLASS_E_NOAGGREGATION;
+
+ hr = This->pfnCreateInstance( &This->clsid, (LPVOID*) &punk );
+ if (SUCCEEDED(hr))
+ {
+ hr = IUnknown_QueryInterface( punk, riid, ppobj );
+
+ IUnknown_Release( punk );
+ }
+ else
+ {
+ WARN("Cannot create an instance object. 0x%08x\n", hr);
+ }
+ return hr;
+}
+
+static HRESULT WINAPI mscorecf_LockServer(IClassFactory *iface, BOOL dolock)
+{
+ FIXME("(%p)->(%d),stub!\n",iface,dolock);
+ return S_OK;
+}
+
+static const struct IClassFactoryVtbl mscorecf_vtbl =
+{
+ mscorecf_QueryInterface,
+ mscorecf_AddRef,
+ mscorecf_Release,
+ mscorecf_CreateInstance,
+ mscorecf_LockServer
+};
HRESULT WINAPI CorBindToRuntimeHost(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor,
LPCWSTR pwszHostConfigFile, VOID *pReserved,
@@ -126,25 +227,13 @@
case DLL_WINE_PREATTACH:
return FALSE; /* prefer native version */
case DLL_PROCESS_ATTACH:
+ runtimehost_init();
DisableThreadLibraryCalls(hinstDLL);
break;
case DLL_PROCESS_DETACH:
expect_no_runtimes();
- break;
- }
- return TRUE;
-}
-
-BOOL WINAPI _CorDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
-{
- FIXME("(%p, %d, %p): stub\n", hinstDLL, fdwReason, lpvReserved);
-
- switch (fdwReason)
- {
- case DLL_PROCESS_ATTACH:
- DisableThreadLibraryCalls(hinstDLL);
- break;
- case DLL_PROCESS_DETACH:
+ if (lpvReserved) break; /* process is terminating */
+ runtimehost_uninit();
break;
}
return TRUE;
@@ -246,6 +335,9 @@
if (SUCCEEDED(ret))
{
+ if(pwszVersion)
+ pVersion[0] = pwszVersion[0];
+
*dwDirectoryLength = dwDirectory;
ret = ICLRRuntimeInfo_GetRuntimeDirectory(info, pDirectory,
dwDirectoryLength);
}
@@ -258,7 +350,7 @@
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);
+ TRACE("(%s, %p, %d, %p)\n", debugstr_w(pExe), pVersion, cchBuffer,
dwlength);
if(!dwlength)
return E_POINTER;
@@ -504,11 +596,25 @@
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
- FIXME("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(riid),
ppv);
+ mscorecf *This;
+ HRESULT hr;
+
+ TRACE("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(riid),
ppv);
+
if(!ppv)
return E_INVALIDARG;
- return E_NOTIMPL;
+ This = HeapAlloc(GetProcessHeap(), 0, sizeof(mscorecf));
+
+ This->IClassFactory_iface.lpVtbl = &mscorecf_vtbl;
+ This->pfnCreateInstance = &create_monodata;
+ This->ref = 1;
+ This->clsid = *rclsid;
+
+ hr = IClassFactory_QueryInterface( &This->IClassFactory_iface, riid, ppv );
+ IClassFactory_Release(&This->IClassFactory_iface);
+
+ return hr;
}
HRESULT WINAPI DllRegisterServer(void)
@@ -526,6 +632,11 @@
return S_FALSE;
}
+void WINAPI CoEEShutDownCOM(void)
+{
+ FIXME("stub.\n");
+}
+
INT WINAPI ND_RU1( const void *ptr, INT offset )
{
return *((const BYTE *)ptr + offset);
Modified: trunk/reactos/dll/win32/mscoree/mscoree_private.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mscoree/mscoree_…
==============================================================================
--- trunk/reactos/dll/win32/mscoree/mscoree_private.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mscoree/mscoree_private.h [iso-8859-1] Mon Jun 4 10:46:54
2012
@@ -27,11 +27,19 @@
extern HRESULT WINAPI CLRMetaHost_GetVersionFromFile(ICLRMetaHost* iface,
LPCWSTR pwzFilePath, LPWSTR pwzBuffer, DWORD *pcchBuffer) DECLSPEC_HIDDEN;
+typedef struct _VTableFixup {
+ DWORD rva;
+ WORD count;
+ WORD type;
+} VTableFixup;
+
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;
+extern HRESULT assembly_create(ASSEMBLY **out, LPCWSTR file) DECLSPEC_HIDDEN;
+extern HRESULT assembly_from_hmodule(ASSEMBLY **out, HMODULE hmodule) DECLSPEC_HIDDEN;
+extern HRESULT assembly_release(ASSEMBLY *assembly) DECLSPEC_HIDDEN;
+extern HRESULT assembly_get_runtime_version(ASSEMBLY *assembly, LPSTR *version)
DECLSPEC_HIDDEN;
+extern HRESULT assembly_get_vtable_fixups(ASSEMBLY *assembly, VTableFixup **fixups, DWORD
*count) DECLSPEC_HIDDEN;
/* Mono embedding */
typedef struct _MonoDomain MonoDomain;
@@ -44,6 +52,7 @@
typedef struct _MonoString MonoString;
typedef struct _MonoMethod MonoMethod;
typedef struct _MonoProfiler MonoProfiler;
+typedef struct _MonoThread MonoThread;
typedef struct loaded_mono loaded_mono;
typedef struct RuntimeHost RuntimeHost;
@@ -137,6 +146,7 @@
BOOL is_shutdown;
MonoImage* (CDECL *mono_assembly_get_image)(MonoAssembly *assembly);
+ MonoAssembly* (CDECL *mono_assembly_load_from)(MonoImage *image, const char *fname,
MonoImageOpenStatus *status);
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);
@@ -144,10 +154,12 @@
void (CDECL *mono_config_parse)(const char *filename);
MonoAssembly* (CDECL *mono_domain_assembly_open) (MonoDomain *domain, const char
*name);
void (CDECL *mono_free)(void *);
+ MonoImage* (CDECL *mono_image_open_from_module_handle)(HMODULE module_handle, char*
fname, UINT has_entry_point, MonoImageOpenStatus* status);
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);
+ void* (CDECL *mono_marshal_get_vtfixup_ftnptr)(MonoImage *image, DWORD token, WORD
type);
MonoDomain* (CDECL *mono_object_get_domain)(MonoObject *obj);
MonoObject* (CDECL *mono_object_new)(MonoDomain *domain, MonoClass *klass);
void* (CDECL *mono_object_unbox)(MonoObject *obj);
@@ -163,6 +175,7 @@
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);
+ MonoThread* (CDECL *mono_thread_attach)(MonoDomain *domain);
};
/* loaded runtime interfaces */
@@ -186,4 +199,9 @@
extern HRESULT CorDebug_Create(ICLRRuntimeHost *runtimehost, IUnknown** ppUnk)
DECLSPEC_HIDDEN;
+extern HRESULT create_monodata(REFIID riid, LPVOID *ppObj) DECLSPEC_HIDDEN;
+
+extern void runtimehost_init(void);
+extern void runtimehost_uninit(void);
+
#endif /* __MSCOREE_PRIVATE__ */
Modified: trunk/reactos/media/doc/README.WINE
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=…
==============================================================================
--- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original)
+++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Mon Jun 4 10:46:54 2012
@@ -95,7 +95,7 @@
reactos/dll/win32/msadp32.acm # Synced to Wine-1.3.37
reactos/dll/win32/mscat32 # Synced to Wine-1.3.37
reactos/dll/win32/mscms # Synced to Wine-1.5.4
-reactos/dll/win32/mscoree # Synced to Wine-1.3.37
+reactos/dll/win32/mscoree # Synced to Wine-1.5.4
reactos/dll/win32/msctf # 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