예제 #1
0
        public Dictionary <String, String> GetFixedFileInfo()
        {
            VersionItem root = VSVersionInfo;

            Dictionary <String, String> ffi = root.Value as Dictionary <String, String>;

            Dictionary <String, String> ret = new Dictionary <String, String>(ffi);           // this copies contents

            return(ret);
        }
예제 #2
0
        // VS_VERSION parsing assisted by looking at the source of the Vestris ResourceLib ( http://www.codeproject.com/KB/library/ResourceLib.aspx )
        // it helped with figuring out how to processing padding; my recursive approach diffthers from his though

        internal static VersionResourceData TryCreate(Byte[] data, ResourceLang lang)
        {
            using (MemoryStream s = new MemoryStream(data))
                using (BinaryReader rdr = new BinaryReader(s, Encoding.Unicode)) {        // good thing VS_VERSION_INFO uses UTF16 throughout
                    try {
                        VersionItem root = RecurseItem(Mode.Root, rdr);

                        return(new VersionResourceData(root, data, lang));
                    } catch (AnolisException) {
                        // TODO: how should this be logged?
                        return(null);
                    }
                }        //using
        }
예제 #3
0
        public Dictionary <String, String> GetStringTable()
        {
            VersionItem item = GetFirstItem(VSVersionInfo, Mode.StringTable);

            if (item == null)
            {
                return(null);
            }

            Dictionary <String, String> ret = new Dictionary <String, String>();

            foreach (VersionItem str in item.Children)
            {
                ret.Add(str.Key, str.Value == null ? String.Empty : str.Value.ToString());
            }

            return(ret);
        }
예제 #4
0
        internal static VersionResourceData TryCreate(Byte[] data, ResourceLang lang)
        {
            using (MemoryStream s = new MemoryStream(data))
                using (BinaryReader rdr = new BinaryReader(s, Encoding.Unicode)) {        // good thing VS_VERSION_INFO uses UTF16 throughout
                    // new approach:
                    // recursively build a tree of versionitem classes then handle them intelligently afterwards

                    Mode mode = Mode.Root;

                    VersionItem root = new VersionItem();
                    root.Mode         = mode;
                    root.wLength      = rdr.ReadUInt16();
                    root.wValueLength = rdr.ReadUInt16();
                    root.wType        = rdr.ReadUInt16();
                    root.szKey        = GetKey(mode, rdr, out mode);
                    root.padding      = Pad(rdr);

                    UInt32 signature = rdr.ReadUInt32();
                    if (signature != 0xFEEF04BD)
                    {
                        throw new InvalidOperationException("lol wtf");
                    }
                    rdr.ReadBytes(48);               // this is where FixedFileInfo goes (58 - 4)

                    Byte[] padding2 = Pad(rdr);

                    List <Object> children = new List <Object>();

                    //                1   2   3   4                               5                     6
                    Int32 bytesRead = 2 + 2 + 2 + ((root.szKey.Length * 2) + 2) + root.padding.Length + 4 + 48; _bytesRead = bytesRead;
                    while (bytesRead < root.wLength)
                    {
                        VersionItem child = RecurseItem(GetNextMode(mode), rdr);                   // no need to switch since the children will always be VersionItems
                        children.Add(child);

                        bytesRead += child.wLength;
                    }

                    root.children = children.ToArray();

                    return(null);
                }        //using
        }
예제 #5
0
        private VersionItem GetFirstItem(VersionItem parent, Mode mode)
        {
            if (parent.Mode == mode)
            {
                return(parent);
            }

            foreach (VersionItem item in parent.Children)
            {
                if (item.Mode == mode)
                {
                    return(item);
                }

                VersionItem match = GetFirstItem(item, mode);
                if (match != null)
                {
                    return(match);
                }
            }

            return(null);
        }
