Пример #1
0
        public byte[] PeekHeader(int length)
        {
            GKZipFile.DebugLog($"Extracting {Name} to memory");

            if (FileEntryOffset == null)
            {
                GetFileEntryOffset();
            }

            using (var fs = new FileStream(Parent.ZIPPath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                fs.Seek(FileEntryOffset.Value + 26, SeekOrigin.Begin);
                var lengthBytes = new byte[4];
                fs.Read(lengthBytes, 0, 4);
                var n = BitConverter.ToInt16(lengthBytes, 0);
                var m = BitConverter.ToInt16(lengthBytes, 2);

                var targetOffset = FileEntryOffset.Value + 30 + n + m;
                GKZipFile.DebugLog($"Seeking to {targetOffset} ({FileEntryOffset} + 30 + {n} + {m}");
                fs.Seek(targetOffset, SeekOrigin.Begin);
                using (var outputStream = new MemoryStream())
                {
                    if (CompressionMethod > 0x0)
                    {
                        GKZipFile.DebugLog("Passing file through DeflateStream as CompressionMethod is > 0x0");

                        using (var contentStream = new MemoryStream())
                        {
                            contentStream.SetLength(CompressedSize);
                            fs.Read(contentStream.GetBuffer(), 0, CompressedSize);

                            // contentStream now has *just* our compressed file, so we can use a deflatestream and target it
                            using (var decompStream = new DeflateStream(contentStream, CompressionMode.Decompress))
                            {
                                var buffer = new byte[length];

                                decompStream.Read(buffer, 0, length);
                                outputStream.Write(buffer, 0, length);
                            }
                        }
                    }
                    else
                    {
                        var buff = new byte[length];
                        fs.Read(buff, 0, length);
                        outputStream.Write(buff, 0, length);
                    }
                    outputStream.Flush();
                    outputStream.Close();

                    return(outputStream.ToArray());
                }
            }
        }
Пример #2
0
        /// <summary>
        /// In batch extraction, we provide a list of input files to search and perform extractions from based on a predicate.
        /// </summary>
        /// <param name="inputFiles"></param>
        /// <param name="outputDirectoryPath"></param>
        /// <param name="predicate"></param>
        static public void BatchExtract(string[] inputFiles, string outputDirectoryPath, Func <CDEntry, bool> predicate)
        {
            var outputDirectory = default(DirectoryInfo);

            if (!Directory.Exists(outputDirectoryPath))
            {
                outputDirectory = Directory.CreateDirectory(outputDirectoryPath);
            }
            else
            {
                outputDirectory = new DirectoryInfo(outputDirectoryPath);
            }

            var activeTasks = new List <Task>();

            foreach (var item in inputFiles)
            {
                var inputFile = new FileInfo(item);
                var match     = Regex.Match(inputFile.Name, @"(?<udid>[\w\W]*?)_files\.zip");
                if (!match.Success)
                {
                    throw new Exception($"Is this even a GK Zip? {inputFile.Name}");
                }


                var udid = match.Groups["udid"].Value;
                Directory.CreateDirectory(outputDirectory.FullName + "\\" + udid);

                activeTasks.Add(Task.Factory.StartNew(() =>
                {
                    var gkz = new GKZipFile(item, false);
                    var sw  = new Stopwatch();
                    sw.Start();
                    GKZipFile.DebugLog($"Starting item with udid {udid} {item}");
                    var reviewedEntries = 0;
                    foreach (var entry in gkz)
                    {
                        if (predicate(entry))
                        {
                            entry.ExtractToFolder(outputDirectory.FullName + "\\" + udid + "\\");
                            GKZipFile.DebugLog($"Extracted {entry.Name} to .\\{udid}");
                        }
                        reviewedEntries++;
                    }
                    sw.Stop();
                    GKZipFile.DebugLog($"({udid}) - Work completed in {sw.ElapsedMilliseconds}ms ({reviewedEntries} entries)");
                }));
            }

            Task.WaitAll(activeTasks.ToArray());
        }
Пример #3
0
        /// <summary>
        /// This only works if we've populated our CentralDirectory property (set the second parameter of parse call to true)
        /// </summary>
        /// <returns>Successful or not</returns>
        public bool GetFileEntryOffset()
        {
            if (FileEntryOffset != null)
            {
                return(true);
            }

            CompressedSize   = BitConverter.ToInt32(Parent.CentralDirectory, (int)RelativeOffset + 20);
            UncompressedSize = BitConverter.ToInt32(Parent.CentralDirectory, (int)RelativeOffset + 24);

            var cur    = 0;
            var bFound = false;

            while (cur < LengthExtraFieldM)
            {
                var relPos = (int)RelativeOffset + 46 + LengthFileNameN;
                var length = BitConverter.ToInt16(Parent.CentralDirectory, cur + relPos + 2);

                if (Parent.CentralDirectory[relPos + cur] == 0x1 && Parent.CentralDirectory[relPos + cur + 1] == 0x00)
                {
                    FileEntryOffset = BitConverter.ToInt64(Parent.CentralDirectory, cur + relPos + 4);
                    bFound          = true;
                }
                cur += length + 4;
            }

            GKZipFile.DebugLog($"RE: {Name}");
            if (!bFound)
            {
                FileEntryOffset = (long)BitConverter.ToUInt32(Parent.CentralDirectory, (int)RelativeOffset + 42);
                GKZipFile.DebugLog($"File absolute offset is (loop failed; fallback value): {FileEntryOffset}");
                return(false);
            }
            else
            {
                GKZipFile.DebugLog($"File absolute offset is {FileEntryOffset}");
                return(true);
            }
        }
Пример #4
0
        public byte[] ExtractToMemory()
        {
            GKZipFile.DebugLog($"Extracting {Name} to memory");

            if (FileEntryOffset == null)
            {
                GetFileEntryOffset();
            }

            using (var fs = new FileStream(Parent.ZIPPath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                fs.Seek(FileEntryOffset.Value + 26, SeekOrigin.Begin);
                var lengthBytes = new byte[4];
                fs.Read(lengthBytes, 0, 4);
                var n = BitConverter.ToInt16(lengthBytes, 0);
                var m = BitConverter.ToInt16(lengthBytes, 2);

                var targetOffset = FileEntryOffset.Value + 30 + n + m;
                GKZipFile.DebugLog($"Seeking to {targetOffset} ({FileEntryOffset} + 30 + {n} + {m}");
                fs.Seek(targetOffset, SeekOrigin.Begin);
                using (var outputStream = new MemoryStream())
                {
                    if (CompressionMethod > 0x0)
                    {
                        GKZipFile.DebugLog("Passing file through DeflateStream as CompressionMethod is > 0x0");

                        using (var contentStream = new MemoryStream())
                        {
                            contentStream.SetLength(CompressedSize);
                            fs.Read(contentStream.GetBuffer(), 0, CompressedSize);

                            // contentStream now has *just* our compressed file, so we can use a deflatestream and target it
                            using (var decompStream = new DeflateStream(contentStream, CompressionMode.Decompress))
                            {
                                var bytesRead = 0;
                                //var offset = 0;
                                var bytesToRead    = 2048;
                                var buffer         = new byte[bytesToRead];
                                var totalBytesRead = 0;
                                while (true)
                                {
                                    bytesRead = decompStream.Read(buffer, 0, bytesToRead);
                                    if (bytesRead == 0)
                                    {
                                        break;
                                    }
                                    outputStream.Write(buffer, 0, bytesRead);
                                    totalBytesRead += bytesRead;
                                }
                            }
                        }
                    }
                    else
                    {
                        var bytesToRead    = 2048;
                        var buffer         = new byte[bytesToRead];
                        var totalBytesRead = 0;

                        while (totalBytesRead < CompressedSize)
                        {
                            if (totalBytesRead + bytesToRead > CompressedSize)
                            {
                                bytesToRead = CompressedSize - totalBytesRead;
                                buffer      = new byte[bytesToRead]; // adjust the length of the buffer
                            }

                            fs.Read(buffer, 0, bytesToRead);
                            outputStream.Write(buffer, 0, bytesToRead);
                            totalBytesRead += bytesToRead;
                        }
                    }
                    outputStream.Flush();
                    outputStream.Close();

                    return(outputStream.ToArray());
                }
                fs.Close();
            }
        }