Build libmonoutils under none desktop Windows API family.
authorlateralusX <lateralusx.github@gmail.com>
Tue, 4 Oct 2016 12:45:43 +0000 (14:45 +0200)
committerlateralusX <lateralusx.github@gmail.com>
Tue, 4 Oct 2016 12:45:43 +0000 (14:45 +0200)
Initial work to build libmonoutils under none desktop Windows API families.

26 files changed:
mono/utils/Makefile.am
mono/utils/atomic.c
mono/utils/mono-compiler.h
mono/utils/mono-dl-windows-uwp.c [new file with mode: 0644]
mono/utils/mono-dl-windows.c
mono/utils/mono-dl-windows.h [new file with mode: 0644]
mono/utils/mono-io-portability.c
mono/utils/mono-log-common.c
mono/utils/mono-log-windows.c
mono/utils/mono-logger.c
mono/utils/mono-mmap-internals.h
mono/utils/mono-mmap-windows-uwp.c [new file with mode: 0644]
mono/utils/mono-mmap-windows.c [new file with mode: 0644]
mono/utils/mono-mmap-windows.h [new file with mode: 0644]
mono/utils/mono-mmap.c
mono/utils/mono-proclib-windows-uwp.c [new file with mode: 0644]
mono/utils/mono-proclib-windows.c [new file with mode: 0644]
mono/utils/mono-proclib-windows.h [new file with mode: 0644]
mono/utils/mono-proclib.c
mono/utils/mono-rand-windows-uwp.c [new file with mode: 0644]
mono/utils/mono-rand-windows.c [new file with mode: 0644]
mono/utils/mono-rand-windows.h [new file with mode: 0644]
mono/utils/mono-rand.c
mono/utils/networking-missing.c
msvc/libmonoutils.vcxproj
msvc/libmonoutils.vcxproj.filters

index 3e29ab15df46efe42c1bb846bc2a57b0ef1345f8..5bc5bbd600326c90c774a43f7280e805ff0e1c04 100644 (file)
@@ -27,6 +27,7 @@ monoutils_sources = \
        mono-dl-darwin.c        \
        mono-dl-posix.c         \
        mono-dl.h               \
+       mono-dl-windows.h       \
        mono-log-windows.c      \
        mono-log-common.c       \
        mono-log-posix.c        \
@@ -40,8 +41,10 @@ monoutils_sources = \
        mono-filemap.c          \
        mono-math.c             \
        mono-mmap.c             \
+       mono-mmap-windows.c             \
        mono-mmap.h             \
        mono-mmap-internals.h   \
+       mono-mmap-windows.h     \
        mono-os-mutex.h         \
        mono-coop-mutex.h               \
        mono-once.h             \
@@ -49,7 +52,9 @@ monoutils_sources = \
        mono-networkinterfaces.c                \
        mono-networkinterfaces.h                \
        mono-proclib.c          \
+       mono-proclib-windows.c          \
        mono-proclib.h          \
+       mono-proclib-windows.h          \
        mono-publib.c           \
        mono-string.h           \
        mono-time.c             \
@@ -149,7 +154,9 @@ monoutils_sources = \
        networking-windows.c    \
        networking.h    \
        mono-rand.c     \
+       mono-rand-windows.c     \
        mono-rand.h \
+       mono-rand-windows.h \
        memfuncs.c \
        memfuncs.h \
        parse.c \
index 86afad502ffe27947c4bf7718bc49abbd4ded33c..2f5e8a8a673a8688e78c577b57b7c194effaad76 100644 (file)
@@ -581,6 +581,10 @@ InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
        return(old);
 }
 
+#endif
 #endif
 
+#if defined(HOST_WIN32) && defined(_MSC_VER)
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_atomic_lnk4221(void) {}
 #endif
index d03ba8051aa565a53319b35aad89cecae2b9f450..0a78e55f8377b91ae3693baa63e59c962beaaa8a 100644 (file)
 #include <direct.h>
 #define mkdir(x)       _mkdir(x)
 
-/* GCC specific functions aren't available */
-#define __builtin_return_address(x)    NULL
-
 #define __func__ __FUNCTION__
 
 #include <BaseTsd.h>
diff --git a/mono/utils/mono-dl-windows-uwp.c b/mono/utils/mono-dl-windows-uwp.c
new file mode 100644 (file)
index 0000000..8bb8e6c
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * mono-dl-windows-uwp.c: UWP dl 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/utils/mono-dl-windows.h"
+
+void*
+mono_dl_lookup_symbol_in_process (const char *symbol_name)
+{
+       g_unsupported_api ("EnumProcessModules");
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return NULL;
+}
+
+char*
+mono_dl_current_error_string (void)
+{
+       char *ret = NULL;
+       TCHAR buf [1024];
+       DWORD code = GetLastError ();
+
+       if (!FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
+               code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, G_N_ELEMENTS(buf) - 1, NULL))
+               buf[0] = TEXT('\0');
+
+       ret = u16to8 (buf);
+       return ret;
+}
+
+#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_dl_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
index 9e3efa796f7aa93503ab2fa1712d2be476519c73..04f695d22de38e15d4a199142b400023df9e5f1c 100644 (file)
@@ -13,6 +13,7 @@
 #if defined(HOST_WIN32)
 
 #include "mono/utils/mono-dl.h"
+#include "mono/utils/mono-dl-windows.h"
 #include "mono/utils/mono-embed.h"
 #include "mono/utils/mono-path.h"
 
@@ -25,7 +26,6 @@
 #include <windows.h>
 #include <psapi.h>
 
