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