Build libmonoruntime under none desktop Windows API family.
authorlateralusX <lateralusx.github@gmail.com>
Thu, 13 Oct 2016 07:41:12 +0000 (09:41 +0200)
committerlateralusX <lateralusx.github@gmail.com>
Thu, 13 Oct 2016 07:41:12 +0000 (09:41 +0200)
Initial work to build libmonoruntime under none desktop Windows API families.

46 files changed:
mono/metadata/Makefile.am
mono/metadata/appdomain.c
mono/metadata/boehm-gc.c
mono/metadata/console-win32-internals.h [new file with mode: 0644]
mono/metadata/console-win32-uwp.c [new file with mode: 0644]
mono/metadata/console-win32.c
mono/metadata/coree-internals.h [new file with mode: 0644]
mono/metadata/coree-windows-uwp.c [new file with mode: 0644]
mono/metadata/coree.c
mono/metadata/domain.c
mono/metadata/file-io-internals.h [new file with mode: 0644]
mono/metadata/file-io-windows-internals.h [new file with mode: 0644]
mono/metadata/file-io-windows-uwp.c [new file with mode: 0644]
mono/metadata/file-io-windows.c [new file with mode: 0644]
mono/metadata/file-io.c
mono/metadata/icall-internals.h [new file with mode: 0644]
mono/metadata/icall-windows-internals.h [new file with mode: 0644]
mono/metadata/icall-windows-uwp.c [new file with mode: 0644]
mono/metadata/icall-windows.c [new file with mode: 0644]
mono/metadata/icall.c
mono/metadata/lock-tracer.c
mono/metadata/marshal-internals.h [new file with mode: 0644]
mono/metadata/marshal-windows-internals.h [new file with mode: 0644]
mono/metadata/marshal-windows-uwp.c [new file with mode: 0644]
mono/metadata/marshal-windows.c [new file with mode: 0644]
mono/metadata/marshal.c
mono/metadata/mono-security-windows-internals.h [new file with mode: 0644]
mono/metadata/mono-security-windows-uwp.c [new file with mode: 0644]
mono/metadata/mono-security-windows.c [new file with mode: 0644]
mono/metadata/mono-security.c
mono/metadata/null-gc.c
mono/metadata/process-internals.h [new file with mode: 0644]
mono/metadata/process-windows-internals.h [new file with mode: 0644]
mono/metadata/process-windows-uwp.c [new file with mode: 0644]
mono/metadata/process-windows.c [new file with mode: 0644]
mono/metadata/process.c
mono/metadata/remoting.c
mono/metadata/sgen-os-coop.c
mono/metadata/socket-io-windows-internals.h
mono/metadata/socket-io-windows.c
mono/metadata/socket-io.c
mono/metadata/w32semaphore-win32.c
msvc/libmonoruntime.vcxproj
msvc/libmonoruntime.vcxproj.filters
msvc/pedump.vcxproj
msvc/pedump.vcxproj.filters

index 49f7ea0f44b7f6e2172e01858a5981cbc894d3cc..c662c8c76f8ee4d9a4a14dc115279e5e7c77e5d4 100644 (file)
@@ -1,6 +1,17 @@
 if HOST_WIN32
 win32_sources = \
        console-win32.c \
+       console-win32-internals.h \
+       file-io-windows.c \
+       file-io-windows-internals.h \
+       icall-windows.c \
+       icall-windows-internals.h \
+       marshal-windows.c \
+       marshal-windows-internals.h \
+       mono-security-windows.c \
+       mono-security-windows-internals.h \
+       process-windows.c \
+       process-windows-internals.h \
        w32mutex-win32.c \
        w32semaphore-win32.c \
        w32event-win32.c \
@@ -121,6 +132,7 @@ common_sources = \
        console-io.h            \
        coree.c                 \
        coree.h                 \
+       coree-internals.h \
        culture-info.h          \
        culture-info-tables.h   \
        debug-helpers.c         \
@@ -138,10 +150,12 @@ common_sources = \
        exception-internals.h   \
        file-io.c               \
        file-io.h               \
+       file-io-internals.h \
        filewatcher.c           \
        filewatcher.h           \
        gc-internals.h          \
        icall.c                 \
+       icall-internals.h \
        icall-def.h             \
        image.c                 \
        image-internals.h       \
@@ -153,6 +167,7 @@ common_sources = \
        lock-tracer.h           \
        marshal.c               \
        marshal.h               \
+       marshal-internals.h \
        mempool.c               \
        mempool.h               \
        mempool-internals.h     \
@@ -190,6 +205,7 @@ common_sources = \
        socket-io.h             \
        process.c               \
        process.h               \
+       process-internals.h \
        profiler.c              \
        profiler-private.h      \
        rand.h                  \
index 17dc65aa8021ccde664fce4b1a0d9587570f1ceb..b4c20c8e22bd57c6fad22d3e588661b55df19a35 100644 (file)
@@ -1415,7 +1415,12 @@ shadow_copy_sibling (gchar *src, gint srclen, const char *extension, gchar *targ
        dest = g_utf8_to_utf16 (target, strlen (target), NULL, NULL, NULL);
        
        DeleteFile (dest);
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
        copy_result = CopyFile (orig, dest, FALSE);
+#else
+       copy_result = SUCCEEDED (CopyFile2 (orig, dest, NULL));
+#endif
 
        /* Fix for bug #556884 - make sure the files have the correct mode so that they can be
         * overwritten when updated in their original locations. */
@@ -1743,7 +1748,11 @@ mono_make_shadow_copy (const char *filename, MonoError *oerror)
                return (char *)filename;
        }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
        copy_result = CopyFile (orig, dest, FALSE);
+#else
+       copy_result = SUCCEEDED (CopyFile2 (orig, dest, NULL));
+#endif
 
        /* Fix for bug #556884 - make sure the files have the correct mode so that they can be
         * overwritten when updated in their original locations. */
index e48ba580c73f266155bb39888bdbcaac58651675..d3debe1cd03665f7ffe5df29c3a55de1bd885660 100644 (file)
@@ -1942,8 +1942,9 @@ mono_gchandle_free_domain (MonoDomain *domain)
 
 }
 #else
-       #ifdef _MSC_VER
-               // Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
-               void __mono_win32_boehm_gc_quiet_lnk4221(void) {}
-       #endif
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_boehm_gc_quiet_lnk4221(void) {}
+#endif
 #endif /* no Boehm GC */
