protected static FileInfoBaseStruct ReadFileInfoBaseStruct(byte[] buffer, int offset, out int nextOffset) { var fibs = new FileInfoBaseStruct { Length = BitConverter.ToInt16(buffer, offset), ValueLength = BitConverter.ToInt16(buffer, offset + 2), Type = BitConverter.ToInt16(buffer, offset + 4) }; int len = FindLengthUnicodeSZ(buffer, offset + 6, offset + fibs.Length); fibs.Key = Encoding.Unicode.GetString(buffer, offset + 6, len * 2); // Padding fibs.ValueOffset = ((offset + 6 + (len + 1) * 2) + 3) & (~3); fibs.EndOffset = offset + fibs.Length; nextOffset = (fibs.EndOffset + 3) & (~3); return(fibs); }
protected static IEnumerable <Tuple <uint, string, string> > ReadVersionInfoInternal(byte[] buffer, FileInfoBaseStruct fibs) { int sfiOrValOffset = (fibs.ValueOffset + fibs.ValueLength + 3) & (~3); while (sfiOrValOffset < fibs.Length) { int nextSfiOrValOffset; var sfiOrVal = ReadFileInfoBaseStruct(buffer, sfiOrValOffset, out nextSfiOrValOffset); if (sfiOrVal.Key == "StringFileInfo") { int stOffset = sfiOrVal.ValueOffset; while (stOffset < sfiOrVal.EndOffset) { int nextStOffset; var st = ReadFileInfoBaseStruct(buffer, stOffset, out nextStOffset); uint langCharset = uint.Parse(st.Key, NumberStyles.HexNumber); int striOffset = st.ValueOffset; while (striOffset < st.EndOffset) { int nextStriOffset; var stri = ReadFileInfoBaseStruct(buffer, striOffset, out nextStriOffset); // Here stri.ValueLength is in words! int len = FindLengthUnicodeSZ(buffer, stri.ValueOffset, stri.ValueOffset + (stri.ValueLength * 2)); string value = Encoding.Unicode.GetString(buffer, stri.ValueOffset, len * 2); yield return(Tuple.Create(langCharset, stri.Key, value)); striOffset = nextStriOffset; } stOffset = nextStOffset; } } else if (sfiOrVal.Key == "VarFileInfo") { int varOffset = sfiOrVal.ValueOffset; while (varOffset < sfiOrVal.EndOffset) { int nextVarOffset; var var = ReadFileInfoBaseStruct(buffer, varOffset, out nextVarOffset); if (var.Key != "Translation") { throw new Exception(var.Key); } int langOffset = var.ValueOffset; while (langOffset < var.EndOffset) { unchecked { // We invert the order suggested by the Var description! uint high = (uint)BitConverter.ToInt16(buffer, langOffset); uint low = (uint)BitConverter.ToInt16(buffer, langOffset + 2); uint lang = (high << 16) | low; langOffset += 4; } } varOffset = nextVarOffset; } } else { Debug.WriteLine("Unrecognized " + sfiOrVal.Key); } sfiOrValOffset = nextSfiOrValOffset; } }