Пример #1
0
 private static void SerializeEntryList(string filename, EntryListInfo eli)
 {
     try
     {
         using (FileStream fs = new FileStream(filename + ".dat", FileMode.Create, FileAccess.Write, FileShare.None, 32768))
         {
             BinaryFormatter bf = new BinaryFormatter();
             bf.Serialize(fs, eli);
         }
     }
     catch (Exception e)
     {
         Debug.WriteLine(
             String.Format("ERROR: Couldn't serialize {0}.dat because of exception:\n{1}", filename, e.Message)
             );
     }
 }
Пример #2
0
        private static EntryListInfo DeserializeEntryList(string filename)
        {
            EntryListInfo eli = null;

            try
            {
                using (FileStream fs = new FileStream(filename + ".dat", FileMode.Open, FileAccess.Read, FileShare.Read, 32768))
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    eli = (EntryListInfo)bf.Deserialize(fs);
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(
                    String.Format("ERROR: Couldn't deserialize {0}.dat because of exception:\n{1}", filename, e.Message)
                    );
            }
            return(eli);
        }
Пример #3
0
        public static void Rebuild(string[] args)
        {
            if (!Directory.Exists(args[1]))
            {
                Console.Error.WriteLine("Directory '{0}' doesn't exist!", args[1]);
            }
            args[1] = Path.GetFullPath(args[1]);
            // demo vol
            byte[] rofsHeader = new byte[4] {
                (byte)'R', (byte)'o', (byte)'F', (byte)'S'
            };
            byte[] headerString = null;
            if (args.Length > 3)
            {
                g_compressedFlag = 0x2;
                g_directoryFlag  = 0x1;
                headerString     = rofsHeader;
                g_demoVol        = true;
            }
            else
            {
                g_compressedFlag = 0x02000000;
                g_directoryFlag  = 0x01000000;
                headerString     = BitConverter.GetBytes(~BitConverter.ToUInt32(rofsHeader, 0));
                g_demoVol        = false;
            }
            uint numFolders = 0, numFiles = 0, namesLength = 0;
            List <HeaderEntry> rootDir = null;

#if DEBUG
            // building the entry list takes for freaking ever due to all the decompressing
            // so when debugging we do it once, then save the results to a file
            // then on the next run, we don't have to wait for the same info to be recollected
            string        serializeName = Path.GetFileName(args[1]);
            EntryListInfo eli           = DeserializeEntryList(serializeName);
            //Console.WriteLine("Press enter to continue");
            //Console.ReadLine();
            if (eli == null)
            {
#endif
            //DateTime start = DateTime.Now;
            List <HeaderEntry> fileHeaders = BuildEntryList(args[1], ref numFolders, ref numFiles, out namesLength);
            // The dot<nul> for the root entry needs accounting for
            namesLength += g_demoVol ? 4u : 2u;
            rootDir      = new List <HeaderEntry>(1);
            HeaderEntry rootEntry = new HeaderEntry();
            rootDir.Add(rootEntry);
            rootEntry.children     = fileHeaders;
            rootEntry.fullFileName = ".";
            // wait for all the decompression jobs to finish before continuing
            while (Interlocked.CompareExchange(ref g_jobsFinished, g_jobsStarted, g_jobsStarted) != g_jobsStarted)
            {
                Thread.Sleep(100);
            }
            //DateTime end = DateTime.Now;
            //TimeSpan dur = end - start;
            //Console.WriteLine("Building entry list took {0}ms/{1}s", dur.TotalMilliseconds, dur.TotalSeconds);
#if DEBUG
            // still in the if(eli == null) case
            eli               = new EntryListInfo();
            eli.namesLength   = namesLength;
            eli.numCompressed = (uint)g_numCompressed;
            eli.numFiles      = numFiles;
            eli.numFolders    = numFolders;
            eli.root          = rootDir;
            SerializeEntryList(serializeName, eli);
        }     // end of eli == null

        else
        {
            g_numCompressed = (int)eli.numCompressed;
            numFiles        = eli.numFiles;
            numFolders      = eli.numFolders;
            namesLength     = eli.namesLength;
            rootDir         = eli.root;
        }
#endif
            byte[] volHead = BuildHeaderFromList(headerString, rootDir, numFolders, numFiles, namesLength);
            using (FileStream fs = new FileStream(args[2], FileMode.Create, FileAccess.Write))
            {
                byte[] blank = new byte[8191];
                fs.Write(volHead, 0, volHead.Length);
                Stack <List <HeaderEntry> > entryStack  = new Stack <List <HeaderEntry> >();
                List <HeaderEntry>          curIterList = rootDir;
                while (true)
                {
                    if (curIterList.Count == 0)
                    {
                        if (entryStack.Count == 0)
                        {
                            break;
                        }
                        curIterList = entryStack.Pop();
                        continue;
                    }
                    int         last  = curIterList.Count - 1;
                    HeaderEntry entry = curIterList[last];
                    curIterList.RemoveAt(last);
                    if (entry.children == null)
                    {
                        fs.Seek(entry.fileDataPosition, SeekOrigin.Begin);
                        Console.WriteLine("Reading {0} to write to the vol at {1:x}", Path.GetFileName(entry.fullFileName), entry.fileDataPosition);
                        byte[] data = File.ReadAllBytes(entry.fullFileName);
                        fs.Write(data, 0, data.Length);
                        fs.Write(blank, 0, 0x800 - (data.Length % 0x800));
                    }
                    else
                    {
                        entryStack.Push(curIterList);
                        Console.WriteLine("Moving to directory {0}", Path.GetFileName(entry.fullFileName));
                        curIterList = entry.children;
                    }
                }
            }
        }