예제 #6
0
        private static VersionItem RecurseItem(VersionItemMode mode, BinaryReader rdr)
        {
            Int64 initPos = rdr.BaseStream.Position;

            VersionItem item = new VersionItem(mode);

            item.Length      = rdr.ReadUInt16();
            item.ValueLength = rdr.ReadUInt16();
            item.Type        = rdr.ReadUInt16();
            item.Key         = GetKey(mode, rdr, out item._mode);

            rdr.Align4();

            mode = item.Mode;

            List <VersionItem> children = new List <VersionItem>();

            while (rdr.BaseStream.Position < initPos + item.Length)
            {
                switch (mode)
                {
                case Mode.Root:

                    if (item.Value == null)
                    {
                        Byte[] ffiBytes = rdr.ReadBytes(item.ValueLength);                                   // this is where FixedFileInfo goes
                        /*Byte[] padding2 = */ rdr.Align4();

                        if (ffiBytes.Length >= 52)                                  // 52 == 0x34

                        {
                            VSFixedFileInfo ffi = new VSFixedFileInfo(ffiBytes);

                            if (ffi.Signature != 0xFEEF04BD)
                            {
                                throw new InvalidOperationException("Unrecognised VS_VERSIONINFO Signature");
                            }

                            Dictionary <String, String> ffiDict = FfiToDict(ffi);

                            item.Value = ffiDict;
                        }
                        else
                        {
                            throw new InvalidOperationException("Unexpected VS_FIXEDFILEINFO length");
                        }
                    }

                    goto default;

                case Mode.String:

                    Byte[] bytes = rdr.ReadBytes(item.ValueLength * 2);
                    String s     = Encoding.Unicode.GetString(bytes.SubArray(0, bytes.Length - 2));                            // miss out the null terminator
                    item.Value = s;

                    break;

                case Mode.Var:

                    Byte[] data = rdr.ReadBytes(item.ValueLength);                               // wValueLength = size in bytes
                    item.Value = data;

                    // data is a DWORD array indicating the language and code page combinations supported by this file.
                    // The low-order word of each DWORD must contain a Microsoft language identifier, and the high-order word must contain the IBM code page number.
                    // Either high-order or low-order word can be zero, indicating that the file is language or code page independent.
                    // ms-help://MS.MSDNQTR.v90.en/winui/winui/windowsuserinterface/resources/versioninformation/versioninformationreference/versioninformationstructures/var.htm

                    break;

                default:
                    VersionItem child = RecurseItem(GetNextMode(mode), rdr);
                    children.Add(child);

                    break;
                }

                // the reader was corrupted before entering the third String of the first StringTable of the StringFileInfo
                // so let's see if padding here helps

                rdr.Align4();
            }

            rdr.Align4();

            item.Children = children.ToArray();

            return(item);
        }
예제 #7
0
 private VersionResourceData(VersionItem root, Byte[] rawData, ResourceLang lang) : base(lang, rawData)
 {
     VSVersionInfo = root;
 }
예제 #8
0
        private static VersionItem RecurseItem(Mode mode, BinaryReader rdr)
        {
            Int64 initPos = rdr.BaseStream.Position;

            VersionItem item = new VersionItem();

            item.wLength      = rdr.ReadUInt16();
            item.wValueLength = rdr.ReadUInt16();
            item.wType        = rdr.ReadUInt16();
            item.szKey        = GetKey(mode, rdr, out item.Mode);
            item.padding      = Pad(rdr);

            mode = item.Mode;

            List <Object> children = new List <Object>();

            //                1   2   3   4                               5
            Int32 bytesRead = 2 + 2 + 2 + ((item.szKey.Length * 2) + 2) + item.padding.Length; _bytesRead += bytesRead;

            while (bytesRead < item.wLength)
            {
                switch (mode)
                {
                case Mode.String:

                    Byte[] bytes = rdr.ReadBytes(item.wValueLength * 2);
                    String s     = Encoding.Unicode.GetString(bytes.SubArray(0, bytes.Length - 2));                            // miss out the null terminator
                    children.Add(s);

                    bytesRead  += item.wValueLength * 2;
                    _bytesRead += item.wValueLength * 2;

                    if (bytesRead != item.wLength)
                    {
                        throw new InvalidOperationException("More bytes left over?");
                    }

                    break;

                case Mode.Var:

                    Byte[] data = rdr.ReadBytes(item.wValueLength);   // wValueLength = size in bytes

                    children.Add(data);                               // I'll figure out what to do with the data later

                    bytesRead  += item.wValueLength;
                    _bytesRead += item.wValueLength;

                    if (bytesRead != item.wLength)
                    {
                        throw new InvalidOperationException("More bytes left over?");
                    }

                    break;

                default:
                    VersionItem child = RecurseItem(GetNextMode(mode), rdr);
                    children.Add(child);

                    bytesRead += child.wLength;                             // after here (this breakpoint being triggered when children.count == 8) the while() loop continues, it's as if bytesRead isn't set properly such that it thinks VarFileInfo is a member of the Strings in the StringTable rather than a new section entirely

                    break;
                }

                // the reader was corrupted before entering the third String of the first StringTable of the StringFileInfo
                // so let's see if padding here helps

                Int32 padding = Pad(rdr).Length;

                bytesRead  += padding;
                _bytesRead += padding;
            }

            Int64 currentPos = rdr.BaseStream.Position;


            if (bytesRead > item.wLength)
            {
                // seek backwards so that it lines up
                Int64 goBack = bytesRead - item.wLength;
                rdr.BaseStream.Seek(-goBack, SeekOrigin.Current);
            }

            item.children = children.ToArray();

            return(item);
        }