Exemple #1
0
        public RarStream(string rarPath)
        {
            bool     oldNameFormat = true;
            RarBlock block         = null;

            using (RarReader rdr = new RarReader(rarPath, RarReadMode.RAR))
                while ((block = rdr.Read()) != null)
                {
                    if (block is RarVolumeHeaderBlock && ((block.Flags & (ushort)RarVolumeHeaderBlock.FlagValues.Volume) != 0))
                    {
                        oldNameFormat = (block.Flags & (ushort)RarVolumeHeaderBlock.FlagValues.NewNumbering) == 0;
                    }
                    else if (block is RarPackedFileBlock)
                    {
                        if ((block.Flags & (ushort)RarPackedFileBlock.FlagValues.SplitBefore) != 0)
                        {
                            throw new InvalidDataException("You must start with the first volume from a RAR set");
                        }

                        break;
                    }
                }

            // this constructor implementation picks the first packed file encountered in the archive and sets up to read it
            //  an alternate constructor might have a parameter to specify the packed file to read.
            string packedFileName = null;
            string nextFileName   = rarPath;

            while (File.Exists(nextFileName))
            {
                using (RarReader rdr = new RarReader(nextFileName, RarReadMode.RAR))
                    while ((block = rdr.Read()) != null)
                    {
                        RarPackedFileBlock fblock = block as RarPackedFileBlock;
                        if (fblock != null)
                        {
                            if (string.IsNullOrEmpty(packedFileName))
                            {
                                packedFileName = fblock.FileName;
                            }

                            if (packedFileName == fblock.FileName)
                            {
                                if (fblock.CompressionMethod != 0x30)
                                {
                                    throw new InvalidDataException("Compressed RARs are not supported");
                                }

                                currentVol                      = new RarVolume();
                                currentVol.FilePath             = nextFileName;
                                currentVol.PackedFileRangeStart = packedFileLength;
                                currentVol.PackedFileRangeEnd   = packedFileLength + (long)fblock.PackedSize - 1;
                                currentVol.PackedFileOffset     = fblock.BlockPosition + fblock.RawData.LongLength;

                                rarVolumes.Add(currentVol);

                                packedFileLength += (long)fblock.PackedSize;
                            }
                        }
                    }

                nextFileName = RarFileNameFinder.FindNextFileName(nextFileName, oldNameFormat);
            }

            currentVol = rarVolumes[0];
        }
