internal unsafe static IntPtr ConvertToNative(int flags, string strManaged, IntPtr pNativeBuffer) { if (strManaged == null) { return(IntPtr.Zero); } StubHelpers.CheckStringLength(strManaged.Length); byte *ptr = (byte *)((void *)pNativeBuffer); int num; if (ptr != null || Marshal.SystemMaxDBCSCharSize == 1) { num = (strManaged.Length + 1) * Marshal.SystemMaxDBCSCharSize; if (ptr == null) { ptr = (byte *)((void *)Marshal.AllocCoTaskMem(num + 1)); } num = strManaged.ConvertToAnsi(ptr, num + 1, (flags & 255) != 0, flags >> 8 != 0); } else { byte[] src = AnsiCharMarshaler.DoAnsiConversion(strManaged, (flags & 255) != 0, flags >> 8 != 0, out num); ptr = (byte *)((void *)Marshal.AllocCoTaskMem(num + 2)); Buffer.Memcpy(ptr, 0, src, 0, num); } ptr[num] = 0; ptr[num + 1] = 0; return((IntPtr)((void *)ptr)); }
internal unsafe static IntPtr ConvertToNative(string strManaged, bool fBestFit, bool fThrowOnUnmappableChar, ref int cch) { if (strManaged == null) { return(IntPtr.Zero); } cch = strManaged.Length; StubHelpers.CheckStringLength(cch); int cb = 4 + (cch + 1) * Marshal.SystemMaxDBCSCharSize; byte *ptr = (byte *)((void *)Marshal.AllocCoTaskMem(cb)); int * ptr2 = (int *)ptr; ptr += 4; if (cch == 0) { *ptr = 0; *ptr2 = 0; } else { int num; byte[] src = AnsiCharMarshaler.DoAnsiConversion(strManaged, fBestFit, fThrowOnUnmappableChar, out num); Buffer.Memcpy(ptr, 0, src, 0, num); ptr[num] = 0; *ptr2 = num; } return(new IntPtr((void *)ptr)); }
internal unsafe static string ConvertToManaged(IntPtr bstr) { if (IntPtr.Zero == bstr) { return(null); } uint num = Win32Native.SysStringByteLen(bstr); StubHelpers.CheckStringLength(num); string text; if (num == 1U) { text = string.FastAllocateString(0); } else { text = new string((char *)((void *)bstr), 0, (int)(num / 2U)); } if ((num & 1U) == 1U) { text.SetTrailByte(((byte *)bstr.ToPointer())[num - 1U]); } return(text); }
private unsafe IntPtr ConvertStringBuilderToNative(StringBuilder pManagedHome, int dwFlags) { IntPtr intPtr; if (AsAnyMarshaler.IsAnsi(dwFlags)) { StubHelpers.CheckStringLength(pManagedHome.Capacity); int num = pManagedHome.Capacity * Marshal.SystemMaxDBCSCharSize + 4; intPtr = Marshal.AllocCoTaskMem(num); byte *ptr = (byte *)((void *)intPtr); *(ptr + num - 3) = 0; *(ptr + num - 2) = 0; *(ptr + num - 1) = 0; if (AsAnyMarshaler.IsIn(dwFlags)) { int num2; byte[] src = AnsiCharMarshaler.DoAnsiConversion(pManagedHome.ToString(), AsAnyMarshaler.IsBestFit(dwFlags), AsAnyMarshaler.IsThrowOn(dwFlags), out num2); Buffer.Memcpy(ptr, 0, src, 0, num2); ptr[num2] = 0; } if (AsAnyMarshaler.IsOut(dwFlags)) { this.backPropAction = AsAnyMarshaler.BackPropAction.StringBuilderAnsi; } } else { int num3 = pManagedHome.Capacity * 2 + 4; intPtr = Marshal.AllocCoTaskMem(num3); byte *ptr2 = (byte *)((void *)intPtr); *(ptr2 + num3 - 1) = 0; *(ptr2 + num3 - 2) = 0; if (AsAnyMarshaler.IsIn(dwFlags)) { int num4 = pManagedHome.Length * 2; pManagedHome.InternalCopy(intPtr, num4); ptr2[num4] = 0; (ptr2 + num4)[1] = 0; } if (AsAnyMarshaler.IsOut(dwFlags)) { this.backPropAction = AsAnyMarshaler.BackPropAction.StringBuilderUnicode; } } return(intPtr); }
private static IntPtr ConvertStringToNative(string pManagedHome, int dwFlags) { IntPtr intPtr; if (AsAnyMarshaler.IsAnsi(dwFlags)) { intPtr = CSTRMarshaler.ConvertToNative(dwFlags & 65535, pManagedHome, IntPtr.Zero); } else { StubHelpers.CheckStringLength(pManagedHome.Length); int num = (pManagedHome.Length + 1) * 2; intPtr = Marshal.AllocCoTaskMem(num); string.InternalCopy(pManagedHome, intPtr, num); } return(intPtr); }
internal static IntPtr ConvertToNative(int flags, string strManaged) { if (strManaged == null) { return(IntPtr.Zero); } int length = strManaged.Length; StubHelpers.CheckStringLength(length); byte[] str = null; int len = 0; if (length > 0) { str = AnsiCharMarshaler.DoAnsiConversion(strManaged, (flags & 255) != 0, flags >> 8 != 0, out len); } return(Win32Native.SysAllocStringByteLen(str, (uint)len)); }
internal unsafe static IntPtr ConvertToNative(string strManaged, IntPtr pNativeBuffer) { if (strManaged == null) { return(IntPtr.Zero); } StubHelpers.CheckStringLength(strManaged.Length); byte b; bool flag = strManaged.TryGetTrailByte(out b); uint num = (uint)(strManaged.Length * 2); if (flag) { num += 1U; } byte *ptr; if (pNativeBuffer != IntPtr.Zero) { *(int *)pNativeBuffer.ToPointer() = (int)num; ptr = (byte *)pNativeBuffer.ToPointer() + 4; } else { ptr = (byte *)Win32Native.SysAllocStringByteLen(null, num).ToPointer(); } fixed(string text = strManaged) { char *ptr2 = text; if (ptr2 != null) { ptr2 += RuntimeHelpers.OffsetToStringData / 2; } Buffer.Memcpy(ptr, (byte *)ptr2, (strManaged.Length + 1) * 2); } if (flag) { ptr[num - 1U] = b; } return((IntPtr)((void *)ptr)); }
internal static unsafe string?ConvertToManaged(IntPtr bstr) { if (IntPtr.Zero == bstr) { return(null); } else { uint length = Marshal.SysStringByteLen(bstr); // Intentionally checking the number of bytes not characters to match the behavior // of ML marshalers. This prevents roundtripping of very large strings as the check // in the managed->native direction is done on String length but considering that // it's completely moot on 32-bit and not expected to be important on 64-bit either, // the ability to catch random garbage in the BSTR's length field outweighs this // restriction. If an ordinary null-terminated string is passed instead of a BSTR, // chances are that the length field - possibly being unallocated memory - contains // a heap fill pattern that will have the highest bit set, caught by the check. StubHelpers.CheckStringLength(length); string ret; if (length == 1) { // In the empty string case, we need to use FastAllocateString rather than the // String .ctor, since newing up a 0 sized string will always return String.Empty. // When we marshal that out as a bstr, it can wind up getting modified which // corrupts string.Empty. ret = string.FastAllocateString(0); } else { ret = new string((char *)bstr, 0, (int)(length / 2)); } if ((length & 1) == 1) { // odd-sized strings need to have the trailing byte saved in their sync block ret.SetTrailByte(((byte *)bstr)[length - 1]); } return(ret); } }
internal unsafe static IntPtr ConvertToNative(int flags, string strManaged, IntPtr pNativeBuffer) { if (strManaged == null) { return(IntPtr.Zero); } StubHelpers.CheckStringLength(strManaged.Length); byte *ptr = (byte *)((void *)pNativeBuffer); int num; if (ptr != null) { num = (strManaged.Length + 1) * 3; num = strManaged.GetBytesFromEncoding(ptr, num, Encoding.UTF8); } else { num = Encoding.UTF8.GetByteCount(strManaged); ptr = (byte *)((void *)Marshal.AllocCoTaskMem(num + 1)); strManaged.GetBytesFromEncoding(ptr, num, Encoding.UTF8); } ptr[num] = 0; return((IntPtr)((void *)ptr)); }
private unsafe IntPtr ConvertStringBuilderToNative(StringBuilder pManagedHome, int dwFlags) { IntPtr pNativeHome; // P/Invoke can be used to call Win32 apis that don't strictly follow CLR in/out semantics and thus may // leave garbage in the buffer in circumstances that we can't detect. To prevent us from crashing when // converting the contents back to managed, put a hidden NULL terminator past the end of the official buffer. // Unmanaged layout: // +====================================+ // | Extra hidden NULL | // +====================================+ \ // | | | // | [Converted] NULL-terminated string | |- buffer that the target may change // | | | // +====================================+ / <-- native home // Cache StringBuilder capacity and length to ensure we don't allocate a certain amount of // native memory and then walk beyond its end if the StringBuilder concurrently grows erroneously. int pManagedHomeCapacity = pManagedHome.Capacity; int pManagedHomeLength = pManagedHome.Length; if (pManagedHomeLength > pManagedHomeCapacity) { ThrowHelper.ThrowInvalidOperationException(); } // Note that StringBuilder.Capacity is the number of characters NOT including any terminators. if (IsAnsi(dwFlags)) { StubHelpers.CheckStringLength(pManagedHomeCapacity); // marshal the object as Ansi string (UnmanagedType.LPStr) int allocSize = checked ((pManagedHomeCapacity * Marshal.SystemMaxDBCSCharSize) + 4); pNativeHome = Marshal.AllocCoTaskMem(allocSize); byte *ptr = (byte *)pNativeHome; *(ptr + allocSize - 3) = 0; *(ptr + allocSize - 2) = 0; *(ptr + allocSize - 1) = 0; if (IsIn(dwFlags)) { int length = Marshal.StringToAnsiString(pManagedHome.ToString(), ptr, allocSize, IsBestFit(dwFlags), IsThrowOn(dwFlags)); Debug.Assert(length < allocSize, "Expected a length less than the allocated size"); } if (IsOut(dwFlags)) { backPropAction = BackPropAction.StringBuilderAnsi; } } else { // marshal the object as Unicode string (UnmanagedType.LPWStr) int allocSize = checked ((pManagedHomeCapacity * 2) + 4); pNativeHome = Marshal.AllocCoTaskMem(allocSize); byte *ptr = (byte *)pNativeHome; *(ptr + allocSize - 1) = 0; *(ptr + allocSize - 2) = 0; if (IsIn(dwFlags)) { pManagedHome.InternalCopy(pNativeHome, pManagedHomeLength); // null-terminate the native string int length = pManagedHomeLength * 2; *(ptr + length + 0) = 0; *(ptr + length + 1) = 0; } if (IsOut(dwFlags)) { backPropAction = BackPropAction.StringBuilderUnicode; } } return(pNativeHome); }
// Token: 0x06004233 RID: 16947 RVA: 0x000F5AB8 File Offset: 0x000F3CB8 internal static void CheckStringLength(int length) { StubHelpers.CheckStringLength((uint)length); }