コード例 #1
0
ファイル: BlobHeap.cs プロジェクト: haise0/dnlib-h0
        /// <inheritdoc/>
        protected override void WriteToImpl(DataWriter writer)
        {
            if (originalData is not null)
            {
                writer.WriteBytes(originalData);
            }
            else
            {
                writer.WriteByte(0);
            }

            uint offset = originalData is not null ? (uint)originalData.Length : 1;

            foreach (var data in cached)
            {
                int rawLen = GetRawDataSize(data);
                if (userRawData is not null && userRawData.TryGetValue(offset, out var rawData))
                {
                    if (rawData.Length != rawLen)
                    {
                        throw new InvalidOperationException("Invalid length of raw data");
                    }
                    writer.WriteBytes(rawData);
                }
コード例 #2
0
        /// <summary>
        /// Write a value
        /// </summary>
        /// <param name="argType">The ctor arg type, field type, or property type</param>
        /// <param name="value">The value to write</param>
        void WriteElem(TypeSig argType, CAArgument value)
        {
            if (argType is null)
            {
                helper.Error("Custom attribute: Arg type is null");
                argType = value.Type;
                if (argType is null)
                {
                    return;
                }
            }
            if (!recursionCounter.Increment())
            {
                helper.Error("Infinite recursion");
                return;
            }

            TypeSig       underlyingType;
            ITypeDefOrRef tdr;

            switch (argType.ElementType)
            {
            case ElementType.Boolean:
                if (!VerifyTypeAndValue(value, ElementType.Boolean))
                {
                    writer.WriteBoolean(ToUInt64(value.Value) != 0);
                }
                else
                {
                    writer.WriteBoolean((bool)value.Value);
                }
                break;

            case ElementType.Char:
                if (!VerifyTypeAndValue(value, ElementType.Char))
                {
                    writer.WriteUInt16((ushort)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteUInt16((ushort)(char)value.Value);
                }
                break;

            case ElementType.I1:
                if (!VerifyTypeAndValue(value, ElementType.I1))
                {
                    writer.WriteSByte((sbyte)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteSByte((sbyte)value.Value);
                }
                break;

            case ElementType.U1:
                if (!VerifyTypeAndValue(value, ElementType.U1))
                {
                    writer.WriteByte((byte)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteByte((byte)value.Value);
                }
                break;

            case ElementType.I2:
                if (!VerifyTypeAndValue(value, ElementType.I2))
                {
                    writer.WriteInt16((short)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteInt16((short)value.Value);
                }
                break;

            case ElementType.U2:
                if (!VerifyTypeAndValue(value, ElementType.U2))
                {
                    writer.WriteUInt16((ushort)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteUInt16((ushort)value.Value);
                }
                break;

            case ElementType.I4:
                if (!VerifyTypeAndValue(value, ElementType.I4))
                {
                    writer.WriteInt32((int)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteInt32((int)value.Value);
                }
                break;

            case ElementType.U4:
                if (!VerifyTypeAndValue(value, ElementType.U4))
                {
                    writer.WriteUInt32((uint)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteUInt32((uint)value.Value);
                }
                break;

            case ElementType.I8:
                if (!VerifyTypeAndValue(value, ElementType.I8))
                {
                    writer.WriteInt64((long)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteInt64((long)value.Value);
                }
                break;

            case ElementType.U8:
                if (!VerifyTypeAndValue(value, ElementType.U8))
                {
                    writer.WriteUInt64(ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteUInt64((ulong)value.Value);
                }
                break;

            case ElementType.R4:
                if (!VerifyTypeAndValue(value, ElementType.R4))
                {
                    writer.WriteSingle((float)ToDouble(value.Value));
                }
                else
                {
                    writer.WriteSingle((float)value.Value);
                }
                break;

            case ElementType.R8:
                if (!VerifyTypeAndValue(value, ElementType.R8))
                {
                    writer.WriteDouble(ToDouble(value.Value));
                }
                else
                {
                    writer.WriteDouble((double)value.Value);
                }
                break;

            case ElementType.String:
                if (VerifyTypeAndValue(value, ElementType.String, typeof(UTF8String)))
                {
                    WriteUTF8String((UTF8String)value.Value);
                }
                else if (VerifyTypeAndValue(value, ElementType.String, typeof(string)))
                {
                    WriteUTF8String((string)value.Value);
                }
                else
                {
                    WriteUTF8String(UTF8String.Empty);
                }
                break;

            case ElementType.ValueType:
                tdr            = ((TypeDefOrRefSig)argType).TypeDefOrRef;
                underlyingType = GetEnumUnderlyingType(argType);
                if (!(underlyingType is null))
                {
                    WriteElem(underlyingType, value);
                }
                else if (tdr is TypeRef && TryWriteEnumUnderlyingTypeValue(value.Value))
                {
                    // No error. Assume it's an enum that couldn't be resolved.
                }
                else
                {
                    helper.Error("Custom attribute value is not an enum");
                }
                break;
コード例 #3
0
ファイル: MarshalBlobWriter.cs プロジェクト: haise0/dnlib-h0
        byte[] Write(MarshalType marshalType)
        {
            if (marshalType is null)
            {
                return(null);
            }

            var type = marshalType.NativeType;

            if (type != NativeType.RawBlob)
            {
                if ((uint)type > byte.MaxValue)
                {
                    helper.Error("Invalid MarshalType.NativeType");
                }
                writer.WriteByte((byte)type);
            }
            bool canWrite = true;

            switch (type)
            {
            case NativeType.FixedSysString:
                var fixedSysString = (FixedSysStringMarshalType)marshalType;
                if (fixedSysString.IsSizeValid)
                {
                    WriteCompressedUInt32((uint)fixedSysString.Size);
                }
                break;

            case NativeType.SafeArray:
                var safeArray = (SafeArrayMarshalType)marshalType;
                if (UpdateCanWrite(safeArray.IsVariantTypeValid, "VariantType", ref canWrite))
                {
                    WriteCompressedUInt32((uint)safeArray.VariantType);
                }
                if (UpdateCanWrite(safeArray.IsUserDefinedSubTypeValid, "UserDefinedSubType", ref canWrite))
                {
                    Write(safeArray.UserDefinedSubType.AssemblyQualifiedName);
                }
                break;

            case NativeType.FixedArray:
                var fixedArray = (FixedArrayMarshalType)marshalType;
                if (UpdateCanWrite(fixedArray.IsSizeValid, "Size", ref canWrite))
                {
                    WriteCompressedUInt32((uint)fixedArray.Size);
                }
                if (UpdateCanWrite(fixedArray.IsElementTypeValid, "ElementType", ref canWrite))
                {
                    WriteCompressedUInt32((uint)fixedArray.ElementType);
                }
                break;

            case NativeType.Array:
                var array = (ArrayMarshalType)marshalType;
                if (UpdateCanWrite(array.IsElementTypeValid, "ElementType", ref canWrite))
                {
                    WriteCompressedUInt32((uint)array.ElementType);
                }
                if (UpdateCanWrite(array.IsParamNumberValid, "ParamNumber", ref canWrite))
                {
                    WriteCompressedUInt32((uint)array.ParamNumber);
                }
                if (UpdateCanWrite(array.IsSizeValid, "Size", ref canWrite))
                {
                    WriteCompressedUInt32((uint)array.Size);
                }
                if (UpdateCanWrite(array.IsFlagsValid, "Flags", ref canWrite))
                {
                    WriteCompressedUInt32((uint)array.Flags);
                }
                break;

            case NativeType.CustomMarshaler:
                var custMarshaler = (CustomMarshalType)marshalType;
                Write(custMarshaler.Guid);
                Write(custMarshaler.NativeTypeName);
                var cm     = custMarshaler.CustomMarshaler;
                var cmName = cm is null ? string.Empty : FullNameFactory.AssemblyQualifiedName(cm, this);
                Write(cmName);
                Write(custMarshaler.Cookie);
                break;

            case NativeType.IUnknown:
            case NativeType.IDispatch:
            case NativeType.IntF:
                var iface = (InterfaceMarshalType)marshalType;
                if (iface.IsIidParamIndexValid)
                {
                    WriteCompressedUInt32((uint)iface.IidParamIndex);
                }
                break;

            case NativeType.RawBlob:
                var data = ((RawMarshalType)marshalType).Data;
                if (data is not null)
                {
                    writer.WriteBytes(data);
                }
                break;

            default:
                break;
            }

            return(outStream.ToArray());
        }
コード例 #4
0
        void Write(TypeSig typeSig)
        {
            const ElementType DEFAULT_ELEMENT_TYPE = ElementType.Boolean;

            if (typeSig == null)
            {
                helper.Error("TypeSig is null");
                writer.WriteByte((byte)DEFAULT_ELEMENT_TYPE);
                return;
            }
            if (!recursionCounter.Increment())
            {
                helper.Error("Infinite recursion");
                writer.WriteByte((byte)DEFAULT_ELEMENT_TYPE);
                return;
            }

            uint count;

            switch (typeSig.ElementType)
            {
            case ElementType.Void:
            case ElementType.Boolean:
            case ElementType.Char:
            case ElementType.I1:
            case ElementType.U1:
            case ElementType.I2:
            case ElementType.U2:
            case ElementType.I4:
            case ElementType.U4:
            case ElementType.I8:
            case ElementType.U8:
            case ElementType.R4:
            case ElementType.R8:
            case ElementType.String:
            case ElementType.TypedByRef:
            case ElementType.I:
            case ElementType.U:
            case ElementType.Object:
            case ElementType.Sentinel:
                writer.WriteByte((byte)typeSig.ElementType);
                break;

            case ElementType.Ptr:
            case ElementType.ByRef:
            case ElementType.SZArray:
            case ElementType.Pinned:
                writer.WriteByte((byte)typeSig.ElementType);
                Write(typeSig.Next);
                break;

            case ElementType.ValueType:
            case ElementType.Class:
                writer.WriteByte((byte)typeSig.ElementType);
                Write(((TypeDefOrRefSig)typeSig).TypeDefOrRef);
                break;

            case ElementType.Var:
            case ElementType.MVar:
                writer.WriteByte((byte)typeSig.ElementType);
                WriteCompressedUInt32(((GenericSig)typeSig).Number);
                break;

            case ElementType.Array:
                writer.WriteByte((byte)typeSig.ElementType);
                var ary = (ArraySig)typeSig;
                Write(ary.Next);
                WriteCompressedUInt32(ary.Rank);
                if (ary.Rank == 0)
                {
                    break;
                }
                count = WriteCompressedUInt32((uint)ary.Sizes.Count);
                for (uint i = 0; i < count; i++)
                {
                    WriteCompressedUInt32(ary.Sizes[(int)i]);
                }
                count = WriteCompressedUInt32((uint)ary.LowerBounds.Count);
                for (uint i = 0; i < count; i++)
                {
                    WriteCompressedInt32(ary.LowerBounds[(int)i]);
                }
                break;

            case ElementType.GenericInst:
                writer.WriteByte((byte)typeSig.ElementType);
                var gis = (GenericInstSig)typeSig;
                Write(gis.GenericType);
                count = WriteCompressedUInt32((uint)gis.GenericArguments.Count);
                for (uint i = 0; i < count; i++)
                {
                    Write(gis.GenericArguments[(int)i]);
                }
                break;

            case ElementType.ValueArray:
                writer.WriteByte((byte)typeSig.ElementType);
                Write(typeSig.Next);
                WriteCompressedUInt32((typeSig as ValueArraySig).Size);
                break;

            case ElementType.FnPtr:
                writer.WriteByte((byte)typeSig.ElementType);
                Write((typeSig as FnPtrSig).Signature);
                break;

            case ElementType.CModReqd:
            case ElementType.CModOpt:
                writer.WriteByte((byte)typeSig.ElementType);
                Write((typeSig as ModifierSig).Modifier);
                Write(typeSig.Next);
                break;

            case ElementType.Module:
                writer.WriteByte((byte)typeSig.ElementType);
                WriteCompressedUInt32((typeSig as ModuleSig).Index);
                Write(typeSig.Next);
                break;

            case ElementType.End:
            case ElementType.R:
            case ElementType.Internal:
            default:
                helper.Error("Unknown or unsupported element type");
                writer.WriteByte((byte)DEFAULT_ELEMENT_TYPE);
                break;
            }

            recursionCounter.Decrement();
        }
コード例 #5
0
        /// <summary>
        /// Write a value
        /// </summary>
        /// <param name="argType">The ctor arg type, field type, or property type</param>
        /// <param name="value">The value to write</param>
        void WriteElem(TypeSig argType, CAArgument value)
        {
            if (argType == null)
            {
                helper.Error("Custom attribute: Arg type is null");
                argType = value.Type;
                if (argType == null)
                {
                    return;
                }
            }
            if (!recursionCounter.Increment())
            {
                helper.Error("Infinite recursion");
                return;
            }

            TypeSig       underlyingType;
            ITypeDefOrRef tdr;

            switch (argType.ElementType)
            {
            case ElementType.Boolean:
                if (!VerifyTypeAndValue(value, ElementType.Boolean))
                {
                    writer.WriteBoolean(ToUInt64(value.Value) != 0);
                }
                else
                {
                    writer.WriteBoolean((bool)value.Value);
                }
                break;

            case ElementType.Char:
                if (!VerifyTypeAndValue(value, ElementType.Char))
                {
                    writer.WriteUInt16((ushort)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteUInt16((ushort)(char)value.Value);
                }
                break;

            case ElementType.I1:
                if (!VerifyTypeAndValue(value, ElementType.I1))
                {
                    writer.WriteSByte((sbyte)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteSByte((sbyte)value.Value);
                }
                break;

            case ElementType.U1:
                if (!VerifyTypeAndValue(value, ElementType.U1))
                {
                    writer.WriteByte((byte)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteByte((byte)value.Value);
                }
                break;

            case ElementType.I2:
                if (!VerifyTypeAndValue(value, ElementType.I2))
                {
                    writer.WriteInt16((short)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteInt16((short)value.Value);
                }
                break;

            case ElementType.U2:
                if (!VerifyTypeAndValue(value, ElementType.U2))
                {
                    writer.WriteUInt16((ushort)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteUInt16((ushort)value.Value);
                }
                break;

            case ElementType.I4:
                if (!VerifyTypeAndValue(value, ElementType.I4))
                {
                    writer.WriteInt32((int)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteInt32((int)value.Value);
                }
                break;

            case ElementType.U4:
                if (!VerifyTypeAndValue(value, ElementType.U4))
                {
                    writer.WriteUInt32((uint)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteUInt32((uint)value.Value);
                }
                break;

            case ElementType.I8:
                if (!VerifyTypeAndValue(value, ElementType.I8))
                {
                    writer.WriteInt64((long)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteInt64((long)value.Value);
                }
                break;

            case ElementType.U8:
                if (!VerifyTypeAndValue(value, ElementType.U8))
                {
                    writer.WriteUInt64(ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteUInt64((ulong)value.Value);
                }
                break;

            case ElementType.R4:
                if (!VerifyTypeAndValue(value, ElementType.R4))
                {
                    writer.WriteSingle((float)ToDouble(value.Value));
                }
                else
                {
                    writer.WriteSingle((float)value.Value);
                }
                break;

            case ElementType.R8:
                if (!VerifyTypeAndValue(value, ElementType.R8))
                {
                    writer.WriteDouble(ToDouble(value.Value));
                }
                else
                {
                    writer.WriteDouble((double)value.Value);
                }
                break;

            case ElementType.String:
                if (VerifyTypeAndValue(value, ElementType.String, typeof(UTF8String)))
                {
                    WriteUTF8String((UTF8String)value.Value);
                }
                else if (VerifyTypeAndValue(value, ElementType.String, typeof(string)))
                {
                    WriteUTF8String((string)value.Value);
                }
                else
                {
                    WriteUTF8String(UTF8String.Empty);
                }
                break;

            case ElementType.ValueType:
                tdr            = ((TypeDefOrRefSig)argType).TypeDefOrRef;
                underlyingType = GetEnumUnderlyingType(argType);
                if (underlyingType != null)
                {
                    WriteElem(underlyingType, value);
                }
                else if (tdr is TypeRef && TryWriteEnumUnderlyingTypeValue(value.Value))
                {
                    // No error. Assume it's an enum that couldn't be resolved.
                }
                else
                {
                    helper.Error("Custom attribute value is not an enum");
                }
                break;

            case ElementType.Class:
                tdr = ((TypeDefOrRefSig)argType).TypeDefOrRef;
                if (CheckCorLibType(argType, "Type"))
                {
                    if (CheckCorLibType(value.Type, "Type"))
                    {
                        if (value.Value is TypeSig ts)
                        {
                            WriteType(ts);
                        }
                        else if (value.Value == null)
                        {
                            WriteUTF8String(null);
                        }
                        else
                        {
                            helper.Error("Custom attribute value is not a type");
                            WriteUTF8String(UTF8String.Empty);
                        }
                    }
                    else
                    {
                        helper.Error("Custom attribute value type is not System.Type");
                        WriteUTF8String(UTF8String.Empty);
                    }
                    break;
                }
                else if (tdr is TypeRef && TryWriteEnumUnderlyingTypeValue(value.Value))
                {
                    // No error. Assume it's an enum that couldn't be resolved.
                    break;
                }
                goto default;

            case ElementType.SZArray:
                WriteValue(argType, value);
                break;

            case ElementType.Object:
                WriteFieldOrPropType(value.Type);
                WriteElem(value.Type, value);
                break;

            case ElementType.End:
            case ElementType.Void:
            case ElementType.Ptr:
            case ElementType.ByRef:
            case ElementType.Var:
            case ElementType.Array:
            case ElementType.GenericInst:
            case ElementType.TypedByRef:
            case ElementType.ValueArray:
            case ElementType.I:
            case ElementType.U:
            case ElementType.R:
            case ElementType.FnPtr:
            case ElementType.MVar:
            case ElementType.CModReqd:
            case ElementType.CModOpt:
            case ElementType.Internal:
            case ElementType.Module:
            case ElementType.Sentinel:
            case ElementType.Pinned:
            default:
                helper.Error("Invalid or unsupported element type in custom attribute");
                break;
            }

            recursionCounter.Decrement();
        }