Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/System.Private.Interop/src/Shared/McgMarshal.cs')
-rw-r--r--src/System.Private.Interop/src/Shared/McgMarshal.cs176
1 files changed, 172 insertions, 4 deletions
diff --git a/src/System.Private.Interop/src/Shared/McgMarshal.cs b/src/System.Private.Interop/src/Shared/McgMarshal.cs
index d6ef590c2..40ddc4f9d 100644
--- a/src/System.Private.Interop/src/Shared/McgMarshal.cs
+++ b/src/System.Private.Interop/src/Shared/McgMarshal.cs
@@ -4,8 +4,12 @@
// ----------------------------------------------------------------------------------
// Interop library code
//
-// Marshalling helpers used by MCG
-//
+// Marshalling helpers used by MCG generated stub
+// McgMarshal covers full marshalling surface area and is entrypoint for all marshalling support.
+// In long term:
+// 1. MCG generated code should call McgMarshal to do marshalling
+// 2. Public Marhshal API should call McgMarshal to do marshalling
+
// NOTE:
// These source code are being published to InternalAPIs and consumed by RH builds
// Use PublishInteropAPI.bat to keep the InternalAPI copies in sync
@@ -143,7 +147,7 @@ namespace System.Runtime.InteropServices
}
#if ENABLE_MIN_WINRT
- public static unsafe void SetExceptionErrorCode(Exception exception, int errorCode)
+ public static unsafe void SetExceptionErrorCode(Exception exception, int errorCode)
{
InteropExtensions.SetExceptionErrorCode(exception, errorCode);
}
@@ -364,6 +368,149 @@ namespace System.Runtime.InteropServices
{
return PInvokeMarshal.ByValAnsiStringToString(pchBuffer, charCount);
}
+
+ /// <summary>
+ /// CoTaskMemAlloc + ZeroMemory
+ /// @TODO - we can probably optimize the zero memory part later
+ /// </summary>
+ public unsafe static void* CoTaskMemAllocAndZeroMemory(IntPtr size)
+ {
+ void *ptr = (void*)PInvokeMarshal.CoTaskMemAlloc(new UIntPtr((void*)size));
+ if (ptr == null)
+ return ptr;
+
+ byte *pByte = (byte*)ptr;
+ long lSize = size.ToInt64();
+ while (lSize > 0)
+ {
+ lSize--;
+ (*pByte++) = 0;
+ }
+
+ return ptr;
+ }
+
+ /// <summary>
+ /// Free allocated memory. The allocated memory should be allocated by CoTaskMemAlloc
+ /// </summary>
+ public static void SafeCoTaskMemFree(IntPtr allocatedMemory)
+ {
+ if (allocatedMemory != IntPtr.Zero)
+ PInvokeMarshal.CoTaskMemFree(allocatedMemory);
+ }
+
+ /// <summary>
+ /// Free allocated memory. The allocated memory should be allocated by CoTaskMemAlloc
+ /// </summary>
+ public static unsafe void SafeCoTaskMemFree(void* pv)
+ {
+ if (pv != null)
+ PInvokeMarshal.CoTaskMemFree(new IntPtr(pv));
+ }
+
+ /// <summary>
+ /// Allocate a buffer with enough size to store the unicode characters saved in source
+ /// Buffer is allocated with CoTaskMemAlloc
+ /// </summary>
+ public unsafe static void *AllocUnicodeBuffer(string source)
+ {
+ if (source == null)
+ return null;
+
+ int byteLen = checked((source.Length + 1) * 2);
+
+ char* pBuf = (char*)PInvokeMarshal.CoTaskMemAlloc(new UIntPtr((uint)byteLen));
+ if (pBuf == null)
+ throw new System.OutOfMemoryException();
+
+ return pBuf;
+ }
+
+ /// <summary>
+ /// Copy unicode characters in source into dest, and terminating with null
+ /// </summary>
+ public unsafe static void CopyUnicodeString(string source, void* _dest)
+ {
+ if (source == null)
+ return;
+
+ char* dest = (char *)_dest;
+ fixed (char* pSource = source)
+ {
+ int len = source.Length;
+ char* src = pSource;
+
+ // Copy characters one by one, including the null terminator
+ for (int i = 0; i <= len; ++i)
+ {
+ *(dest++) = *(src++);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Convert String to BSTR
+ /// </summary>
+ public unsafe static ushort* ConvertStringToBSTR(
+ ushort* ptrToFirstCharInBSTR,
+ string strManaged)
+ {
+ if (strManaged == null)
+ return null;
+
+ if (ptrToFirstCharInBSTR == null)
+ {
+ // If caller don't provided buffer, allocate the buffer and create string using SysAllocStringLen
+ fixed (char* ch = strManaged)
+ {
+ return (ushort*) ExternalInterop.SysAllocStringLen(ch, (uint)strManaged.Length);
+ }
+ }
+ else
+ {
+ // If caller provided a buffer, construct the BSTR manually.
+
+ // set length
+ *((int*)ptrToFirstCharInBSTR - 1) = checked(strManaged.Length * 2);
+
+ // copy characters from the managed string
+ fixed (char* ch = strManaged)
+ {
+ InteropExtensions.Memcpy(
+ (System.IntPtr)ptrToFirstCharInBSTR,
+ (System.IntPtr)ch,
+ (strManaged.Length + 1) * 2);
+ }
+
+ return ptrToFirstCharInBSTR;
+ }
+ }
+
+ /// <summary>
+ /// Convert BSTR to String
+ /// </summary>
+ public unsafe static string ConvertBSTRToString(ushort* bstr)
+ {
+ if (bstr == null)
+ return null;
+ return new string((char*)bstr, 0, (int)ExternalInterop.SysStringLen(bstr));
+ }
+
+ /// <summary>
+ /// Free Allocated BSTR
+ /// </summary>
+ public static unsafe void SysFreeString(void* pBSTR)
+ {
+ SysFreeString(new IntPtr(pBSTR));
+ }
+
+ /// <summary>
+ /// Free Allocated BSTR
+ /// </summary>
+ public unsafe static void SysFreeString(IntPtr pBSTR)
+ {
+ ExternalInterop.SysFreeString(pBSTR);
+ }
#endif
#if ENABLE_MIN_WINRT
@@ -975,7 +1122,7 @@ namespace System.Runtime.InteropServices
#endregion
/// <summary>
- /// This method returns HR for the exception being thrown.
+ /// This method propagate the exception being thrown.
/// 1. On Windows8+, WinRT scenarios we do the following.
/// a. Check whether the exception has any IRestrictedErrorInfo associated with it.
/// If so, it means that this exception was actually caused by a native exception in which case we do simply use the same
@@ -983,6 +1130,27 @@ namespace System.Runtime.InteropServices
/// b. If not, this is actually a managed exception and in this case we RoOriginateLanguageException with the msg, hresult and the IErrorInfo
/// associated with the managed exception. This helps us to retrieve the same exception in case it comes back to native.
/// 2. On win8 and for classic COM scenarios.
+ /// a. This method should not be called
+ /// </summary>
+ /// <param name="ex"></param>
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static bool PropagateException(Exception ex)
+ {
+#if ENABLE_WINRT
+ return ExceptionHelpers.PropagateException(ex);
+#else
+ // TODO : ExceptionHelpers should be platform specific , move it to
+ // seperate source files
+ return true;
+#endif
+ }
+
+ /// <summary>
+ /// This method returns HR for the exception being thrown.
+ /// 1. On Windows8+, WinRT scenarios
+ /// The work to propagate the exception should have already performed in the exception filter
+ /// by calling PropagateException()
+ /// 2. On win8 and for classic COM scenarios.
/// a. We create IErrorInfo for the given Exception object and SetErrorInfo with the given IErrorInfo.
/// </summary>
/// <param name="ex"></param>