diff --git a/mono/metadata/console-win32-internals.h b/mono/metadata/console-win32-internals.h
new file mode 100644 (file)
index 0000000..e0cd222
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_CONSOLE_WIN32_INTERNALS_H__
+#define __MONO_CONSOLE_WIN32_INTERNALS_H__
+
+#include <config.h>
+#include <glib.h>
+
+#include "mono/metadata/object.h"
+#include "mono/metadata/object-internals.h"
+#include "mono/utils/mono-error.h"
+#include "mono/utils/mono-error-internals.h"
+#include <mono/metadata/console-io.h>
+
+#endif /* __MONO_CONSOLE_WIN32_INTERNALS_H__ */
+
diff --git a/mono/metadata/console-win32-uwp.c b/mono/metadata/console-win32-uwp.c
new file mode 100644 (file)
index 0000000..56d4336
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * console-win32-uwp.c: UWP console support for Mono.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+*/
+#include <config.h>
+#include <glib.h>
+
+#if G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT)
+#include <Windows.h>
+#include "mono/metadata/console-win32-internals.h"
+
+MonoBoolean
+ves_icall_System_ConsoleDriver_Isatty (HANDLE handle)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("Console");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "Console");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+MonoBoolean
+ves_icall_System_ConsoleDriver_SetEcho (MonoBoolean want_echo)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("Console");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "Console");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+MonoBoolean
+ves_icall_System_ConsoleDriver_SetBreak (MonoBoolean want_break)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("Console");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "Console");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+gint32
+ves_icall_System_ConsoleDriver_InternalKeyAvailable (gint32 timeout)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("Console");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "Console");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+MonoBoolean
+ves_icall_System_ConsoleDriver_TtySetup (MonoString *keypad, MonoString *teardown, MonoArray **control_chars, int **size)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("Console");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "Console");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+#else /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_console_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
index c7c8c49017b6182ee292e7d2d9fc373621384b22..06a0244477e1afd5e3a0ba40d4fddcd4c8e56ed1 100644 (file)
@@ -41,11 +41,11 @@ mono_console_handle_async_ops (void)
 {
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
 MonoBoolean
 ves_icall_System_ConsoleDriver_Isatty (HANDLE handle)
 {
        DWORD mode;
-
        return GetConsoleMode (handle, &mode) != 0;
 }
 
@@ -72,3 +72,4 @@ ves_icall_System_ConsoleDriver_TtySetup (MonoString *keypad, MonoString *teardow
 {
        return FALSE;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
diff --git a/mono/metadata/coree-internals.h b/mono/metadata/coree-internals.h
new file mode 100644 (file)
index 0000000..3df754f
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_COREE_INTERNALS_H__
+#define __MONO_COREE_INTERNALS_H__
+
+#include <config.h>
+#include <glib.h>
+
+#ifdef HOST_WIN32
+#include <Windows.h>
+
+BOOL STDMETHODCALLTYPE
+_CorDllMain (HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved);
+
+__int32 STDMETHODCALLTYPE
+_CorExeMain (void);
+
+void STDMETHODCALLTYPE
+CorExitProcess (int exitCode);
+
+STDAPI
+_CorValidateImage (PVOID *ImageBase, LPCWSTR FileName);
+
+STDAPI_(VOID)
+_CorImageUnloading (PVOID ImageBase);
+
+STDAPI
+CorBindToRuntimeEx (LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor,
+                   DWORD startupFlags, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);
+
+STDAPI
+CorBindToRuntime (LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor,
+                 REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);
+
+HMODULE WINAPI
+MonoLoadImage (LPCWSTR FileName);
+
+void mono_coree_set_act_ctx (const char *file_name);
+#endif /* HOST_WIN32 */
+
+#endif /* __MONO_COREE_INTERNALS_H__ */
+
diff --git a/mono/metadata/coree-windows-uwp.c b/mono/metadata/coree-windows-uwp.c
new file mode 100644 (file)
index 0000000..7aacb5e
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * coree-windows-uwp.c: UWP coree support for Mono.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+*/
+#include <config.h>
+#include <glib.h>
+
+#if G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT)
+#include <Windows.h>
+#include "mono/metadata/coree-internals.h"
+
+BOOL STDMETHODCALLTYPE
+_CorDllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved)
+{
+       g_unsupported_api ("_CorDllMain");
+       return FALSE;
+}
+
+__int32 STDMETHODCALLTYPE
+_CorExeMain(void)
+{
+       g_unsupported_api ("_CorExeMain");
+       ExitProcess (EXIT_FAILURE);
+}
+
+STDAPI
+_CorValidateImage(PVOID *ImageBase, LPCWSTR FileName)
+{
+       g_unsupported_api ("_CorValidateImage");
+       return E_UNEXPECTED;
+}
+
+HMODULE WINAPI
+MonoLoadImage(LPCWSTR FileName)
+{
+       g_unsupported_api ("MonoLoadImage");
+       return NULL;
+}
+
+void
+mono_coree_set_act_ctx (const char *file_name)
+{
+       g_unsupported_api ("CreateActCtx, ActivateActCtx");
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return;
+}
+
+#else /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_coree_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
index 4436229376e10101b1d16f827601c72f466d2328..428fb9b989f80b6fea16ac5b54aad5cdf52cceb3 100644 (file)
@@ -12,8 +12,8 @@
 
 #ifdef HOST_WIN32
 
-#include <string.h>
 #include <glib.h>
+#include <string.h>
 #include <mono/io-layer/io-layer.h>
 #include <mono/utils/mono-path.h>
 #include "cil-coff.h"
 #include "threads.h"
 #include "environment.h"
 #include "coree.h"
+#include "coree-internals.h"
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
 #include <shellapi.h>
+#endif
 
 HMODULE coree_module_handle = NULL;
 
@@ -68,6 +71,7 @@ mono_get_module_file_name (HMODULE module_handle)
 }
 
 /* Entry point called by LdrLoadDll of ntdll.dll after _CorValidateImage. */
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
 BOOL STDMETHODCALLTYPE _CorDllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved)
 {
        MonoAssembly* assembly;
@@ -134,8 +138,10 @@ BOOL STDMETHODCALLTYPE _CorDllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpRes
 
        return TRUE;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
 /* Called by ntdll.dll reagardless of entry point after _CorValidateImage. */
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
 __int32 STDMETHODCALLTYPE _CorExeMain(void)
 {
        MonoError error;
@@ -207,6 +213,7 @@ __int32 STDMETHODCALLTYPE _CorExeMain(void)
        /* return does not terminate the process. */
        ExitProcess (mono_environment_exitcode_get ());
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
 /* Called by msvcrt.dll when shutting down. */
 void STDMETHODCALLTYPE CorExitProcess(int exitCode)
@@ -223,6 +230,7 @@ void STDMETHODCALLTYPE CorExitProcess(int exitCode)
 }
 
 /* Called by ntdll.dll before _CorDllMain and _CorExeMain. */
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
 STDAPI _CorValidateImage(PVOID *ImageBase, LPCWSTR FileName)
 {
        IMAGE_DOS_HEADER* DosHeader;
@@ -385,6 +393,7 @@ STDAPI _CorValidateImage(PVOID *ImageBase, LPCWSTR FileName)
 
        return STATUS_SUCCESS;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
 /* Called by ntdll.dll. */
 STDAPI_(VOID) _CorImageUnloading(PVOID ImageBase)
@@ -406,6 +415,7 @@ STDAPI CorBindToRuntime(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, REFCLSID r
        return CorBindToRuntimeEx (pwszVersion, pwszBuildFlavor, 0, rclsid, riid, ppv);
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
 HMODULE WINAPI MonoLoadImage(LPCWSTR FileName)
 {
        HANDLE FileHandle;
@@ -482,6 +492,7 @@ CloseFile:
        CloseHandle(FileHandle);
        return NULL;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
 typedef struct _EXPORT_FIXUP
 {
@@ -499,14 +510,14 @@ typedef struct _EXPORT_FIXUP
 
 /* Has to be binary ordered. */
 static const EXPORT_FIXUP ExportFixups[] = {
-       {"CorBindToRuntime", &CorBindToRuntime},
-       {"CorBindToRuntimeEx", &CorBindToRuntimeEx},
-       {"CorExitProcess", &CorExitProcess},
-       {"_CorDllMain", &_CorDllMain},
-       {"_CorExeMain", &_CorExeMain},
-       {"_CorImageUnloading", &_CorImageUnloading},
-       {"_CorValidateImage", &_CorValidateImage},
-       {NULL, NULL}
+       {"CorBindToRuntime", {&CorBindToRuntime}},
+       {"CorBindToRuntimeEx", {&CorBindToRuntimeEx}},
+       {"CorExitProcess", {&CorExitProcess}},
+       {"_CorDllMain", {&_CorDllMain}},
+       {"_CorExeMain", {&_CorExeMain}},
+       {"_CorImageUnloading", {&_CorImageUnloading}},
+       {"_CorValidateImage", {&_CorValidateImage}},
+       {NULL, {NULL}}
 };
 
 #define EXPORT_FIXUP_COUNT (sizeof(ExportFixups) / sizeof(EXPORT_FIXUP) - 1)
@@ -795,7 +806,15 @@ STDAPI MonoFixupExe(HMODULE ModuleHandle)
                        ImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)((DWORD_PTR)DosHeader + ImportDir->VirtualAddress);
                        while (ImportDesc->Name && ImportDesc->OriginalFirstThunk)
                        {
-                               ImportModuleHandle = LoadLibraryA((PCSTR)((DWORD_PTR)DosHeader + ImportDesc->Name));
+                               gchar *file_utf8 = (gchar *)((DWORD_PTR)DosHeader + ImportDesc->Name);
+
+                               gunichar2 *file_utf16 = g_utf8_to_utf16 (file_utf8, (glong)strlen (file_utf8), NULL, NULL, NULL);
+                               ImportModuleHandle = NULL;
+                               if (file_utf16 != NULL) {
+                                       ImportModuleHandle = LoadLibraryW(file_utf16);
+                                       g_free (file_utf16);
+                               }
+
                                if (ImportModuleHandle == NULL)
                                        return E_FAIL;
 
@@ -828,8 +847,9 @@ STDAPI MonoFixupExe(HMODULE ModuleHandle)
        return S_OK;
 }
 
-static void
-mono_set_act_ctx (const char* file_name)
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+void
+mono_coree_set_act_ctx (const char* file_name)
 {
        typedef HANDLE (WINAPI* CREATEACTCTXW_PROC) (PCACTCTXW pActCtx);
        typedef BOOL (WINAPI* ACTIVATEACTCTX_PROC) (HANDLE hActCtx, ULONG_PTR* lpCookie);
@@ -888,6 +908,7 @@ mono_set_act_ctx (const char* file_name)
        if (handle != INVALID_HANDLE_VALUE)
                ActivateActCtx_proc (handle, &cookie);
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
 void
 mono_load_coree (const char* exe_file_name)
@@ -901,7 +922,7 @@ mono_load_coree (const char* exe_file_name)
                return;
 
        if (!init_from_coree && exe_file_name)
-               mono_set_act_ctx (exe_file_name);
+               mono_coree_set_act_ctx (exe_file_name);
 
        /* ntdll.dll loads mscoree.dll from the system32 directory. */
        required_size = GetSystemDirectory (NULL, 0);
index d280e30982144af7f8bd20328d420f38e742ad9b..dfb3c29eefc5af88d07cdc37c168c66c6f39a58c 100644 (file)
@@ -522,7 +522,7 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
        if (domain)
                g_assert_not_reached ();
 
-#ifdef HOST_WIN32
+#if defined(HOST_WIN32) && G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
        /* Avoid system error message boxes. */
        SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
 #endif
diff --git a/mono/metadata/file-io-internals.h b/mono/metadata/file-io-internals.h
new file mode 100644 (file)
index 0000000..3fe5970
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_FILE_IO_INTERNALS_H__
+#define __MONO_FILE_IO_INTERNALS_H__
+
+#include <config.h>
+#include <glib.h>
+#include "mono/metadata/object.h"
+#include "mono/metadata/object-internals.h"
+
+gboolean
+mono_file_io_move_file (gunichar2 *path, gunichar2 *dest, gint32 *error);
+
+gboolean
+mono_file_io_copy_file (gunichar2 *path, gunichar2 *dest, gboolean overwrite, gint32 *error);
+
+gint64
+mono_file_io_get_file_size (HANDLE handle, gint32 *error);
+
+gboolean
+mono_file_io_lock_file (HANDLE handle, gint64 position, gint64 length, gint32 *error);
+
+gboolean
+mono_file_io_replace_file (gunichar2 *destinationFileName, gunichar2 *sourceFileName,
+                          gunichar2 *destinationBackupFileName, guint32 flags, gint32 *error);
+
+gboolean
+mono_file_io_unlock_file (HANDLE handle, gint64 position, gint64 length, gint32 *error);
+
+#endif /* __MONO_FILE_IO_INTERNALS_H__ */
diff --git a/mono/metadata/file-io-windows-internals.h b/mono/metadata/file-io-windows-internals.h
new file mode 100644 (file)
index 0000000..df372e8
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef _MONO_METADATA_FILEIO_WINDOWS_H_
+#define _MONO_METADATA_FILEIO_WINDOWS_H_
+
+#include <config.h>
+#include <glib.h>
+
+#ifdef HOST_WIN32
+#include "mono/metadata/file-io.h"
+#include "mono/metadata/file-io-internals.h"
+#endif /* HOST_WIN32 */
+#endif /* _MONO_METADATA_FILEIO_WINDOWS_H_ */
diff --git a/mono/metadata/file-io-windows-uwp.c b/mono/metadata/file-io-windows-uwp.c
new file mode 100644 (file)
index 0000000..2ece546
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * file-io-windows-uwp.c: UWP file-io support for Mono.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+*/
+#include <config.h>
+#include <glib.h>
+
+#if G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT)
+#include <Windows.h>
+#include "mono/metadata/file-io-windows-internals.h"
+
+gboolean
+mono_file_io_move_file (gunichar2 *path, gunichar2 *dest, gint32 *error)
+{
+       gboolean result = FALSE;
+       MONO_ENTER_GC_SAFE;
+
+       result = MoveFileEx (path, dest, MOVEFILE_COPY_ALLOWED);
+       if (result == FALSE) {
+               *error=GetLastError ();
+       }
+
+       MONO_EXIT_GC_SAFE;
+       return result;
+}
+
+gboolean
+mono_file_io_replace_file (gunichar2 *destinationFileName, gunichar2 *sourceFileName,
+                          gunichar2 *destinationBackupFileName, guint32 flags, gint32 *error)
+{
+       gboolean result = FALSE;
+       MONO_ENTER_GC_SAFE;
+
+       result = ReplaceFile (destinationFileName, sourceFileName, destinationBackupFileName, flags, NULL, NULL);
+       if (result == FALSE) {
+               *error=GetLastError ();
+       }
+
+       MONO_EXIT_GC_SAFE;
+       return result;
+}
+
+gboolean
+mono_file_io_copy_file (gunichar2 *path, gunichar2 *dest, gboolean overwrite, gint32 *error)
+{
+       gboolean                                                result = FALSE;
+       COPYFILE2_EXTENDED_PARAMETERS   copy_param = {0};
+
+       copy_param.dwSize = sizeof (COPYFILE2_EXTENDED_PARAMETERS);
+       copy_param.dwCopyFlags = (!overwrite) ? COPY_FILE_FAIL_IF_EXISTS : 0;
+
+       MONO_ENTER_GC_SAFE;
+
+       result = SUCCEEDED (CopyFile2 (path, dest, &copy_param));
+       if (result == FALSE) {
+               *error=GetLastError ();
+       }
+
+       MONO_EXIT_GC_SAFE;
+       return result;
+}
+
+gint64
+mono_file_io_get_file_size (HANDLE handle, gint32 *error)
+{
+       LARGE_INTEGER length;
+
+       MONO_ENTER_GC_SAFE;
+
+       if (!GetFileSizeEx (handle, &length)) {
+               *error=GetLastError ();
+               length.QuadPart = INVALID_FILE_SIZE;
+       }
+
+       MONO_EXIT_GC_SAFE;
+       return length.QuadPart;
+}
+
+gboolean
+mono_file_io_lock_file (HANDLE handle, gint64 position, gint64 length, gint32 *error)
+{
+       gboolean result = FALSE;
+       MONO_ENTER_GC_SAFE;
+
+       result = LockFile (handle, position & 0xFFFFFFFF, position >> 32,
+                          length & 0xFFFFFFFF, length >> 32);
+
+       if (result == FALSE) {
+               *error = GetLastError ();
+       }
+
+       MONO_EXIT_GC_SAFE;
+       return result;
+}
+
+gboolean
+mono_file_io_unlock_file (HANDLE handle, gint64 position, gint64 length, gint32 *error)
+{
+       gboolean result = FALSE;
+       MONO_ENTER_GC_SAFE;
+
+       result = UnlockFile (handle, position & 0xFFFFFFFF, position >> 32,
+                            length & 0xFFFFFFFF, length >> 32);
+
+       if (result == FALSE) {
+               *error = GetLastError ();
+       }
+
+       MONO_EXIT_GC_SAFE;
+       return result;
+}
+
+#else /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_file_io_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
diff --git a/mono/metadata/file-io-windows.c b/mono/metadata/file-io-windows.c
new file mode 100644 (file)
index 0000000..fcd76cc
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * file-io-windows.c: Windows File IO internal calls.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#include <config.h>
+#include <glib.h>
+
+#if defined(HOST_WIN32)
+#include <WinSock2.h>
+#include <Windows.h>
+#include "mono/metadata/file-io-windows-internals.h"
+
+gunichar2
+ves_icall_System_IO_MonoIO_get_VolumeSeparatorChar ()
+{
+       return (gunichar2) ':'; /* colon */
+}
+
+gunichar2
+ves_icall_System_IO_MonoIO_get_DirectorySeparatorChar ()
+{
+       return (gunichar2) '\\';        /* backslash */
+}
+
+gunichar2
+ves_icall_System_IO_MonoIO_get_AltDirectorySeparatorChar ()
+{
+       return (gunichar2) '/'; /* forward slash */
+}
+
+gunichar2
+ves_icall_System_IO_MonoIO_get_PathSeparator ()
+{
+       return (gunichar2) ';'; /* semicolon */
+}
+
+void ves_icall_System_IO_MonoIO_DumpHandles (void)
+{
+       return;
+}
+#endif /* HOST_WIN32 */
index 1e0422e35fbc0f069b63b3136850af188a785384..dd722f289a958c6a8c6452a9fc6bb073d7268fe5 100644 (file)
@@ -29,6 +29,7 @@
 #include <mono/metadata/object.h>
 #include <mono/io-layer/io-layer.h>
 #include <mono/metadata/file-io.h>
+#include <mono/metadata/file-io-internals.h>
 #include <mono/metadata/exception.h>
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/marshal.h>
@@ -606,33 +607,55 @@ ves_icall_System_IO_MonoIO_SetCurrentDirectory (MonoString *path,
        return(ret);
 }
 
-MonoBoolean
-ves_icall_System_IO_MonoIO_MoveFile (MonoString *path, MonoString *dest,
-                                    gint32 *error)
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+gboolean
+mono_file_io_move_file (gunichar2 *path, gunichar2 *dest, gint32 *error)
 {
-       gboolean ret;
+       gboolean result = FALSE;
        MONO_ENTER_GC_SAFE;
-       
+
+       result = MoveFile (path, dest);
+       if (result == FALSE) {
+               *error=GetLastError ();
+       }
+
+       MONO_EXIT_GC_SAFE;
+       return result;
+}
+#endif /* HAVE_CLASSIC_WINAPI_SUPPORT */
+
+MonoBoolean
+ves_icall_System_IO_MonoIO_MoveFile (MonoString *path, MonoString *dest, gint32 *error)
+{
        *error=ERROR_SUCCESS;
+       return mono_file_io_move_file (mono_string_chars (path), mono_string_chars (dest), error);
+}
 
-       ret=MoveFile (mono_string_chars (path), mono_string_chars (dest));
-       if(ret==FALSE) {
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+gboolean
+mono_file_io_replace_file (gunichar2 *destinationFileName, gunichar2 *sourceFileName,
+                          gunichar2 *destinationBackupFileName, guint32 flags, gint32 *error)
+{
+       gboolean result = FALSE;
+       MONO_ENTER_GC_SAFE;
+
+       result = ReplaceFile (destinationFileName, sourceFileName, destinationBackupFileName, flags, NULL, NULL);
+       if (result == FALSE) {
                *error=GetLastError ();
        }
 
        MONO_EXIT_GC_SAFE;
-       return(ret);
+       return result;
 }
+#endif /* HAVE_CLASSIC_WINAPI_SUPPORT */
 
 MonoBoolean
 ves_icall_System_IO_MonoIO_ReplaceFile (MonoString *sourceFileName, MonoString *destinationFileName,
                                        MonoString *destinationBackupFileName, MonoBoolean ignoreMetadataErrors,
                                        gint32 *error)
 {
-       gboolean ret;
        gunichar2 *utf16_sourceFileName = NULL, *utf16_destinationFileName = NULL, *utf16_destinationBackupFileName = NULL;
        guint32 replaceFlags = REPLACEFILE_WRITE_THROUGH;
-       MONO_ENTER_GC_SAFE;
 
        if (sourceFileName)
                utf16_sourceFileName = mono_string_chars (sourceFileName);
@@ -646,31 +669,33 @@ ves_icall_System_IO_MonoIO_ReplaceFile (MonoString *sourceFileName, MonoString *
                replaceFlags |= REPLACEFILE_IGNORE_MERGE_ERRORS;
 
        /* FIXME: source and destination file names must not be NULL, but apparently they might be! */
-       ret = ReplaceFile (utf16_destinationFileName, utf16_sourceFileName, utf16_destinationBackupFileName,
-                        replaceFlags, NULL, NULL);
-       if (ret == FALSE)
-               *error = GetLastError ();
+       return mono_file_io_replace_file (utf16_destinationFileName, utf16_sourceFileName,
+                                         utf16_destinationBackupFileName, replaceFlags, error);
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+gboolean
+mono_file_io_copy_file (gunichar2 *path, gunichar2 *dest, gboolean overwrite, gint32 *error)
+{
+       gboolean result = FALSE;
+       MONO_ENTER_GC_SAFE;
+
+       result = CopyFile (path, dest, !overwrite);
+       if (result == FALSE) {
+               *error=GetLastError ();
+       }
 
        MONO_EXIT_GC_SAFE;
-       return ret;
+       return result;
 }
+#endif /* HAVE_CLASSIC_WINAPI_SUPPORT */
 
 MonoBoolean
 ves_icall_System_IO_MonoIO_CopyFile (MonoString *path, MonoString *dest,
                                     MonoBoolean overwrite, gint32 *error)
 {
-       gboolean ret;
-       MONO_ENTER_GC_SAFE;
-       
        *error=ERROR_SUCCESS;
-       
-       ret=CopyFile (mono_string_chars (path), mono_string_chars (dest), !overwrite);
-       if(ret==FALSE) {
-               *error=GetLastError ();
-       }
-       
-       MONO_EXIT_GC_SAFE;
-       return(ret);
+       return mono_file_io_copy_file (mono_string_chars (path), mono_string_chars (dest), overwrite, error);
 }
 
 MonoBoolean
@@ -948,23 +973,31 @@ ves_icall_System_IO_MonoIO_Flush (HANDLE handle, gint32 *error)
        return(ret);
 }
 
-gint64 
-ves_icall_System_IO_MonoIO_GetLength (HANDLE handle, gint32 *error)
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+gint64
+mono_file_io_get_file_size (HANDLE handle, gint32 *error)
 {
        gint64 length;
        guint32 length_hi;
+
        MONO_ENTER_GC_SAFE;
 
-       *error=ERROR_SUCCESS;
-       
        length = GetFileSize (handle, &length_hi);
        if(length==INVALID_FILE_SIZE) {
                *error=GetLastError ();
        }
-       
+
        MONO_EXIT_GC_SAFE;
        return length | ((gint64)length_hi << 32);
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+gint64
+ves_icall_System_IO_MonoIO_GetLength (HANDLE handle, gint32 *error)
+{
+       *error=ERROR_SUCCESS;
+       return mono_file_io_get_file_size (handle, error);
+}
 
 /* FIXME make gc suspendable */
 MonoBoolean
@@ -1113,48 +1146,34 @@ ves_icall_System_IO_MonoIO_DuplicateHandle (HANDLE source_process_handle, HANDLE
        return(TRUE);
 }
 
+#ifndef HOST_WIN32
 gunichar2 
 ves_icall_System_IO_MonoIO_get_VolumeSeparatorChar ()
 {
-#if defined (TARGET_WIN32)
-       return (gunichar2) ':'; /* colon */
-#else
        return (gunichar2) '/'; /* forward slash */
-#endif
 }
 
 gunichar2 
 ves_icall_System_IO_MonoIO_get_DirectorySeparatorChar ()
 {
-#if defined (TARGET_WIN32)
-       return (gunichar2) '\\';        /* backslash */
-#else
        return (gunichar2) '/'; /* forward slash */
-#endif
 }
 
 gunichar2 
 ves_icall_System_IO_MonoIO_get_AltDirectorySeparatorChar ()
 {
-#if defined (TARGET_WIN32)
-       return (gunichar2) '/'; /* forward slash */
-#else
        if (IS_PORTABILITY_SET)
                return (gunichar2) '\\';        /* backslash */
        else
                return (gunichar2) '/'; /* forward slash */
-#endif
 }
 
 gunichar2 
 ves_icall_System_IO_MonoIO_get_PathSeparator ()
 {
-#if defined (TARGET_WIN32)
-       return (gunichar2) ';'; /* semicolon */
-#else
        return (gunichar2) ':'; /* colon */
-#endif
 }
+#endif /* !HOST_WIN32 */
 
 static const gunichar2
 invalid_path_chars [] = {
@@ -1197,38 +1216,56 @@ ves_icall_System_IO_MonoIO_get_InvalidPathChars ()
        return chars;
 }
 
-void ves_icall_System_IO_MonoIO_Lock (HANDLE handle, gint64 position,
-                                     gint64 length, gint32 *error)
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+gboolean
+mono_file_io_lock_file (HANDLE handle, gint64 position, gint64 length, gint32 *error)
 {
-       gboolean ret;
+       gboolean result = FALSE;
        MONO_ENTER_GC_SAFE;
-       
-       *error=ERROR_SUCCESS;
-       
-       ret=LockFile (handle, position & 0xFFFFFFFF, position >> 32,
-                     length & 0xFFFFFFFF, length >> 32);
-       if (ret == FALSE) {
+
+       result = LockFile (handle, position & 0xFFFFFFFF, position >> 32,
+                          length & 0xFFFFFFFF, length >> 32);
+
+       if (result == FALSE) {
                *error = GetLastError ();
        }
 
        MONO_EXIT_GC_SAFE;
+       return result;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
-void ves_icall_System_IO_MonoIO_Unlock (HANDLE handle, gint64 position,
-                                       gint64 length, gint32 *error)
+void ves_icall_System_IO_MonoIO_Lock (HANDLE handle, gint64 position,
+                                     gint64 length, gint32 *error)
 {
-       gboolean ret;
-       MONO_ENTER_GC_SAFE;
-       
        *error=ERROR_SUCCESS;
+       mono_file_io_lock_file (handle, position, length, error);
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+gboolean
+mono_file_io_unlock_file (HANDLE handle, gint64 position, gint64 length, gint32 *error)
+{
+       gboolean result = FALSE;
+       MONO_ENTER_GC_SAFE;
        
-       ret=UnlockFile (handle, position & 0xFFFFFFFF, position >> 32,
-                       length & 0xFFFFFFFF, length >> 32);
-       if (ret == FALSE) {
+       result = UnlockFile (handle, position & 0xFFFFFFFF, position >> 32,
+                            length & 0xFFFFFFFF, length >> 32);
+
+       if (result == FALSE) {
                *error = GetLastError ();
        }
 
        MONO_EXIT_GC_SAFE;
+       return result;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+void ves_icall_System_IO_MonoIO_Unlock (HANDLE handle, gint64 position,
+                                       gint64 length, gint32 *error)
+{
+       *error=ERROR_SUCCESS;
+       mono_file_io_unlock_file (handle, position, length, error);
 }
 
 //Support for io-layer free mmap'd files.
@@ -1274,11 +1311,12 @@ mono_filesize_from_fd (int fd)
 
 #endif
 
+#ifndef HOST_WIN32
 void mono_w32handle_dump (void);
 
 void ves_icall_System_IO_MonoIO_DumpHandles (void)
 {
-#ifndef HOST_WIN32
+
        mono_w32handle_dump ();
-#endif
 }
+#endif /* !HOST_WIN32 */
diff --git a/mono/metadata/icall-internals.h b/mono/metadata/icall-internals.h
new file mode 100644 (file)
index 0000000..e2ec776
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_METADATA_ICALL_INTERNALS_H__
+#define __MONO_METADATA_ICALL_INTERNALS_H__
+
+#include <config.h>
+#include <glib.h>
+#include <mono/metadata/object-internals.h>
+
+// On Windows platform implementation of bellow methods are hosted in separate source file
+// icall-windows.c or icall-windows-*.c. On other platforms the implementation is still keept
+// in icall.c still declared as static and in some places even inlined.
+#ifdef HOST_WIN32
+void
+mono_icall_make_platform_path (gchar *path);
+
+const gchar *
+mono_icall_get_file_path_prefix (const gchar *path);
+
+gpointer
+mono_icall_module_get_hinstance (MonoReflectionModule *module);
+
+MonoString *
+mono_icall_get_machine_name (void);
+
+int
+mono_icall_get_platform (void);
+
+MonoString *
+mono_icall_get_new_line (void);
+
+MonoBoolean
+mono_icall_is_64bit_os (void);
+
+MonoArray *
+mono_icall_get_environment_variable_names (void);
+
+void
+mono_icall_set_environment_variable (MonoString *name, MonoString *value);
+
+MonoString *
+mono_icall_get_windows_folder_path (int folder);
+
+void
+mono_icall_broadcast_setting_change (void);
+
+void
+mono_icall_write_windows_debug_string (MonoString *message);
+
+MonoBoolean
+mono_icall_close_process (gpointer handle);
+
+gint32
+mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds);
+#endif  /* HOST_WIN32 */
+
+// On platforms not using classic WIN API support the  implementation of bellow methods are hosted in separate source file
+// icall-windows-*.c. On platforms using classic WIN API the implementation is still keept in icall.c and still declared
+// static and in some places even inlined.
+#if !G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+MonoArray *
+mono_icall_get_logical_drives (void);
+
+guint32
+mono_icall_drive_info_get_drive_type (MonoString *root_path_name);
+
+MonoBoolean
+mono_icall_get_process_working_set_size (gpointer handle, gsize *min, gsize *max);
+
+MonoBoolean
+mono_icall_set_process_working_set_size (gpointer handle, gsize min, gsize max);
+
+gint32
+mono_icall_get_priority_class (gpointer handle);
+
+MonoBoolean
+mono_icall_set_priority_class (gpointer handle, gint32 priorityClass);
+#endif  /* !G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+#endif /* __MONO_METADATA_ICALL_INTERNALS_H__ */
diff --git a/mono/metadata/icall-windows-internals.h b/mono/metadata/icall-windows-internals.h
new file mode 100644 (file)
index 0000000..0093767
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_METADATA_ICALL_WINDOWS_INTERNALS_H__
+#define __MONO_METADATA_ICALL_WINDOWS_INTERNALS_H__
+
+#include <config.h>
+#include <glib.h>
+
+#ifdef HOST_WIN32
+#include "mono/metadata/icall-internals.h"
+#include "mono/metadata/object.h"
+#include "mono/metadata/object-internals.h"
+#include "mono/metadata/class.h"
+#include "mono/metadata/class-internals.h"
+#endif /* HOST_WIN32 */
+#endif /* __MONO_METADATA_ICALL_WINDOWS_INTERNALS_H__ */
diff --git a/mono/metadata/icall-windows-uwp.c b/mono/metadata/icall-windows-uwp.c
new file mode 100644 (file)
index 0000000..f273198
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * icall-windows-uwp.c: UWP icall support for Mono.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+*/
+#include <config.h>
+#include <glib.h>
+
+#if G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT)
+#include <Windows.h>
+#include "mono/metadata/icall-windows-internals.h"
+
+MonoString *
+mono_icall_get_machine_name (void)
+{
+       g_unsupported_api ("GetComputerName");
+       return mono_string_new (mono_domain_get (), "mono");
+}
+
+MonoString *
+mono_icall_get_windows_folder_path (int folder)
+{
+       g_unsupported_api ("SHGetFolderPath");
+       return mono_string_new (mono_domain_get (), "");
+}
+
+MonoArray *
+mono_icall_get_logical_drives (void)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("GetLogicalDriveStrings");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "GetLogicalDriveStrings");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return NULL;
+}
+
+void
+mono_icall_broadcast_setting_change (void)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("SendMessageTimeout");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "SendMessageTimeout");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return;
+}
+
+guint32
+mono_icall_drive_info_get_drive_type (MonoString *root_path_name)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("GetDriveType");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "GetDriveType");
+       mono_error_set_pending_exception (&mono_error);
+
+       return DRIVE_UNKNOWN;
+}
+
+gint32
+mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("WaitForInputIdle");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "WaitForInputIdle");
+       mono_error_set_pending_exception (&mono_error);
+
+       return WAIT_TIMEOUT;
+}
+
+MonoBoolean
+mono_icall_get_process_working_set_size (gpointer handle, gsize *min, gsize *max)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("GetProcessWorkingSetSize");
+
+       mono_error_set_not_supported(&mono_error, G_UNSUPPORTED_API, "GetProcessWorkingSetSize");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+MonoBoolean
+mono_icall_set_process_working_set_size (gpointer handle, gsize min, gsize max)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("SetProcessWorkingSetSize");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "SetProcessWorkingSetSize");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+gint32
+mono_icall_get_priority_class (gpointer handle)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("GetPriorityClass");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "GetPriorityClass");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+MonoBoolean
+mono_icall_set_priority_class (gpointer handle, gint32 priorityClass)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("SetPriorityClass");
+
+       mono_error_set_not_supported(&mono_error, G_UNSUPPORTED_API, "SetPriorityClass");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+#else /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_icall_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
diff --git a/mono/metadata/icall-windows.c b/mono/metadata/icall-windows.c
new file mode 100644 (file)
index 0000000..6c80211
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * icall-windows.c: Windows icall support.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#include <config.h>
+#include <glib.h>
+
+#if defined(HOST_WIN32)
+#include <WinSock2.h>
+#include <Windows.h>
+#include "mono/metadata/icall-windows-internals.h"
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+#include <shlobj.h>
+#endif
+
+void
+mono_icall_make_platform_path (gchar *path)
+{
+       for (size_t i = strlen (path); i > 0; i--)
+               if (path [i-1] == '\\')
+                       path [i-1] = '/';
+}
+
+const gchar *
+mono_icall_get_file_path_prefix (const gchar *path)
+{
+       if (*path == '/' && *(path + 1) == '/') {
+               return "file:";
+       } else {
+               return "file:///";
+       }
+}
+
+gpointer
+mono_icall_module_get_hinstance (MonoReflectionModule *module)
+{
+       if (module->image && module->image->is_module_handle)
+               return module->image->raw_data;
+
+       return (gpointer) (-1);
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+MonoString *
+mono_icall_get_machine_name (void)
+{
+       gunichar2 *buf;
+       guint32 len;
+       MonoString *result;
+
+       len = MAX_COMPUTERNAME_LENGTH + 1;
+       buf = g_new (gunichar2, len);
+
+       result = NULL;
+       if (GetComputerName (buf, (PDWORD) &len)) {
+               MonoError error;
+               result = mono_string_new_utf16_checked (mono_domain_get (), buf, len, &error);
+               mono_error_set_pending_exception (&error);
+       }
+
+       g_free (buf);
+       return result;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+int
+mono_icall_get_platform (void)
+{
+       /* Win32NT */
+       return 2;
+}
+
+MonoString *
+mono_icall_get_new_line (void)
+{
+       return mono_string_new (mono_domain_get (), "\r\n");
+}
+
+MonoBoolean
+mono_icall_is_64bit_os (void)
+{
+#if SIZEOF_VOID_P == 8
+       return TRUE;
+#else
+       gboolean isWow64Process = FALSE;
+       if (IsWow64Process (GetCurrentProcess (), &isWow64Process)) {
+               return (MonoBoolean)isWow64Process;
+       }
+       return FALSE;
+#endif
+}
+
+MonoArray *
+mono_icall_get_environment_variable_names (void)
+{
+       MonoError error;
+       MonoArray *names;
+       MonoDomain *domain;
+       MonoString *str;
+       WCHAR* env_strings;
+       WCHAR* env_string;
+       WCHAR* equal_str;
+       int n = 0;
+
+       env_strings = GetEnvironmentStrings();
+
+       if (env_strings) {
+               env_string = env_strings;
+               while (*env_string != '\0') {
+               /* weird case that MS seems to skip */
+                       if (*env_string != '=')
+                               n++;
+                       while (*env_string != '\0')
+                               env_string++;
+                       env_string++;
+               }
+       }
+
+       domain = mono_domain_get ();
+       names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
+       if (mono_error_set_pending_exception (&error))
+               return NULL;
+
+       if (env_strings) {
+               n = 0;
+               env_string = env_strings;
+               while (*env_string != '\0') {
+                       /* weird case that MS seems to skip */
+                       if (*env_string != '=') {
+                               equal_str = wcschr(env_string, '=');
+                               g_assert(equal_str);
+                               str = mono_string_new_utf16_checked (domain, env_string, (gint32)(equal_str - env_string), &error);
+                               if (mono_error_set_pending_exception (&error))
+                                       return NULL;
+
+                               mono_array_setref (names, n, str);
+                               n++;
+                       }
+                       while (*env_string != '\0')
+                               env_string++;
+                       env_string++;
+               }
+
+               FreeEnvironmentStrings (env_strings);
+       }
+
+       return names;
+}
+
+void
+mono_icall_set_environment_variable (MonoString *name, MonoString *value)
+{
+       gunichar2 *utf16_name, *utf16_value;
+
+       utf16_name = mono_string_to_utf16 (name);
+       if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
+               SetEnvironmentVariable (utf16_name, NULL);
+               g_free (utf16_name);
+               return;
+       }
+
+       utf16_value = mono_string_to_utf16 (value);
+
+       SetEnvironmentVariable (utf16_name, utf16_value);
+
+       g_free (utf16_name);
+       g_free (utf16_value);
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+MonoString *
+mono_icall_get_windows_folder_path (int folder)
+{
+       #ifndef CSIDL_FLAG_CREATE
+               #define CSIDL_FLAG_CREATE       0x8000
+       #endif
+
+       WCHAR path [MAX_PATH];
+       /* Create directory if no existing */
+       if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
+               int len = 0;
+               while (path [len])
+                       ++ len;
+               MonoError error;
+               MonoString *res = mono_string_new_utf16_checked (mono_domain_get (), path, len, &error);
+               mono_error_set_pending_exception (&error);
+               return res;
+       }
+       return mono_string_new (mono_domain_get (), "");
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+void
+mono_icall_broadcast_setting_change (void)
+{
+       SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, (WPARAM)NULL, (LPARAM)L"Environment", SMTO_ABORTIFHUNG, 2000, 0);
+}
+
+gint32
+mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
+{
+       return WaitForInputIdle (handle, milliseconds);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+void
+mono_icall_write_windows_debug_string (MonoString *message)
+{
+       OutputDebugString (mono_string_chars (message));
+}
+
+MonoBoolean
+mono_icall_close_process (gpointer handle)
+{
+       return (MonoBoolean)(CloseHandle (handle));
+}
+#endif /* HOST_WIN32 */
index df28c606b3ccfbb96a6f65f617ca4e33951ac634..ed0ac7e81b8aaec0edb33efd984abd270f30d307 100644 (file)
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
-#if defined (HOST_WIN32)
-#include <stdlib.h>
-#endif
 #if defined (HAVE_WCHAR_H)
 #include <wchar.h>
 #endif
-
+#include "mono/metadata/icall-internals.h"
 #include "mono/utils/mono-membar.h"
 #include <mono/metadata/object.h>
 #include <mono/metadata/threads.h>
 #include <mono/utils/mono-os-mutex.h>
 #include <mono/utils/mono-threads.h>
 
-#if defined (HOST_WIN32)
-#include <windows.h>
-#include <shlobj.h>
-#endif
 #include "decimal-ms.h"
 #include "number-ms.h"
 
@@ -158,6 +151,20 @@ mono_class_init_checked (MonoClass *klass, MonoError *error)
                mono_error_set_for_class_failure (error, klass);
 }
 
+#ifndef HOST_WIN32
+static inline void
+mono_icall_make_platform_path (gchar *path)
+{
+       return;
+}
+
+static inline const gchar *
+mono_icall_get_file_path_prefix (const gchar *path)
+{
+       return "file://";
+}
+#endif /* HOST_WIN32 */
+
 ICALL_EXPORT MonoObject *
 ves_icall_System_Array_GetValueImpl (MonoArray *arr, guint32 pos)
 {
@@ -4505,25 +4512,13 @@ ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *asse
 
        replace_shadow_path (domain, dirname, &absolute);
        g_free (dirname);
-#if HOST_WIN32
-       {
-               gint i;
-               for (i = strlen (absolute) - 1; i >= 0; i--)
-                       if (absolute [i] == '\\')
-                               absolute [i] = '/';
-       }
-#endif
+
+       mono_icall_make_platform_path (absolute);
+
        if (escaped) {
                uri = g_filename_to_uri (absolute, NULL, NULL);
        } else {
-               const char *prepend = "file://";
-#if HOST_WIN32
-               if (*absolute == '/' && *(absolute + 1) == '/') {
-                       prepend = "file:";
-               } else {
-                       prepend = "file:///";
-               }
-#endif
+               const gchar *prepend = mono_icall_get_file_path_prefix (absolute);
                uri = g_strconcat (prepend, absolute, NULL);
        }
 
@@ -5312,25 +5307,14 @@ fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *a
 
        codebase = NULL;
        if (absolute != NULL && *absolute != '\0') {
-               const gchar *prepend = "file://";
                gchar *result;
 
                codebase = g_strdup (absolute);
 
-#if HOST_WIN32
-               {
-                       gint i;
-                       for (i = strlen (codebase) - 1; i >= 0; i--)
-                               if (codebase [i] == '\\')
-                                       codebase [i] = '/';
+               mono_icall_make_platform_path (codebase);
+
+               const gchar *prepend = mono_icall_get_file_path_prefix (codebase);
 
-                       if (*codebase == '/' && *(codebase + 1) == '/') {
-                               prepend = "file:";
-                       } else {
-                               prepend = "file:///";
-                       }
-               }
-#endif
                result = g_strconcat (prepend, codebase, NULL);
                g_free (codebase);
                codebase = result;
@@ -5743,15 +5727,18 @@ ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle r
        return mono_string_new_handle (domain, image->guid, error);
 }
 
+#ifndef HOST_WIN32
+static inline gpointer
+mono_icall_module_get_hinstance (MonoReflectionModule *module)
+{
+       return (gpointer) (-1);
+}
+#endif /* HOST_WIN32 */
+
 ICALL_EXPORT gpointer
 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModule *module)
 {
-#ifdef HOST_WIN32
-       if (module->image && module->image->is_module_handle)
-               return module->image->raw_data;
-#endif
-
-       return (gpointer) (-1);
+       return mono_icall_module_get_hinstance (module);
 }
 
 ICALL_EXPORT void
@@ -6478,28 +6465,11 @@ ves_icall_System_Environment_get_UserName (void)
        return mono_string_new (mono_domain_get (), g_get_user_name ());
 }
 
-
-ICALL_EXPORT MonoString *
-ves_icall_System_Environment_get_MachineName (void)
+#ifndef HOST_WIN32
+static MonoString *
+mono_icall_get_machine_name (void)
 {
-#if defined (HOST_WIN32)
-       gunichar2 *buf;
-       guint32 len;
-       MonoString *result;
-
-       len = MAX_COMPUTERNAME_LENGTH + 1;
-       buf = g_new (gunichar2, len);
-
-       result = NULL;
-       if (GetComputerName (buf, (PDWORD) &len)) {
-               MonoError error;
-               result = mono_string_new_utf16_checked (mono_domain_get (), buf, len, &error);
-               mono_error_set_pending_exception (&error);
-       }
-
-       g_free (buf);
-       return result;
-#elif !defined(DISABLE_SOCKETS)
+#if !defined(DISABLE_SOCKETS)
        MonoString *result;
        char *buf;
        int n;
@@ -6522,14 +6492,19 @@ ves_icall_System_Environment_get_MachineName (void)
        return mono_string_new (mono_domain_get (), "mono");
 #endif
 }
+#endif /* !HOST_WIN32 */
 
-ICALL_EXPORT int
-ves_icall_System_Environment_get_Platform (void)
+ICALL_EXPORT MonoString *
+ves_icall_System_Environment_get_MachineName (void)
+{
+       return mono_icall_get_machine_name ();
+}
+
+#ifndef HOST_WIN32
+static inline int
+mono_icall_get_platform (void)
 {
-#if defined (TARGET_WIN32)
-       /* Win32NT */
-       return 2;
-#elif defined(__MACH__)
+#if defined(__MACH__)
        /* OSX */
        //
        // Notice that the value is hidden from user code, and only exposed
@@ -6544,29 +6519,36 @@ ves_icall_System_Environment_get_Platform (void)
        return 4;
 #endif
 }
+#endif /* !HOST_WIN32 */
+
+ICALL_EXPORT int
+ves_icall_System_Environment_get_Platform (void)
+{
+       return mono_icall_get_platform ();
+}
+
+#ifndef HOST_WIN32
+static inline MonoString *
+mono_icall_get_new_line (void)
+{
+       return mono_string_new (mono_domain_get (), "\n");
+}
+#endif /* !HOST_WIN32 */
 
 ICALL_EXPORT MonoString *
 ves_icall_System_Environment_get_NewLine (void)
 {
-#if defined (HOST_WIN32)
-       return mono_string_new (mono_domain_get (), "\r\n");
-#else
-       return mono_string_new (mono_domain_get (), "\n");
-#endif
+       return mono_icall_get_new_line ();
 }
 
-ICALL_EXPORT MonoBoolean
-ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
+#ifndef HOST_WIN32
+static inline MonoBoolean
+mono_icall_is_64bit_os (void)
 {
 #if SIZEOF_VOID_P == 8
        return TRUE;
 #else
-#ifdef HOST_WIN32
-       gboolean isWow64Process = FALSE;
-       if (IsWow64Process (GetCurrentProcess (), &isWow64Process)) {
-               return (MonoBoolean)isWow64Process;
-       }
-#elif defined(HAVE_SYS_UTSNAME_H)
+#if defined(HAVE_SYS_UTSNAME_H)
        struct utsname name;
 
        if (uname (&name) >= 0) {
@@ -6576,6 +6558,13 @@ ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
        return FALSE;
 #endif
 }
+#endif /* !HOST_WIN32 */
+
+ICALL_EXPORT MonoBoolean
+ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
+{
+       return mono_icall_is_64bit_os ();
+}
 
 ICALL_EXPORT MonoStringHandle
 ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
@@ -6626,65 +6615,10 @@ ves_icall_System_Environment_GetCoomandLineArgs (void)
        return result;
 }
 
-ICALL_EXPORT MonoArray *
-ves_icall_System_Environment_GetEnvironmentVariableNames (void)
+#ifndef HOST_WIN32
+static MonoArray *
+mono_icall_get_environment_variable_names (void)
 {
-#ifdef HOST_WIN32
-       MonoError error;
-       MonoArray *names;
-       MonoDomain *domain;
-       MonoString *str;
-       WCHAR* env_strings;
-       WCHAR* env_string;
-       WCHAR* equal_str;
-       int n = 0;
-
-       env_strings = GetEnvironmentStrings();
-
-       if (env_strings) {
-               env_string = env_strings;
-               while (*env_string != '\0') {
-               /* weird case that MS seems to skip */
-                       if (*env_string != '=')
-                               n++;
-                       while (*env_string != '\0')
-                               env_string++;
-                       env_string++;
-               }
-       }
-
-       domain = mono_domain_get ();
-       names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
-
-       if (env_strings) {
-               n = 0;
-               env_string = env_strings;
-               while (*env_string != '\0') {
-                       /* weird case that MS seems to skip */
-                       if (*env_string != '=') {
-                               equal_str = wcschr(env_string, '=');
-                               g_assert(equal_str);
-                               MonoError error;
-                               str = mono_string_new_utf16_checked (domain, env_string, equal_str-env_string, &error);
-                               if (mono_error_set_pending_exception (&error))
-                                       return NULL;
-
-                               mono_array_setref (names, n, str);
-                               n++;
-                       }
-                       while (*env_string != '\0')
-                               env_string++;
-                       env_string++;
-               }
-
-               FreeEnvironmentStrings (env_strings);
-       }
-
-       return names;
-
-#else
        MonoError error;
        MonoArray *names;
        MonoDomain *domain;
@@ -6715,34 +6649,22 @@ ves_icall_System_Environment_GetEnvironmentVariableNames (void)
        }
 
        return names;
-#endif
 }
+#endif /* !HOST_WIN32 */
 
-ICALL_EXPORT void
-ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
+ICALL_EXPORT MonoArray *
+ves_icall_System_Environment_GetEnvironmentVariableNames (void)
+{
+       return mono_icall_get_environment_variable_names ();
+}
+
+#ifndef HOST_WIN32
+static void
+mono_icall_set_environment_variable (MonoString *name, MonoString *value)
 {
-#ifdef HOST_WIN32
-       gunichar2 *utf16_name, *utf16_value;
-#else
        gchar *utf8_name, *utf8_value;
        MonoError error;
-#endif
-
-#ifdef HOST_WIN32
-       utf16_name = mono_string_to_utf16 (name);
-       if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
-               SetEnvironmentVariable (utf16_name, NULL);
-               g_free (utf16_name);
-               return;
-       }
-
-       utf16_value = mono_string_to_utf16 (value);
 
-       SetEnvironmentVariable (utf16_name, utf16_value);
-
-       g_free (utf16_name);
-       g_free (utf16_value);
-#else
        utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
        if (mono_error_set_pending_exception (&error))
                return;
@@ -6763,7 +6685,13 @@ ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, M
 
        g_free (utf8_name);
        g_free (utf8_value);
-#endif
+}
+#endif /* !HOST_WIN32 */
+
+ICALL_EXPORT void
+ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
+{
+       mono_icall_set_environment_variable (name, value);
 }
 
 ICALL_EXPORT void