-
 const char*
 mono_dl_get_so_prefix (void)
 {
@@ -48,14 +48,20 @@ mono_dl_open_file (const char *file, int flags)
        gpointer hModule = NULL;
        if (file) {
                gunichar2* file_utf16 = g_utf8_to_utf16 (file, strlen (file), NULL, NULL, NULL);
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
                guint last_sem = SetErrorMode (SEM_FAILCRITICALERRORS);
+#endif
                guint32 last_error = 0;
 
                hModule = LoadLibrary (file_utf16);
                if (!hModule)
                        last_error = GetLastError ();
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
                SetErrorMode (last_sem);
+#endif
+
                g_free (file_utf16);
 
                if (!hModule)
@@ -73,23 +79,15 @@ mono_dl_close_handle (MonoDl *module)
                FreeLibrary (module->handle);
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
 void*
-mono_dl_lookup_symbol (MonoDl *module, const char *symbol_name)
+mono_dl_lookup_symbol_in_process (const char *symbol_name)
 {
        HMODULE *modules;
        DWORD buffer_size = sizeof (HMODULE) * 1024;
        DWORD needed, i;
        gpointer proc = NULL;
 
-       /* get the symbol directly from the specified module */
-       if (!module->main_module)
-               return GetProcAddress (module->handle, symbol_name);
-
-       /* get the symbol from the main module */
-       proc = GetProcAddress (module->handle, symbol_name);
-       if (proc != NULL)
-               return proc;
-
        /* get the symbol from the loaded DLLs */
        modules = (HMODULE *) g_malloc (buffer_size);
        if (modules == NULL)
@@ -129,6 +127,25 @@ mono_dl_lookup_symbol (MonoDl *module, const char *symbol_name)
        g_free (modules);
        return NULL;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+void*
+mono_dl_lookup_symbol (MonoDl *module, const char *symbol_name)
+{
+       gpointer proc = NULL;
+
+       /* get the symbol directly from the specified module */
+       if (!module->main_module)
+               return GetProcAddress (module->handle, symbol_name);
+
+       /* get the symbol from the main module */
+       proc = GetProcAddress (module->handle, symbol_name);
+       if (proc != NULL)
+               return proc;
+
+       /* get the symbol from the loaded DLLs */
+       return mono_dl_lookup_symbol_in_process (symbol_name);
+}
 
 int
 mono_dl_convert_flags (int flags)
@@ -136,6 +153,7 @@ mono_dl_convert_flags (int flags)
        return 0;
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
 char*
 mono_dl_current_error_string (void)
 {
@@ -153,6 +171,7 @@ mono_dl_current_error_string (void)
        }
        return ret;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
 int
 mono_dl_get_executable_path (char *buf, int buflen)
@@ -165,5 +184,4 @@ mono_dl_get_system_dir (void)
 {
        return NULL;
 }
-
 #endif
diff --git a/mono/utils/mono-dl-windows.h b/mono/utils/mono-dl-windows.h
new file mode 100644 (file)
index 0000000..5215418
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef __MONO_UTILS_DL_WINDOWS_H__
+#define __MONO_UTILS_DL_WINDOWS_H__
+
+#include <config.h>
+#include <glib.h>
+
+#ifdef HOST_WIN32
+#include "mono/utils/mono-dl.h"
+
+void*
+mono_dl_lookup_symbol_in_process (const char *symbol_name);
+#endif /* HOST_WIN32 */
+#endif /* __MONO_UTILS_DL_WINDOWS_H__ */
+
index 54c6320d2b6f6a08bc8fc2fe249f315bbde8cac8..f423096a7800194c73af530b756e897f9b8050c9 100644 (file)
@@ -387,4 +387,11 @@ static inline gchar *mono_portability_find_file_internal (GString **report, cons
        g_free (new_pathname);
        return(NULL);
 }
+
+#else /* DISABLE_PORTABILITY */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_mono_io_portability_quiet_lnk4221(void) {}
 #endif
+#endif /* DISABLE_PORTABILITY */
index 4948b91b80fbd84435428d56098e47d751d3b2a0..bdb6dffb50e27f1838959452b585907afa062bbf 100644 (file)
@@ -26,6 +26,7 @@
 #include <process.h>
 #endif
 #include "mono-logger-internals.h"
+#include "mono-proclib.h"
 
 static FILE *logFile = NULL;
 static void *logUserData = NULL;
@@ -119,7 +120,7 @@ mono_log_write_logfile (const char *log_domain, GLogLevelFlags level, mono_bool
                struct tm *tod;
                time(&t);
                tod = localtime(&t);
-               pid = _getpid();
+               pid = mono_process_current_pid ();
                strftime(logTime, sizeof(logTime), "%F %T", tod);
 #endif
                fprintf (logFile, "%s level[%c] mono[%d]: %s\n", logTime, mapLogFileLevel (level), pid, message);
index f6cd987fbba85c31ebda11b966b220ef3067f7ac..ab5db470e1941f75bd2e712d119f979ffa6ff602 100644 (file)
@@ -24,6 +24,7 @@
 #include <time.h>
 #include <process.h>
 #include "mono-logger-internals.h"
+#include "mono-proclib.h"
 
 static FILE *logFile = NULL;
 static void *logUserData = NULL;
@@ -88,7 +89,7 @@ void
 mono_log_write_syslog(const char *domain, GLogLevelFlags level, mono_bool hdr, const char *message)
 {
        time_t t;
-       pid_t pid;
+       int pid;
        char logTime [80];
 
        if (logFile == NULL)
@@ -97,7 +98,7 @@ mono_log_write_syslog(const char *domain, GLogLevelFlags level, mono_bool hdr, c
        struct tm *tod;
        time(&t);
        tod = localtime(&t);
-       pid = _getpid();
+       pid = mono_process_current_pid ();
        strftime(logTime, sizeof(logTime), "%F %T", tod);
 
        fprintf (logFile, "%s level[%c] mono[%d]: %s\n", logTime, mapLogFileLevel (level), pid, message);
index b4367a73367dc03ff57c2a4d76cbc6fab9d9b553..5cc59c77fbe6dd87bf56d097df56dc7380e9baf9 100644 (file)
@@ -291,7 +291,7 @@ mono_trace_set_mask_string (const char *value)
                        continue;
                }
                for (i = 0; valid_flags[i]; i++) {
-                       int len = strlen (valid_flags[i]);
+                       size_t len = strlen (valid_flags[i]);
                        if (strncmp (tok, valid_flags[i], len) == 0 && (tok[len] == 0 || tok[len] == ',')) {
                                flags |= valid_masks[i];
                                tok += len;
index faca70b8ca95e655d759182f8538356a5291a8e5..90695609f0875b608f7c6ad3069b970459e4e86c 100644 (file)
 
 #include "mono-compiler.h"
 
-int mono_pages_not_faulted (void *addr, size_t length);
+void *
+malloc_shared_area (int pid);
+
+char*
+aligned_address (char *mem, size_t size, size_t alignment);
+
+void
+account_mem (MonoMemAccountType type, ssize_t size);
+
+int
+mono_pages_not_faulted (void *addr, size_t length);
 
 #endif /* __MONO_UTILS_MMAP_INTERNAL_H__ */
 
diff --git a/mono/utils/mono-mmap-windows-uwp.c b/mono/utils/mono-mmap-windows-uwp.c
new file mode 100644 (file)
index 0000000..5565200
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * mono-dl-windows-uwp.c: UWP dl 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/utils/mono-mmap-windows.h>
+
+void*
+mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle)
+{
+       void *ptr;
+       int mflags = 0;
+       HANDLE file, mapping;
+       int prot = mono_mmap_win_prot_from_flags (flags);
+
+       mflags = FILE_MAP_READ;
+       if (flags & MONO_MMAP_WRITE)
+               mflags = FILE_MAP_COPY;
+
+       file = (HANDLE) _get_osfhandle (fd);
+       mapping = CreateFileMappingFromApp (file, NULL, prot, length, NULL);
+
+       if (mapping == NULL)
+               return NULL;
+
+       ptr = MapViewOfFileFromApp (mapping, mflags, offset, length);
+
+       if (ptr == NULL) {
+               CloseHandle (mapping);
+               return NULL;
+       }
+
+       *ret_handle = (void*)mapping;
+       return ptr;
+}
+
+int
+mono_file_unmap (void *addr, void *handle)
+{
+       UnmapViewOfFile (addr);
+       CloseHandle ((HANDLE)handle);
+       return 0;
+}
+
+#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_mmap_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
diff --git a/mono/utils/mono-mmap-windows.c b/mono/utils/mono-mmap-windows.c
new file mode 100644 (file)
index 0000000..6fe7766
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * mono-mmap-windows.c: Windows support for mapping code into the process address space
+ *
+ * Author:
+ *   Mono Team (mono-list@lists.ximian.com)
+ *
+ * Copyright 2001-2008 Novell, Inc.
+ * 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 <Windows.h>
+#include "mono/utils/mono-mmap-windows.h"
+#include <mono/utils/mono-counters.h>
+#include <io.h>
+
+static void *malloced_shared_area = NULL;
+
+int
+mono_pagesize (void)
+{
+       SYSTEM_INFO info;
+       static int saved_pagesize = 0;
+       if (saved_pagesize)
+               return saved_pagesize;
+       GetSystemInfo (&info);
+       saved_pagesize = info.dwAllocationGranularity;
+       return saved_pagesize;
+}
+
+int
+mono_mmap_win_prot_from_flags (int flags)
+{
+       int prot = flags & (MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC);
+       switch (prot) {
+       case 0: prot = PAGE_NOACCESS; break;
+       case MONO_MMAP_READ: prot = PAGE_READONLY; break;
+       case MONO_MMAP_READ|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READ; break;
+       case MONO_MMAP_READ|MONO_MMAP_WRITE: prot = PAGE_READWRITE; break;
+       case MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; break;
+       case MONO_MMAP_WRITE: prot = PAGE_READWRITE; break;
+       case MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; break;
+       case MONO_MMAP_EXEC: prot = PAGE_EXECUTE; break;
+       default:
+               g_assert_not_reached ();
+       }
+       return prot;
+}
+
+void*
+mono_valloc (void *addr, size_t length, int flags, MonoMemAccountType type)
+{
+       void *ptr;
+       int mflags = MEM_RESERVE|MEM_COMMIT;
+       int prot = mono_mmap_win_prot_from_flags (flags);
+       /* translate the flags */
+
+       ptr = VirtualAlloc (addr, length, mflags, prot);
+
+       account_mem (type, (ssize_t)length);
+
+       return ptr;
+}
+
+void*
+mono_valloc_aligned (size_t length, size_t alignment, int flags, MonoMemAccountType type)
+{
+       int prot = mono_mmap_win_prot_from_flags (flags);
+       char *mem = VirtualAlloc (NULL, length + alignment, MEM_RESERVE, prot);
+       char *aligned;
+
+       if (!mem)
+               return NULL;
+
+       aligned = aligned_address (mem, length, alignment);
+
+       aligned = VirtualAlloc (aligned, length, MEM_COMMIT, prot);
+       g_assert (aligned);
+
+       account_mem (type, (ssize_t)length);
+
+       return aligned;
+}
+
+int
+mono_vfree (void *addr, size_t length, MonoMemAccountType type)
+{
+       MEMORY_BASIC_INFORMATION mbi;
+       SIZE_T query_result = VirtualQuery (addr, &mbi, sizeof (mbi));
+       BOOL res;
+
+       g_assert (query_result);
+
+       res = VirtualFree (mbi.AllocationBase, 0, MEM_RELEASE);
+
+       g_assert (res);
+
+       account_mem (type, -(ssize_t)length);
+
+       return 0;
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+void*
+mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle)
+{
+       void *ptr;
+       int mflags = 0;
+       HANDLE file, mapping;
+       int prot = mono_mmap_win_prot_from_flags (flags);
+       /* translate the flags */
+       /*if (flags & MONO_MMAP_PRIVATE)
+               mflags |= MAP_PRIVATE;
+       if (flags & MONO_MMAP_SHARED)
+               mflags |= MAP_SHARED;
+       if (flags & MONO_MMAP_ANON)
+               mflags |= MAP_ANONYMOUS;
+       if (flags & MONO_MMAP_FIXED)
+               mflags |= MAP_FIXED;
+       if (flags & MONO_MMAP_32BIT)
+               mflags |= MAP_32BIT;*/
+
+       mflags = FILE_MAP_READ;
+       if (flags & MONO_MMAP_WRITE)
+               mflags = FILE_MAP_COPY;
+
+       file = (HANDLE) _get_osfhandle (fd);
+
+       mapping = CreateFileMapping (file, NULL, prot, 0, 0, NULL);
+
+       if (mapping == NULL)
+               return NULL;
+
+       ptr = MapViewOfFile (mapping, mflags, 0, offset, length);
+
+       if (ptr == NULL) {
+               CloseHandle (mapping);
+               return NULL;
+       }
+       *ret_handle = (void*)mapping;
+       return ptr;
+}
+
+int
+mono_file_unmap (void *addr, void *handle)
+{
+       UnmapViewOfFile (addr);
+       CloseHandle ((HANDLE)handle);
+       return 0;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+int
+mono_mprotect (void *addr, size_t length, int flags)
+{
+       DWORD oldprot;
+       int prot = mono_mmap_win_prot_from_flags (flags);
+
+       if (flags & MONO_MMAP_DISCARD) {
+               VirtualFree (addr, length, MEM_DECOMMIT);
+               VirtualAlloc (addr, length, MEM_COMMIT, prot);
+               return 0;
+       }
+       return VirtualProtect (addr, length, prot, &oldprot) == 0;
+}
+
+void*
+mono_shared_area (void)
+{
+       if (!malloced_shared_area)
+               malloced_shared_area = malloc_shared_area (0);
+       /* get the pid here */
+       return malloced_shared_area;
+}
+
+void
+mono_shared_area_remove (void)
+{
+       if (malloced_shared_area)
+               g_free (malloced_shared_area);
+       malloced_shared_area = NULL;
+}
+
+void*
+mono_shared_area_for_pid (void *pid)
+{
+       return NULL;
+}
+
+void
+mono_shared_area_unload (void *area)
+{
+}
+
+int
+mono_shared_area_instances (void **array, int count)
+{
+       return 0;
+}
+
+#endif
diff --git a/mono/utils/mono-mmap-windows.h b/mono/utils/mono-mmap-windows.h
new file mode 100644 (file)
index 0000000..44da254
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __MONO_UTILS_MMAP_WINDOWS_H__
+#define __MONO_UTILS_MMAP_WINDOWS_H__
+
+#include <config.h>
+#include <glib.h>
+
+#ifdef HOST_WIN32
+#include "mono/utils/mono-mmap.h"
+#include "mono/utils/mono-mmap-internals.h"
+
+int
+mono_mmap_win_prot_from_flags (int flags);
+#endif /* HOST_WIN32 */
+#endif /* __MONO_UTILS_MMAP_WINDOWS_H__ */
+
index 491318465faf804a0767d46b45b838d8020814b5..91fe5a12def4517d7c1d364df7117cef53aa988f 100644 (file)
@@ -8,12 +8,9 @@
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "config.h"
+#include <config.h>
 
-#ifdef HOST_WIN32
-#include <windows.h>
-#include <io.h>
-#else
+#ifndef HOST_WIN32
 #include <sys/types.h>
 #if HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -29,7 +26,7 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <errno.h>
-#endif
+#endif /* !HOST_WIN32 */
 
 #include "mono-mmap.h"
 #include "mono-mmap-internals.h"
@@ -38,7 +35,6 @@
 #include <mono/utils/atomic.h>
 #include <mono/utils/mono-counters.h>
 
-
 #define BEGIN_CRITICAL_SECTION do { \
        MonoThreadInfo *__info = mono_thread_info_current_unchecked (); \
        if (__info) __info->inside_critical_region = TRUE;      \
@@ -63,9 +59,7 @@ typedef struct {
        short stats_end;
 } SAreaHeader;
 
-static void* malloced_shared_area = NULL;
-
-static void*
+void*
 malloc_shared_area (int pid)
 {
        int size = mono_pagesize ();
@@ -78,7 +72,7 @@ malloc_shared_area (int pid)
        return sarea;
 }
 
-static char*
+char*
 aligned_address (char *mem, size_t size, size_t alignment)
 {
        char *aligned = (char*)((size_t)(mem + (alignment - 1)) & ~(alignment - 1));
@@ -88,7 +82,7 @@ aligned_address (char *mem, size_t size, size_t alignment)
 
 static volatile size_t allocation_count [MONO_MEM_ACCOUNT_MAX];
 
-static void
+void
 account_mem (MonoMemAccountType type, ssize_t size)
 {
 #if SIZEOF_VOID_P == 4
@@ -135,186 +129,12 @@ mono_mem_account_register_counters (void)
 }
 
 #ifdef HOST_WIN32
-
-int
-mono_pagesize (void)
-{
-       SYSTEM_INFO info;
-       static int saved_pagesize = 0;
-       if (saved_pagesize)
-               return saved_pagesize;
-       GetSystemInfo (&info);
-       saved_pagesize = info.dwAllocationGranularity;
-       return saved_pagesize;
-}
-
-static int
-prot_from_flags (int flags)
-{
-       int prot = flags & (MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC);
-       switch (prot) {
-       case 0: prot = PAGE_NOACCESS; break;
-       case MONO_MMAP_READ: prot = PAGE_READONLY; break;
-       case MONO_MMAP_READ|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READ; break;
-       case MONO_MMAP_READ|MONO_MMAP_WRITE: prot = PAGE_READWRITE; break;
-       case MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; break;
-       case MONO_MMAP_WRITE: prot = PAGE_READWRITE; break;
-       case MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; break;
-       case MONO_MMAP_EXEC: prot = PAGE_EXECUTE; break;
-       default:
-               g_assert_not_reached ();
-       }
-       return prot;
-}
-
-void*
-mono_valloc (void *addr, size_t length, int flags, MonoMemAccountType type)
-{
-       void *ptr;
-       int mflags = MEM_RESERVE|MEM_COMMIT;
-       int prot = prot_from_flags (flags);
-       /* translate the flags */
-
-       ptr = VirtualAlloc (addr, length, mflags, prot);
-
-       account_mem (type, (ssize_t)length);
-
-       return ptr;
-}
-
-void*
-mono_valloc_aligned (size_t length, size_t alignment, int flags, MonoMemAccountType type)
-{
-       int prot = prot_from_flags (flags);
-       char *mem = VirtualAlloc (NULL, length + alignment, MEM_RESERVE, prot);
-       char *aligned;
-
-       if (!mem)
-               return NULL;
-
-       aligned = aligned_address (mem, length, alignment);
-
-       aligned = VirtualAlloc (aligned, length, MEM_COMMIT, prot);
-       g_assert (aligned);
-
-       account_mem (type, (ssize_t)length);
-
-       return aligned;
-}
-
+// Windows specific implementation in mono-mmap-windows.c
 #define HAVE_VALLOC_ALIGNED
 
-int
-mono_vfree (void *addr, size_t length, MonoMemAccountType type)
-{
-       MEMORY_BASIC_INFORMATION mbi;
-       SIZE_T query_result = VirtualQuery (addr, &mbi, sizeof (mbi));
-       BOOL res;
-
-       g_assert (query_result);
-
-       res = VirtualFree (mbi.AllocationBase, 0, MEM_RELEASE);
-
-       g_assert (res);
-
-       account_mem (type, -(ssize_t)length);
-
-       return 0;
-}
-
-void*
-mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle)
-{
-       void *ptr;
-       int mflags = 0;
-       HANDLE file, mapping;
-       int prot = prot_from_flags (flags);
-       /* translate the flags */
-       /*if (flags & MONO_MMAP_PRIVATE)
-               mflags |= MAP_PRIVATE;
-       if (flags & MONO_MMAP_SHARED)
-               mflags |= MAP_SHARED;
-       if (flags & MONO_MMAP_ANON)
-               mflags |= MAP_ANONYMOUS;
-       if (flags & MONO_MMAP_FIXED)
-               mflags |= MAP_FIXED;
-       if (flags & MONO_MMAP_32BIT)
-               mflags |= MAP_32BIT;*/
-
-       mflags = FILE_MAP_READ;
-       if (flags & MONO_MMAP_WRITE)
-               mflags = FILE_MAP_COPY;
-
-       file = (HANDLE) _get_osfhandle (fd);
-       mapping = CreateFileMapping (file, NULL, prot, 0, 0, NULL);
-       if (mapping == NULL)
-               return NULL;
-       ptr = MapViewOfFile (mapping, mflags, 0, offset, length);
-       if (ptr == NULL) {
-               CloseHandle (mapping);
-               return NULL;
-       }
-       *ret_handle = (void*)mapping;
-       return ptr;
-}
-
-int
-mono_file_unmap (void *addr, void *handle)
-{
-       UnmapViewOfFile (addr);
-       CloseHandle ((HANDLE)handle);
-       return 0;
-}
-
-int
-mono_mprotect (void *addr, size_t length, int flags)
-{
-       DWORD oldprot;
-       int prot = prot_from_flags (flags);
-
-       if (flags & MONO_MMAP_DISCARD) {
-               VirtualFree (addr, length, MEM_DECOMMIT);
-               VirtualAlloc (addr, length, MEM_COMMIT, prot);
-               return 0;
-       }
-       return VirtualProtect (addr, length, prot, &oldprot) == 0;
-}
-
-void*
-mono_shared_area (void)
-{
-       if (!malloced_shared_area)
-               malloced_shared_area = malloc_shared_area (0);
-       /* get the pid here */
-       return malloced_shared_area;
-}
-
-void
-mono_shared_area_remove (void)
-{
-       if (malloced_shared_area)
-               g_free (malloced_shared_area);
-       malloced_shared_area = NULL;
-}
-
-void*
-mono_shared_area_for_pid (void *pid)
-{
-       return NULL;
-}
-
-void
-mono_shared_area_unload (void *area)
-{
-}
-
-int
-mono_shared_area_instances (void **array, int count)
-{
-       return 0;
-}
-
 #else
+
+static void* malloced_shared_area = NULL;
 #if defined(HAVE_MMAP)
 
 /**
diff --git a/mono/utils/mono-proclib-windows-uwp.c b/mono/utils/mono-proclib-windows-uwp.c
new file mode 100644 (file)
index 0000000..e278ecc
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * mono-proclib-windows-uwp.c: UWP proclib 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/utils/mono-proclib.h>
+
+gint32
+mono_cpu_usage (MonoCpuUsageState *prev)
+{
+       gint32 cpu_usage = 0;
+       gint64 cpu_total_time;
+       gint64 cpu_busy_time;
+       guint64 idle_time;
+       guint64 kernel_time;
+       guint64 user_time;
+       guint64 current_time;
+       guint64 creation_time;
+       guint64 exit_time;
+
+       GetSystemTimeAsFileTime ((FILETIME*)&current_time);
+       if (!GetProcessTimes (GetCurrentProcess (), (FILETIME*)&creation_time, (FILETIME*)&exit_time, (FILETIME*)&kernel_time, (FILETIME*)&user_time)) {
+               g_error ("GetProcessTimes() failed, error code is %d\n", GetLastError ());
+               return -1;
+       }
+
+       // GetProcessTimes user_time is a sum of user time spend by all threads in the process.
+       // This means that the total user time can be more than real time. In order to adjust for this
+       // the total available time that we can be scheduled depends on the number of available cores.
+       // For example, having 2 threads running 100% on a 2 core system for 100 ms will return a user_time of 200ms
+       // but the current_time - creation_time will only be 100ms but by adjusting the available time based on number of
+       // of availalbe cores will gives use the total load of the process.
+       guint64 total_available_time = (current_time - creation_time) * mono_cpu_count ();
+
+       idle_time = total_available_time - (kernel_time + user_time);
+
+       cpu_total_time = (gint64)((idle_time - (prev ? prev->idle_time : 0)) + (user_time - (prev ? prev->user_time : 0)) + (kernel_time - (prev ? prev->kernel_time : 0)));
+       cpu_busy_time = (gint64)(cpu_total_time - (idle_time - (prev ? prev->idle_time : 0)));
+
+       if (prev) {
+               prev->idle_time = idle_time;
+               prev->kernel_time = kernel_time;
+               prev->user_time = user_time;
+       }
+
+       if (cpu_total_time > 0 && cpu_busy_time > 0)
+               cpu_usage = (gint32)(cpu_busy_time * 100 / cpu_total_time);
+
+       return cpu_usage;
+}
+
+#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_proclib_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
diff --git a/mono/utils/mono-proclib-windows.c b/mono/utils/mono-proclib-windows.c
new file mode 100644 (file)
index 0000000..6386a51
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * mono-proclib-windows.c: Windows proclib 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>
+
+#ifdef HOST_WIN32
+#include <windows.h>
+#include "mono/utils/mono-proclib.h"
+
+int
+mono_process_current_pid ()
+{
+       return (int) GetCurrentProcessId ();
+}
+
+/**
+ * mono_cpu_count:
+ *
+ * Return the number of processors on the system.
+ */
+int
+mono_cpu_count (void)
+{
+       SYSTEM_INFO info;
+       GetSystemInfo (&info);
+       return info.dwNumberOfProcessors;
+}
+
+/*
+ * This function returns the cpu usage in percentage,
+ * normalized on the number of cores.
+ *
+ * Warning : the percentage returned can be > 100%. This
+ * might happens on systems like Android which, for
+ * battery and performance reasons, shut down cores and
+ * lie about the number of active cores.
+ */
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+gint32
+mono_cpu_usage (MonoCpuUsageState *prev)
+{
+       gint32 cpu_usage = 0;
+       gint64 cpu_total_time;
+       gint64 cpu_busy_time;
+       guint64 idle_time;
+       guint64 kernel_time;
+       guint64 user_time;
+
+       if (!GetSystemTimes ((FILETIME*) &idle_time, (FILETIME*) &kernel_time, (FILETIME*) &user_time)) {
+               g_error ("GetSystemTimes() failed, error code is %d\n", GetLastError ());
+               return -1;
+       }
+
+       cpu_total_time = (gint64)((user_time - (prev ? prev->user_time : 0)) + (kernel_time - (prev ? prev->kernel_time : 0)));
+       cpu_busy_time = (gint64)(cpu_total_time - (idle_time - (prev ? prev->idle_time : 0)));
+
+       if (prev) {
+               prev->idle_time = idle_time;
+               prev->kernel_time = kernel_time;
+               prev->user_time = user_time;
+       }
+
+       if (cpu_total_time > 0 && cpu_busy_time > 0)
+               cpu_usage = (gint32)(cpu_busy_time * 100 / cpu_total_time);
+
+       return cpu_usage;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+#endif /* HOST_WIN32*/
diff --git a/mono/utils/mono-proclib-windows.h b/mono/utils/mono-proclib-windows.h
new file mode 100644 (file)
index 0000000..f14c7a4
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef __MONO_UTILS_PROCLIB_WINDOWS_H__
+#define __MONO_UTILS_PROCLIB_WINDOWS_H__
+
+#include <config.h>
+#include <glib.h>
+
+#ifdef HOST_WIN32
+#include <process.h>
+#include "mono/utils/mono-proclib.h"
+
+#endif /* HOST_WIN32 */
+#endif /* __MONO_UTILS_PROCLIB_WINDOWS_H__ */
+
index 79da32b45118f4e6f992207c723ce14f880477c0..9c37ccf2ec11874e121c4a394e980461c8a3c9f3 100644 (file)
 #include <sched.h>
 #endif
 
-#ifdef HOST_WIN32
-#include <windows.h>
-#include <process.h>
-#endif
-
 #if defined(_POSIX_VERSION)
 #include <sys/errno.h>
 #include <sys/param.h>
@@ -187,7 +182,7 @@ get_pid_status_item_buf (int pid, const char *item, char *rbuf, int blen, MonoPr
        char buf [256];
        char *s;
        FILE *f;
-       int len = strlen (item);
+       size_t len = strlen (item);
 
        g_snprintf (buf, sizeof (buf), "/proc/%d/status", pid);
        f = fopen (buf, "r");
@@ -286,7 +281,7 @@ mono_process_get_name (gpointer pid, char *buf, int len)
        char fname [128];
        FILE *file;
        char *p;
-       int r;
+       size_t r;
        sprintf (fname, "/proc/%d/cmdline", GPOINTER_TO_INT (pid));
        buf [0] = 0;
        file = fopen (fname, "r");
@@ -443,7 +438,8 @@ get_process_stat_item (int pid, int pos, int sum, MonoProcessError *error)
        char buf [512];
        char *s, *end;
        FILE *f;
-       int len, i;
+       size_t len;
+       int i;
        gint64 value;
 
        g_snprintf (buf, sizeof (buf), "/proc/%d/stat", pid);
@@ -637,31 +633,27 @@ mono_process_get_data (gpointer pid, MonoProcessData data)
        return mono_process_get_data_with_error (pid, data, &error);
 }
 
+#ifndef HOST_WIN32
 int
 mono_process_current_pid ()
 {
 #if defined(HAVE_UNISTD_H)
        return (int) getpid ();
-#elif defined(HOST_WIN32)
-       return (int) GetCurrentProcessId ();
 #else
 #error getpid
 #endif
 }
+#endif /* !HOST_WIN32 */
 
 /**
  * mono_cpu_count:
  *
  * Return the number of processors on the system.
  */
+#ifndef HOST_WIN32
 int
 mono_cpu_count (void)
 {
-#ifdef HOST_WIN32
-       SYSTEM_INFO info;
-       GetSystemInfo (&info);
-       return info.dwNumberOfProcessors;
-#else
 #ifdef PLATFORM_ANDROID
        /* Android tries really hard to save power by powering off CPUs on SMP phones which
         * means the normal way to query cpu count returns a wrong value with userspace API.
@@ -779,10 +771,10 @@ mono_cpu_count (void)
                        return count;
        }
 #endif
-#endif /* HOST_WIN32 */
        /* FIXME: warn */
        return 1;
 }
+#endif /* !HOST_WIN32 */
 
 static void
 get_cpu_times (int cpu_id, gint64 *user, gint64 *systemt, gint64 *irq, gint64 *sirq, gint64 *idle)
@@ -889,14 +881,13 @@ mono_atexit (void (*func)(void))
  * battery and performance reasons, shut down cores and
  * lie about the number of active cores.
  */
+#ifndef HOST_WIN32
 gint32
 mono_cpu_usage (MonoCpuUsageState *prev)
 {
        gint32 cpu_usage = 0;
        gint64 cpu_total_time;
        gint64 cpu_busy_time;
-
-#ifndef HOST_WIN32
        struct rusage resource_usage;
        gint64 current_time;
        gint64 kernel_time;
@@ -919,28 +910,10 @@ mono_cpu_usage (MonoCpuUsageState *prev)
                prev->user_time = user_time;
                prev->current_time = current_time;
        }
-#else
-       guint64 idle_time;
-       guint64 kernel_time;
-       guint64 user_time;
-
-       if (!GetSystemTimes ((FILETIME*) &idle_time, (FILETIME*) &kernel_time, (FILETIME*) &user_time)) {
-               g_error ("GetSystemTimes() failed, error code is %d\n", GetLastError ());
-               return -1;
-       }
-
-       cpu_total_time = (gint64)((user_time - (prev ? prev->user_time : 0)) + (kernel_time - (prev ? prev->kernel_time : 0)));
-       cpu_busy_time = (gint64)(cpu_total_time - (idle_time - (prev ? prev->idle_time : 0)));
-
-       if (prev) {
-               prev->idle_time = idle_time;
-               prev->kernel_time = kernel_time;
-               prev->user_time = user_time;
-       }
-#endif
 
        if (cpu_total_time > 0 && cpu_busy_time > 0)
                cpu_usage = (gint32)(cpu_busy_time * 100 / cpu_total_time);
 
        return cpu_usage;
 }
+#endif /* !HOST_WIN32 */
diff --git a/mono/utils/mono-rand-windows-uwp.c b/mono/utils/mono-rand-windows-uwp.c
new file mode 100644 (file)
index 0000000..e9030fe
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * mono-rand-windows-uwp.c: UWP rand 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/utils/mono-rand-windows.h"
+
+MONO_WIN32_CRYPT_PROVIDER_HANDLE
+mono_rand_win_open_provider (void)
+{
+       MONO_WIN32_CRYPT_PROVIDER_HANDLE provider = 0;
+
+       if (!BCRYPT_SUCCESS (BCryptOpenAlgorithmProvider (&provider, BCRYPT_RNG_ALGORITHM, NULL, 0)))
+               provider = 0;
+
+       return provider;
+}
+
+gboolean
+mono_rand_win_gen (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider, guchar *buffer, size_t buffer_size)
+{
+       g_assert (provider != 0 && buffer != 0);
+       return (BCRYPT_SUCCESS (BCryptGenRandom (provider, buffer, (ULONG) buffer_size, 0))) ? TRUE : FALSE;
+}
+
+gboolean
+mono_rand_win_seed (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider, guchar *seed, size_t seed_size)
+{
+       g_assert (provider != 0 && seed != 0);
+       return (BCRYPT_SUCCESS (BCryptGenRandom (provider, seed, (ULONG) seed_size, BCRYPT_RNG_USE_ENTROPY_IN_BUFFER))) ? TRUE : FALSE;
+}
+
+void
+mono_rand_win_close_provider (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider)
+{
+       g_assert (provider != 0);
+       BCryptCloseAlgorithmProvider (provider, 0);
+}
+
+#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_rand_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
diff --git a/mono/utils/mono-rand-windows.c b/mono/utils/mono-rand-windows.c
new file mode 100644 (file)
index 0000000..2ff32a9
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * mono-rand-windows.c: Windows rand 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>
+#include "mono-error.h"
+#include "mono-error-internals.h"
+#include "mono-rand.h"
+
+#if defined(HOST_WIN32)
+#include <windows.h>
+#include "mono/utils/mono-rand-windows.h"
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+#ifndef PROV_INTEL_SEC
+#define PROV_INTEL_SEC         22
+#endif
+#ifndef CRYPT_VERIFY_CONTEXT
+#define CRYPT_VERIFY_CONTEXT   0xF0000000
+#endif
+
+MONO_WIN32_CRYPT_PROVIDER_HANDLE
+mono_rand_win_open_provider (void)
+{
+       MONO_WIN32_CRYPT_PROVIDER_HANDLE provider = 0;
+
+       /* There is no need to create a container for just random data,
+        * so we can use CRYPT_VERIFY_CONTEXT (one call) see:
+        * http://blogs.msdn.com/dangriff/archive/2003/11/19/51709.aspx */
+
+       /* We first try to use the Intel PIII RNG if drivers are present */
+       if (!CryptAcquireContext (&provider, NULL, NULL, PROV_INTEL_SEC, CRYPT_VERIFY_CONTEXT)) {
+               /* not a PIII or no drivers available, use default RSA CSP */
+               if (!CryptAcquireContext (&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFY_CONTEXT)) {
+                       /* exception will be thrown in managed code */
+                       provider = 0;
+               }
+       }
+
+       return provider;
+}
+
+void
+mono_rand_win_close_provider (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider)
+{
+       CryptReleaseContext (provider, 0);
+}
+
+gboolean
+mono_rand_win_gen (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider, guchar *buffer, size_t buffer_size)
+{
+       return CryptGenRandom (provider, (DWORD) buffer_size, buffer);
+}
+
+gboolean
+mono_rand_win_seed (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider, guchar *seed, size_t seed_size)
+{
+       /* add seeding material to the RNG */
+       return CryptGenRandom (provider, (DWORD) seed_size, seed);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+/**
+ * mono_rand_open:
+ *
+ * Returns: True if random source is global, false if mono_rand_init can be called repeatedly to get randomness instances.
+ *
+ * Initializes entire RNG system. Must be called once per process before calling mono_rand_init.
+ */
+gboolean
+mono_rand_open (void)
+{
+       return FALSE;
+}
+
+/**
+ * mono_rand_init:
+ * @seed: A string containing seed data
+ * @seed_size: Length of seed string
+ *
+ * Returns: On success, a non-NULL handle which can be used to fetch random data from mono_rand_try_get_bytes. On failure, NULL.
+ *
+ * Initializes an RNG client.
+ */
+gpointer
+mono_rand_init (guchar *seed, gint seed_size)
+{
+       MONO_WIN32_CRYPT_PROVIDER_HANDLE provider = 0;
+
+       /* try to open crypto provider. */
+       provider = mono_rand_win_open_provider ();
+
+       /* seed the CSP with the supplied buffer (if present) */
+       if (provider != 0 && seed != NULL) {
+               /* the call we replace the seed with random - this isn't what is
+                * expected from the class library user */
+               guchar *data = g_malloc (seed_size);
+               if (data != NULL) {
+                       memcpy (data, seed, seed_size);
+                       /* add seeding material to the RNG */
+                       mono_rand_win_seed (provider, data, seed_size);
+                       /* zeroize and free */
+                       memset (data, 0, seed_size);
+                       g_free (data);
+               }
+       }
+
+       return (gpointer) provider;
+}
+
+/**
+ * mono_rand_try_get_bytes:
+ * @handle: A pointer to an RNG handle. Handle is set to NULL on failure.
+ * @buffer: A buffer into which to write random data.
+ * @buffer_size: Number of bytes to write into buffer.
+ * @error: Set on error.
+ *
+ * Returns: FALSE on failure and sets @error, TRUE on success.
+ *
+ * Extracts bytes from an RNG handle.
+ */
+gboolean
+mono_rand_try_get_bytes (gpointer *handle, guchar *buffer, gint buffer_size, MonoError *error)
+{
+       MONO_WIN32_CRYPT_PROVIDER_HANDLE provider;
+
+       mono_error_init (error);
+
+       g_assert (handle);
+       provider = (MONO_WIN32_CRYPT_PROVIDER_HANDLE) *handle;
+
+       /* generate random bytes */
+       if (!mono_rand_win_gen (provider, buffer, buffer_size)) {
+               mono_rand_win_close_provider (provider);
+               /* we may have lost our context with CryptoAPI, but all hope isn't lost yet! */
+               provider = mono_rand_win_open_provider ();
+               if (provider != 0) {
+
+                       /* retry generate of random bytes */
+                       if (!mono_rand_win_gen (provider, buffer, buffer_size)) {
+                               /* failure, close provider */
+                               mono_rand_win_close_provider (provider);
+                               provider = 0;
+                       }
+               }
+
+               /* make sure client gets new opened provider handle or NULL on failure */
+               *handle = (gpointer) provider;
+               if (*handle == 0) {
+                       /* exception will be thrown in managed code */
+                       mono_error_set_execution_engine (error, "Failed to gen random bytes (%d)", GetLastError ());
+                       return FALSE;
+               }
+       }
+       return TRUE;
+}
+
+/**
+ * mono_rand_close:
+ * @handle: An RNG handle.
+ *
+ * Releases an RNG handle.
+ */
+void
+mono_rand_close (gpointer handle)
+{
+       mono_rand_win_close_provider ((MONO_WIN32_CRYPT_PROVIDER_HANDLE) handle);
+}
+#endif /* HOST_WIN32 */
diff --git a/mono/utils/mono-rand-windows.h b/mono/utils/mono-rand-windows.h
new file mode 100644 (file)
index 0000000..f60c121
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef _MONO_UTILS_RAND_WINDOWS_H_
+#define _MONO_UTILS_RAND_WINDOWS_H_
+
+#include <config.h>
+#include <glib.h>
+
+#ifdef HOST_WIN32
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+#include <wincrypt.h>
+#define MONO_WIN32_CRYPT_PROVIDER_HANDLE HCRYPTPROV
+
+#else
+
+#include <bcrypt.h>
+#define MONO_WIN32_CRYPT_PROVIDER_HANDLE BCRYPT_ALG_HANDLE
+#endif
+
+MONO_WIN32_CRYPT_PROVIDER_HANDLE
+mono_rand_win_open_provider (void);
+
+gboolean
+mono_rand_win_gen (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider, guchar *buffer, size_t buffer_size);
+
+gboolean
+mono_rand_win_seed (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider, guchar *seed, size_t seed_size);
+
+void
+mono_rand_win_close_provider (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider);
+
+#endif /* HOST_WIN32 */
+#endif /* _MONO_UTILS_RAND_WINDOWS_H_ */
+
index 0e5a85384705341e3c5233e0db110fae07201803..1ac91179382d2ffb4ee7f5e826bca141e7cc4bb5 100644 (file)
@@ -13,7 +13,6 @@
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-
 #include <glib.h>
 #include <config.h>
 
 #include "metadata/object.h"
 
 #ifdef HOST_WIN32
-
-#include <windows.h>
-#include <wincrypt.h>
-
-#ifndef PROV_INTEL_SEC
-#define PROV_INTEL_SEC         22
-#endif
-#ifndef CRYPT_VERIFY_CONTEXT
-#define CRYPT_VERIFY_CONTEXT   0xF0000000
-#endif
-
-/**
- * mono_rand_open:
- *
- * Returns: True if random source is global, false if mono_rand_init can be called repeatedly to get randomness instances.
- *
- * Initializes entire RNG system. Must be called once per process before calling mono_rand_init.
- */
-gboolean
-mono_rand_open (void)
-{
-       return FALSE;
-}
-
-/**
- * mono_rand_init:
- * @seed: A string containing seed data
- * @seed_size: Length of seed string
- *
- * Returns: On success, a non-NULL handle which can be used to fetch random data from mono_rand_try_get_bytes. On failure, NULL.
- *
- * Initializes an RNG client.
- */
-gpointer
-mono_rand_init (guchar *seed, gint seed_size)
-{
-       HCRYPTPROV provider = 0;
-
-       /* There is no need to create a container for just random data,
-        * so we can use CRYPT_VERIFY_CONTEXT (one call) see: 
-        * http://blogs.msdn.com/dangriff/archive/2003/11/19/51709.aspx */
-
-       /* We first try to use the Intel PIII RNG if drivers are present */
-       if (!CryptAcquireContext (&provider, NULL, NULL, PROV_INTEL_SEC, CRYPT_VERIFY_CONTEXT)) {
-               /* not a PIII or no drivers available, use default RSA CSP */
-               if (!CryptAcquireContext (&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFY_CONTEXT)) {
-                       /* exception will be thrown in managed code */
-                       provider = 0;
-               }
-       }
-
-       /* seed the CSP with the supplied buffer (if present) */
-       if (provider != 0 && seed) {
-               /* the call we replace the seed with random - this isn't what is
-                * expected from the class library user */
-               guchar *data = g_malloc (seed_size);
-               if (data) {
-                       memcpy (data, seed, seed_size);
-                       /* add seeding material to the RNG */
-                       CryptGenRandom (provider, seed_size, data);
-                       /* zeroize and free */
-                       memset (data, 0, seed_size);
-                       g_free (data);
-               }
-       }
-
-       return (gpointer) provider;
-}
-
-/**
- * mono_rand_try_get_bytes:
- * @handle: A pointer to an RNG handle. Handle is set to NULL on failure.
- * @buffer: A buffer into which to write random data.
- * @buffer_size: Number of bytes to write into buffer.
- * @error: Set on error.
- *
- * Returns: FALSE on failure and sets @error, TRUE on success.
- *
- * Extracts bytes from an RNG handle.
- */
-gboolean
-mono_rand_try_get_bytes (gpointer *handle, guchar *buffer, gint buffer_size, MonoError *error)
-{
-       HCRYPTPROV provider;
-
-       mono_error_init (error);
-
-       g_assert (handle);
-       provider = (HCRYPTPROV) *handle;
-
-       if (!CryptGenRandom (provider, buffer_size, buffer)) {
-               CryptReleaseContext (provider, 0);
-               /* we may have lost our context with CryptoAPI, but all hope isn't lost yet! */
-               provider = (HCRYPTPROV) mono_rand_init (NULL, 0);
-               if (!CryptGenRandom (provider, buffer_size, buffer)) {
-                       /* exception will be thrown in managed code */
-                       CryptReleaseContext (provider, 0);
-                       *handle = 0;
-                       mono_error_set_execution_engine (error, "Failed to gen random bytes (%d)", GetLastError ());
-                       return FALSE;
-               }
-       }
-       return TRUE;
-}
-
-/**
- * mono_rand_close:
- * @handle: An RNG handle.
- * @buffer: A buffer into which to write random data.
- * @buffer_size: Number of bytes to write into buffer.
- *
- * Releases an RNG handle.
- */
-void
-mono_rand_close (gpointer handle)
-{
-       CryptReleaseContext ((HCRYPTPROV) handle, 0);
-}
-
+// Windows specific implementation in mono-rand-windows.c
 #elif defined (HAVE_SYS_UN_H) && !defined(__native_client__)
 
 #include <errno.h>
index c3501f25268fdc6b74b4bea84595698f1139a935..763c85b0d3757f6244eef499a30492de291cc39d 100644 (file)
@@ -53,4 +53,10 @@ inet_pton (int family, const char *address, void *inaddrp)
        return -1;
 }
 
+#else /* !HAVE_INET_PTON */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_networking_missing_lnk4221(void) {}
+#endif
 #endif /* !HAVE_INET_PTON */
index ca9ce67c4658365ada96d183ab9f909a5e9a2ec0..5f2d80f47a6dee4d3cf0566fa981ec9ba4216a07 100644 (file)
     <ClCompile Include="..\mono\utils\mono-log-common.c" />\r
     <ClCompile Include="..\mono\utils\mono-math.c" />\r
     <ClCompile Include="..\mono\utils\mono-md5.c" />\r
+    <ClCompile Include="..\mono\utils\mono-mmap-windows.c" />\r
     <ClCompile Include="..\mono\utils\mono-mmap.c" />\r
     <ClCompile Include="..\mono\utils\mono-networkinterfaces.c" />\r
+    <ClCompile Include="..\mono\utils\mono-proclib-windows.c" />\r
+    <ClCompile Include="..\mono\utils\mono-rand-windows.c" />\r
     <ClCompile Include="..\mono\utils\mono-rand.c" />\r
     <ClCompile Include="..\mono\utils\mono-threads-state-machine.c" />\r
     <ClCompile Include="..\mono\utils\networking.c" />\r
     <ClInclude Include="..\mono\utils\mono-counters.h" />\r
     <ClInclude Include="..\mono\utils\mono-digest.h" />\r
     <ClInclude Include="..\mono\utils\mono-dl-fallback.h" />\r
+    <ClInclude Include="..\mono\utils\mono-dl-windows.h" />\r
     <ClInclude Include="..\mono\utils\mono-dl.h" />\r
     <ClInclude Include="..\mono\utils\mono-error-internals.h" />\r
     <ClInclude Include="..\mono\utils\mono-error.h" />\r
     <ClInclude Include="..\mono\utils\mono-math.h" />\r
     <ClInclude Include="..\mono\utils\mono-membar.h" />\r
     <ClInclude Include="..\mono\utils\mono-memory-model.h" />\r
+    <ClInclude Include="..\mono\utils\mono-mmap-windows.h" />\r
     <ClInclude Include="..\mono\utils\mono-mmap.h" />\r
     <ClInclude Include="..\mono\utils\mono-networkinterfaces.h" />\r
     <ClInclude Include="..\mono\utils\mono-once.h" />\r
     <ClInclude Include="..\mono\utils\mono-os-semaphore.h" />\r
     <ClInclude Include="..\mono\utils\mono-path.h" />\r
     <ClInclude Include="..\mono\utils\mono-poll.h" />\r
+    <ClInclude Include="..\mono\utils\mono-proclib-windows.h" />\r
     <ClInclude Include="..\mono\utils\mono-proclib.h" />\r
     <ClInclude Include="..\mono\utils\mono-property-hash.h" />\r
     <ClInclude Include="..\mono\utils\mono-publib.h" />\r
+    <ClInclude Include="..\mono\utils\mono-rand-windows.h" />\r
     <ClInclude Include="..\mono\utils\mono-rand.h" />\r
     <ClInclude Include="..\mono\utils\mono-sigcontext.h" />\r
     <ClInclude Include="..\mono\utils\mono-stack-unwinding.h" />\r
   <ImportGroup Label="ExtensionTargets">\r
     <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />\r
   </ImportGroup>\r
-</Project>
+</Project>
\ No newline at end of file
index dae5e304a8738c178927c709bde9b29795b02e85..f74ea0cb33c66b7a97f36ed73dd04fc2f5716d84 100644 (file)
     <ClCompile Include="..\mono\utils\mono-log-windows.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\mono\utils\mono-rand-windows.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\utils\mono-proclib-windows.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\utils\mono-mmap-windows.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="..\mono\utils\atomic.h">\r
     <ClInclude Include="..\mono\utils\valgrind.h">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\mono\utils\mono-rand-windows.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\utils\mono-dl-windows.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\utils\mono-mmap-windows.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\utils\mono-proclib-windows.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Filter Include="Header Files">\r