private static bool VerifyEntry(ArcEntry entry, IProgress?progress) { var buffer = ArrayPool <byte> .Shared.Rent(BufferSize); try { using var inputStream = entry.Open(); var hash = new Adler32(); while (true) { var bytesInBuffer = inputStream.Read(buffer); if (bytesInBuffer == 0) { break; } hash.ComputeHash(buffer, 0, bytesInBuffer); progress?.AddValue(bytesInBuffer); } return(entry.Hash == hash.Hash); } finally { ArrayPool <byte> .Shared.Return(buffer); } }
public void Write(Stream target, IEnumerable <ArcFile> files) { var fileList = files.AsList(); using var buffer = new MemoryStream(); var writer = new BinaryWriter(buffer); writer.Write(0x19751120); writer.Write(0x00000001); writer.Write(fileList.Count); writer.Write(0x00000002); buffer.Position += fileList.Count * 0x10; var entries = fileList.Select(file => { var entry = new ArcEntry { CompressedSize = file.CompressedSize, DecompressedSize = file.DecompressedSize, NameOffset = (int)buffer.Position }; writer.Write(Encodings.CP437.GetBytes(file.Name)); writer.Write((byte)0x00); return(entry); }).ToList(); void Pad0X20() { var padding = new byte[(0x20 - (buffer.Position & 0x1F)) & 0x1F]; if (padding.Length > 0) { writer.Write(padding); } } for (var i = 0; i < fileList.Count; i++) { Pad0X20(); entries[i].Offset = (int)buffer.Position; writer.Write(fileList[i].Data); } Pad0X20(); buffer.Position = 0x10; foreach (var entry in entries) { writer.Write(entry.NameOffset); writer.Write(entry.Offset); writer.Write(entry.DecompressedSize); writer.Write(entry.CompressedSize); } writer.Flush(); target.Write(buffer.GetBuffer(), 0, (int)buffer.Length); }
private static void ReadArcEntries(IEnumerable <Partition <ArchivePartitionEntry> > partitions, Stream stream, int baseOffset) { foreach (var partition in partitions) { foreach (var lba in partition.Lba) { stream.Position = baseOffset + lba.Offset * 6; lba.UnknownItems = Enumerable.Range(0, lba.Count) .Select(x => ArcEntry.Read(stream)).ToArray(); } } }
public static void ArcEntryWriter(string filename, ArcEntry entrytowrite) { try { using (BinaryWriter bw = new BinaryWriter(File.Open(filename, FileMode.Create))) { bw.Write(entrytowrite.UncompressedData); bw.Close(); } } catch (UnauthorizedAccessException) { MessageBox.Show("Unable to access the file. Maybe it's already in use by another proccess?", "Cannot write this file."); return; } }
public static void ArcEntryWriter(string filename, ArcEntry entrytowrite) { try { using (BinaryWriter bw = new BinaryWriter(File.Open(filename, FileMode.Create))) { bw.Write(entrytowrite.UncompressedData); bw.Close(); } } catch (Exception ex) { ExceptionCatchAll(ex); return; } }
List<ArcEntry> ReadDirectory(Stream strm) { BinaryReader rd = new BinaryReader(strm); Extension[] exts; int numExts; List<ArcEntry> result = new List<ArcEntry>(); byte[] buf = new byte[4]; byte[] namebuf = new byte[8]; rd.ReadInt32(); numExts = rd.ReadInt32(); exts = new Extension[numExts]; for (int i = 0; i < numExts; i++) { rd.Read(buf, 0, 4); exts[i].Ext = Encoding.ASCII.GetString(buf).TrimEnd('\0'); exts[i].FirstEntryOffset = rd.ReadInt32(); exts[i].NumFiles = rd.ReadInt32(); } for (int i = 0; i < numExts; i++) { strm.Seek(exts[i].FirstEntryOffset, SeekOrigin.Begin); for (int j = 0; j < exts[i].NumFiles; j++) { ArcEntry ae = new ArcEntry(); rd.Read(namebuf, 0, 8); ae.Filename = String.Format("{0}.{1}", Encoding.ASCII.GetString(namebuf).TrimEnd('\0'), exts[i].Ext); ae.Length = rd.ReadInt32(); ae.Offset = rd.ReadInt32(); result.Add(ae); } } return result; }
ArcEntry[] GetDirectory(Stream strm) { BinaryReader rd = new BinaryReader(strm); byte[] buf = new byte[4]; Int32 ver; Int32 numFiles; ArcEntry[] results; rd.Read(buf, 0, 4); ver = rd.ReadInt32(); if (ver != 1) return null; if (Encoding.ASCII.GetString(buf) != "YPAC") return null; numFiles = rd.ReadInt32(); rd.ReadInt32(); // dummy read results = new ArcEntry[numFiles]; for (int i = 0; i < numFiles; i++) { byte[] nameBuf = new byte[6 * 16]; string fname; rd.Read(nameBuf, 0, 6*16); fname = Encoding.ASCII.GetString(nameBuf); fname = fname.Substring(0, fname.IndexOf('\0')); // remove everything from the first \0 char onwards fname = fname.Substring(1); // remove leading "\" results[i].FileName = fname; results[i].Offset = (int)rd.ReadInt64(); results[i].Length = (int)rd.ReadUInt64(); } return results; }
List<ArcEntry> GetDirectory(Stream strm, bool CheckOnly) { List<ArcEntry> results = new List<ArcEntry>(); BinaryReader rd = new BinaryReader(strm); uint id; byte fnLength; byte[] nameBuf; int offset; id = rd.ReadUInt32(); if (id != 0xbac04ac0) return null; if (rd.ReadInt32() != 0) return null; if (CheckOnly) return results; while (rd.ReadByte() == 0) { ArcEntry ae = new ArcEntry(); fnLength = rd.ReadByte(); nameBuf = new byte[fnLength]; rd.Read(nameBuf, 0, fnLength); ae.FileName = Encoding.ASCII.GetString(nameBuf); ae.Length = rd.ReadInt32(); rd.ReadInt32(); // skip rd.ReadInt32(); // skip results.Add(ae); } offset = (int)strm.Position; for (int i = 0; i < results.Count; i++) { results[i].Offset = offset; offset += results[i].Length; } return results; }
private void btnReplaceReplace_Click(object sender, EventArgs e) { if (AllFiles == true) { //Checks All filenames for searched term. Gets to the parent node, checks all the children nodes, their tags, filenames, etc. for the term. //Goes to top node to begin iteration. TreeNode tn = Mainfrm.FindRootNode(Mainfrm.TreeSource.SelectedNode); Mainfrm.TreeSource.SelectedNode = tn; List <TreeNode> Nodes = new List <TreeNode>(); Mainfrm.AddChildren(Nodes, Mainfrm.TreeSource.SelectedNode); Mainfrm.TreeSource.BeginUpdate(); int RenameCount = 0; foreach (TreeNode tno in Nodes) { //Gets the node as a ArcEntryWrapper to allow access to all the variables and data. ArcEntryWrapper awrapper = tno as ArcEntryWrapper; if (awrapper != null) { if (awrapper.Tag as MaterialTextureReference == null || awrapper.Tag as LMTM3AEntry == null || awrapper.Tag as ModelBoneEntry == null || awrapper.Tag as MaterialMaterialEntry == null || awrapper.Tag as ModelGroupEntry == null || awrapper.Tag as Mission == null || awrapper.Tag as EffectNode == null) { { if (awrapper.Tag as string != null) { //Replaces the Term in the folder. string FolderName = awrapper.Tag as string; FolderName = FolderName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Text = tno.Text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Name = tno.Name.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); RenameCount++; } else { //Goes through the treenode to replace all the names of the node. ArcEntry enty = new ArcEntry(); TextureEntry tenty = new TextureEntry(); ResourcePathListEntry lrpenty = new ResourcePathListEntry(); MSDEntry msdenty = new MSDEntry(); MaterialEntry matent = new MaterialEntry(); LMTEntry lmtenty = new LMTEntry(); ChainListEntry cstenty = new ChainListEntry(); ChainEntry chnenty = new ChainEntry(); ChainCollisionEntry cclentry = new ChainCollisionEntry(); ModelEntry mdlentry = new ModelEntry(); MissionEntry misenty = new MissionEntry(); GemEntry gementy = new GemEntry(); EffectListEntry eflenty = new EffectListEntry(); if (tno.Tag as ArcEntry != null) { enty = tno.Tag as ArcEntry; enty.EntryName = enty.EntryName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); enty.TrueName = enty.TrueName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); enty.FileName = enty.FileName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Tag = enty; tno.Text = tno.Text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Name = tno.Name.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); } else if (tno.Tag as TextureEntry != null) { tenty = tno.Tag as TextureEntry; tenty.EntryName = tenty.EntryName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tenty.TrueName = tenty.TrueName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tenty.FileName = tenty.FileName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Tag = tenty; tno.Text = tno.Text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Name = tno.Name.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); } else if (tno.Tag as ResourcePathListEntry != null) { lrpenty = tno.Tag as ResourcePathListEntry; lrpenty.EntryName = lrpenty.EntryName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); lrpenty.TrueName = lrpenty.TrueName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); lrpenty.FileName = lrpenty.FileName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Tag = lrpenty; tno.Text = tno.Text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Name = tno.Name.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); } else if (tno.Tag as LMTEntry != null) { lmtenty = tno.Tag as LMTEntry; lmtenty.EntryName = lmtenty.EntryName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); lmtenty.TrueName = lmtenty.TrueName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); lmtenty.FileName = lmtenty.FileName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Tag = lmtenty; tno.Text = tno.Text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Name = tno.Name.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); } else if (tno.Tag as MaterialEntry != null) { matent = tno.Tag as MaterialEntry; matent.EntryName = matent.EntryName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); matent.TrueName = matent.TrueName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); matent.FileName = matent.FileName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Tag = matent; tno.Text = tno.Text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Name = tno.Name.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); } else if (tno.Tag as MSDEntry != null) { msdenty = tno.Tag as MSDEntry; msdenty.EntryName = msdenty.EntryName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); msdenty.TrueName = msdenty.TrueName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); msdenty.FileName = msdenty.FileName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Tag = msdenty; tno.Text = tno.Text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Name = tno.Name.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); } else if (tno.Tag as ChainListEntry != null) { cstenty = tno.Tag as ChainListEntry; cstenty.EntryName = cstenty.EntryName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); cstenty.TrueName = cstenty.TrueName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); cstenty.FileName = cstenty.FileName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Tag = cstenty; tno.Text = tno.Text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Name = tno.Name.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); } else if (tno.Tag as ChainEntry != null) { chnenty = tno.Tag as ChainEntry; chnenty.EntryName = chnenty.EntryName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); chnenty.TrueName = chnenty.TrueName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); chnenty.FileName = chnenty.FileName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Tag = chnenty; tno.Text = tno.Text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Name = tno.Name.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); } else if (tno.Tag as ChainCollisionEntry != null) { cclentry = tno.Tag as ChainCollisionEntry; cclentry.EntryName = cclentry.EntryName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); cclentry.TrueName = cclentry.TrueName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); cclentry.FileName = cclentry.FileName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Tag = cclentry; tno.Text = tno.Text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Name = tno.Name.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); } else if (tno.Tag as ModelEntry != null) { mdlentry = tno.Tag as ModelEntry; mdlentry.EntryName = mdlentry.EntryName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); mdlentry.TrueName = mdlentry.TrueName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); mdlentry.FileName = mdlentry.FileName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Tag = mdlentry; tno.Text = tno.Text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Name = tno.Name.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); } else if (tno.Tag as MissionEntry != null) { misenty = tno.Tag as MissionEntry; misenty.EntryName = misenty.EntryName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); misenty.TrueName = misenty.TrueName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); misenty.FileName = misenty.FileName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Tag = misenty; tno.Text = tno.Text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Name = tno.Name.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); } else if (tno.Tag as GemEntry != null) { gementy = tno.Tag as GemEntry; gementy.EntryName = gementy.EntryName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); gementy.TrueName = gementy.TrueName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); gementy.FileName = gementy.FileName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Tag = gementy; tno.Text = tno.Text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Name = tno.Name.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); } else if (tno.Tag as EffectListEntry != null) { eflenty = tno.Tag as EffectListEntry; eflenty.EntryName = eflenty.EntryName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); eflenty.TrueName = eflenty.TrueName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); eflenty.FileName = eflenty.FileName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Tag = eflenty; tno.Text = tno.Text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Name = tno.Name.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); } RenameCount++; } } } } if (tno.Tag as string != null && tno.Tag as string == "Folder") { //Replaces the Term in the folder. string FolderName = tno.Text as string; FolderName = FolderName.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Text = tno.Text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); tno.Name = tno.Name.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); RenameCount++; } } Mainfrm.TreeSource.Update(); Mainfrm.TreeSource.EndUpdate(); MessageBox.Show("Replaced " + txtReplaceFind.Text + " with " + txtReplaceReplace.Text + " in " + RenameCount + " file and folder names."); Mainfrm.OpenFileModified = true; RenameCount = 0; } else { if (Mainfrm.TreeSource.SelectedNode.Tag is ResourcePathListEntry) { //Gets the text, then replaces every instance of the search term with the new term. string text = Mainfrm.txtRPList.Text; text = text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); Mainfrm.txtRPList.Text = text; } else if (Mainfrm.TreeSource.SelectedNode.Tag is MaterialEntry) { TreeNodeCollection TNoCollection = Mainfrm.TreeSource.SelectedNode.Nodes; foreach (TreeNode node in TNoCollection) { if (node.Tag as string != null) { if (node.Text as string == "Textures") { Mainfrm.TreeSource.SelectedNode = node; break; } } } TNoCollection = Mainfrm.TreeSource.SelectedNode.Nodes; Mainfrm.TreeSource.BeginUpdate(); foreach (TreeNode node in TNoCollection) { string Namer = node.Name as string; node.Text = node.Text.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); Namer = Namer.Replace(txtReplaceFind.Text, txtReplaceReplace.Text); node.Name = Namer; } Mainfrm.TreeSource.SelectedNode = Mainfrm.TreeSource.SelectedNode.Parent; //Now to update the Material file with all these, Whether they're changed or not. TreeNode Parentnode = Mainfrm.TreeSource.SelectedNode; MaterialEntry ParentMateial = Parentnode.Tag as MaterialEntry; MaterialTextureReference texref = new MaterialTextureReference(); string TermToInject = ""; //int count = 0; for (int i = 0; i < TNoCollection.Count; i++) { texref = TNoCollection[i].Tag as MaterialTextureReference; TermToInject = TNoCollection[i].Text; //Now for the actual file update. List <byte> NameToInject = new List <byte>(); NameToInject.AddRange(Encoding.ASCII.GetBytes(TermToInject)); int OffsetToUse; OffsetToUse = 64 + (88 * (texref.Index - 1)); byte[] NewName = new byte[64]; Array.Copy(NameToInject.ToArray(), 0, NewName, 0, NameToInject.ToArray().Length); Array.Copy(NewName, 0, ParentMateial.UncompressedData, OffsetToUse, NewName.Length); ParentMateial.CompressedData = Zlibber.Compressor(ParentMateial.UncompressedData); } Mainfrm.TreeSource.SelectedNode.Tag = ParentMateial; Mainfrm.OpenFileModified = true; Mainfrm.TreeSource.Update(); Mainfrm.TreeSource.EndUpdate(); } } }
private ArcEntry[] GetDirectory(Stream strm, bool CheckOnly) { BinaryReader rd = new BinaryReader(strm); ArcEntry[] results = null; byte[] idBuffer = new byte[4]; long NameTableOffset; int numFiles; long HeaderPos, FilenamePos; char ch; strm.Read(idBuffer, 0, 4); if (Encoding.ASCII.GetString(idBuffer) != "OAF!") return null; rd.ReadUInt32(); rd.ReadUInt32(); NameTableOffset = rd.ReadInt64(); numFiles = rd.ReadInt32(); rd.ReadInt32(); results = new ArcEntry[numFiles]; if (CheckOnly) return results; FilenamePos = NameTableOffset; for (int i = 0; i < numFiles; i++) { results[i].StartOffset = rd.ReadInt32(); results[i].Flags = rd.ReadInt32(); results[i].UncompressedLength = rd.ReadInt32(); results[i].CompressedLength = rd.ReadInt32(); rd.ReadInt32(); // some kind of ID? // store current position HeaderPos = strm.Position; // jump to file name table strm.Seek(FilenamePos, SeekOrigin.Begin); results[i].Filename = ""; do { ch = (char)strm.ReadByte(); if (ch == 0) break; results[i].Filename += ch; } while (true); // save current position in file name table FilenamePos = strm.Position; // ...and jump back to the main entry table strm.Seek(HeaderPos, SeekOrigin.Begin); } return results; }
private void btnROK_Click(object sender, EventArgs e) { string newname = txtRename.Text; //Checks for blank/null names. if (newname == null || newname == "") { MessageBox.Show("This must have a name and cannot be null!", "Ahem"); return; } if (OriginalName == txtRename.Text) { DialogResult = DialogResult.OK; Hide(); return; } //Checks for existing name in directory. foreach (TreeNode c in node_.Parent.Nodes) { ArcEntry ae = new ArcEntry(); ArcEntry se = new ArcEntry(); if (node_.Tag is ArcEntry) { ae = node_.Tag as ArcEntry; } if (c.Tag is ArcEntry) { se = c.Tag as ArcEntry; } /* * //Checks the nodes in the same directory for existing name AND extension and will stop if there's a node with the same type in the same directory. * if (c.Text == txtRename.Text && c.Tag as string != "MaterialChildTexture") * { * if (ae != se && ae.FileExt == se.FileExt) * { * MessageBox.Show("That name already exists on a resource of the same type on the same level. \nTry a different name.", "Oh Boy"); * return; * } * } */ } //Changes the name to what was chosen. Should reflect on the Treeview. treeview.SelectedNode.Text = txtRename.Text; treeview.SelectedNode.Name = txtRename.Text; //Ensures the TrueName gets change so it gets reflected in the save. ArcEntry aey = new ArcEntry(); if (treeview.SelectedNode.Tag is ArcEntry) { aey = treeview.SelectedNode.Tag as ArcEntry; aey.TrueName = txtRename.Text; } else if (treeview.SelectedNode.Tag != null && treeview.SelectedNode.Tag as string == "Folder") { } else if (treeview.SelectedNode.Tag != null && treeview.SelectedNode.Tag is MaterialTextureReference) { //Goes about accessing and updating the data inside the material in a roundabout way. MaterialTextureReference texref = treeview.SelectedNode.Tag as MaterialTextureReference; MaterialEntry mentry = new MaterialEntry(); TreeNode parent = treeview.SelectedNode.Parent; TreeNode child = treeview.SelectedNode; treeview.SelectedNode = parent; parent = treeview.SelectedNode.Parent; treeview.SelectedNode = parent; mentry = treeview.SelectedNode.Tag as MaterialEntry; if (mentry != null) { //Now for the actual file update. List <byte> NameToInject = new List <byte>(); NameToInject.AddRange(Encoding.ASCII.GetBytes(txtRename.Text)); int OffsetToUse; OffsetToUse = 64 + (88 * (texref.Index - 1)); byte[] NewName = new byte[64]; Array.Copy(NameToInject.ToArray(), 0, NewName, 0, NameToInject.ToArray().Length); Array.Copy(NewName, 0, mentry.UncompressedData, OffsetToUse, NewName.Length); mentry.CompressedData = Zlibber.Compressor(mentry.UncompressedData); treeview.SelectedNode.Tag = mentry; } treeview.SelectedNode = child; } Mainfrm.OpenFileModified = true; //Closes form with changes made above. DialogResult = DialogResult.OK; Hide(); }
ArcEntry[] GetDirectory(Stream strm, bool CheckOnly) { byte[] buf = new byte[56]; int numFiles; int DirOffset; BinaryReader rd; string id, name; ArcEntry[] result; rd = new BinaryReader(strm); rd.Read(buf, 0, 56); id = Encoding.ASCII.GetString(buf); if (id != ID) return null; DirOffset = rd.ReadInt32(); if ((strm.Length - DirOffset) % 64 != 0) return null; numFiles = (int)(strm.Length - DirOffset) / 64; result = new ArcEntry[numFiles]; if (CheckOnly) return result; // only need to return non-null here strm.Seek(DirOffset, SeekOrigin.Begin); for (int i = 0; i < numFiles; i++) { byte[] nameBuf = new byte[56]; rd.Read(nameBuf, 0, 56); name = Encoding.ASCII.GetString(nameBuf); name = name.Substring(0, name.IndexOf('\0')); result[i].Filename = name; result[i].Offset = rd.ReadInt32(); result[i].Length = rd.ReadInt32(); } return result; }
ArcEntry[] GetDirectory(Stream strm) { int NumFiles; ArcEntry[] results = null; BinaryReader rd = new BinaryReader(strm); if (rd.ReadUInt32() != grar_magic) return null; NumFiles = rd.ReadInt32(); results = new ArcEntry[NumFiles]; for (int i = 0; i < NumFiles; i++) { results[i].id = rd.ReadUInt32(); results[i].Offset = rd.ReadInt32(); results[i].CompressedLength = rd.ReadInt32(); results[i].Length = rd.ReadInt32(); } return results; }
private string GenerateFilename(ArcEntry ae) { return String.Format("0x{0:x8}{1}.raw", ae.id, ae.CompressedLength > 0 ? "P" : ""); }