@@ -6795,36 +6723,27 @@ ves_icall_System_Environment_GetGacPath (MonoError *error)
        return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
 }
 
-ICALL_EXPORT MonoString*
-ves_icall_System_Environment_GetWindowsFolderPath (int folder)
+#ifndef HOST_WIN32
+static inline MonoString *
+mono_icall_get_windows_folder_path (int folder)
 {
-#if defined (HOST_WIN32)
-       #ifndef CSIDL_FLAG_CREATE
-               #define CSIDL_FLAG_CREATE       0x8000
-       #endif
-
-       WCHAR path [MAX_PATH];
-       /* Create directory if no existing */
-       if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
-               int len = 0;
-               while (path [len])
-                       ++ len;
-               MonoError error;
-               MonoString *res = mono_string_new_utf16_checked (mono_domain_get (), path, len, &error);
-               mono_error_set_pending_exception (&error);
-               return res;
-       }
-#else
        g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
-#endif
        return mono_string_new (mono_domain_get (), "");
 }
+#endif /* !HOST_WIN32 */
 
-ICALL_EXPORT MonoArray *
-ves_icall_System_Environment_GetLogicalDrives (void)
+ICALL_EXPORT MonoString*
+ves_icall_System_Environment_GetWindowsFolderPath (int folder)
+{
+       return mono_icall_get_windows_folder_path (folder);
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static MonoArray *
+mono_icall_get_logical_drives (void)
 {
        MonoError error;
-        gunichar2 buf [256], *ptr, *dname;
+       gunichar2 buf [256], *ptr, *dname;
        gunichar2 *u16;
        guint initial_size = 127, size = 128;
        gint ndrives;
@@ -6879,6 +6798,13 @@ leave:
 
        return result;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+ICALL_EXPORT MonoArray *
+ves_icall_System_Environment_GetLogicalDrives (void)
+{
+       return mono_icall_get_logical_drives ();
+}
 
 ICALL_EXPORT MonoString *
 ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
@@ -6940,7 +6866,7 @@ ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
        *int_code_page = -1;
 
        g_get_charset (&cset);
-       c = codepage = strdup (cset);
+       c = codepage = g_strdup (cset);
        for (c = codepage; *c; c++){
                if (isascii (*c) && isalpha (*c))
                        *c = tolower (*c);
@@ -6987,12 +6913,18 @@ ves_icall_System_Environment_get_HasShutdownStarted (void)
        return FALSE;
 }
 
+#ifndef HOST_WIN32
+static inline void
+mono_icall_broadcast_setting_change (void)
+{
+       return;
+}
+#endif /* !HOST_WIN32 */
+
 ICALL_EXPORT void
 ves_icall_System_Environment_BroadcastSettingChange (void)
 {
-#ifdef HOST_WIN32
-       SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, (WPARAM)NULL, (LPARAM)L"Environment", SMTO_ABORTIFHUNG, 2000, 0);
-#endif
+       mono_icall_broadcast_setting_change ();
 }
 
 ICALL_EXPORT
@@ -7181,12 +7113,21 @@ ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *
        return result;
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static inline guint32
+mono_icall_drive_info_get_drive_type (MonoString *root_path_name)
+{
+       return GetDriveType (mono_string_chars (root_path_name));
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
 ICALL_EXPORT guint32
 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
 {
-       return GetDriveType (mono_string_chars (root_path_name));
+       return mono_icall_drive_info_get_drive_type (root_path_name);
 }
-#endif
+
+#endif /* PLATFORM_NO_DRIVEINFO */
 
 ICALL_EXPORT gpointer
 ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method)
@@ -7205,15 +7146,8 @@ ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
 
        path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
 
-#if defined (HOST_WIN32)
-       /* Avoid mixing '/' and '\\' */
-       {
-               gint i;
-               for (i = strlen (path) - 1; i >= 0; i--)
-                       if (path [i] == '/')
-                               path [i] = '\\';
-       }
-#endif
+       mono_icall_make_platform_path (path);
+
        mcpath = mono_string_new (mono_domain_get (), path);
        g_free (path);
 
@@ -7301,15 +7235,8 @@ ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
 
        path = g_path_get_dirname (mono_get_config_dir ());
 
-#if defined (HOST_WIN32)
-       /* Avoid mixing '/' and '\\' */
-       {
-               gint i;
-               for (i = strlen (path) - 1; i >= 0; i--)
-                       if (path [i] == '/')
-                               path [i] = '\\';
-       }
-#endif
+       mono_icall_make_platform_path (path);
+
        ipath = mono_string_new (mono_domain_get (), path);
        g_free (path);
 
@@ -7364,14 +7291,18 @@ ves_icall_System_Diagnostics_Debugger_Log (int level, MonoString *category, Mono
                mono_get_runtime_callbacks ()->debug_log (level, category, message);
 }
 
+#ifndef HOST_WIN32
+static inline void
+mono_icall_write_windows_debug_string (MonoString *message)
+{
+       g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
+}
+#endif /* !HOST_WIN32 */
+
 ICALL_EXPORT void
 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
 {
-#if defined (HOST_WIN32)
-       OutputDebugString (mono_string_chars (message));
-#else
-       g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
-#endif
+       mono_icall_write_windows_debug_string (message);
 }
 
 /* Only used for value types */
@@ -8049,14 +7980,18 @@ ves_icall_Microsoft_Win32_NativeMethods_GetExitCodeProcess (gpointer handle, gin
        return GetExitCodeProcess (handle, (guint32*) exitcode);
 }
 
+#ifndef HOST_WIN32
+static inline MonoBoolean
+mono_icall_close_process (gpointer handle)
+{
+       return CloseProcess (handle);
+}
+#endif /* !HOST_WIN32 */
+
 ICALL_EXPORT MonoBoolean
 ves_icall_Microsoft_Win32_NativeMethods_CloseProcess (gpointer handle)
 {
-#if defined(TARGET_WIN32) || defined(HOST_WIN32)
-       return CloseHandle (handle);
-#else
-       return CloseProcess (handle);
-#endif
+       return mono_icall_close_process (handle);
 }
 
 ICALL_EXPORT MonoBoolean
@@ -8065,27 +8000,46 @@ ves_icall_Microsoft_Win32_NativeMethods_TerminateProcess (gpointer handle, gint3
        return TerminateProcess (handle, exitcode);
 }
 
+#ifndef HOST_WIN32
+static inline gint32
+mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
+{
+       return WAIT_TIMEOUT;
+}
+#endif /* !HOST_WIN32 */
+
 ICALL_EXPORT gint32
 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
 {
-#ifdef HOST_WIN32
-       return WaitForInputIdle (handle, milliseconds);
-#else
-       /*TODO: Not implemented*/
-       return WAIT_TIMEOUT;
-#endif
+       return mono_icall_wait_for_input_idle (handle, milliseconds);
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static inline MonoBoolean
+mono_icall_get_process_working_set_size (gpointer handle, gsize *min, gsize *max)
+{
+       return GetProcessWorkingSetSize (handle, min, max);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
 ICALL_EXPORT MonoBoolean
 ves_icall_Microsoft_Win32_NativeMethods_GetProcessWorkingSetSize (gpointer handle, gsize *min, gsize *max)
 {
-       return GetProcessWorkingSetSize (handle, min, max);
+       return mono_icall_get_process_working_set_size (handle, min, max);
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static inline MonoBoolean
+mono_icall_set_process_working_set_size (gpointer handle, gsize min, gsize max)
+{
+       return SetProcessWorkingSetSize (handle, min, max);
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
 ICALL_EXPORT MonoBoolean
 ves_icall_Microsoft_Win32_NativeMethods_SetProcessWorkingSetSize (gpointer handle, gsize min, gsize max)
 {
-       return SetProcessWorkingSetSize (handle, min, max);
+       return mono_icall_set_process_working_set_size (handle, min, max);
 }
 
 ICALL_EXPORT MonoBoolean
@@ -8100,16 +8054,32 @@ ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
        return mono_process_current_pid ();
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static inline gint32
+mono_icall_get_priority_class (gpointer handle)
+{
+       return GetPriorityClass (handle);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
 ICALL_EXPORT gint32
 ves_icall_Microsoft_Win32_NativeMethods_GetPriorityClass (gpointer handle)
 {
-       return GetPriorityClass (handle);
+       return mono_icall_get_priority_class (handle);
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static inline MonoBoolean
+mono_icall_set_priority_class (gpointer handle, gint32 priorityClass)
+{
+       return SetPriorityClass (handle, priorityClass);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
 ICALL_EXPORT MonoBoolean
 ves_icall_Microsoft_Win32_NativeMethods_SetPriorityClass (gpointer handle, gint32 priorityClass)
 {
-       return SetPriorityClass (handle, priorityClass);
+       return mono_icall_set_priority_class (handle, priorityClass);
 }
 
 ICALL_EXPORT MonoBoolean
index 66f7d6b560d084cac2f07ffc20249e62b699c8f9..551f8a751e8e1d58edac3c6186346d64fd46100c 100644 (file)
@@ -141,8 +141,9 @@ mono_locks_lock_released (RuntimeLocks kind, gpointer lock)
        add_record (RECORD_LOCK_RELEASED, kind, lock);
 }
 #else
-       #ifdef _MSC_VER
-               // Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
-               void __mono_win32_lock_tracer_quiet_lnk4221(void) {}
-       #endif
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_lock_tracer_quiet_lnk4221(void) {}
+#endif
 #endif /* LOCK_TRACER */
diff --git a/mono/metadata/marshal-internals.h b/mono/metadata/marshal-internals.h
new file mode 100644 (file)
index 0000000..e19613a
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_METADATA_MARSHAL_INTERNALS_H__
+#define __MONO_METADATA_MARSHAL_INTERNALS_H__
+
+#include <config.h>
+#include <glib.h>
+#include <mono/metadata/object-internals.h>
+
+// On Windows platform implementation of bellow methods are hosted in separate source file
+// masrshal-windows.c or marshal-windows-*.c. On other platforms the implementation is still keept
+// in marshal.c still declared as static and in some places even inlined.
+#ifdef HOST_WIN32
+void*
+mono_marshal_alloc_co_task_mem (size_t size);
+
+void
+mono_marshal_free_co_task_mem (void *ptr);
+
+gpointer
+mono_marshal_realloc_co_task_mem (gpointer ptr, size_t size);
+
+void*
+mono_marshal_alloc_hglobal (size_t size);
+
+gpointer
+mono_marshal_realloc_hglobal (gpointer ptr, size_t size);
+
+void
+mono_marshal_free_hglobal (void *ptr);
+
+gpointer
+mono_string_to_lpstr (MonoString *s);
+#endif  /* HOST_WIN32 */
+
+#endif /* __MONO_METADATA_MARSHAL_INTERNALS_H__ */
diff --git a/mono/metadata/marshal-windows-internals.h b/mono/metadata/marshal-windows-internals.h
new file mode 100644 (file)
index 0000000..d6b3f45
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_METADATA_MARSHAL_WINDOWS_INTERNALS_H__
+#define __MONO_METADATA_MARSHAL_WINDOWS_INTERNALS_H__
+
+#include <config.h>
+#include <glib.h>
+
+#ifdef HOST_WIN32
+#include "mono/metadata/marshal.h"
+#include "mono/metadata/marshal-internals.h"
+#include "mono/metadata/exception.h"
+#endif /* HOST_WIN32 */
+
+#endif /* __MONO_METADATA_MARSHAL_WINDOWS_INTERNALS_H__ */
diff --git a/mono/metadata/marshal-windows-uwp.c b/mono/metadata/marshal-windows-uwp.c
new file mode 100644 (file)
index 0000000..a2fa813
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * marshal-windows-uwp.c: UWP marshal support for Mono.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+*/
+#include <config.h>
+#include <glib.h>
+
+#if G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT)
+#include <Windows.h>
+#include "mono/metadata/marshal-windows-internals.h"
+
+void *
+mono_marshal_alloc_hglobal (size_t size)
+{
+       return HeapAlloc (GetProcessHeap (), 0, size);
+}
+
+gpointer
+mono_marshal_realloc_hglobal (gpointer ptr, size_t size)
+{
+       return HeapReAlloc (GetProcessHeap (), 0, ptr, size);
+}
+
+void
+mono_marshal_free_hglobal (gpointer ptr)
+{
+       HeapFree (GetProcessHeap (), 0, ptr);
+       return;
+}
+
+#else /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_marshal_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
diff --git a/mono/metadata/marshal-windows.c b/mono/metadata/marshal-windows.c
new file mode 100644 (file)
index 0000000..db9d8be
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * marshal-windows.c: Windows marshal support.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#include <config.h>
+#include <glib.h>
+
+#if defined(HOST_WIN32)
+#include <WinSock2.h>
+#include <Windows.h>
+#include <objbase.h>
+#include "mono/metadata/marshal-windows-internals.h"
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+void*
+mono_marshal_alloc_hglobal (size_t size)
+{
+       return GlobalAlloc (GMEM_FIXED, size);
+}
+
+gpointer
+mono_marshal_realloc_hglobal (gpointer ptr, size_t size)
+{
+       return GlobalReAlloc (ptr, size, GMEM_MOVEABLE);
+}
+
+void
+mono_marshal_free_hglobal (gpointer ptr)
+{
+       GlobalFree (ptr);
+       return;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+void*
+mono_marshal_alloc_co_task_mem (size_t size)
+{
+       return CoTaskMemAlloc (size);
+}
+
+void
+mono_marshal_free_co_task_mem (void *ptr)
+{
+       CoTaskMemFree (ptr);
+       return;
+}
+
+gpointer
+mono_marshal_realloc_co_task_mem (gpointer ptr, size_t size)
+{
+       return CoTaskMemRealloc (ptr, size);
+}
+
+gpointer
+ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi (MonoString *string)
+{
+       MonoError error;
+       char* tres, *ret;
+       size_t len;
+       tres = mono_string_to_utf8_checked (string, &error);
+       if (mono_error_set_pending_exception (&error))
+               return NULL;
+       if (!tres)
+               return tres;
+
+       /*
+        * mono_string_to_utf8_checked() returns a memory area at least as large as the size of the
+        * MonoString, even if it contains NULL characters. The copy we allocate here has to be equally
+        * large.
+        */
+       len = MAX (strlen (tres) + 1, string->length);
+       ret = ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal ((gpointer)len);
+       memcpy (ret, tres, len);
+       g_free (tres);
+       return ret;
+}
+
+gpointer
+ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalUni (MonoString *string)
+{
+       if (string == NULL)
+               return NULL;
+       else {
+               size_t len = ((mono_string_length (string) + 1) * 2);
+               gunichar2 *res = ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal ((gpointer)len);
+
+               memcpy (res, mono_string_chars (string), mono_string_length (string) * 2);
+               res [mono_string_length (string)] = 0;
+               return res;
+       }
+}
+
+gpointer
+mono_string_to_lpstr (MonoString *s)
+{
+       char *as, *tmp;
+       glong len;
+       GError *error = NULL;
+
+       if (s == NULL)
+               return NULL;
+
+       if (!s->length) {
+               as = CoTaskMemAlloc (1);
+               as [0] = '\0';
+               return as;
+       }
+
+       tmp = g_utf16_to_utf8 (mono_string_chars (s), s->length, NULL, &len, &error);
+       if (error) {
+               MonoException *exc = mono_get_exception_argument ("string", error->message);
+               g_error_free (error);
+               mono_set_pending_exception (exc);
+               return NULL;
+       } else {
+               as = CoTaskMemAlloc (len + 1);
+               memcpy (as, tmp, len + 1);
+               g_free (tmp);
+               return as;
+       }
+}
+
+#endif /* HOST_WIN32 */
index d771d22d2ee6833810f31e5b6bbb39fbbf3fdc93..a725148ad78c8b9aef410fb93b77ee9bca0e011c 100644 (file)
@@ -20,6 +20,7 @@
 #include "loader.h"
 #include "cil-coff.h"
 #include "metadata/marshal.h"
+#include "metadata/marshal-internals.h"
 #include "metadata/method-builder.h"
 #include "metadata/tabledefs.h"
 #include "metadata/exception.h"
 #include <string.h>
 #include <errno.h>
 
-#if defined(HOST_WIN32)
-#include <objbase.h>
-#endif
-
 /* #define DEBUG_RUNTIME_CODE */
 
 #define OPDEF(a,b,c,d,e,f,g,h,i,j) \
@@ -110,8 +107,10 @@ mono_marshal_string_to_utf16 (MonoString *s);
 static void *
 mono_marshal_string_to_utf16_copy (MonoString *s);
 
+#ifndef HOST_WIN32
 static gpointer
 mono_string_to_lpstr (MonoString *string_obj);
+#endif
 
 static MonoStringBuilder *
 mono_string_utf8_to_builder2 (char *text);
@@ -1080,42 +1079,16 @@ mono_string_builder_to_utf16 (MonoStringBuilder *sb)
 }
 
 /* This is a JIT icall, it sets the pending exception and returns NULL on error. */
+#ifndef HOST_WIN32
 static gpointer
 mono_string_to_lpstr (MonoString *s)
 {
-#ifdef TARGET_WIN32
-       char *as, *tmp;
-       glong len;
-       GError *error = NULL;
-
-       if (s == NULL)
-               return NULL;
-
-       if (!s->length) {
-               as = CoTaskMemAlloc (1);
-               as [0] = '\0';
-               return as;
-       }
-
-       tmp = g_utf16_to_utf8 (mono_string_chars (s), s->length, NULL, &len, &error);
-       if (error) {
-               MonoException *exc = mono_get_exception_argument ("string", error->message);
-               g_error_free (error);
-               mono_set_pending_exception (exc);
-               return NULL;
-       } else {
-               as = CoTaskMemAlloc (len + 1);
-               memcpy (as, tmp, len + 1);
-               g_free (tmp);
-               return as;
-       }
-#else
        MonoError error;
        char *result = mono_string_to_utf8_checked (s, &error);
        mono_error_set_pending_exception (&error);
        return result;
-#endif
-}      
+}
+#endif /* HOST_WIN32 */
 
 gpointer
 mono_string_to_ansibstr (MonoString *string_obj)
@@ -10524,6 +10497,18 @@ mono_marshal_get_array_accessor_wrapper (MonoMethod *method)
        return res;     
 }
 
+#ifndef HOST_WIN32
+static inline void*
+mono_marshal_alloc_co_task_mem (size_t size)
+{
+       if ((gulong)size == 0)
+               /* This returns a valid pointer for size 0 on MS.NET */
+               size = 4;
+
+       return g_try_malloc ((gulong)size);
+}
+#endif
+
 void*
 mono_marshal_alloc (gulong size, MonoError *error)
 {
@@ -10531,13 +10516,10 @@ mono_marshal_alloc (gulong size, MonoError *error)
 
        mono_error_init (error);
 
-#ifdef HOST_WIN32
-       res = CoTaskMemAlloc (size);
-#else
-       res = g_try_malloc ((gulong)size);
+       res = mono_marshal_alloc_co_task_mem (size);
        if (!res)
                mono_error_set_out_of_memory (error, "Could not allocate %lu bytes", size);
-#endif
+
        return res;
 }
 
@@ -10555,14 +10537,19 @@ ves_icall_marshal_alloc (gulong size)
        return ret;
 }
 
-void
-mono_marshal_free (gpointer ptr)
+#ifndef HOST_WIN32
+static inline void
+mono_marshal_free_co_task_mem (void *ptr)
 {
-#ifdef HOST_WIN32
-       CoTaskMemFree (ptr);
-#else
        g_free (ptr);
+       return;
+}
 #endif
+
+void
+mono_marshal_free (gpointer ptr)
+{
+       mono_marshal_free_co_task_mem (ptr);
 }
 
 void
@@ -10961,35 +10948,14 @@ ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf (MonoReflectionType *t
        return info->fields [match_index].offset;
 }
 
+#ifndef HOST_WIN32
 gpointer
 ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi (MonoString *string)
 {
        MonoError error;
-#ifdef HOST_WIN32
-       char* tres, *ret;
-       size_t len;
-       tres = mono_string_to_utf8_checked (string, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
-       if (!tres)
-               return tres;
-
-       /*
-        * mono_string_to_utf8_checked() returns a memory area at least as large as the size of the
-        * MonoString, even if it contains NULL characters. The copy we allocate here has to be equally
-        * large.
-        */
-       len = MAX (strlen (tres) + 1, string->length);
-       ret = ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal (len);
-       memcpy (ret, tres, len);
-       g_free (tres);
-       return ret;
-
-#else
        char *ret = mono_string_to_utf8_checked (string, &error);
        mono_error_set_pending_exception (&error);
        return ret;
-#endif
 }
 
 gpointer
@@ -10998,17 +10964,14 @@ ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalUni (MonoString
        if (string == NULL)
                return NULL;
        else {
-#ifdef TARGET_WIN32
-               gunichar2 *res = ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal 
-                       ((mono_string_length (string) + 1) * 2);
-#else
                gunichar2 *res = (gunichar2 *)g_malloc ((mono_string_length (string) + 1) * 2);
-#endif
+
                memcpy (res, mono_string_chars (string), mono_string_length (string) * 2);
                res [mono_string_length (string)] = 0;
                return res;
        }
 }
+#endif /* !HOST_WIN32 */
 
 static void
 mono_struct_delete_old (MonoClass *klass, char *ptr)
@@ -11077,6 +11040,14 @@ ves_icall_System_Runtime_InteropServices_Marshal_DestroyStructure (gpointer src,
        mono_struct_delete_old (klass, (char *)src);
 }
 
+#ifndef HOST_WIN32
+static inline void *
+mono_marshal_alloc_hglobal (size_t size)
+{
+       return g_try_malloc (size);
+}
+#endif
+
 void*
 ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal (gpointer size)
 {
@@ -11087,11 +11058,8 @@ ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal (gpointer size)
                /* This returns a valid pointer for size 0 on MS.NET */
                s = 4;
 
-#ifdef HOST_WIN32
-       res = GlobalAlloc (GMEM_FIXED, s);
-#else
-       res = g_try_malloc (s);
-#endif
+       res = mono_marshal_alloc_hglobal (s);
+
        if (!res) {
                mono_set_pending_exception (mono_domain_get ()->out_of_memory_ex);
                return NULL;
@@ -11100,6 +11068,14 @@ ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal (gpointer size)
        return res;
 }
 
+#ifndef HOST_WIN32
+static inline gpointer
+mono_marshal_realloc_hglobal (gpointer ptr, size_t size)
+{
+       return g_try_realloc (ptr, size);
+}
+#endif
+
 gpointer
 ves_icall_System_Runtime_InteropServices_Marshal_ReAllocHGlobal (gpointer ptr, gpointer size)
 {
@@ -11111,11 +11087,8 @@ ves_icall_System_Runtime_InteropServices_Marshal_ReAllocHGlobal (gpointer ptr, g
                return NULL;
        }
 
-#ifdef HOST_WIN32
-       res = GlobalReAlloc (ptr, s, GMEM_MOVEABLE);
-#else
-       res = g_try_realloc (ptr, s);
-#endif
+       res = mono_marshal_realloc_hglobal (ptr, s);
+
        if (!res) {
                mono_set_pending_exception (mono_domain_get ()->out_of_memory_ex);
                return NULL;
@@ -11124,30 +11097,26 @@ ves_icall_System_Runtime_InteropServices_Marshal_ReAllocHGlobal (gpointer ptr, g
        return res;
 }
 
-void
-ves_icall_System_Runtime_InteropServices_Marshal_FreeHGlobal (void *ptr)
+#ifndef HOST_WIN32
+static inline void
+mono_marshal_free_hglobal (gpointer ptr)
 {
-#ifdef HOST_WIN32
-       GlobalFree (ptr);
-#else
        g_free (ptr);
+       return;
+}
 #endif
+
+void
+ves_icall_System_Runtime_InteropServices_Marshal_FreeHGlobal (void *ptr)
+{
+       mono_marshal_free_hglobal (ptr);
 }
 
 void*
 ves_icall_System_Runtime_InteropServices_Marshal_AllocCoTaskMem (int size)
 {
-       void *res;
-
-#ifdef HOST_WIN32
-       res = CoTaskMemAlloc (size);
-#else
-       if ((gulong)size == 0)
-               /* This returns a valid pointer for size 0 on MS.NET */
-               size = 4;
+       void *res = mono_marshal_alloc_co_task_mem (size);
 
-       res = g_try_malloc ((gulong)size);
-#endif
        if (!res) {
                mono_set_pending_exception (mono_domain_get ()->out_of_memory_ex);
                return NULL;
@@ -11158,23 +11127,23 @@ ves_icall_System_Runtime_InteropServices_Marshal_AllocCoTaskMem (int size)
 void
 ves_icall_System_Runtime_InteropServices_Marshal_FreeCoTaskMem (void *ptr)
 {
-#ifdef HOST_WIN32
-       CoTaskMemFree (ptr);
-#else
-       g_free (ptr);
-#endif
+       mono_marshal_free_co_task_mem (ptr);
+       return;
 }
 
+#ifndef HOST_WIN32
+static inline gpointer
+mono_marshal_realloc_co_task_mem (gpointer ptr, size_t size)
+{
+       return g_try_realloc (ptr, (gulong)size);
+}
+#endif
+
 gpointer
 ves_icall_System_Runtime_InteropServices_Marshal_ReAllocCoTaskMem (gpointer ptr, int size)
 {
-       void *res;
+       void *res = mono_marshal_realloc_co_task_mem (ptr, size);
 
-#ifdef HOST_WIN32
-       res = CoTaskMemRealloc (ptr, size);
-#else
-       res = g_try_realloc (ptr, (gulong)size);
-#endif
        if (!res) {
                mono_set_pending_exception (mono_domain_get ()->out_of_memory_ex);
                return NULL;
diff --git a/mono/metadata/mono-security-windows-internals.h b/mono/metadata/mono-security-windows-internals.h
new file mode 100644 (file)
index 0000000..a7cc247
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_METADATA_MONO_SECURITY_WINDOWS_INTERNALS_H__
+#define __MONO_METADATA_MONO_SECURITY_WINDOWS_INTERNALS_H__
+
+#include <config.h>
+#include <glib.h>
+
+#ifdef HOST_WIN32
+#include "mono/metadata/security.h"
+#include "mono/metadata/object.h"
+#include "mono/metadata/object-internals.h"
+#include "mono/metadata/metadata.h"
+#include "mono/metadata/metadata-internals.h"
+
+gint32
+mono_security_win_get_token_name (gpointer token, gunichar2 ** uniname);
+
+gboolean
+mono_security_win_is_machine_protected (gunichar2 *path);
+
+gboolean
+mono_security_win_is_user_protected (gunichar2 *path);
+
+gboolean
+mono_security_win_protect_machine (gunichar2 *path);
+
+gboolean
+mono_security_win_protect_user (gunichar2 *path);
+#endif /* HOST_WIN32 */
+
+#endif /* __MONO_METADATA_MONO_SECURITY_WINDOWS_INTERNALS_H__ */
diff --git a/mono/metadata/mono-security-windows-uwp.c b/mono/metadata/mono-security-windows-uwp.c
new file mode 100644 (file)
index 0000000..791e76c
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * mono-security-windows-uwp.c: UWP security support for Mono.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+*/
+#include <config.h>
+#include <glib.h>
+
+#if G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT)
+#include <Windows.h>
+#include "mono/metadata/mono-security-windows-internals.h"
+
+gpointer
+ves_icall_System_Security_Principal_WindowsIdentity_GetCurrentToken (void)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("OpenThreadToken, OpenProcessToken");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "OpenThreadToken, OpenProcessToken");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return NULL;
+}
+
+MonoArray*
+ves_icall_System_Security_Principal_WindowsIdentity_GetRoles (gpointer token)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("GetTokenInformation");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "GetTokenInformation");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return NULL;
+}
+
+gpointer
+ves_icall_System_Security_Principal_WindowsImpersonationContext_DuplicateToken (gpointer token)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("DuplicateToken");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "DuplicateToken");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return NULL;
+}
+
+gboolean
+ves_icall_System_Security_Principal_WindowsImpersonationContext_SetCurrentToken (gpointer token)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("ImpersonateLoggedOnUser");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "ImpersonateLoggedOnUser");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+gboolean
+ves_icall_System_Security_Principal_WindowsImpersonationContext_RevertToSelf (void)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("RevertToSelf");
+
+       mono_error_set_not_supported(&mono_error, G_UNSUPPORTED_API, "RevertToSelf");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+gint32
+mono_security_win_get_token_name (gpointer token, gunichar2 ** uniname)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("GetTokenInformation");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "GetTokenInformation");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return 0;
+}
+
+gboolean
+mono_security_win_is_machine_protected (gunichar2 *path)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("GetNamedSecurityInfo, LocalFree");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "GetNamedSecurityInfo, LocalFree");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+gboolean
+mono_security_win_is_user_protected (gunichar2 *path)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("GetNamedSecurityInfo, LocalFree");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "GetNamedSecurityInfo, LocalFree");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+gboolean
+mono_security_win_protect_machine (gunichar2 *path)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("BuildTrusteeWithSid, SetEntriesInAcl, SetNamedSecurityInfo, LocalFree, FreeSid");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "BuildTrusteeWithSid, SetEntriesInAcl, SetNamedSecurityInfo, LocalFree, FreeSid");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+gboolean
+mono_security_win_protect_user (gunichar2 *path)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("BuildTrusteeWithSid, SetEntriesInAcl, SetNamedSecurityInfo, LocalFree");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "BuildTrusteeWithSid, SetEntriesInAcl, SetNamedSecurityInfo, LocalFree");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+#else /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_mono_security_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
diff --git a/mono/metadata/mono-security-windows.c b/mono/metadata/mono-security-windows.c
new file mode 100644 (file)
index 0000000..fda26d3
--- /dev/null
@@ -0,0 +1,495 @@
+/*
+ * mono-security-windows.c: Windows security support.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#include <config.h>
+#include <glib.h>
+
+#if defined(HOST_WIN32)
+#include <WinSock2.h>
+#include <Windows.h>
+#include "mono/metadata/mono-security-windows-internals.h"
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+#include <aclapi.h>
+#include <accctrl.h>
+#endif
+
+#ifndef PROTECTED_DACL_SECURITY_INFORMATION
+#define PROTECTED_DACL_SECURITY_INFORMATION    0x80000000L
+#endif
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static gunichar2*
+GetSidName (gunichar2 *server, PSID sid, gint32 *size)
+{
+       gunichar2 *uniname = NULL;
+       DWORD cchName = 0;
+       DWORD cchDomain = 0;
+       SID_NAME_USE peUse; /* out */
+
+       LookupAccountSid (server, sid, NULL, &cchName, NULL,
+               &cchDomain, &peUse);
+
+       if ((cchName > 0) && (cchDomain > 0)) {
+               gunichar2 *user = g_malloc0 ((cchName + 1) * 2);
+               gunichar2 *domain = g_malloc0 ((cchDomain + 1) * 2);
+
+               LookupAccountSid (server, sid, user, &cchName, domain,
+                       &cchDomain, &peUse);
+
+               if (cchName > 0) {
+                       if (cchDomain > 0) {
+                               /* domain/machine name included (+ sepearator) */
+                               *size = cchName + cchDomain + 1;
+                               uniname = g_malloc0 ((*size + 1) * 2);
+                               memcpy (uniname, domain, cchDomain * 2);
+                               *(uniname + cchDomain) = '\\';
+                               memcpy (uniname + cchDomain + 1, user, cchName * 2);
+                               g_free (user);
+                       }
+                       else {
+                               /* no domain / machine */
+                               *size = cchName;
+                               uniname = user;
+                       }
+               }
+               else {
+                       /* nothing -> return NULL */
+                       g_free (user);
+               }
+
+               g_free (domain);
+       }
+
+       return uniname;
+}
+
+gpointer
+ves_icall_System_Security_Principal_WindowsIdentity_GetCurrentToken (void)
+{
+       gpointer token = NULL;
+
+       /* Note: This isn't a copy of the Token - we must not close it!!!
+        * http://www.develop.com/kbrown/book/html/whatis_windowsprincipal.html
+        */
+
+       /* thread may be impersonating somebody */
+       if (OpenThreadToken (GetCurrentThread (), MAXIMUM_ALLOWED, 1, &token) == 0) {
+               /* if not take the process identity */
+               OpenProcessToken (GetCurrentProcess (), MAXIMUM_ALLOWED, &token);
+       }
+
+       return token;
+}
+
+gint32
+mono_security_win_get_token_name (gpointer token, gunichar2 ** uniname)
+{
+       gint32 size = 0;
+
+       GetTokenInformation (token, TokenUser, NULL, size, (PDWORD)&size);
+       if (size > 0) {
+               TOKEN_USER *tu = g_malloc0 (size);
+               if (GetTokenInformation (token, TokenUser, tu, size, (PDWORD)&size)) {
+                       *uniname = GetSidName (NULL, tu->User.Sid, &size);
+               }
+               g_free (tu);
+       }
+
+       return size;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+MonoString*
+ves_icall_System_Security_Principal_WindowsIdentity_GetTokenName (gpointer token)
+{
+       MonoError error;
+       MonoString *result = NULL;
+       gunichar2 *uniname = NULL;
+       gint32 size = 0;
+
+       mono_error_init (&error);
+
+       size = mono_security_win_get_token_name (token, &uniname);
+
+       if (size > 0) {
+               result = mono_string_new_utf16_checked (mono_domain_get (), uniname, size, &error);
+       }
+       else
+               result = mono_string_new (mono_domain_get (), "");
+
+       if (uniname)
+               g_free (uniname);
+
+       mono_error_set_pending_exception (&error);
+       return result;
+}
+
+gpointer
+ves_icall_System_Security_Principal_WindowsIdentity_GetUserToken (MonoString *username)
+{
+       gpointer token = NULL;
+
+       /* TODO: MS has something like this working in Windows 2003 (client and
+        * server) but works only for domain accounts (so it's quite limiting).
+        * http://www.develop.com/kbrown/book/html/howto_logonuser.html
+        */
+       g_warning ("Unsupported on Win32 (anyway requires W2K3 minimum)");
+       return token;
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+MonoArray*
+ves_icall_System_Security_Principal_WindowsIdentity_GetRoles (gpointer token)
+{
+       MonoError error;
+       MonoArray *array = NULL;
+       MonoDomain *domain = mono_domain_get ();
+
+       gint32 size = 0;
+
+       GetTokenInformation (token, TokenGroups, NULL, size, (PDWORD)&size);
+       if (size > 0) {
+               TOKEN_GROUPS *tg = g_malloc0 (size);
+               if (GetTokenInformation (token, TokenGroups, tg, size, (PDWORD)&size)) {
+                       int i=0;
+                       int num = tg->GroupCount;
+
+                       array = mono_array_new_checked (domain, mono_get_string_class (), num, &error);
+                       if (mono_error_set_pending_exception (&error)) {
+                               g_free (tg);
+                               return NULL;
+                       }
+
+                       for (i=0; i < num; i++) {
+                               gint32 size = 0;
+                               gunichar2 *uniname = GetSidName (NULL, tg->Groups [i].Sid, &size);
+
+                               if (uniname) {
+                                       MonoString *str = mono_string_new_utf16_checked (domain, uniname, size, &error);
+                                       if (!is_ok (&error)) {
+                                               g_free (uniname);
+                                               g_free (tg);
+                                               mono_error_set_pending_exception (&error);
+                                               return NULL;
+                                       }
+                                       mono_array_setref (array, i, str);
+                                       g_free (uniname);
+                               }
+                       }
+               }
+               g_free (tg);
+       }
+
+       if (!array) {
+               /* return empty array of string, i.e. string [0] */
+               array = mono_array_new_checked (domain, mono_get_string_class (), 0, &error);
+               mono_error_set_pending_exception (&error);
+       }
+       return array;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+gboolean
+ves_icall_System_Security_Principal_WindowsImpersonationContext_CloseToken (gpointer token)
+{
+       gboolean result = TRUE;
+       result = (CloseHandle (token) != 0);
+       return result;
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+gpointer
+ves_icall_System_Security_Principal_WindowsImpersonationContext_DuplicateToken (gpointer token)
+{
+       gpointer dupe = NULL;
+
+       if (DuplicateToken (token, SecurityImpersonation, &dupe) == 0) {
+               dupe = NULL;
+       }
+       return dupe;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+gboolean
+ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupId (gpointer user, gpointer group)
+{
+       gboolean result = FALSE;
+
+       /* The convertion from an ID to a string is done in managed code for Windows */
+       g_warning ("IsMemberOfGroupId should never be called on Win32");
+       return result;
+}
+
+gboolean
+ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupName (gpointer user, MonoString *group)
+{
+       gboolean result = FALSE;
+
+       /* Windows version use a cache built using WindowsIdentity._GetRoles */
+       g_warning ("IsMemberOfGroupName should never be called on Win32");
+       return result;
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static PSID
+GetAdministratorsSid (void)
+{
+       SID_IDENTIFIER_AUTHORITY admins = { SECURITY_NT_AUTHORITY };
+       PSID pSid = NULL;
+       if (!AllocateAndInitializeSid (&admins, 2, SECURITY_BUILTIN_DOMAIN_RID,
+               DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSid))
+               return NULL;
+       /* Note: this SID must be freed with FreeSid () */
+       return pSid;
+}
+
+static PSID
+GetEveryoneSid (void)
+{
+       SID_IDENTIFIER_AUTHORITY everyone = { SECURITY_WORLD_SID_AUTHORITY };
+       PSID pSid = NULL;
+       if (!AllocateAndInitializeSid (&everyone, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSid))
+               return NULL;
+       /* Note: this SID must be freed with FreeSid () */
+       return pSid;
+}
+
+static PSID
+GetCurrentUserSid (void)
+{
+       PSID sid = NULL;
+       guint32 size = 0;
+       gpointer token = ves_icall_System_Security_Principal_WindowsIdentity_GetCurrentToken ();
+
+       GetTokenInformation (token, TokenUser, NULL, size, (PDWORD)&size);
+       if (size > 0) {
+               TOKEN_USER *tu = g_malloc0 (size);
+               if (GetTokenInformation (token, TokenUser, tu, size, (PDWORD)&size)) {
+                       DWORD length = GetLengthSid (tu->User.Sid);
+                       sid = (PSID) g_malloc0 (length);
+                       if (!CopySid (length, sid, tu->User.Sid)) {
+                               g_free (sid);
+                               sid = NULL;
+                       }
+               }
+               g_free (tu);
+       }
+       /* Note: this SID must be freed with g_free () */
+       return sid;
+}
+
+static ACCESS_MASK
+GetRightsFromSid (PSID sid, PACL acl)
+{
+       ACCESS_MASK rights = 0;
+       TRUSTEE trustee;
+
+       BuildTrusteeWithSidW (&trustee, sid);
+       if (GetEffectiveRightsFromAcl (acl, &trustee, &rights) != ERROR_SUCCESS)
+               return 0;
+
+       return rights;
+}
+
+gboolean
+mono_security_win_is_machine_protected (gunichar2 *path)
+{
+       gboolean success = FALSE;
+       PACL pDACL = NULL;
+       PSECURITY_DESCRIPTOR pSD = NULL;
+       PSID pEveryoneSid = NULL;
+
+       DWORD dwRes = GetNamedSecurityInfoW (path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, &pSD);
+       if (dwRes != ERROR_SUCCESS)
+               return FALSE;
+
+       /* We check that Everyone is still limited to READ-ONLY -
+       but not if new entries have been added by an Administrator */
+
+       pEveryoneSid = GetEveryoneSid ();
+       if (pEveryoneSid) {
+               ACCESS_MASK rights = GetRightsFromSid (pEveryoneSid, pDACL);
+               /* http://msdn.microsoft.com/library/en-us/security/security/generic_access_rights.asp?frame=true */
+               success = (rights == (READ_CONTROL | SYNCHRONIZE | FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES));
+               FreeSid (pEveryoneSid);
+       }
+       /* Note: we don't need to check our own access -
+       we'll know soon enough when reading the file */
+
+       if (pSD)
+               LocalFree (pSD);
+
+       return success;
+}
+
+gboolean
+mono_security_win_is_user_protected (gunichar2 *path)
+{
+       gboolean success = FALSE;
+       PACL pDACL = NULL;
+       PSID pEveryoneSid = NULL;
+       PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
+
+       DWORD dwRes = GetNamedSecurityInfoW (path, SE_FILE_OBJECT,
+               DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, &pSecurityDescriptor);
+       if (dwRes != ERROR_SUCCESS)
+               return FALSE;
+
+       /* We check that our original entries in the ACL are in place -
+       but not if new entries have been added by the user */
+
+       /* Everyone should be denied */
+       pEveryoneSid = GetEveryoneSid ();
+       if (pEveryoneSid) {
+               ACCESS_MASK rights = GetRightsFromSid (pEveryoneSid, pDACL);
+               success = (rights == 0);
+               FreeSid (pEveryoneSid);
+       }
+       /* Note: we don't need to check our own access -
+       we'll know soon enough when reading the file */
+
+       if (pSecurityDescriptor)
+               LocalFree (pSecurityDescriptor);
+
+       return success;
+}
+
+gboolean
+mono_security_win_protect_machine (gunichar2 *path)
+{
+       PSID pEveryoneSid = GetEveryoneSid ();
+       PSID pAdminsSid = GetAdministratorsSid ();
+       DWORD retval = -1;
+
+       if (pEveryoneSid && pAdminsSid) {
+               PACL pDACL = NULL;
+               EXPLICIT_ACCESS ea [2];
+               ZeroMemory (&ea, 2 * sizeof (EXPLICIT_ACCESS));
+
+               /* grant all access to the BUILTIN\Administrators group */
+               BuildTrusteeWithSidW (&ea [0].Trustee, pAdminsSid);
+               ea [0].grfAccessPermissions = GENERIC_ALL;
+               ea [0].grfAccessMode = SET_ACCESS;
+               ea [0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
+               ea [0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+               ea [0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
+
+               /* read-only access everyone */
+               BuildTrusteeWithSidW (&ea [1].Trustee, pEveryoneSid);
+               ea [1].grfAccessPermissions = GENERIC_READ;
+               ea [1].grfAccessMode = SET_ACCESS;
+               ea [1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
+               ea [1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+               ea [1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
+
+               retval = SetEntriesInAcl (2, ea, NULL, &pDACL);
+               if (retval == ERROR_SUCCESS) {
+                       /* with PROTECTED_DACL_SECURITY_INFORMATION we */
+                       /* remove any existing ACL (like inherited ones) */
+                       retval = SetNamedSecurityInfo (path, SE_FILE_OBJECT,
+                               DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
+                               NULL, NULL, pDACL, NULL);
+               }
+               if (pDACL)
+                       LocalFree (pDACL);
+       }
+
+       if (pEveryoneSid)
+               FreeSid (pEveryoneSid);
+       if (pAdminsSid)
+               FreeSid (pAdminsSid);
+       return (retval == ERROR_SUCCESS);
+}
+
+gboolean
+mono_security_win_protect_user (gunichar2 *path)
+{
+       DWORD retval = -1;
+
+       PSID pCurrentSid = GetCurrentUserSid ();
+       if (pCurrentSid) {
+               PACL pDACL = NULL;
+               EXPLICIT_ACCESS ea;
+               ZeroMemory (&ea, sizeof (EXPLICIT_ACCESS));
+
+               /* grant exclusive access to the current user */
+               BuildTrusteeWithSidW (&ea.Trustee, pCurrentSid);
+               ea.grfAccessPermissions = GENERIC_ALL;
+               ea.grfAccessMode = SET_ACCESS;
+               ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
+               ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
+               ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
+
+               retval = SetEntriesInAcl (1, &ea, NULL, &pDACL);
+               if (retval == ERROR_SUCCESS) {
+                       /* with PROTECTED_DACL_SECURITY_INFORMATION we
+                          remove any existing ACL (like inherited ones) */
+                       retval = SetNamedSecurityInfo (path, SE_FILE_OBJECT,
+                               DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
+                               NULL, NULL, pDACL, NULL);
+               }
+
+               if (pDACL)
+                       LocalFree (pDACL);
+               g_free (pCurrentSid); /* g_malloc0 */
+       }
+
+       return (retval == ERROR_SUCCESS);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+MonoBoolean
+ves_icall_Mono_Security_Cryptography_KeyPairPersistence_CanSecure (MonoString *root)
+{
+       gint32 flags;
+
+       /* ACL are nice... unless you have FAT or other uncivilized filesystem */
+       if (!GetVolumeInformation (mono_string_chars (root), NULL, 0, NULL, NULL, (LPDWORD)&flags, NULL, 0))
+               return FALSE;
+       return ((flags & FS_PERSISTENT_ACLS) == FS_PERSISTENT_ACLS);
+}
+
+MonoBoolean
+ves_icall_Mono_Security_Cryptography_KeyPairPersistence_IsMachineProtected (MonoString *path)
+{
+       gboolean ret = FALSE;
+
+       /* no one, but the owner, should have write access to the directory */
+       ret = mono_security_win_is_machine_protected (mono_string_chars (path));
+       return (MonoBoolean)ret;
+}
+
+MonoBoolean
+ves_icall_Mono_Security_Cryptography_KeyPairPersistence_IsUserProtected (MonoString *path)
+{
+       gboolean ret = FALSE;
+
+       /* no one, but the user, should have access to the directory */
+       ret = mono_security_win_is_user_protected (mono_string_chars (path));
+       return (MonoBoolean)ret;
+}
+
+MonoBoolean
+ves_icall_Mono_Security_Cryptography_KeyPairPersistence_ProtectMachine (MonoString *path)
+{
+       gboolean ret = FALSE;
+
+       /* read/write to owner, read to everyone else */
+       ret = mono_security_win_protect_machine (mono_string_chars (path));
+       return (MonoBoolean)ret;
+}
+
+MonoBoolean
+ves_icall_Mono_Security_Cryptography_KeyPairPersistence_ProtectUser (MonoString *path)
+{
+       gboolean ret = FALSE;
+
+       /* read/write to user, no access to everyone else */
+       ret = mono_security_win_protect_user (mono_string_chars (path));
+       return (MonoBoolean)ret;
+}
+#endif /* HOST_WIN32 */
index 865b9ca1e04236ec1a7c7840436fca8c6e02de8a..09b8cd44abe6deaba2428602aa257022dbf21a88 100644 (file)
 #include <mono/io-layer/io-layer.h>
 #include <mono/utils/strenc.h>
 
-#ifdef HOST_WIN32
-
-#include <aclapi.h>
-#include <accctrl.h>
-
-#ifndef PROTECTED_DACL_SECURITY_INFORMATION
-#define PROTECTED_DACL_SECURITY_INFORMATION    0x80000000L
-#endif
-
-#else
-
+#ifndef HOST_WIN32
 #include <config.h>
 #ifdef HAVE_GRP_H
 #include <grp.h>
 #endif
 
 #endif /* defined(__GNUC__) */
-
-#endif /* not HOST_WIN32 */
-
+#endif /* !HOST_WIN32 */
 
 /* internal functions - reuse driven */
 
-#ifdef HOST_WIN32
-
 /* ask a server to translate a SID into a textual representation */
-static gunichar2*
-GetSidName (gunichar2 *server, PSID sid, gint32 *size) 
-{
-       gunichar2 *uniname = NULL;
-       DWORD cchName = 0;
-       DWORD cchDomain = 0;
-       SID_NAME_USE peUse; /* out */
-
-       LookupAccountSid (server, sid, NULL, &cchName, NULL, 
-               &cchDomain, &peUse); 
-       
-       if ((cchName > 0) && (cchDomain > 0)) {
-               gunichar2 *user = g_malloc0 ((cchName + 1) * 2);
-               gunichar2 *domain = g_malloc0 ((cchDomain + 1) * 2);
-
-               LookupAccountSid (server, sid, user, &cchName, domain,
-                       &cchDomain, &peUse);
-
-               if (cchName > 0) {
-                       if (cchDomain > 0) {
-                               /* domain/machine name included (+ sepearator) */
-                               *size = cchName + cchDomain + 1;
-                               uniname = g_malloc0 ((*size + 1) * 2);
-                               memcpy (uniname, domain, cchDomain * 2);
-                               *(uniname + cchDomain) = '\\';
-                               memcpy (uniname + cchDomain + 1, user, cchName * 2);
-                               g_free (user);
-                       }
-                       else {
-                               /* no domain / machine */
-                               *size = cchName;
-                               uniname = user;
-                       }
-               }
-               else {
-                       /* nothing -> return NULL */
-                       g_free (user);
-               }
-
-               g_free (domain);
-       }
-
-       return uniname;
-}
-
-
-#else /* not HOST_WIN32 */
-
+#ifndef HOST_WIN32
 #define MONO_SYSCONF_DEFAULT_SIZE      ((size_t) 1024)
 
 /*
@@ -133,7 +72,6 @@ static size_t mono_sysconf (int name)
        return (size == -1) ? MONO_SYSCONF_DEFAULT_SIZE : size;
 }
 
-
 static gchar*
 GetTokenName (uid_t uid)
 {
@@ -174,7 +112,6 @@ GetTokenName (uid_t uid)
        return uname;
 }
 
-
 static gboolean
 IsMemberInList (uid_t user, struct group *g) 
 {
@@ -201,7 +138,6 @@ IsMemberInList (uid_t user, struct group *g)
        return result;
 }
 
-
 static gboolean
 IsDefaultGroup (uid_t user, gid_t group)
 {
@@ -241,7 +177,6 @@ IsDefaultGroup (uid_t user, gid_t group)
        return result;
 }
 
-
 static gboolean
 IsMemberOf (gid_t user, struct group *g) 
 {
@@ -255,37 +190,34 @@ IsMemberOf (gid_t user, struct group *g)
        /* is the user in the group list */
        return IsMemberInList (user, g);
 }
-
-#endif
-
+#endif /* !HOST_WIN32 */
 
 /* ICALLS */
 
-
 /* System.Security.Principal.WindowsIdentity */
 
-
+#ifndef HOST_WIN32
 gpointer
 ves_icall_System_Security_Principal_WindowsIdentity_GetCurrentToken (void)
 {
-       gpointer token = NULL;
+       return GINT_TO_POINTER (geteuid ());
+}
+
+static gint32
+internal_get_token_name (gpointer token, gunichar2 ** uniname)
+{
+       gint32 size = 0;
 
-#ifdef HOST_WIN32
-       /* Note: This isn't a copy of the Token - we must not close it!!!
-        * http://www.develop.com/kbrown/book/html/whatis_windowsprincipal.html
-        */
+       gchar *uname = GetTokenName ((uid_t) GPOINTER_TO_INT (token));
 
-       /* thread may be impersonating somebody */
-       if (OpenThreadToken (GetCurrentThread (), MAXIMUM_ALLOWED, 1, &token) == 0) {
-               /* if not take the process identity */
-               OpenProcessToken (GetCurrentProcess (), MAXIMUM_ALLOWED, &token);
+       if (uname) {
+               size = strlen (uname);
+               *uniname = g_utf8_to_utf16 (uname, size, NULL, NULL, NULL);
+               g_free (uname);
        }
-#else
-       token = GINT_TO_POINTER (geteuid ());
-#endif
-       return token;
-}
 
+       return size;
+}
 
 MonoString*
 ves_icall_System_Security_Principal_WindowsIdentity_GetTokenName (gpointer token)
@@ -296,24 +228,8 @@ ves_icall_System_Security_Principal_WindowsIdentity_GetTokenName (gpointer token
        gint32 size = 0;
 
        mono_error_init (&error);
-#ifdef HOST_WIN32
-       GetTokenInformation (token, TokenUser, NULL, size, (PDWORD)&size);
-       if (size > 0) {
-               TOKEN_USER *tu = g_malloc0 (size);
-               if (GetTokenInformation (token, TokenUser, tu, size, (PDWORD)&size)) {
-                       uniname = GetSidName (NULL, tu->User.Sid, &size);
-               }
-               g_free (tu);
-       }
-#else 
-       gchar *uname = GetTokenName ((uid_t) GPOINTER_TO_INT (token));
 
-       if (uname) {
-               size = strlen (uname);
-               uniname = g_utf8_to_utf16 (uname, size, NULL, NULL, NULL);
-               g_free (uname);
-       }
-#endif /* HOST_WIN32 */
+       size = internal_get_token_name (token, &uniname);
 
        if (size > 0) {
                result = mono_string_new_utf16_checked (mono_domain_get (), uniname, size, &error);
@@ -327,22 +243,12 @@ ves_icall_System_Security_Principal_WindowsIdentity_GetTokenName (gpointer token
        mono_error_set_pending_exception (&error);
        return result;
 }
+#endif  /* !HOST_WIN32 */
 
-
+#ifndef HOST_WIN32
 gpointer
 ves_icall_System_Security_Principal_WindowsIdentity_GetUserToken (MonoString *username)
 {
-#ifdef HOST_WIN32
-       gpointer token = NULL;
-
-       /* TODO: MS has something like this working in Windows 2003 (client and
-        * server) but works only for domain accounts (so it's quite limiting).
-        * http://www.develop.com/kbrown/book/html/howto_logonuser.html
-        */
-       g_warning ("Unsupported on Win32 (anyway requires W2K3 minimum)");
-
-#else /* HOST_WIN32*/
-
 #ifdef HAVE_GETPWNAM_R
        struct passwd pwd;
        size_t fbufsize;
@@ -380,59 +286,26 @@ ves_icall_System_Security_Principal_WindowsIdentity_GetUserToken (MonoString *us
        g_free (fbuf);
 #endif
        g_free (utf8_name);
-#endif
+
        return token;
 }
-
+#endif /* HOST_WIN32 */
 
 /* http://www.dotnet247.com/247reference/msgs/39/195403.aspx
 // internal static string[] WindowsIdentity._GetRoles (IntPtr token)
 */
+
+#ifndef HOST_WIN32
 MonoArray*
-ves_icall_System_Security_Principal_WindowsIdentity_GetRoles (gpointer token) 
+ves_icall_System_Security_Principal_WindowsIdentity_GetRoles (gpointer token)
 {
        MonoError error;
        MonoArray *array = NULL;
-       MonoDomain *domain = mono_domain_get (); 
-#ifdef HOST_WIN32
-       gint32 size = 0;
-
-       GetTokenInformation (token, TokenGroups, NULL, size, (PDWORD)&size);
-       if (size > 0) {
-               TOKEN_GROUPS *tg = g_malloc0 (size);
-               if (GetTokenInformation (token, TokenGroups, tg, size, (PDWORD)&size)) {
-                       int i=0;
-                       int num = tg->GroupCount;
-
-                       array = mono_array_new_checked (domain, mono_get_string_class (), num, &error);
-                       if (mono_error_set_pending_exception (&error)) {
-                               g_free (tg);
-                               return NULL;
-                       }
+       MonoDomain *domain = mono_domain_get ();
 
-                       for (i=0; i < num; i++) {
-                               gint32 size = 0;
-                               gunichar2 *uniname = GetSidName (NULL, tg->Groups [i].Sid, &size);
-
-                               if (uniname) {
-                                       MonoString *str = mono_string_new_utf16_checked (domain, uniname, size, &error);
-                                       if (!is_ok (&error)) {
-                                               g_free (uniname);
-                                               g_free (tg);
-                                               mono_error_set_pending_exception (&error);
-                                               return NULL;
-                                       }
-                                       mono_array_setref (array, i, str);
-                                       g_free (uniname);
-                               }
-                       }
-               }
-               g_free (tg);
-       }
-#else
        /* POSIX-compliant systems should use IsMemberOfGroupId or IsMemberOfGroupName */
        g_warning ("WindowsIdentity._GetRoles should never be called on POSIX");
-#endif
+
        if (!array) {
                /* return empty array of string, i.e. string [0] */
                array = mono_array_new_checked (domain, mono_get_string_class (), 0, &error);
@@ -440,39 +313,27 @@ ves_icall_System_Security_Principal_WindowsIdentity_GetRoles (gpointer token)
        }
        return array;
 }
-
+#endif /* !HOST_WIN32 */
 
 /* System.Security.Principal.WindowsImpersonationContext */
 
-
+#ifndef HOST_WIN32
 gboolean
 ves_icall_System_Security_Principal_WindowsImpersonationContext_CloseToken (gpointer token)
 {
-       gboolean result = TRUE;
-
-#ifdef HOST_WIN32
-       result = (CloseHandle (token) != 0);
-#endif
-       return result;
+       return TRUE;
 }
+#endif /* !HOST_WIN32 */
 
-
+#ifndef HOST_WIN32
 gpointer
 ves_icall_System_Security_Principal_WindowsImpersonationContext_DuplicateToken (gpointer token)
 {
-       gpointer dupe = NULL;
-
-#ifdef HOST_WIN32
-       if (DuplicateToken (token, SecurityImpersonation, &dupe) == 0) {
-               dupe = NULL;
-       }
-#else
-       dupe = token;
-#endif
-       return dupe;
+       return token;
 }
+#endif /* !HOST_WIN32 */
 
-
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
 gboolean
 ves_icall_System_Security_Principal_WindowsImpersonationContext_SetCurrentToken (gpointer token)
 {
@@ -480,28 +341,22 @@ ves_icall_System_Security_Principal_WindowsImpersonationContext_SetCurrentToken
        return (ImpersonateLoggedOnUser (token) != 0);
 }
 
-
 gboolean
 ves_icall_System_Security_Principal_WindowsImpersonationContext_RevertToSelf (void)
 {
        /* Posix version implemented in /mono/mono/io-layer/security.c */
        return (RevertToSelf () != 0);
 }
-
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
 /* System.Security.Principal.WindowsPrincipal */
 
+#ifndef HOST_WIN32
 gboolean
 ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupId (gpointer user, gpointer group)
 {
        gboolean result = FALSE;
 
-#ifdef HOST_WIN32
-       /* The convertion from an ID to a string is done in managed code for Windows */
-       g_warning ("IsMemberOfGroupId should never be called on Win32");
-
-#else /* HOST_WIN32 */
-
 #ifdef HAVE_GETGRGID_R
        struct group grp;
        size_t fbufsize;
@@ -533,22 +388,13 @@ ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupId (gpointer
        g_free (fbuf);
 #endif
 
-#endif /* HOST_WIN32 */
-
        return result;
 }
 
-
 gboolean
 ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupName (gpointer user, MonoString *group)
 {
        gboolean result = FALSE;
-
-#ifdef HOST_WIN32
-       /* Windows version use a cache built using WindowsIdentity._GetRoles */
-       g_warning ("IsMemberOfGroupName should never be called on Win32");
-
-#else /* HOST_WIN32 */
        gchar *utf8_groupname;
 
        utf8_groupname = mono_unicode_to_external (mono_string_chars (group));
@@ -581,232 +427,15 @@ ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupName (gpoint
 #endif
                g_free (utf8_groupname);
        }
-#endif /* HOST_WIN32 */
 
        return result;
 }
-
+#endif /* !HOST_WIN32 */
 
 /* Mono.Security.Cryptography IO related internal calls */
 
-#ifdef HOST_WIN32
-
-static PSID
-GetAdministratorsSid (void) 
-{
-       SID_IDENTIFIER_AUTHORITY admins = SECURITY_NT_AUTHORITY;
-       PSID pSid = NULL;
-       if (!AllocateAndInitializeSid (&admins, 2, SECURITY_BUILTIN_DOMAIN_RID, 
-               DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSid)) 
-               return NULL;
-       /* Note: this SID must be freed with FreeSid () */
-       return pSid;
-}
-
-
-static PSID
-GetEveryoneSid (void)
-{
-       SID_IDENTIFIER_AUTHORITY everyone = SECURITY_WORLD_SID_AUTHORITY;
-       PSID pSid = NULL;
-       if (!AllocateAndInitializeSid (&everyone, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSid))
-               return NULL;
-       /* Note: this SID must be freed with FreeSid () */
-       return pSid;
-}
-
-
-static PSID
-GetCurrentUserSid (void) 
-{
-       PSID sid = NULL;
-       guint32 size = 0;
-       gpointer token = ves_icall_System_Security_Principal_WindowsIdentity_GetCurrentToken ();
-
-       GetTokenInformation (token, TokenUser, NULL, size, (PDWORD)&size);
-       if (size > 0) {
-               TOKEN_USER *tu = g_malloc0 (size);
-               if (GetTokenInformation (token, TokenUser, tu, size, (PDWORD)&size)) {
-                       DWORD length = GetLengthSid (tu->User.Sid);
-                       sid = (PSID) g_malloc0 (length);
-                       if (!CopySid (length, sid, tu->User.Sid)) {
-                               g_free (sid);
-                               sid = NULL;
-                       }
-               }
-               g_free (tu);
-       }
-       /* Note: this SID must be freed with g_free () */
-       return sid;
-}
-
-
-static ACCESS_MASK
-GetRightsFromSid (PSID sid, PACL acl) 
-{
-       ACCESS_MASK rights = 0;
-       TRUSTEE trustee;
-
-       BuildTrusteeWithSidW (&trustee, sid);
-       if (GetEffectiveRightsFromAcl (acl, &trustee, &rights) != ERROR_SUCCESS)
-               return 0;
-
-       return rights;
-}
-
-
-static gboolean 
-IsMachineProtected (gunichar2 *path)
-{
-       gboolean success = FALSE;
-       PACL pDACL = NULL;
-       PSECURITY_DESCRIPTOR pSD = NULL;
-       PSID pEveryoneSid = NULL;
-
-       DWORD dwRes = GetNamedSecurityInfoW (path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, &pSD);
-       if (dwRes != ERROR_SUCCESS)
-               return FALSE;
-
-       /* We check that Everyone is still limited to READ-ONLY -
-       but not if new entries have been added by an Administrator */
-
-       pEveryoneSid = GetEveryoneSid ();
-       if (pEveryoneSid) {
-               ACCESS_MASK rights = GetRightsFromSid (pEveryoneSid, pDACL);
-               /* http://msdn.microsoft.com/library/en-us/security/security/generic_access_rights.asp?frame=true */
-               success = (rights == (READ_CONTROL | SYNCHRONIZE | FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES));
-               FreeSid (pEveryoneSid);
-       }
-       /* Note: we don't need to check our own access - 
-       we'll know soon enough when reading the file */
-
-       if (pSD)
-               LocalFree (pSD);
-
-       return success;
-}
-
-
-static gboolean 
-IsUserProtected (gunichar2 *path)
-{
-       gboolean success = FALSE;
-       PACL pDACL = NULL;
-       PSID pEveryoneSid = NULL;
-       PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
-
-       DWORD dwRes = GetNamedSecurityInfoW (path, SE_FILE_OBJECT, 
-               DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, &pSecurityDescriptor);
-       if (dwRes != ERROR_SUCCESS)
-               return FALSE;
-
-       /* We check that our original entries in the ACL are in place -
-       but not if new entries have been added by the user */
-
-       /* Everyone should be denied */
-       pEveryoneSid = GetEveryoneSid ();
-       if (pEveryoneSid) {
-               ACCESS_MASK rights = GetRightsFromSid (pEveryoneSid, pDACL);
-               success = (rights == 0);
-               FreeSid (pEveryoneSid);
-       }
-       /* Note: we don't need to check our own access - 
-       we'll know soon enough when reading the file */
-
-       if (pSecurityDescriptor)
-               LocalFree (pSecurityDescriptor);
-
-       return success;
-}
-
-
-static gboolean 
-ProtectMachine (gunichar2 *path)
-{
-       PSID pEveryoneSid = GetEveryoneSid ();
-       PSID pAdminsSid = GetAdministratorsSid ();
-       DWORD retval = -1;
-
-       if (pEveryoneSid && pAdminsSid) {
-               PACL pDACL = NULL;
-               EXPLICIT_ACCESS ea [2];
-               ZeroMemory (&ea, 2 * sizeof (EXPLICIT_ACCESS));
-
-               /* grant all access to the BUILTIN\Administrators group */
-               BuildTrusteeWithSidW (&ea [0].Trustee, pAdminsSid);
-               ea [0].grfAccessPermissions = GENERIC_ALL;
-               ea [0].grfAccessMode = SET_ACCESS;
-               ea [0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
-               ea [0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
-               ea [0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
-
-               /* read-only access everyone */
-               BuildTrusteeWithSidW (&ea [1].Trustee, pEveryoneSid);
-               ea [1].grfAccessPermissions = GENERIC_READ;
-               ea [1].grfAccessMode = SET_ACCESS;
-               ea [1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
-               ea [1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
-               ea [1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
-
-               retval = SetEntriesInAcl (2, ea, NULL, &pDACL);
-               if (retval == ERROR_SUCCESS) {
-                       /* with PROTECTED_DACL_SECURITY_INFORMATION we */
-                       /* remove any existing ACL (like inherited ones) */
-                       retval = SetNamedSecurityInfo (path, SE_FILE_OBJECT, 
-                               DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
-                               NULL, NULL, pDACL, NULL);
-               }
-               if (pDACL)
-                       LocalFree (pDACL);
-       }
-
-       if (pEveryoneSid)
-               FreeSid (pEveryoneSid);
-       if (pAdminsSid)
-               FreeSid (pAdminsSid);
-       return (retval == ERROR_SUCCESS);
-}
-
-
-static gboolean 
-ProtectUser (gunichar2 *path)
-{
-       DWORD retval = -1;
-
-       PSID pCurrentSid = GetCurrentUserSid ();
-       if (pCurrentSid) {
-               PACL pDACL = NULL;
-               EXPLICIT_ACCESS ea;
-               ZeroMemory (&ea, sizeof (EXPLICIT_ACCESS));
-
-               /* grant exclusive access to the current user */
-               BuildTrusteeWithSidW (&ea.Trustee, pCurrentSid);
-               ea.grfAccessPermissions = GENERIC_ALL;
-               ea.grfAccessMode = SET_ACCESS;
-               ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
-               ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
-               ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
-
-               retval = SetEntriesInAcl (1, &ea, NULL, &pDACL);
-               if (retval == ERROR_SUCCESS) {
-                       /* with PROTECTED_DACL_SECURITY_INFORMATION we
-                          remove any existing ACL (like inherited ones) */
-                       retval = SetNamedSecurityInfo (path, SE_FILE_OBJECT, 
-                               DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
-                               NULL, NULL, pDACL, NULL);
-               }
-
-               if (pDACL)
-                       LocalFree (pDACL);
-               g_free (pCurrentSid); /* g_malloc0 */
-       }
-
-       return (retval == ERROR_SUCCESS);
-}
-
-#else
-
-static gboolean 
+#ifndef HOST_WIN32
+static gboolean
 IsProtected (MonoString *path, gint32 protection) 
 {
        gboolean result = FALSE;
@@ -822,7 +451,7 @@ IsProtected (MonoString *path, gint32 protection)
 }
 
 
-static gboolean 
+static gboolean
 Protect (MonoString *path, gint32 file_mode, gint32 add_dir_mode)
 {
        gboolean result = FALSE;
@@ -840,85 +469,53 @@ Protect (MonoString *path, gint32 file_mode, gint32 add_dir_mode)
        return result;
 }
 
-#endif /* not HOST_WIN32 */
-
-
 MonoBoolean
 ves_icall_Mono_Security_Cryptography_KeyPairPersistence_CanSecure (MonoString *root)
 {
-#if HOST_WIN32
-       gint32 flags;
-
-       /* ACL are nice... unless you have FAT or other uncivilized filesystem */
-       if (!GetVolumeInformation (mono_string_chars (root), NULL, 0, NULL, NULL, (LPDWORD)&flags, NULL, 0))
-               return FALSE;
-       return ((flags & FS_PERSISTENT_ACLS) == FS_PERSISTENT_ACLS);
-#else
        /* we assume some kind of security is applicable outside Windows */
        return TRUE;
-#endif
 }
 
-
 MonoBoolean
 ves_icall_Mono_Security_Cryptography_KeyPairPersistence_IsMachineProtected (MonoString *path)
 {
        gboolean ret = FALSE;
 
        /* no one, but the owner, should have write access to the directory */
-#ifdef HOST_WIN32
-       ret = IsMachineProtected (mono_string_chars (path));
-#else
        ret = IsProtected (path, (S_IWGRP | S_IWOTH));
-#endif
-       return ret;
+       return (MonoBoolean)ret;
 }
 
-
 MonoBoolean
 ves_icall_Mono_Security_Cryptography_KeyPairPersistence_IsUserProtected (MonoString *path)
 {
        gboolean ret = FALSE;
 
        /* no one, but the user, should have access to the directory */
-#ifdef HOST_WIN32
-       ret = IsUserProtected (mono_string_chars (path));
-#else
        ret = IsProtected (path, (S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH));
-#endif
-       return ret;
+       return (MonoBoolean)ret;
 }
 
-
 MonoBoolean
 ves_icall_Mono_Security_Cryptography_KeyPairPersistence_ProtectMachine (MonoString *path)
 {
        gboolean ret = FALSE;
 
        /* read/write to owner, read to everyone else */
-#ifdef HOST_WIN32
-       ret = ProtectMachine (mono_string_chars (path));
-#else
        ret = Protect (path, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH), (S_IXUSR | S_IXGRP | S_IXOTH));
-#endif
-       return ret;
+       return (MonoBoolean)ret;
 }
 
-
 MonoBoolean
 ves_icall_Mono_Security_Cryptography_KeyPairPersistence_ProtectUser (MonoString *path)
 {
        gboolean ret = FALSE;
        
        /* read/write to user, no access to everyone else */
-#ifdef HOST_WIN32
-       ret = ProtectUser (mono_string_chars (path));
-#else
        ret = Protect (path, (S_IRUSR | S_IWUSR), S_IXUSR);
-#endif
-       return ret;
+       return (MonoBoolean)ret;
 }
-
+#endif /* !HOST_WIN32 */
 
 /*
  * Returns TRUE if there is "something" where the Authenticode signature is 
@@ -930,7 +527,7 @@ MonoBoolean
 ves_icall_System_Security_Policy_Evidence_IsAuthenticodePresent (MonoReflectionAssembly *refass)
 {
        if (refass && refass->assembly && refass->assembly->image) {
-               return mono_image_has_authenticode_entry (refass->assembly->image);
+               return (MonoBoolean)mono_image_has_authenticode_entry (refass->assembly->image);
        }
        return FALSE;
 }
index c501a6b27709e1ee977b37b6023776b28c4c6726..b3224372ddef5b678b1d512be8e23fa527bbdf8e 100644 (file)
@@ -556,8 +556,9 @@ mono_gc_is_null (void)
        return TRUE;
 }
 #else
-       #ifdef _MSC_VER
-               // Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
-               void __mono_win32_null_gc_quiet_lnk4221(void) {}
-       #endif
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_null_gc_quiet_lnk4221(void) {}
+#endif
 #endif /* HAVE_NULL_GC */
diff --git a/mono/metadata/process-internals.h b/mono/metadata/process-internals.h
new file mode 100644 (file)
index 0000000..cfc34e8
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_METADATA_PROCESS_INTERNALS_H__
+#define __MONO_METADATA_PROCESS_INTERNALS_H__
+
+#include <config.h>
+#include <glib.h>
+
+// On Windows platform implementation of bellow methods are hosted in separate source file
+// process-windows.c or process-windows-*.c. On other platforms the implementation is still keept
+// in process.c still declared as static and in some places even inlined.
+#ifdef HOST_WIN32
+gchar*
+mono_process_quote_path (const gchar *path);
+
+gchar*
+mono_process_unquote_application_name (gchar *path);
+
+gboolean
+mono_process_get_shell_arguments (MonoProcessStartInfo *proc_start_info, gunichar2 **shell_path,
+                                 MonoString **cmd);
+#endif  /* HOST_WIN32 */
+
+// On platforms not using classic WIN API support the  implementation of bellow methods are hosted in separate source file
+// process-windows-*.c. On platforms using classic WIN API the implementation is still keept in process.c and still declared
+// static and in some places even inlined.
+#if !G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+void
+process_get_fileversion (MonoObject *filever, gunichar2 *filename, MonoError *error);
+
+void
+mono_process_init_startup_info (HANDLE stdin_handle, HANDLE stdout_handle,
+                               HANDLE stderr_handle,STARTUPINFO *startinfo);
+
+gboolean
+mono_process_create_process (MonoProcInfo *mono_process_info, gunichar2 *shell_path, MonoString *cmd,
+                            guint32 creation_flags, gchar *env_vars, gunichar2 *dir, STARTUPINFO *start_info,
+                            PROCESS_INFORMATION *process_info);
+#endif  /* !G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+// Shared between all platforms and implemented in process.c.
+gboolean
+mono_process_complete_path (const gunichar2 *appname, gchar **completed);
+
+#endif /* __MONO_METADATA_PROCESS_INTERNALS_H__ */
diff --git a/mono/metadata/process-windows-internals.h b/mono/metadata/process-windows-internals.h
new file mode 100644 (file)
index 0000000..68721fa
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_METADATA_PROCESS_WINDOWS_INTERNALS_H__
+#define __MONO_METADATA_PROCESS_WINDOWS_INTERNALS_H__
+
+#include <config.h>
+#include <glib.h>
+
+#ifdef HOST_WIN32
+#include "mono/metadata/process.h"
+#include "mono/metadata/process-internals.h"
+#include "mono/metadata/object.h"
+#include "mono/metadata/object-internals.h"
+#include "mono/metadata/exception.h"
+
+// On platforms not using classic WIN API support the  implementation of bellow methods are hosted in separate source file
+// process-windows-*.c. On platforms using classic WIN API the implementation is still keept in process.c and still declared
+// static and in some places even inlined.
+#if !G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+gboolean
+mono_process_win_enum_processes (DWORD *pids, DWORD count, DWORD *needed);
+#endif  /* !G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+#endif /* HOST_WIN32 */
+
+#endif /* __MONO_METADATA_PROCESS_WINDOWS_INTERNALS_H__ */
diff --git a/mono/metadata/process-windows-uwp.c b/mono/metadata/process-windows-uwp.c
new file mode 100644 (file)
index 0000000..905555f
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * process-windows-uwp.c: UWP process support for Mono.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+*/
+#include <config.h>
+#include <glib.h>
+
+#if G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT)
+#include <Windows.h>
+#include "mono/metadata/process-windows-internals.h"
+
+gboolean
+mono_process_win_enum_processes (DWORD *pids, DWORD count, DWORD *needed)
+{
+       g_unsupported_api ("EnumProcesses");
+       *needed = 0;
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+HANDLE
+ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid)
+{
+       HANDLE handle;
+
+       /* GetCurrentProcess returns a pseudo-handle, so use
+        * OpenProcess instead
+        */
+       handle = OpenProcess (PROCESS_ALL_ACCESS, TRUE, pid);
+       if (handle == NULL)
+               /* FIXME: Throw an exception */
+               return NULL;
+       return handle;
+}
+
+void
+process_get_fileversion (MonoObject *filever, gunichar2 *filename, MonoError *error)
+{
+       g_unsupported_api ("GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue, VerLanguageName");
+
+       mono_error_init (error);
+       mono_error_set_not_supported (error, G_UNSUPPORTED_API, "GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue, VerLanguageName");
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+}
+
+MonoObject*
+process_add_module (HANDLE process, HMODULE mod, gunichar2 *filename, gunichar2 *modulename, MonoClass *proc_class, MonoError *error)
+{
+       g_unsupported_api ("GetModuleInformation");
+
+       mono_error_init (error);
+       mono_error_set_not_supported (error, G_UNSUPPORTED_API, "GetModuleInformation");
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return NULL;
+}
+
+MonoArray *
+ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this_obj, HANDLE process)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("EnumProcessModules, GetModuleBaseName, GetModuleFileNameEx");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "EnumProcessModules, GetModuleBaseName, GetModuleFileNameEx");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return NULL;
+}
+
+MonoBoolean
+ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoProcessStartInfo *proc_start_info, MonoProcInfo *process_info)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("ShellExecuteEx");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "ShellExecuteEx");
+       mono_error_set_pending_exception (&mono_error);
+
+       process_info->pid = (guint32)(-ERROR_NOT_SUPPORTED);
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+MonoString *
+ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE process)
+{
+       MonoError error;
+       MonoString *string;
+       gunichar2 name[MAX_PATH];
+       guint32 len;
+
+       len = GetModuleFileName (NULL, name, G_N_ELEMENTS (name));
+       if (len == 0)
+               return NULL;
+
+       string = mono_string_new_utf16_checked (mono_domain_get (), name, len, &error);
+       if (!mono_error_ok (&error))
+               mono_error_set_pending_exception (&error);
+
+       return string;
+}
+
+void
+mono_process_init_startup_info (HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle, STARTUPINFO *startinfo)
+{
+       startinfo->cb = sizeof(STARTUPINFO);
+       startinfo->dwFlags = 0;
+       startinfo->hStdInput = INVALID_HANDLE_VALUE;
+       startinfo->hStdOutput = INVALID_HANDLE_VALUE;
+       startinfo->hStdError = INVALID_HANDLE_VALUE;
+       return;
+}
+
+gboolean
+mono_process_create_process (MonoProcInfo *mono_process_info, gunichar2 *shell_path, MonoString *cmd, guint32 creation_flags,
+                            gchar *env_vars, gunichar2 *dir, STARTUPINFO *start_info, PROCESS_INFORMATION *process_info)
+{
+       MonoError       mono_error;
+       gchar           *api_name = "";
+
+       if (mono_process_info->username) {
+               api_name = "CreateProcessWithLogonW";
+       } else {
+               api_name = "CreateProcess";
+       }
+
+       memset (&process_info, 0, sizeof (PROCESS_INFORMATION));
+       g_unsupported_api (api_name);
+
+       mono_error_init (&mono_error);
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, api_name);
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+#else /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_process_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
diff --git a/mono/metadata/process-windows.c b/mono/metadata/process-windows.c
new file mode 100644 (file)
index 0000000..847612d
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * process-windows.c: Windows process support.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include <config.h>
+#include <glib.h>
+
+#if defined(HOST_WIN32)
+#include <WinSock2.h>
+#include <Windows.h>
+#include "mono/metadata/process-windows-internals.h"
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static inline gboolean
+mono_process_win_enum_processes (DWORD *pids, DWORD count, DWORD *needed)
+{
+       return EnumProcesses (pids, count, needed);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+MonoArray *
+ves_icall_System_Diagnostics_Process_GetProcesses_internal (void)
+{
+       MonoError error;
+       MonoArray *procs;
+       gboolean ret;
+       DWORD needed;
+       int count;
+       DWORD *pids;
+
+       count = 512;
+       do {
+               pids = g_new0 (DWORD, count);
+               ret = mono_process_win_enum_processes (pids, count * sizeof (guint32), &needed);
+               if (ret == FALSE) {
+                       MonoException *exc;
+
+                       g_free (pids);
+                       pids = NULL;
+                       exc = mono_get_exception_not_supported ("This system does not support EnumProcesses");
+                       mono_set_pending_exception (exc);
+                       return NULL;
+               }
+               if (needed < (count * sizeof (guint32)))
+                       break;
+               g_free (pids);
+               pids = NULL;
+               count = (count * 3) / 2;
+       } while (TRUE);
+
+       count = needed / sizeof (guint32);
+       procs = mono_array_new_checked (mono_domain_get (), mono_get_int32_class (), count, &error);
+       if (mono_error_set_pending_exception (&error)) {
+               g_free (pids);
+               return NULL;
+       }
+
+       memcpy (mono_array_addr (procs, guint32, 0), pids, needed);
+       g_free (pids);
+       pids = NULL;
+
+       return procs;
+}
+
+gchar*
+mono_process_quote_path (const gchar *path)
+{
+       gchar *res = g_shell_quote (path);
+       gchar *q = res;
+       while (*q) {
+               if (*q == '\'')
+                       *q = '\"';
+               q++;
+       }
+       return res;
+}
+
+gchar*
+mono_process_unquote_application_name (gchar *appname)
+{
+       size_t len = strlen (appname);
+       if (len) {
+               if (appname[len-1] == '\"')
+                       appname[len-1] = '\0';
+               if (appname[0] == '\"')
+                       appname++;
+       }
+
+       return appname;
+}
+
+gboolean
+mono_process_get_shell_arguments (MonoProcessStartInfo *proc_start_info, gunichar2 **shell_path, MonoString **cmd)
+{
+       gchar           *spath = NULL;
+       gchar           *new_cmd, *cmd_utf8;
+       MonoError       mono_error;
+
+       *shell_path = NULL;
+       *cmd = proc_start_info->arguments;
+
+       mono_process_complete_path (mono_string_chars (proc_start_info->filename), &spath);
+       if (spath != NULL) {
+               /* Seems like our CreateProcess does not work as the windows one.
+                * This hack is needed to deal with paths containing spaces */
+               if (*cmd) {
+                       cmd_utf8 = mono_string_to_utf8_checked (*cmd, &mono_error);
+                       if (!mono_error_set_pending_exception (&mono_error)) {
+                               new_cmd = g_strdup_printf ("%s %s", spath, cmd_utf8);
+                               *cmd = mono_string_new_wrapper (new_cmd);
+                               g_free (cmd_utf8);
+                               g_free (new_cmd);
+                       } else {
+                               *cmd = NULL;
+                       }
+               }
+               else {
+                       *cmd = mono_string_new_wrapper (spath);
+               }
+
+               g_free (spath);
+       }
+
+       return (*cmd != NULL) ? TRUE : FALSE;
+}
+#endif /* HOST_WIN32 */
index 96814db8480518f5f35f83caea8c66f18a9ec520..b1bff0b5ecad403e85d7f82ada5d42f06d08b8c5 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <mono/metadata/object-internals.h>
 #include <mono/metadata/process.h>
+#include <mono/metadata/process-internals.h>
 #include <mono/metadata/assembly.h>
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/image.h>
 #define LOGDEBUG(...)  
 /* define LOGDEBUG(...) g_message(__VA_ARGS__)  */
 
-#ifdef _WIN32
+#if defined(HOST_WIN32) && G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
 #include <shellapi.h>
 #endif
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
 HANDLE
 ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid)
 {
@@ -50,6 +52,7 @@ ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid)
                return NULL;
        return handle;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
 
 static MonoImage *system_assembly;
 
@@ -196,11 +199,11 @@ process_set_field_bool (MonoObject *obj, const gchar *fieldname,
 #define SFI_SPECIALBUILD       "\\StringFileInfo\\%02X%02X%02X%02X\\SpecialBuild"
 #define EMPTY_STRING           (gunichar2*)"\000\000"
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
 static void
 process_module_string_read (MonoObject *filever, gpointer data,
-                                                       const gchar *fieldname,
-                                                       guchar lang_hi, guchar lang_lo,
-                                                       const gchar *key, MonoError *error)
+                           const gchar *fieldname, guchar lang_hi, guchar lang_lo,
+                           const gchar *key, MonoError *error)
 {
        gchar *lang_key_utf8;
        gunichar2 *lang_key, *buffer;
@@ -367,6 +370,7 @@ process_get_fileversion (MonoObject *filever, gunichar2 *filename, MonoError *er
                g_free (data);
        }
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
 static void
 process_get_assembly_fileversion (MonoObject *filever, MonoAssembly *assembly)
@@ -409,6 +413,7 @@ get_process_module (MonoAssembly *assembly, MonoClass *proc_class, MonoError *er
        return item;
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
 static MonoObject*
 process_add_module (HANDLE process, HMODULE mod, gunichar2 *filename, gunichar2 *modulename, MonoClass *proc_class, MonoError *error)
 {
@@ -451,6 +456,7 @@ process_add_module (HANDLE process, HMODULE mod, gunichar2 *filename, gunichar2
 
        return item;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
 static GPtrArray*
 get_domain_assemblies (MonoDomain *domain)
@@ -476,6 +482,7 @@ get_domain_assemblies (MonoDomain *domain)
 }
 
 /* Returns an array of System.Diagnostics.ProcessModule */
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
 MonoArray *
 ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this_obj, HANDLE process)
 {
@@ -546,6 +553,7 @@ ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this_obj,
 
        return arr;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
 void
 ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObject *this_obj, MonoString *filename)
@@ -569,53 +577,38 @@ ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObject
 }
 
 /* Only used when UseShellExecute is false */
-static gchar *
-quote_path (const gchar *path)
+#ifndef HOST_WIN32
+static inline gchar *
+mono_process_quote_path (const gchar *path)
 {
-       gchar *res = g_shell_quote (path);
-#ifdef TARGET_WIN32
-       {
-       gchar *q = res;
-       while (*q) {
-               if (*q == '\'')
-                       *q = '\"';
-               q++;
-       }
-       }
-#endif
-       return res;
+       return g_shell_quote (path);
 }
 
+static inline gchar *
+mono_process_unquote_application_name (gchar *path)
+{
+       return path;
+}
+#endif /* !HOST_WIN32 */
+
 /* Only used when UseShellExecute is false */
-static gboolean
-complete_path (const gunichar2 *appname, gchar **completed)
+gboolean
+mono_process_complete_path (const gunichar2 *appname, gchar **completed)
 {
        gchar *utf8app, *utf8appmemory;
        gchar *found;
 
-       utf8appmemory = utf8app = g_utf16_to_utf8 (appname, -1, NULL, NULL, NULL);
-#ifdef TARGET_WIN32 // Should this happen on all platforms? 
-       {
-               // remove the quotes around utf8app.
-               size_t len;
-               len = strlen (utf8app);
-               if (len) {
-                       if (utf8app[len-1] == '\"')
-                               utf8app[len-1] = '\0';
-                       if (utf8app[0] == '\"')
-                               utf8app++;
-               }
-       }
-#endif
+       utf8appmemory = g_utf16_to_utf8 (appname, -1, NULL, NULL, NULL);
+       utf8app = mono_process_unquote_application_name (utf8appmemory);
 
        if (g_path_is_absolute (utf8app)) {
-               *completed = quote_path (utf8app);
+               *completed = mono_process_quote_path (utf8app);
                g_free (utf8appmemory);
                return TRUE;
        }
 
        if (g_file_test (utf8app, G_FILE_TEST_IS_EXECUTABLE) && !g_file_test (utf8app, G_FILE_TEST_IS_DIR)) {
-               *completed = quote_path (utf8app);
+               *completed = mono_process_quote_path (utf8app);
                g_free (utf8appmemory);
                return TRUE;
        }
@@ -627,12 +620,13 @@ complete_path (const gunichar2 *appname, gchar **completed)
                return FALSE;
        }
 
-       *completed = quote_path (found);
+       *completed = mono_process_quote_path (found);
        g_free (found);
        g_free (utf8appmemory);
        return TRUE;
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
 MonoBoolean
 ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoProcessStartInfo *proc_start_info, MonoProcInfo *process_info)
 {
@@ -684,62 +678,102 @@ ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoProcessStartIn
 
        return ret;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static inline void
+mono_process_init_startup_info (HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle, STARTUPINFO *startinfo)
+{
+       startinfo->cb = sizeof(STARTUPINFO);
+       startinfo->dwFlags = STARTF_USESTDHANDLES;
+       startinfo->hStdInput = stdin_handle;
+       startinfo->hStdOutput = stdout_handle;
+       startinfo->hStdError = stderr_handle;
+       return;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+#ifndef HOST_WIN32
+static gboolean
+mono_process_get_shell_arguments (MonoProcessStartInfo *proc_start_info, gunichar2 **shell_path, MonoString **cmd)
+{
+       gchar *spath = NULL;
+
+       *shell_path = NULL;
+       *cmd = proc_start_info->arguments;
+
+       mono_process_complete_path (mono_string_chars (proc_start_info->filename), &spath);
+       if (spath != NULL) {
+               *shell_path = g_utf8_to_utf16 (spath, -1, NULL, NULL, NULL);
+               g_free (spath);
+       }
+
+       return (*shell_path != NULL) ? TRUE : FALSE;
+}
+#endif /* !HOST_WIN32 */
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static gboolean
+mono_process_create_process (MonoProcInfo *mono_process_info, gunichar2 *shell_path,
+                            MonoString *cmd, guint32 creation_flags, gchar *env_vars,
+                            gunichar2 *dir, STARTUPINFO *start_info, PROCESS_INFORMATION *process_info)
+{
+       gboolean result = FALSE;
+
+       if (mono_process_info->username) {
+               guint32 logon_flags = mono_process_info->load_user_profile ? LOGON_WITH_PROFILE : 0;
+
+               result = CreateProcessWithLogonW (mono_string_chars (mono_process_info->username),
+                                                 mono_process_info->domain ? mono_string_chars (mono_process_info->domain) : NULL,
+                                                 (const gunichar2 *)mono_process_info->password,
+                                                 logon_flags,
+                                                 shell_path,
+                                                 cmd ? mono_string_chars (cmd) : NULL,
+                                                 creation_flags,
+                                                 env_vars, dir, start_info, process_info);
+
+       } else {
+
+               result = CreateProcess (shell_path,
+                                       cmd ? mono_string_chars (cmd): NULL,
+                                       NULL,
+                                       NULL,
+                                       TRUE,
+                                       creation_flags,
+                                       env_vars,
+                                       dir,
+                                       start_info,
+                                       process_info);
+
+       }
+
+       return result;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
 MonoBoolean
-ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoProcessStartInfo *proc_start_info, HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle, MonoProcInfo *process_info)
+ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoProcessStartInfo *proc_start_info, HANDLE stdin_handle,
+                                                            HANDLE stdout_handle, HANDLE stderr_handle, MonoProcInfo *process_info)
 {
-       MonoError error G_GNUC_UNUSED;
        gboolean ret;
        gunichar2 *dir;
        STARTUPINFO startinfo={0};
        PROCESS_INFORMATION procinfo;
        gunichar2 *shell_path = NULL;
        gchar *env_vars = NULL;
-       gboolean free_shell_path = TRUE;
-       gchar *spath = NULL;
-       MonoString *cmd = proc_start_info->arguments;
-       guint32 creation_flags, logon_flags;
-       
-       startinfo.cb = sizeof(STARTUPINFO);
-       startinfo.dwFlags = STARTF_USESTDHANDLES;
-       startinfo.hStdInput = stdin_handle;
-       startinfo.hStdOutput = stdout_handle;
-       startinfo.hStdError = stderr_handle;
+       MonoString *cmd = NULL;
+       guint32 creation_flags;
+
+       mono_process_init_startup_info (stdin_handle, stdout_handle, stderr_handle, &startinfo);
 
        creation_flags = CREATE_UNICODE_ENVIRONMENT;
        if (proc_start_info->create_no_window)
                creation_flags |= CREATE_NO_WINDOW;
        
-       shell_path = mono_string_chars (proc_start_info->filename);
-       complete_path (shell_path, &spath);
-       if (spath == NULL) {
+       if (mono_process_get_shell_arguments (proc_start_info, &shell_path, &cmd) == FALSE) {
                process_info->pid = -ERROR_FILE_NOT_FOUND;
                return FALSE;
        }
-#ifdef TARGET_WIN32
-       /* Seems like our CreateProcess does not work as the windows one.
-        * This hack is needed to deal with paths containing spaces */
-       shell_path = NULL;
-       free_shell_path = FALSE;
-       if (cmd) {
-               gchar *newcmd, *tmp;
-               tmp = mono_string_to_utf8_checked (cmd, &error);
-               if (mono_error_set_pending_exception (&error)) {
-                       g_free (spath);
-                       return NULL;
-               }
-               newcmd = g_strdup_printf ("%s %s", spath, tmp);
-               cmd = mono_string_new_wrapper (newcmd);
-               g_free (tmp);
-               g_free (newcmd);
-       }
-       else {
-               cmd = mono_string_new_wrapper (spath);
-       }
-#else
-       shell_path = g_utf8_to_utf16 (spath, -1, NULL, NULL, NULL);
-#endif
-       g_free (spath);
 
        if (process_info->env_keys) {
                gint i, len; 
@@ -790,20 +824,10 @@ ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoProcessStartInf
        else
                dir = mono_string_chars (proc_start_info->working_directory);
 
-       if (process_info->username) {
-               logon_flags = process_info->load_user_profile ? LOGON_WITH_PROFILE : 0;
-               ret = CreateProcessWithLogonW (
-                       mono_string_chars (process_info->username),
-                       process_info->domain ? mono_string_chars (process_info->domain) : NULL,
-                       (const gunichar2 *)process_info->password, logon_flags, shell_path,
-                       cmd ? mono_string_chars (cmd) : NULL,
-                       creation_flags, env_vars, dir, &startinfo, &procinfo);
-       } else {
-               ret = CreateProcess (shell_path, cmd ? mono_string_chars (cmd): NULL, NULL, NULL, TRUE, creation_flags, env_vars, dir, &startinfo, &procinfo);
-       }
+       ret = mono_process_create_process (process_info, shell_path, cmd, creation_flags, env_vars, dir, &startinfo, &procinfo);
 
        g_free (env_vars);
-       if (free_shell_path)
+       if (shell_path != NULL)
                g_free (shell_path);
 
        if (ret) {
@@ -821,22 +845,24 @@ ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoProcessStartInf
        return ret;
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
 MonoString *
 ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE process)
 {
        MonoError error;
        MonoString *string;
+       gunichar2 name[MAX_PATH];
+       guint32 len;
        gboolean ok;
        HMODULE mod;
-       gunichar2 name[MAX_PATH];
        DWORD needed;
-       guint32 len;
-       
+
        ok = EnumProcessModules (process, &mod, sizeof(mod), &needed);
        if (!ok)
                return NULL;
        
        len = GetModuleBaseName (process, mod, name, MAX_PATH);
+
        if (len == 0)
                return NULL;
        
@@ -848,12 +874,13 @@ ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE process)
        
        return string;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
+#ifndef HOST_WIN32
 /* Returns an array of pids */
 MonoArray *
 ves_icall_System_Diagnostics_Process_GetProcesses_internal (void)
 {
-#if !defined(HOST_WIN32)
        MonoError error;
        MonoArray *procs;
        gpointer *pidarray;
@@ -878,48 +905,8 @@ ves_icall_System_Diagnostics_Process_GetProcesses_internal (void)
        g_free (pidarray);
 
        return procs;
-#else
-       MonoError error;
-       MonoArray *procs;
-       gboolean ret;
-       DWORD needed;
-       int count;
-       guint32 *pids;
-
-       count = 512;
-       do {
-               pids = g_new0 (guint32, count);
-               ret = EnumProcesses (pids, count * sizeof (guint32), &needed);
-               if (ret == FALSE) {
-                       MonoException *exc;
-
-                       g_free (pids);
-                       pids = NULL;
-                       exc = mono_get_exception_not_supported ("This system does not support EnumProcesses");
-                       mono_set_pending_exception (exc);
-                       return NULL;
-               }
-               if (needed < (count * sizeof (guint32)))
-                       break;
-               g_free (pids);
-               pids = NULL;
-               count = (count * 3) / 2;
-       } while (TRUE);
-
-       count = needed / sizeof (guint32);
-       procs = mono_array_new_checked (mono_domain_get (), mono_get_int32_class (), count, &error);
-       if (mono_error_set_pending_exception (&error)) {
-               g_free (pids);
-               return NULL;
-       }
-
-       memcpy (mono_array_addr (procs, guint32, 0), pids, needed);
-       g_free (pids);
-       pids = NULL;
-       
-       return procs;
-#endif
 }
+#endif /* !HOST_WIN32 */
 
 gint64
 ves_icall_System_Diagnostics_Process_GetProcessData (int pid, gint32 data_type, gint32 *error)
index 30595ee5410e1a43cf886966b5e7175899ccf2ff..a29cf91a1cc2fb23cdd1dc9400203e7107d8ac36 100644 (file)
@@ -197,7 +197,10 @@ mono_remoting_marshal_init (void)
                register_icall (mono_marshal_xdomain_copy_out_value, "mono_marshal_xdomain_copy_out_value", "void object object", FALSE);
                register_icall (mono_remoting_wrapper, "mono_remoting_wrapper", "object ptr ptr", FALSE);
                register_icall (mono_upgrade_remote_class_wrapper, "mono_upgrade_remote_class_wrapper", "void object object", FALSE);
+
+#ifndef DISABLE_JIT
                register_icall (mono_compile_method_icall, "mono_compile_method_icall", "ptr ptr", FALSE);
+#endif
 
        }
 
index 32bab7ebcb8655cc6adf94c918beb880ce7a8a72..aab29b6466c453eeb89eba799141674c467ad615 100644 (file)
@@ -67,9 +67,10 @@ mono_gc_get_restart_signal (void)
        return -1;
 }
 #else
-       #ifdef _MSC_VER
-               // Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
-               void __mono_win32_sgen_os_coop_quiet_lnk4221(void) {}
-       #endif
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_sgen_os_coop_quiet_lnk4221(void) {}
+#endif
 #endif /* USE_COOP_GC */
 #endif
index 472d079603db2cc493634d61f35ffa711a90878f..b76f9cbd43e0027c5084eea609e97a03f00d89b1 100644 (file)
@@ -19,6 +19,9 @@ int alertable_WSARecv (SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWOR
 int alertable_send (SOCKET s, char *buf, int len, int flags, gboolean blocking);
 int alertable_sendto (SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen, gboolean blocking);
 int alertable_WSASend (SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, DWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, gboolean blocking);
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT)
 BOOL alertable_TransmitFile (SOCKET hSocket, HANDLE hFile, DWORD nNumberOfBytesToWrite, DWORD nNumberOfBytesPerSend, LPOVERLAPPED lpOverlapped, LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, DWORD dwReserved, gboolean blocking);
+#endif
 
 #endif // __MONO_METADATA_SOCKET_IO_WINDOWS_INTERNALS_H__
index 61d0118f07a843815026fd9963992953cb925474..125dbeb9c4d7176dbf703e2c42e31a54421c975d 100644 (file)
@@ -165,6 +165,7 @@ int alertable_WSASend (SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWOR
        return ret;
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT)
 BOOL alertable_TransmitFile (SOCKET hSocket, HANDLE hFile, DWORD nNumberOfBytesToWrite, DWORD nNumberOfBytesPerSend, LPOVERLAPPED lpOverlapped, LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, DWORD dwReserved, gboolean blocking)
 {
        LOGDEBUG (g_message ("%06d - Performing %s TransmitFile () on socket %d", GetCurrentThreadId (), blocking ? "blocking" : "non-blocking", hSocket));
@@ -205,3 +206,4 @@ BOOL alertable_TransmitFile (SOCKET hSocket, HANDLE hFile, DWORD nNumberOfBytesT
 
        return error == 0;
 }
+#endif /* #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
index 3d59231813a4930c9467ccd3500ab869a1088154..2df84e99c8f9658a398e4c089d1155be2e64906a 100644 (file)
 #include <ifaddrs.h>
 #endif
 
+#if defined(_MSC_VER) && G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT)
+#include <MSWSock.h>
+#endif
+
 #include "mono/io-layer/socket-wrappers.h"
 #ifdef HOST_WIN32
 #include "mono/metadata/socket-io-windows-internals.h"
@@ -1297,6 +1301,7 @@ ves_icall_System_Net_Sockets_Socket_Connect_internal (SOCKET sock, MonoObject *s
        g_free (sa);
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT)
 /* These #defines from mswsock.h from wine.  Defining them here allows
  * us to build this file on a mingw box that doesn't know the magic
  * numbers, but still run on a newer windows box that does.
@@ -1387,6 +1392,7 @@ ves_icall_System_Net_Sockets_Socket_Disconnect_internal (SOCKET sock, MonoBoolea
        if (interrupted)
                *werror = WSAEINTR;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
 
 gint32
 ves_icall_System_Net_Sockets_Socket_Receive_internal (SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, gint32 *werror, gboolean blocking)
@@ -2708,6 +2714,7 @@ ves_icall_System_Net_Dns_GetHostName_internal (MonoString **h_name)
        return TRUE;
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT)
 gboolean
 ves_icall_System_Net_Sockets_Socket_SendFile_internal (SOCKET sock, MonoString *filename, MonoArray *pre_buffer, MonoArray *post_buffer, gint flags, gint32 *werror, gboolean blocking)
 {
@@ -2776,6 +2783,7 @@ ves_icall_System_Net_Sockets_Socket_SendFile_internal (SOCKET sock, MonoString *
 
        return ret;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
 
 gboolean
 ves_icall_System_Net_Sockets_Socket_SupportPortReuse (MonoProtocolType proto)
index d7c6b621a5cec0c9adbb964abe371f25c1a27c8b..bd6bdc97e8e3fcc7d749d0464a758e30e559e846 100644 (file)
@@ -17,6 +17,7 @@ mono_w32semaphore_init (void)
 {
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT)
 gpointer
 ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 initialCount, gint32 maximumCount, MonoString *name, gint32 *error)
 { 
@@ -28,6 +29,7 @@ ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 initialCou
 
        return sem;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
 
 MonoBoolean
 ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (gpointer handle, gint32 releaseCount, gint32 *prevcount)
index 27b57943223773d3fcb4d390e8d7d97196a3593b..06836b9b0f83279c80f69bfadb86467affbc24e2 100644 (file)
     <ClCompile Include="..\mono\metadata\cominterop.c" />\r
     <ClCompile Include="..\mono\metadata\console-win32.c" />\r
     <ClCompile Include="..\mono\metadata\socket-io-windows.c" />\r
+    <ClCompile Include="..\mono\metadata\file-io-windows.c" />\r
+    <ClCompile Include="..\mono\metadata\icall-windows.c" />\r
+    <ClCompile Include="..\mono\metadata\marshal-windows.c" />\r
+    <ClCompile Include="..\mono\metadata\mono-security-windows.c" />\r
+    <ClCompile Include="..\mono\metadata\process-windows.c" />\r
     <ClCompile Include="..\mono\metadata\w32mutex-win32.c" />\r
     <ClCompile Include="..\mono\metadata\w32semaphore-win32.c" />\r
     <ClCompile Include="..\mono\metadata\w32event-win32.c" />\r
     <ClInclude Include="..\mono\metadata\class.h" />\r
     <ClInclude Include="..\mono\metadata\cominterop.h" />\r
     <ClInclude Include="..\mono\metadata\console-io.h" />\r
+    <ClInclude Include="..\mono\metadata\console-win32-internals.h" />\r
+    <ClInclude Include="..\mono\metadata\coree-internals.h" />\r
     <ClInclude Include="..\mono\metadata\coree.h" />\r
     <ClInclude Include="..\mono\metadata\culture-info-tables.h" />\r
     <ClInclude Include="..\mono\metadata\culture-info.h" />\r
     <ClInclude Include="..\mono\metadata\dynamic-stream-internals.h" />\r
     <ClInclude Include="..\mono\metadata\environment.h" />\r
     <ClInclude Include="..\mono\metadata\exception.h" />\r
+    <ClInclude Include="..\mono\metadata\file-io-internals.h" />\r
+    <ClInclude Include="..\mono\metadata\file-io-windows-internals.h" />\r
     <ClInclude Include="..\mono\metadata\file-io.h" />\r
     <ClInclude Include="..\mono\metadata\filewatcher.h" />\r
     <ClInclude Include="..\mono\metadata\gc-internals.h" />\r
     <ClInclude Include="..\mono\metadata\handle.h" />\r
+    <ClInclude Include="..\mono\metadata\icall-windows-internals.h" />\r
+    <ClInclude Include="..\mono\metadata\icall-internals.h" />\r
+    <ClInclude Include="..\mono\metadata\marshal-internals.h" />\r
+    <ClInclude Include="..\mono\metadata\marshal-windows-internals.h" />\r
+    <ClInclude Include="..\mono\metadata\mono-security-windows-internals.h" />\r
     <ClInclude Include="..\mono\metadata\number-ms.h" />\r
+    <ClInclude Include="..\mono\metadata\process-internals.h" />\r
+    <ClInclude Include="..\mono\metadata\process-windows-internals.h" />\r
     <ClInclude Include="..\mono\metadata\remoting.h" />\r
     <ClInclude Include="..\mono\metadata\seq-points-data.h" />\r
     <ClInclude Include="..\mono\metadata\sgen-bridge-internals.h" />\r
index 29ceb5d1f2e9ea1fa8c20837c550472d84137387..10ea5f5b356ae49a74d1e9fa5acba34a46039444 100644 (file)
       <Filter>Source Files\sgen</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\mono\metadata\socket-io-windows.c">\r
+         <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\file-io-windows.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\icall-windows.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\marshal-windows.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\mono-security-windows.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\process-windows.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
   </ItemGroup>\r
     <ClInclude Include="..\mono\metadata\socket-io-windows-internals.h">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\coree-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\console-win32-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\file-io-windows-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\file-io-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\icall-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\icall-windows-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\marshal-windows-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\marshal-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\mono-security-windows-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\process-windows-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\process-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Filter Include="Header Files">\r
index 5a6e9116bd9759204af84f6bbdaa11fd2f611fb0..36dc0ecaab784bf2821ed819726385cece236c45 100644 (file)
@@ -96,7 +96,7 @@
     <ClCompile>\r
       <Optimization>Disabled</Optimization>\r
       <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(MONO_JIT_INCLUDE_DIR);$(MONO_EGLIB_SOURCE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WINDOWS;__WIN32__;HOST_WIN32;TARGET_WIN32;__i386__;TARGET_X86;GC_NOT_DLL;GC_GCJ_SUPPORT;GC_WIN32_THREADS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;_DEBUG;_CONSOLE;_WINDOWS;__WIN32__;HOST_WIN32;TARGET_WIN32;__i386__;TARGET_X86;GC_NOT_DLL;GC_GCJ_SUPPORT;GC_WIN32_THREADS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <MinimalRebuild>true</MinimalRebuild>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <PrecompiledHeader>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
     <ClCompile>\r
       <Optimization>MinSpace</Optimization>\r
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <PrecompiledHeader>\r
       </PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
     <ClCompile>\r
       <Optimization>Disabled</Optimization>\r
       <AdditionalIncludeDirectories>$(MONO_DIR);$(MONO_INCLUDE_DIR);$(MONO_JIT_INCLUDE_DIR);$(MONO_EGLIB_SOURCE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WINDOWS;__WIN32__;HOST_WIN32;TARGET_WIN32;__i386__;TARGET_X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;_DEBUG;_CONSOLE;_WINDOWS;__WIN32__;HOST_WIN32;TARGET_WIN32;__i386__;TARGET_X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <MinimalRebuild>true</MinimalRebuild>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <PrecompiledHeader>\r
     </Midl>\r
     <ClCompile>\r
       <Optimization>MinSpace</Optimization>\r
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <PrecompiledHeader>\r
       </PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
     <ClCompile Include="..\mono\metadata\console-win32.c" />\r
     <ClCompile Include="..\mono\metadata\domain.c" />\r
     <ClCompile Include="..\mono\metadata\environment.c" />\r
+    <ClCompile Include="..\mono\metadata\file-io-windows.c" />\r
     <ClCompile Include="..\mono\metadata\file-io.c" />\r
     <ClCompile Include="..\mono\metadata\filewatcher.c" />\r
     <ClCompile Include="..\mono\metadata\gc.c" />\r
+    <ClCompile Include="..\mono\metadata\icall-windows.c" />\r
     <ClCompile Include="..\mono\metadata\icall.c" />\r
     <ClCompile Include="..\mono\metadata\image.c" />\r
     <ClCompile Include="..\mono\metadata\loader.c" />\r
     <ClCompile Include="..\mono\metadata\locales.c" />\r
+    <ClCompile Include="..\mono\metadata\marshal-windows.c" />\r
     <ClCompile Include="..\mono\metadata\marshal.c" />\r
     <ClCompile Include="..\mono\metadata\metadata.c" />\r
     <ClCompile Include="..\mono\metadata\monitor.c" />\r
     <ClCompile Include="..\mono\metadata\mono-config.c" />\r
+    <ClCompile Include="..\mono\metadata\process-windows.c" />\r
     <ClCompile Include="..\mono\utils\mono-dl.c" />\r
     <ClCompile Include="..\mono\metadata\object.c" />\r
     <ClCompile Include="..\mono\metadata\process.c" />\r
index 7658bc13f5ccac3041bad6c063a548c009266315..d05fff4fa9698c44a9e6d05351d256f696703009 100644 (file)
     <ClCompile Include="..\tools\pedump\pedump.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\process-windows.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\marshal-windows.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\icall-windows.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\file-io-windows.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Filter Include="Header Files">\r