コード例 #1
0
        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));
        }
コード例 #2
0
        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);
                }
            }
        }
コード例 #3
0
        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)));
        }
コード例 #4
0
ファイル: Pak.cs プロジェクト: voidAsterisk/OpenRA
        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;
            }
        }
コード例 #5
0
ファイル: BigFile.cs プロジェクト: wytsep/OpenRA
        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);
            }
        }
コード例 #6
0
ファイル: MixFile.cs プロジェクト: Blackbird88/OpenRA
        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));
        }
コード例 #7
0
        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);
            }
        }
コード例 #8
0
        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;
            }
        }
コード例 #9
0
            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);
            }