internal KeyFile(string filename) { Header = new KeyFileHeader(); Header.Signature = "UNKW"; Header.Version = ""; using (BinaryReader reader = new BinaryReader(File.OpenRead(filename))) { if (reader.BaseStream.Length < 8) { throw new Exception("File is not a KEY V1.1 file (file is too short)"); } // Read Header Header.Signature = new string(reader.ReadChars(4)); Header.Version = new string(reader.ReadChars(4)); if (Header.Signature != "BIFF" && Header.Version != "V1.1") { throw new Exception("File is not a KEY V1.1 file (according to header)"); } Header.FileCount = reader.ReadInt32(); Header.KeyCount = reader.ReadInt32(); reader.ReadInt32(); // NULL Header.FileTableOffset = reader.ReadInt32(); Header.KeyTableOffset = reader.ReadInt32(); Header.BuildYear = reader.ReadInt32(); Header.BuildDay = reader.ReadInt32(); // Read file table FileEntries = new BiffFileEntry[Header.FileCount]; reader.BaseStream.Seek(Header.FileTableOffset, SeekOrigin.Begin); for (int i = 0; i < Header.FileCount; i++) { FileEntries[i] = new BiffFileEntry(); FileEntries[i].Size = reader.ReadInt32(); int offset = reader.ReadInt32(); int size = reader.ReadInt32(); long position = reader.BaseStream.Position; reader.BaseStream.Seek(offset, SeekOrigin.Begin); FileEntries[i].BiffName = Encoding.UTF8.GetString(reader.ReadBytes(size)); reader.BaseStream.Seek(position, SeekOrigin.Begin); } // Read resource names reader.BaseStream.Seek(Header.KeyTableOffset, SeekOrigin.Begin); for (int i = 0; i < Header.KeyCount; i++) { string resName = Encoding.UTF8.GetString(reader.ReadBytes(16)).Replace("\0", ""); ResourceType type = (ResourceType)reader.ReadInt16(); int id = reader.ReadInt32(); int flags = reader.ReadInt32(); int bifIndex = (int)((flags & 0xFFF00000) >> 20); FileEntries[bifIndex].ResourceNames.Add(id, resName); } } }
/// <summary> /// Opens a biff file and reads the header and resource table information /// </summary> /// <param name="filename"></param> /// <param name="keyfile">Can be null</param> public BiffFile(string filename, string keyfilename) { Filename = filename; TableIDLookup = new Dictionary <int, int>(); CachedResources = new Dictionary <int, ResourceEntry>(); Header = new BiffFileHeader(); Header.Signature = "UNKW"; Header.Version = ""; Header.ResCount = 0; Header.ResTableOffset = 0; Table = null; KeyFile keyFile = new KeyFile(keyfilename); biffEntry = keyFile.GetBiffFileEntry(Path.GetFileName(filename)); using (BinaryReader reader = new BinaryReader(File.OpenRead(filename))) { if (reader.BaseStream.Length < 8) { throw new Exception("File is not a BIFF V1.1 file (file is too short)"); } // Read Header Header.Signature = new string(reader.ReadChars(4)); Header.Version = new string(reader.ReadChars(4)); if (Header.Signature != "BIFF" && Header.Version != "V1.1") { throw new Exception("File is not a BIFF V1.1 file (according to header)"); } Header.ResCount = reader.ReadInt32(); reader.ReadInt32(); // NULL Header.ResTableOffset = reader.ReadInt32(); // Read Resource Table Table = new ResourceTableEntry[Header.ResCount]; reader.BaseStream.Seek(Header.ResTableOffset, SeekOrigin.Begin); for (int i = 0; i < Header.ResCount; i++) { Table[i] = new ResourceTableEntry(); Table[i].ID = reader.ReadInt32(); Table[i].Flags = reader.ReadInt32(); Table[i].Offset = reader.ReadInt32(); Table[i].Size = reader.ReadInt32(); Table[i].Type = (ResourceType)reader.ReadInt16(); Table[i].Name = Table[i].ID.ToString(); if (biffEntry != null && biffEntry.ResourceNames.ContainsKey(Table[i].ID)) { Table[i].Name = biffEntry.ResourceNames[Table[i].ID]; } Table[i].Name += "." + Table[i].Type; reader.ReadInt16(); // NULL TableIDLookup.Add(Table[i].ID, i); } } }