Exemple #2
0
        static int CreateReconstructionFile(List <FileInfo> inFiles, DirectoryInfo inFolder, List <string> storeFiles, string srrName, bool savePaths)
        {
            using (FileStream srrfs = new FileStream(srrName, FileMode.Create))
            {
                BinaryWriter bw = new BinaryWriter(srrfs, Encoding.ASCII);
                bw.Write(new SrrHeaderBlock(appName).RawData);

                // we store copies of any files included in the storeFiles list in the .srr using a "store block".  any SFV files used are also included.
                foreach (FileInfo fi in inFiles)
                {
                    if (fi.Extension.ToLower() == ".sfv")
                    {
                        storeFiles.Add(fi.FullName);
                    }
                }

                SrrStoredFileBlock storeBlock = null;
                foreach (string fileName in storeFiles)
                {
                    string searchName = fileName;
                    if (!Path.IsPathRooted(searchName))
                    {
                        searchName = Path.Combine(inFolder.FullName, fileName);
                    }

                    DirectoryInfo searchDir = new DirectoryInfo(Path.GetDirectoryName(searchName));
                    if (searchDir.Exists)
                    {
                        foreach (FileInfo storeFile in searchDir.GetFiles(Path.GetFileName(searchName)))
                        {
                            string fName = savePaths ? MakePathRelative(storeFile.FullName, inFolder.FullName) : storeFile.Name;
                            Console.WriteLine("Storing file: {0}", fName);
                            storeBlock = new SrrStoredFileBlock(fName, (int)storeFile.Length);
                            if (savePaths)
                            {
                                storeBlock.Flags |= (ushort)SrrStoredFileBlock.FlagValues.PathsSaved;
                            }
                            using (FileStream storefs = storeFile.OpenRead())
                                storefs.Read(storeBlock.RawData, storeBlock.FileOffset, (int)storeFile.Length);

                            bw.Write(storeBlock.RawData);
                        }
                    }
                }

                List <string> rarFiles = new List <string>();
                foreach (FileInfo inFile in inFiles)
                {
                    if (inFile.Extension.ToLower() == ".sfv")
                    {
                        using (SfvReader sfvReader = new SfvReader(inFile.FullName))
                        {
                            List <string> sfvRarFiles = new List <string>();
                            SfvEntry      sfvEntry;
                            while ((sfvEntry = sfvReader.Read()) != null)
                            {
                                if (RarFileNameComparer.IsRarFile(sfvEntry.FileName))
                                {
                                    sfvRarFiles.Add(Path.Combine(inFile.DirectoryName, sfvEntry.FileName));
                                }
                                else
                                {
                                    ReportError(string.Format("Warning: Non-RAR file referenced in SFV: {0}\n\tThis file cannot be recreated unless it is stored using -s", sfvEntry.FileName));
                                    continue;
                                }
                            }

                            sfvRarFiles.Sort(new RarFileNameComparer());
                            rarFiles.AddRange(sfvRarFiles);
                        }
                    }
                    else
                    {
                        bool     oldNameFormat = false;
                        RarBlock block         = null;
                        using (RarReader rdr = new RarReader(inFile.FullName, RarReadMode.RAR))
                            while ((block = rdr.Read()) != null)
                            {
                                if (block is RarVolumeHeaderBlock && ((block.Flags & (ushort)RarVolumeHeaderBlock.FlagValues.Volume) != 0))
                                {
                                    if ((block.Flags & (ushort)RarVolumeHeaderBlock.FlagValues.FirstVolume) == 0)
                                    {
                                        throw new InvalidDataException("You must start with the first volume from a RAR set");
                                    }

                                    oldNameFormat = (block.Flags & (ushort)RarVolumeHeaderBlock.FlagValues.NewNumbering) == 0;
                                }
                            }

                        string nextFileName = inFile.FullName;
                        while (File.Exists(nextFileName))
                        {
                            rarFiles.Add(Path.Combine(inFile.DirectoryName, nextFileName));
                            nextFileName = RarFileNameFinder.FindNextFileName(nextFileName, oldNameFormat);
                        }
                    }
                }

                foreach (string fileName in rarFiles)
                {
                    if (!File.Exists(fileName))
                    {
                        ReportError(string.Format("Referenced file not found: {0}", fileName));
                        srrfs.Close();
                        File.Delete(srrName);
                        return(2);
                    }

                    string fName = savePaths ? MakePathRelative(fileName, inFolder.FullName) : Path.GetFileName(fileName);
                    Console.WriteLine("Processing file: {0}", fName);

                    SrrRarFileBlock rarBlock = new SrrRarFileBlock(fName);
                    if (savePaths)
                    {
                        rarBlock.Flags |= (ushort)SrrRarFileBlock.FlagValues.PathsSaved;
                    }

                    bw.Write(rarBlock.RawData);
                    using (RarReader rarReader = new RarReader(fileName, RarReadMode.RAR))
                    {
                        RarBlock block;
                        while ((block = rarReader.Read()) != null)
                        {
                            if (verbose)
                            {
                                Console.WriteLine("\tBlock Type: 0x{0:x2}", block.RawType);
                                Console.WriteLine("\tBlock Size: {0}", block.RawData.Length);
                            }

                            if (block is RarPackedFileBlock)
                            {
                                RarPackedFileBlock fileData = (RarPackedFileBlock)block;

                                if (verbose)
                                {
                                    Console.WriteLine("\t\tCompression Type: 0x{0:x2}", fileData.CompressionMethod);
                                    Console.WriteLine("\t\tPacked Data Size: {0:n0}", fileData.PackedSize);
                                    Console.WriteLine("\t\tFile Size: {0:n0}", fileData.UnpackedSize);
                                    Console.WriteLine("\t\tFile Name: {0}", fileData.FileName);
                                }

                                if (fileData.CompressionMethod != 0x30)
                                {
                                    ReportError(string.Format("Archive uses unsupported compression method: {0}", fileName));
                                    srrfs.Close();
                                    File.Delete(srrName);
                                    return(3);
                                }
                            }
                            else if (block is RarRecoveryBlock)
                            {
                                RarRecoveryBlock subData = (RarRecoveryBlock)block;

                                if (verbose & subData.RecoverySectors > 0)
                                {
                                    Console.WriteLine("\t\tRecovery Record Size: {0:n0}", subData.PackedSize);
                                    Console.WriteLine("\t\tRecovery Sectors: {0:n0}", subData.RecoverySectors);
                                    Console.WriteLine("\t\tProtected Sectors: {0:n0}", subData.DataSectors);
                                }
                            }

                            // store the raw data for any blocks found
                            bw.Write(block.RawData);
                        }
                    }
                }
            }

            Console.WriteLine("\nReconstruction file successfully created: {0}", srrName);

            return(0);
        }