Enabled possibility to exclude SafeArray implementation on Windows.
authorlateralusX <lateralusx.github@gmail.com>
Thu, 1 Dec 2016 11:34:58 +0000 (12:34 +0100)
committerlateralusX <lateralusx.github@gmail.com>
Thu, 1 Dec 2016 11:34:58 +0000 (12:34 +0100)
SafeArray implementation is not available under all Windows API families. This commit
extracts SafeArray methods making it possible to exclude them under Windows API families
not supporting SafeArrays.

mono/metadata/Makefile.am
mono/metadata/cominterop-win32-internals.h [new file with mode: 0644]
mono/metadata/cominterop.c
msvc/libmonoruntime.vcxproj
msvc/libmonoruntime.vcxproj.filters

index bc369533a3f86bdc79f4d09e1c21cce51c292667..3217ba6029a0b85958094b2a3e1264d3acdd78a7 100644 (file)
@@ -2,6 +2,7 @@ if HOST_WIN32
 win32_sources = \
        console-win32.c \
        console-win32-internals.h \
+       cominterop-win32-internals.h \
        file-io-windows.c \
        file-io-windows-internals.h \
        icall-windows.c \
diff --git a/mono/metadata/cominterop-win32-internals.h b/mono/metadata/cominterop-win32-internals.h
new file mode 100644 (file)
index 0000000..ec9f9bd
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_METADATA_COMINTEROP_WIN32_INTERNALS_H__
+#define __MONO_METADATA_COMINTEROP_WIN32_INTERNALS_H__
+
+#include <config.h>
+#include <glib.h>
+
+// On some Windows platforms the implementation of below methods are hosted
+// in separate source files like cominterop-win32-*.c. On other platforms,
+// the implementation is kept in cominterop.c and declared as static and in some
+// cases even inline.
+#if defined(HOST_WIN32) && !G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT)
+
+guint32
+mono_marshal_win_safearray_get_dim (gpointer safearray);
+
+int
+mono_marshal_win_safe_array_get_lbound (gpointer psa, guint nDim, glong* plLbound);
+
+int
+mono_marshal_win_safe_array_get_ubound (gpointer psa, guint nDim, glong* plUbound);
+
+int
+mono_marshal_win_safearray_get_value (gpointer safearray, gpointer indices, gpointer *result);
+
+void
+mono_marshal_win_safearray_end (gpointer safearray, gpointer indices);
+
+gboolean
+mono_marshal_win_safearray_create_internal (UINT cDims, SAFEARRAYBOUND *rgsabound, gpointer *newsafearray);
+
+int
+mono_marshal_win_safearray_set_value (gpointer safearray, gpointer indices, gpointer value);
+
+#endif /* HOST_WIN32 && !G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
+
+#endif /* __MONO_METADATA_COMINTEROP_WIN32_INTERNALS_H__ */
index cf61058a3a7525b92fa2ad8c0f355db5b1289bd0..e3ba400a2c4a59162f573dd7d1c6fa46f9959074 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include "config.h"
+#include <glib.h>
 #ifdef HAVE_ALLOCA_H
 #include <alloca.h>
 #endif
@@ -42,6 +43,7 @@
 
 #if defined(HOST_WIN32)
 #include <oleauto.h>
+#include "mono/metadata/cominterop-win32-internals.h"
 #endif
 
 /*
@@ -3108,53 +3110,95 @@ mono_cominterop_emit_marshal_safearray (EmitMarshalContext *m, int argnum, MonoT
        return conv_arg;
 }
 
-static 
-guint32 mono_marshal_safearray_get_dim (gpointer safearray)
+#ifdef HOST_WIN32
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT)
+static inline guint32
+mono_marshal_win_safearray_get_dim (gpointer safearray)
+{
+       return SafeArrayGetDim (safearray);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
+
+static guint32
+mono_marshal_safearray_get_dim (gpointer safearray)
+{
+       return mono_marshal_win_safearray_get_dim (safearray);
+}
+
+#else /* HOST_WIN32 */
+
+static guint32
+mono_marshal_safearray_get_dim (gpointer safearray)
 {
        guint32 result=0;
-#ifdef HOST_WIN32
-       result = SafeArrayGetDim (safearray);
-#else
        if (com_provider == MONO_COM_MS && init_com_provider_ms ()) {
                result = safe_array_get_dim_ms (safearray);
        } else {
                g_assert_not_reached ();
        }
-#endif
        return result;
 }
+#endif /* HOST_WIN32 */
 
