internal AsAnyMarshaler(IntPtr pvArrayMarshaler)
 {
     this.pvArrayMarshaler = pvArrayMarshaler;
     this.backPropAction   = BackPropAction.None;
     this.layoutType       = null;
     this.cleanupWorkList  = null;
 }
Example #2
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
        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);
        }
Example #7
0
        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);
        }
Example #9
0
        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;
        } 
Example #10
0
        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;
        } 
Example #11
0
        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;
        }
Example #12
0
        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; 
        }