예제 #1
0
 public RecoveryControlEntry(RecoveryControlFile baseFile)
 {
     _baseFile = baseFile;
 }
예제 #2
0
        static bool ProcessRecovery(BinaryReader controlReader, Stream dataStream, string outputPath, bool consoleOutput = true)
        {
            var controlFile = new RecoveryControlFile();

            controlFile.Read(controlReader);

            int i;

            if (consoleOutput)
            {
                Console.WriteLine($"recctrl.bin contents:");
                Console.WriteLine($"{controlFile.Entries.Count} file{(controlFile.Entries.Count == 1 ? "" : "s")}");
                Console.WriteLine($"{controlFile.Versions.Count} variant{(controlFile.Versions.Count == 1 ? "" : "s")}:");
                for (i = 1; i < controlFile.Versions.Count; i++)
                {
                    var numFiles = 0;
                    foreach (var entry in controlFile.Entries)
                    {
                        if (entry.VersionIndex == i)
                        {
                            numFiles++;
                        }
                    }

                    Console.WriteLine($"  - {controlFile.Versions[i]} ({numFiles} file{(numFiles == 1 ? "" : "s")})");
                }

                Console.WriteLine();
                Console.WriteLine($"{controlFile.Devices.Count} device{(controlFile.Devices.Count == 1 ? "" : "s")}:");
                for (i = 0; i < controlFile.Devices.Count; i++)
                {
                    var numFiles = 0;
                    foreach (var entry in controlFile.Entries)
                    {
                        if (entry.DeviceIndex == i)
                        {
                            numFiles++;
                        }
                    }

                    var device = controlFile.Devices[i];
                    Console.WriteLine($"  - {device.Key} = {device.Value} ({numFiles} file{(numFiles == 1 ? "" : "s")})");
                }

                Console.WriteLine();
            }

            if (dataStream != null)
            {
                Console.WriteLine($"Extracting to {outputPath}...");
            }

            i = 0;
            foreach (var entry in controlFile.Entries)
            {
                i++;

                // Make sure directory exists for this file
                var destPath = Path.Combine(outputPath, entry.GetShortPath());

                if (consoleOutput)
                {
                    Console.WriteLine($"({i}/{controlFile.Entries.Count}) {entry.GetShortPath()} ({Util.GetBytesReadable(entry.DecompressedSize)})");
                }

                // Try extracting!
                if (dataStream == null)
                {
                    continue;
                }

                var destDir = Path.GetDirectoryName(destPath);
                if (!Directory.Exists(destDir))
                {
                    Directory.CreateDirectory(destDir);
                }

                try
                {
                    using (var destStream = File.Create(destPath))
                        entry.Extract(dataStream, destStream);

                    // Set last modified time to entry's timestamp
                    File.SetLastWriteTime(destPath, entry.DateTime);
                }
                catch (LzxInvalidWindowSize)
                {
                    Console.WriteLine("!!! Failed to extract due to invalid LZX window size, is the control file corrupt?");
                }
                catch (LzxDataLargerThanAgreed)
                {
                    Console.WriteLine("!!! Failed to extract as LZX data block is larger than expected, is the control file corrupt?");
                }
                catch (LzxDataInvalid)
                {
                    Console.WriteLine("!!! Failed to extract as LZX data is invalid, is the data file corrupt?");
                }
            }

            return(true);
        }