-static 
-int mono_marshal_safe_array_get_lbound (gpointer psa, guint nDim, glong* plLbound)
+#ifdef HOST_WIN32
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT)
+static inline int
+mono_marshal_win_safe_array_get_lbound (gpointer psa, guint nDim, glong* plLbound)
+{
+       return SafeArrayGetLBound (psa, nDim, plLbound);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
+
+static int
+mono_marshal_safe_array_get_lbound (gpointer psa, guint nDim, glong* plLbound)
+{
+       return mono_marshal_win_safe_array_get_lbound (psa, nDim, plLbound);
+}
+
+#else /* HOST_WIN32 */
+
+static int
+mono_marshal_safe_array_get_lbound (gpointer psa, guint nDim, glong* plLbound)
 {
        int result=MONO_S_OK;
-#ifdef HOST_WIN32
-       result = SafeArrayGetLBound (psa, nDim, plLbound);
-#else
        if (com_provider == MONO_COM_MS && init_com_provider_ms ()) {
                result = safe_array_get_lbound_ms (psa, nDim, plLbound);
        } else {
                g_assert_not_reached ();
        }
-#endif
        return result;
 }
+#endif /* HOST_WIN32 */
 
-static 
-int mono_marshal_safe_array_get_ubound (gpointer psa, guint nDim, glong* plUbound)
+#ifdef HOST_WIN32
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT)
+inline static int
+mono_marshal_win_safe_array_get_ubound (gpointer psa, guint nDim, glong* plUbound)
+{
+       return SafeArrayGetUBound (psa, nDim, plUbound);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
+
+static int
+mono_marshal_safe_array_get_ubound (gpointer psa, guint nDim, glong* plUbound)
+{
+       return mono_marshal_win_safe_array_get_ubound (psa, nDim, plUbound);
+}
+
+#else /* HOST_WIN32 */
+
+static int
+mono_marshal_safe_array_get_ubound (gpointer psa, guint nDim, glong* plUbound)
 {
        int result=MONO_S_OK;
-#ifdef HOST_WIN32
-       result = SafeArrayGetUBound (psa, nDim, plUbound);
-#else
        if (com_provider == MONO_COM_MS && init_com_provider_ms ()) {
                result = safe_array_get_ubound_ms (psa, nDim, plUbound);
        } else {
                g_assert_not_reached ();
        }
-#endif
        return result;
 }
+#endif /* HOST_WIN32 */
 
 /* This is an icall */
 static gboolean
@@ -3235,19 +3279,39 @@ mono_marshal_safearray_begin (gpointer safearray, MonoArray **result, gpointer *
 }
 
 /* This is an icall */
-static 
-gpointer mono_marshal_safearray_get_value (gpointer safearray, gpointer indices)
+#ifdef HOST_WIN32
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT)
+static inline int
+mono_marshal_win_safearray_get_value (gpointer safearray, gpointer indices, gpointer *result)
+{
+       return SafeArrayPtrOfIndex (safearray, indices, result);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
+
+static gpointer
+mono_marshal_safearray_get_value (gpointer safearray, gpointer indices)
 {
        MonoError error;
        gpointer result;
-#ifdef HOST_WIN32
-       int hr = SafeArrayPtrOfIndex (safearray, indices, &result);
+
+       int hr = mono_marshal_win_safearray_get_value (safearray, indices, &result);
        if (hr < 0) {
                        cominterop_set_hr_error (&error, hr);
                        mono_error_set_pending_exception (&error);
-                       return NULL;
+                       result = NULL;
        }
-#else
+
+       return result;
+}
+
+#else /* HOST_WIN32 */
+
+static gpointer
+mono_marshal_safearray_get_value (gpointer safearray, gpointer indices)
+{
+       MonoError error;
+       gpointer result;
+
        if (com_provider == MONO_COM_MS && init_com_provider_ms ()) {
                int hr = safe_array_ptr_of_index_ms (safearray, (glong *)indices, &result);
                if (hr < 0) {
@@ -3258,9 +3322,9 @@ gpointer mono_marshal_safearray_get_value (gpointer safearray, gpointer indices)
        } else {
                g_assert_not_reached ();
        }
-#endif
        return result;
 }
+#endif /* HOST_WIN32 */
 
 /* This is an icall */
 static 
@@ -3303,20 +3367,62 @@ gboolean mono_marshal_safearray_next (gpointer safearray, gpointer indices)
        return ret;
 }
 
-static 
-void mono_marshal_safearray_end (gpointer safearray, gpointer indices)
+#ifdef HOST_WIN32
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT)
+static inline void
+mono_marshal_win_safearray_end (gpointer safearray, gpointer indices)
 {
        g_free(indices);
-#ifdef HOST_WIN32
        SafeArrayDestroy (safearray);
-#else
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
+
+static void
+mono_marshal_safearray_end (gpointer safearray, gpointer indices)
+{
+       mono_marshal_win_safearray_end (safearray, indices);
+}
+
+#else /* HOST_WIN32 */
+
+static void
+mono_marshal_safearray_end (gpointer safearray, gpointer indices)
+{
+       g_free(indices);
        if (com_provider == MONO_COM_MS && init_com_provider_ms ()) {
                safe_array_destroy_ms (safearray);
        } else {
                g_assert_not_reached ();
        }
-#endif
 }
+#endif /* HOST_WIN32 */
+
+#ifdef HOST_WIN32
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT)
+static inline gboolean
+mono_marshal_win_safearray_create_internal (UINT cDims, SAFEARRAYBOUND *rgsabound, gpointer *newsafearray)
+{
+       *newsafearray = SafeArrayCreate (VT_VARIANT, cDims, rgsabound);
+       return TRUE;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
+
+static gboolean
+mono_marshal_safearray_create_internal (UINT cDims, SAFEARRAYBOUND *rgsabound, gpointer *newsafearray)
+{
+       return mono_marshal_win_safearray_create_internal (cDims, rgsabound, newsafearray);
+}
+
+#else /* HOST_WIN32 */
+
+static inline gboolean
+mono_marshal_safearray_create_internal (UINT cDims, SAFEARRAYBOUND *rgsabound, gpointer *newsafearray)
+{
+       *newsafearray = safe_array_create_ms (VT_VARIANT, cDims, rgsabound);
+       return TRUE;
+}
+
+#endif /* HOST_WIN32 */
 
 static gboolean
 mono_marshal_safearray_create (MonoArray *input, gpointer *newsafearray, gpointer *indices, gpointer empty)
@@ -3355,28 +3461,37 @@ mono_marshal_safearray_create (MonoArray *input, gpointer *newsafearray, gpointe
                bounds [0].lLbound = 0;
        }
 
-#ifdef HOST_WIN32
-       *newsafearray = SafeArrayCreate (VT_VARIANT, dim, bounds);
-#else
-       *newsafearray = safe_array_create_ms (VT_VARIANT, dim, bounds);
-#endif
-
-       return TRUE;
+       return mono_marshal_safearray_create_internal (dim, bounds, newsafearray);
 }
 
 /* This is an icall */
