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) ); } }
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); }
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; } } } }