public BagFile(string filename, int priority) { bagFilename = filename; bagFilePriority = priority; // A bag file is always accompanied with an .idx counterpart // For example: audio.bag requires the audio.idx file var indexFilename = Path.ChangeExtension(filename, ".idx"); s = GlobalFileSystem.Open(filename); // Build the index and dispose the stream, it is no longer needed after this List <IdxEntry> entries; using (var indexStream = GlobalFileSystem.Open(indexFilename)) { var reader = new IdxReader(indexStream); entries = reader.Entries; } index = entries.ToDictionaryWithConflictLog(x => x.Hash, "{0} (bag format)".F(filename), null, x => "(offs={0}, len={1})".F(x.Offset, x.Length)); }
public InstallShieldCABExtractor(string hdrFilename, int priority = -1) { var fileGroups = new List <FileGroup>(); var fileGroupOffsets = new List <uint>(); this.priority = priority; hdrFile = GlobalFileSystem.Open(hdrFilename); // Strips archive number AND file extension commonName = Regex.Replace(hdrFilename, @"\d*\.[^\.]*$", ""); var signature = hdrFile.ReadUInt32(); if (signature != 0x28635349) { throw new InvalidDataException("Not an Installshield CAB package"); } commonHeader = new CommonHeader(hdrFile); cabDescriptor = new CabDescriptor(hdrFile, commonHeader); /* unknown */ hdrFile.ReadBytes(14); for (var i = 0U; i < MaxFileGroupCount; ++i) { fileGroupOffsets.Add(hdrFile.ReadUInt32()); } hdrFile.Seek(commonHeader.CabDescriptorOffset + cabDescriptor.FileTableOffset, SeekOrigin.Begin); directoryTable = new List <uint>(); for (var i = 0U; i < cabDescriptor.DirectoryCount; ++i) { directoryTable.Add(hdrFile.ReadUInt32()); } foreach (var offset in fileGroupOffsets) { var nextOffset = offset; while (nextOffset != 0) { hdrFile.Seek((long)nextOffset + 4 + commonHeader.CabDescriptorOffset, SeekOrigin.Begin); var descriptorOffset = hdrFile.ReadUInt32(); nextOffset = hdrFile.ReadUInt32(); hdrFile.Seek((long)descriptorOffset + commonHeader.CabDescriptorOffset, SeekOrigin.Begin); fileGroups.Add(new FileGroup(hdrFile, commonHeader.CabDescriptorOffset)); } } hdrFile.Seek(commonHeader.CabDescriptorOffset + cabDescriptor.FileTableOffset + cabDescriptor.FileTableOffset2, SeekOrigin.Begin); foreach (var fileGroup in fileGroups) { for (var index = fileGroup.FirstFile; index <= fileGroup.LastFile; ++index) { AddFileDescriptorToList(index); var fileDescriptor = fileDescriptors[index]; var fullFilePath = "{0}\\{1}\\{2}".F(fileGroup.Name, DirectoryName((uint)fileDescriptor.DirectoryIndex), fileDescriptor.Filename); fileLookup.Add(fullFilePath, index); } } }
public IEnumerable <string> AllFileNames() { var lookup = new Dictionary <uint, string>(); if (Exists("local mix database.dat")) { var db = new XccLocalDatabase(GetContent("local mix database.dat")); foreach (var e in db.Entries) { var hash = PackageEntry.HashFilename(e, type); if (!lookup.ContainsKey(hash)) { lookup.Add(hash, e); } } } if (GlobalFileSystem.Exists("global mix database.dat")) { var db = new XccGlobalDatabase(GlobalFileSystem.Open("global mix database.dat")); foreach (var e in db.Entries) { var hash = PackageEntry.HashFilename(e, type); if (!lookup.ContainsKey(hash)) { lookup.Add(hash, e); } } } return(index.Keys.Select(k => lookup.ContainsKey(k) ? lookup[k] : "{0:X}".F(k))); }
public PakFile(string filename, int priority) { this.filename = filename; this.priority = priority; index = new Dictionary <string, Entry>(); stream = GlobalFileSystem.Open(filename); index = new Dictionary <string, Entry>(); var offset = stream.ReadUInt32(); while (offset != 0) { var file = stream.ReadASCIIZ(); var next = stream.ReadUInt32(); var length = (next == 0 ? (uint)stream.Length : next) - offset; // Ignore duplicate files if (index.ContainsKey(file)) { continue; } index.Add(file, new Entry { Offset = offset, Length = length, Filename = file }); offset = next; } }
public BigFile(string filename, int priority) { Name = filename; Priority = priority; var s = GlobalFileSystem.Open(filename); if (s.ReadASCII(4) != "BIGF") { throw new InvalidDataException("Header is not BIGF"); } // Total archive size. s.ReadUInt32(); var entryCount = s.ReadUInt32(); if (BitConverter.IsLittleEndian) { entryCount = int2.Swap(entryCount); } // First entry offset? This is apparently bogus for EA's .big files // and we don't have to try seeking there since the entries typically start next in EA's .big files. s.ReadUInt32(); for (var i = 0; i < entryCount; i++) { var entry = new Entry(s); entries.Add(entry.Path, entry); } }
public MixFile(string filename, PackageHashType type, int priority) { this.filename = filename; this.priority = priority; this.type = type; s = GlobalFileSystem.Open(filename); // Detect format type s.Seek(0, SeekOrigin.Begin); var isCncMix = s.ReadUInt16() != 0; // The C&C mix format doesn't contain any flags or encryption var isEncrypted = false; if (!isCncMix) { isEncrypted = (s.ReadUInt16() & 0x2) != 0; } List <PackageEntry> entries; if (isEncrypted) { long unused; entries = ParseHeader(DecryptHeader(s, 4, out dataStart), 0, out unused); } else { entries = ParseHeader(s, isCncMix ? 0 : 4, out dataStart); } index = entries.ToDictionaryWithConflictLog(x => x.Hash, "{0} ({1} format, Encrypted: {2}, DataStart: {3})".F(filename, isCncMix ? "C&C" : "RA/TS/RA2", isEncrypted, dataStart), null, x => "(offs={0}, len={1})".F(x.Offset, x.Length)); }
public D2kSoundResources(string filename, int priority) { this.filename = filename; this.priority = priority; s = GlobalFileSystem.Open(filename); s.Seek(0, SeekOrigin.Begin); filenames = new List <string>(); var headerLength = s.ReadUInt32(); while (s.Position < headerLength + 4) { var name = s.ReadASCIIZ(); var offset = s.ReadUInt32(); var length = s.ReadUInt32(); var hash = PackageEntry.HashFilename(name, PackageHashType.Classic); if (!index.ContainsKey(hash)) { index.Add(hash, new PackageEntry(hash, offset, length)); } filenames.Add(name); } }
public InstallShieldPackage(string filename, int priority) { this.filename = filename; this.priority = priority; filenames = new List <string>(); s = GlobalFileSystem.Open(filename); try { // Parse package header var reader = new BinaryReader(s); var signature = reader.ReadUInt32(); if (signature != 0x8C655D13) { throw new InvalidDataException("Not an Installshield package"); } reader.ReadBytes(8); /*var FileCount = */ reader.ReadUInt16(); reader.ReadBytes(4); /*var ArchiveSize = */ reader.ReadUInt32(); reader.ReadBytes(19); var tocAddress = reader.ReadInt32(); reader.ReadBytes(4); var dirCount = reader.ReadUInt16(); // Parse the directory list s.Seek(tocAddress, SeekOrigin.Begin); var tocReader = new BinaryReader(s); var fileCountInDirs = new List <uint>(); // Parse directories for (var i = 0; i < dirCount; i++) { fileCountInDirs.Add(ParseDirectory(tocReader)); } // Parse files foreach (var fileCount in fileCountInDirs) { for (var i = 0; i < fileCount; i++) { ParseFile(reader); } } } catch { Dispose(); throw; } }
public void NextFile() { if (cabFile != null) { cabFile.Dispose(); } ++volumeNumber; cabFile = GlobalFileSystem.Open("{0}{1}.cab".F(commonName, volumeNumber)); if (cabFile.ReadUInt32() != 0x28635349) { throw new InvalidDataException("Not an Installshield CAB package"); } uint fileOffset; if ((fileDes.Flags & FileSplit) != 0) { cabFile.Seek(CommonHeader.Size, SeekOrigin.Current); var head = new VolumeHeader(cabFile); if (index == head.LastFileIndex) { if ((fileDes.Flags & FileCompressed) != 0) { RemainingArchiveStream = head.LastFileSizeCompressed; } else { RemainingArchiveStream = head.LastFileSizeExpanded; } fileOffset = head.LastFileOffset; } else if (index == head.FirstFileIndex) { if ((fileDes.Flags & FileCompressed) != 0) { RemainingArchiveStream = head.FirstFileSizeCompressed; } else { RemainingArchiveStream = head.FirstFileSizeExpanded; } fileOffset = head.FirstFileOffset; } else { throw new Exception("Cannot Resolve Remaining Stream"); } } else { if ((fileDes.Flags & FileCompressed) != 0) { RemainingArchiveStream = fileDes.CompressedSize; } else { RemainingArchiveStream = fileDes.ExpandedSize; } fileOffset = fileDes.DataOffset; } cabFile.Seek(fileOffset, SeekOrigin.Begin); }