-static 
-void mono_marshal_safearray_set_value (gpointer safearray, gpointer indices, gpointer value)
+#ifdef HOST_WIN32
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT)
+static inline int
+mono_marshal_win_safearray_set_value (gpointer safearray, gpointer indices, gpointer value)
+{
+       return SafeArrayPutElement (safearray, indices, value);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
+
+static void
+mono_marshal_safearray_set_value (gpointer safearray, gpointer indices, gpointer value)
 {
        MonoError error;
-#ifdef HOST_WIN32
-       int hr = SafeArrayPutElement (safearray, indices, value);
+       int hr = mono_marshal_win_safearray_set_value (safearray, indices, value);
        if (hr < 0) {
                cominterop_set_hr_error (&error, hr);
                mono_error_set_pending_exception (&error);
                return;
        }
-#else
+}
+
+#else /* HOST_WIN32 */
+
+static void
+mono_marshal_safearray_set_value (gpointer safearray, gpointer indices, gpointer value)
+{
+       MonoError error;
        if (com_provider == MONO_COM_MS && init_com_provider_ms ()) {
                int hr = safe_array_put_element_ms (safearray, (glong *)indices, (void **)value);
                if (hr < 0) {
@@ -3386,8 +3501,8 @@ void mono_marshal_safearray_set_value (gpointer safearray, gpointer indices, gpo
                }
        } else
                g_assert_not_reached ();
-#endif
 }
+#endif /* HOST_WIN32 */
 
 static 
 void mono_marshal_safearray_free_indices (gpointer indices)
index 762947af907c7144679b385094aa5574ac0cdde7..eb199f1dfa19869a6c3756a81d79ddeefa94c67a 100644 (file)
     <ClInclude Include="..\mono\metadata\cil-coff.h" />\r
     <ClInclude Include="..\mono\metadata\class-internals.h" />\r
     <ClInclude Include="..\mono\metadata\class.h" />\r
+    <ClInclude Include="..\mono\metadata\cominterop-win32-internals.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
index d36472937a11002b372216ac0db1d035b0d1d18b..db52a544a495082b6135cb48ea4c4846656d7a7c 100644 (file)
     <ClInclude Include="..\mono\metadata\property-bag.h">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\cominterop-win32-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Filter Include="Header Files">\r