예제 #1
0
        private VersionItem GetFirstItem(VersionItem parent, VersionItemMode mode)
        {
            if (parent.Mode == mode)
            {
                return(parent);
            }

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

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

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

            var item = new VersionItem(mode)
            {
                Length      = rdr.ReadUInt16(),
                ValueLength = rdr.ReadUInt16(),
                Type        = rdr.ReadUInt16()
            };

            item.Key = GetKey(mode, rdr, out item._mode);

            rdr.Align4();

            mode = item.Mode;

            var children = new List <VersionItem>();

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

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

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

                            var ffi = new VSFixedFileInfo(ffiBytes);

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

                            var ffiDict = FfiToDict(ffi);

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

                    goto default;

                case VersionItemMode.String:

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

                    break;

                case VersionItemMode.Var:

                    var 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:
                    var 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);
        }
예제 #3
0
 private VersionResourceData(VersionItem root, byte[] rawData, ResourceLang lang) : base(lang, rawData)
 {
     VSVersionInfo = root;
 }