internal AsAnyMarshaler(IntPtr pvArrayMarshaler) { this.pvArrayMarshaler = pvArrayMarshaler; this.backPropAction = BackPropAction.None; this.layoutType = null; this.cleanupWorkList = null; }
internal AsAnyMarshaler(IntPtr pvArrayMarshaler) { // we need this in case the value being marshaled turns out to be array Debug.Assert(pvArrayMarshaler != IntPtr.Zero, "pvArrayMarshaler must not be null"); this.pvArrayMarshaler = pvArrayMarshaler; backPropAction = BackPropAction.None; layoutType = null; cleanupWorkList = null; }
private unsafe IntPtr ConvertLayoutToNative(object pManagedHome, int dwFlags) { IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOfHelper(pManagedHome.GetType(), false)); if (IsIn(dwFlags)) { System.StubHelpers.StubHelpers.FmtClassUpdateNativeInternal(pManagedHome, (byte *)ptr.ToPointer(), ref this.cleanupWorkList); } if (IsOut(dwFlags)) { this.backPropAction = BackPropAction.Layout; } this.layoutType = pManagedHome.GetType(); return(ptr); }
private unsafe IntPtr ConvertStringBuilderToNative(StringBuilder pManagedHome, int dwFlags) { IntPtr ptr; if (IsAnsi(dwFlags)) { System.StubHelpers.StubHelpers.CheckStringLength(pManagedHome.Capacity); int num = (pManagedHome.Capacity * Marshal.SystemMaxDBCSCharSize) + 4; ptr = Marshal.AllocCoTaskMem(num); byte *pDest = (byte *)ptr; *((pDest + num) - 3) = 0; *((pDest + num) - 2) = 0; *((pDest + num) - 1) = 0; if (IsIn(dwFlags)) { int num2; Buffer.memcpy(AnsiCharMarshaler.DoAnsiConversion(pManagedHome.ToString(), IsBestFit(dwFlags), IsThrowOn(dwFlags), out num2), 0, pDest, 0, num2); pDest[num2] = 0; } if (IsOut(dwFlags)) { this.backPropAction = BackPropAction.StringBuilderAnsi; } return(ptr); } int cb = (pManagedHome.Capacity * 2) + 4; ptr = Marshal.AllocCoTaskMem(cb); byte *numPtr2 = (byte *)ptr; *((numPtr2 + cb) - 1) = 0; *((numPtr2 + cb) - 2) = 0; if (IsIn(dwFlags)) { int len = pManagedHome.Length * 2; pManagedHome.InternalCopy(ptr, len); numPtr2[len] = 0; (numPtr2 + len)[1] = 0; } if (IsOut(dwFlags)) { this.backPropAction = BackPropAction.StringBuilderUnicode; } return(ptr); }
private unsafe IntPtr ConvertLayoutToNative(object pManagedHome, int dwFlags) { // Note that the following call will not throw exception if the type // of pManagedHome is not marshalable. That's intentional because we // want to maintain the original behavior where this was indicated // by TypeLoadException during the actual field marshaling. int allocSize = Marshal.SizeOfHelper(pManagedHome.GetType(), false); IntPtr pNativeHome = Marshal.AllocCoTaskMem(allocSize); // marshal the object as class with layout (UnmanagedType.LPStruct) if (IsIn(dwFlags)) { StubHelpers.FmtClassUpdateNativeInternal(pManagedHome, (byte *)pNativeHome, ref cleanupWorkList); } if (IsOut(dwFlags)) { backPropAction = BackPropAction.Layout; } layoutType = pManagedHome.GetType(); return(pNativeHome); }
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); }
private unsafe IntPtr ConvertArrayToNative(object pManagedHome, int dwFlags) { Type elementType = pManagedHome.GetType().GetElementType() !; VarEnum vt; switch (Type.GetTypeCode(elementType)) { case TypeCode.SByte: vt = VarEnum.VT_I1; break; case TypeCode.Byte: vt = VarEnum.VT_UI1; break; case TypeCode.Int16: vt = VarEnum.VT_I2; break; case TypeCode.UInt16: vt = VarEnum.VT_UI2; break; case TypeCode.Int32: vt = VarEnum.VT_I4; break; case TypeCode.UInt32: vt = VarEnum.VT_UI4; break; case TypeCode.Int64: vt = VarEnum.VT_I8; break; case TypeCode.UInt64: vt = VarEnum.VT_UI8; break; case TypeCode.Single: vt = VarEnum.VT_R4; break; case TypeCode.Double: vt = VarEnum.VT_R8; break; case TypeCode.Char: vt = (IsAnsi(dwFlags) ? (VarEnum)VTHACK_ANSICHAR : VarEnum.VT_UI2); break; case TypeCode.Boolean: vt = (VarEnum)VTHACK_WINBOOL; break; case TypeCode.Object: { if (elementType == typeof(IntPtr)) { vt = (IntPtr.Size == 4 ? VarEnum.VT_I4 : VarEnum.VT_I8); } else if (elementType == typeof(UIntPtr)) { vt = (IntPtr.Size == 4 ? VarEnum.VT_UI4 : VarEnum.VT_UI8); } else { goto default; } break; } default: throw new ArgumentException(SR.Arg_NDirectBadObject); } // marshal the object as C-style array (UnmanagedType.LPArray) int dwArrayMarshalerFlags = (int)vt; if (IsBestFit(dwFlags)) { dwArrayMarshalerFlags |= (1 << 16); } if (IsThrowOn(dwFlags)) { dwArrayMarshalerFlags |= (1 << 24); } MngdNativeArrayMarshaler.CreateMarshaler( pvArrayMarshaler, IntPtr.Zero, // not needed as we marshal primitive VTs only dwArrayMarshalerFlags, IntPtr.Zero); // not needed as we marshal primitive VTs only IntPtr pNativeHome; IntPtr pNativeHomeAddr = new IntPtr(&pNativeHome); MngdNativeArrayMarshaler.ConvertSpaceToNative( pvArrayMarshaler, ref pManagedHome, pNativeHomeAddr); if (IsIn(dwFlags)) { MngdNativeArrayMarshaler.ConvertContentsToNative( pvArrayMarshaler, ref pManagedHome, pNativeHomeAddr); } if (IsOut(dwFlags)) { backPropAction = BackPropAction.Array; } return(pNativeHome); }
private unsafe IntPtr ConvertArrayToNative(object pManagedHome, int dwFlags) { int num; IntPtr ptr; Type elementType = pManagedHome.GetType().GetElementType(); VarEnum enum2 = VarEnum.VT_EMPTY; switch (Type.GetTypeCode(elementType)) { case TypeCode.Object: if (!(elementType == typeof(IntPtr))) { if (elementType == typeof(UIntPtr)) { enum2 = (IntPtr.Size == 4) ? VarEnum.VT_UI4 : VarEnum.VT_UI8; goto Label_010D; } break; } enum2 = (IntPtr.Size == 4) ? VarEnum.VT_I4 : VarEnum.VT_I8; goto Label_010D; case TypeCode.Boolean: enum2 = (VarEnum)0xfe; goto Label_010D; case TypeCode.Char: enum2 = IsAnsi(dwFlags) ? ((VarEnum)0xfd) : VarEnum.VT_UI2; goto Label_010D; case TypeCode.SByte: enum2 = VarEnum.VT_I1; goto Label_010D; case TypeCode.Byte: enum2 = VarEnum.VT_UI1; goto Label_010D; case TypeCode.Int16: enum2 = VarEnum.VT_I2; goto Label_010D; case TypeCode.UInt16: enum2 = VarEnum.VT_UI2; goto Label_010D; case TypeCode.Int32: enum2 = VarEnum.VT_I4; goto Label_010D; case TypeCode.UInt32: enum2 = VarEnum.VT_UI4; goto Label_010D; case TypeCode.Int64: enum2 = VarEnum.VT_I8; goto Label_010D; case TypeCode.UInt64: enum2 = VarEnum.VT_UI8; goto Label_010D; case TypeCode.Single: enum2 = VarEnum.VT_R4; goto Label_010D; case TypeCode.Double: enum2 = VarEnum.VT_R8; goto Label_010D; } throw new ArgumentException(Environment.GetResourceString("Arg_NDirectBadObject")); Label_010D: num = (int)enum2; if (IsBestFit(dwFlags)) { num |= 0x10000; } if (IsThrowOn(dwFlags)) { num |= 0x1000000; } MngdNativeArrayMarshaler.CreateMarshaler(this.pvArrayMarshaler, IntPtr.Zero, num); IntPtr pNativeHome = new IntPtr((void *)&ptr); MngdNativeArrayMarshaler.ConvertSpaceToNative(this.pvArrayMarshaler, ref pManagedHome, pNativeHome); if (IsIn(dwFlags)) { MngdNativeArrayMarshaler.ConvertContentsToNative(this.pvArrayMarshaler, ref pManagedHome, pNativeHome); } if (IsOut(dwFlags)) { this.backPropAction = BackPropAction.Array; } return(ptr); }
private unsafe IntPtr ConvertLayoutToNative(object pManagedHome, int dwFlags) { // Note that the following call will not throw exception if the type // of pManagedHome is not marshalable. That's intentional because we // want to maintain the original behavior where this was indicated // by TypeLoadException during the actual field marshaling. int allocSize = Marshal.SizeOfHelper(pManagedHome.GetType(), false); IntPtr pNativeHome = Marshal.AllocCoTaskMem(allocSize); // marshal the object as class with layout (UnmanagedType.LPStruct) if (IsIn(dwFlags)) { StubHelpers.FmtClassUpdateNativeInternal(pManagedHome, (byte *)pNativeHome.ToPointer(), ref cleanupWorkList); } if (IsOut(dwFlags)) { backPropAction = BackPropAction.Layout; } layoutType = pManagedHome.GetType(); return pNativeHome; }
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 // Note that StringBuilder.Capacity is the number of characters NOT including any terminators. if (IsAnsi(dwFlags)) { StubHelpers.CheckStringLength(pManagedHome.Capacity); // marshal the object as Ansi string (UnmanagedType.LPStr) int allocSize = (pManagedHome.Capacity * 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; byte[] bytes = AnsiCharMarshaler.DoAnsiConversion( pManagedHome.ToString(), IsBestFit(dwFlags), IsThrowOn(dwFlags), out length); Buffer.memcpy( bytes, // src array 0, // src index ptr, // dst buffer 0, // dts index length); // len // null-terminate the native string *(ptr + length) = 0; } if (IsOut(dwFlags)) { backPropAction = BackPropAction.StringBuilderAnsi; } } else { // marshal the object as Unicode string (UnmanagedType.LPWStr) int allocSize = (pManagedHome.Capacity * 2) + 4; pNativeHome = Marshal.AllocCoTaskMem(allocSize); byte* ptr = (byte*)pNativeHome; *(ptr + allocSize - 1) = 0; *(ptr + allocSize - 2) = 0; if (IsIn(dwFlags)) { int length = pManagedHome.Length * 2; pManagedHome.InternalCopy(pNativeHome, length); // null-terminate the native string *(ptr + length + 0) = 0; *(ptr + length + 1) = 0; } if (IsOut(dwFlags)) { backPropAction = BackPropAction.StringBuilderUnicode; } } return pNativeHome; }
private unsafe IntPtr ConvertArrayToNative(object pManagedHome, int dwFlags) { Type elementType = pManagedHome.GetType().GetElementType(); VarEnum vt = VarEnum.VT_EMPTY; switch (Type.GetTypeCode(elementType)) { case TypeCode.SByte: vt = VarEnum.VT_I1; break; case TypeCode.Byte: vt = VarEnum.VT_UI1; break; case TypeCode.Int16: vt = VarEnum.VT_I2; break; case TypeCode.UInt16: vt = VarEnum.VT_UI2; break; case TypeCode.Int32: vt = VarEnum.VT_I4; break; case TypeCode.UInt32: vt = VarEnum.VT_UI4; break; case TypeCode.Int64: vt = VarEnum.VT_I8; break; case TypeCode.UInt64: vt = VarEnum.VT_UI8; break; case TypeCode.Single: vt = VarEnum.VT_R4; break; case TypeCode.Double: vt = VarEnum.VT_R8; break; case TypeCode.Char: vt = (IsAnsi(dwFlags) ? (VarEnum)VTHACK_ANSICHAR : VarEnum.VT_UI2); break; case TypeCode.Boolean: vt = (VarEnum)VTHACK_WINBOOL; break; case TypeCode.Object: { if (elementType == typeof(IntPtr)) { vt = (IntPtr.Size == 4 ? VarEnum.VT_I4 : VarEnum.VT_I8); } else if (elementType == typeof(UIntPtr)) { vt = (IntPtr.Size == 4 ? VarEnum.VT_UI4 : VarEnum.VT_UI8); } else goto default; break; } default: throw new ArgumentException(Environment.GetResourceString("Arg_NDirectBadObject")); } // marshal the object as C-style array (UnmanagedType.LPArray) int dwArrayMarshalerFlags = (int)vt; if (IsBestFit(dwFlags)) dwArrayMarshalerFlags |= (1 << 16); if (IsThrowOn(dwFlags)) dwArrayMarshalerFlags |= (1 << 24); MngdNativeArrayMarshaler.CreateMarshaler( pvArrayMarshaler, IntPtr.Zero, // not needed as we marshal primitive VTs only dwArrayMarshalerFlags); IntPtr pNativeHome; IntPtr pNativeHomeAddr = new IntPtr(&pNativeHome); MngdNativeArrayMarshaler.ConvertSpaceToNative( pvArrayMarshaler, ref pManagedHome, pNativeHomeAddr); if (IsIn(dwFlags)) { MngdNativeArrayMarshaler.ConvertContentsToNative( pvArrayMarshaler, ref pManagedHome, pNativeHomeAddr); } if (IsOut(dwFlags)) { backPropAction = BackPropAction.Array; } return pNativeHome; }
internal AsAnyMarshaler(IntPtr pvArrayMarshaler) { // we need this in case the value being marshaled turns out to be array BCLDebug.Assert(pvArrayMarshaler != IntPtr.Zero, "pvArrayMarshaler must not be null"); this.pvArrayMarshaler = pvArrayMarshaler; this.backPropAction = BackPropAction.None; this.layoutType = null; this.cleanupWorkList = null; }