private void OpenArchive(string path) { try { br = new BinaryReader(File.OpenRead(path), Encoding.Default); //if(Program.ReadCString(br)!="BSA") throw new fommException("File was not a valid BSA archive"); var type = br.ReadUInt32(); var sb = new StringBuilder(64); if (type != 0x00415342 && type != 0x00000100) { //Might be a fallout 2 dat br.BaseStream.Position = br.BaseStream.Length - 8; var TreeSize = br.ReadUInt32(); var DataSize = br.ReadUInt32(); if (DataSize != br.BaseStream.Length) { MessageBox.Show("File is not a valid bsa archive"); br.Close(); return; } br.BaseStream.Position = DataSize - TreeSize - 8; var FileCount = br.ReadInt32(); Files = new BSAFileEntry[FileCount]; for (var i = 0; i < FileCount; i++) { var fileLen = br.ReadInt32(); for (var j = 0; j < fileLen; j++) { sb.Append(br.ReadChar()); } var comp = br.ReadByte(); var realSize = br.ReadUInt32(); var compSize = br.ReadUInt32(); var offset = br.ReadUInt32(); if (sb[0] == '\\') { sb.Remove(0, 1); } Files[i] = new BSAFileEntry(sb.ToString(), offset, compSize, comp == 0 ? 0 : realSize); sb.Length = 0; } } else if (type == 0x0100) { var hashoffset = br.ReadUInt32(); var FileCount = br.ReadUInt32(); Files = new BSAFileEntry[FileCount]; var dataoffset = 12 + hashoffset + FileCount*8; var fnameOffset1 = 12 + FileCount*8; var fnameOffset2 = 12 + FileCount*12; for (var i = 0; i < FileCount; i++) { br.BaseStream.Position = 12 + i*8; var size = br.ReadUInt32(); var offset = br.ReadUInt32() + dataoffset; br.BaseStream.Position = fnameOffset1 + i*4; br.BaseStream.Position = br.ReadInt32() + fnameOffset2; sb.Length = 0; while (true) { var b = br.ReadChar(); if (b == '\0') { break; } sb.Append(b); } Files[i] = new BSAFileEntry(sb.ToString(), offset, size); } } else { var version = br.ReadInt32(); if (version != 0x67 && version != 0x68) { if (MessageBox.Show("This BSA archive has an unknown version number.\n" + "Attempt to open anyway?", "Warning", MessageBoxButtons.YesNo) != DialogResult.Yes) { br.Close(); return; } } br.BaseStream.Position += 4; var flags = br.ReadUInt32(); Compressed = (flags & 0x004) > 0; if ((flags & 0x100) > 0 && version == 0x68) { ContainsFileNameBlobs = true; } else { ContainsFileNameBlobs = false; } var FolderCount = br.ReadInt32(); var FileCount = br.ReadInt32(); br.BaseStream.Position += 12; Files = new BSAFileEntry[FileCount]; var numfiles = new int[FolderCount]; br.BaseStream.Position += 8; for (var i = 0; i < FolderCount; i++) { numfiles[i] = br.ReadInt32(); br.BaseStream.Position += 12; } br.BaseStream.Position -= 8; var filecount = 0; for (var i = 0; i < FolderCount; i++) { int k = br.ReadByte(); while (--k > 0) { sb.Append(br.ReadChar()); } br.BaseStream.Position++; var folder = sb.ToString(); for (var j = 0; j < numfiles[i]; j++) { br.BaseStream.Position += 8; var size = br.ReadUInt32(); var comp = Compressed; if ((size & (1 << 30)) != 0) { comp = !comp; size ^= 1 << 30; } Files[filecount++] = new BSAFileEntry(comp, folder, br.ReadUInt32(), size); } sb.Length = 0; } for (var i = 0; i < FileCount; i++) { while (true) { var c = br.ReadChar(); if (c == '\0') { break; } sb.Append(c); } Files[i].FileName = sb.ToString(); sb.Length = 0; } } } catch (Exception ex) { if (br != null) { br.Close(); } br = null; MessageBox.Show("An error occured trying to open the archive.\n" + ex.Message); return; } tvFolders.Nodes.Add(Path.GetFileNameWithoutExtension(path)); tvFolders.Nodes[0].Nodes.Add("empty"); if (tvFolders.Nodes[0].IsExpanded) { tvFolders.Nodes[0].Collapse(); } tbSearch.Text = ""; UpdateFileList(); bOpen.Text = "Close"; bExtract.Enabled = true; ArchiveOpen = true; bExtractAll.Enabled = true; bPreview.Enabled = true; }
private void OpenArchive(string path) { try { br = new BinaryReader(File.OpenRead(path), Encoding.Default); //if(Program.ReadCString(br)!="BSA") throw new fommException("File was not a valid BSA archive"); var type = br.ReadUInt32(); var sb = new StringBuilder(64); if (type != 0x00415342 && type != 0x00000100) { //Might be a fallout 2 dat br.BaseStream.Position = br.BaseStream.Length - 8; var TreeSize = br.ReadUInt32(); var DataSize = br.ReadUInt32(); if (DataSize != br.BaseStream.Length) { MessageBox.Show("File is not a valid bsa archive"); br.Close(); return; } br.BaseStream.Position = DataSize - TreeSize - 8; var FileCount = br.ReadInt32(); Files = new BSAFileEntry[FileCount]; for (var i = 0; i < FileCount; i++) { var fileLen = br.ReadInt32(); for (var j = 0; j < fileLen; j++) { sb.Append(br.ReadChar()); } var comp = br.ReadByte(); var realSize = br.ReadUInt32(); var compSize = br.ReadUInt32(); var offset = br.ReadUInt32(); if (sb[0] == '\\') { sb.Remove(0, 1); } Files[i] = new BSAFileEntry(sb.ToString(), offset, compSize, comp == 0 ? 0 : realSize); sb.Length = 0; } } else if (type == 0x0100) { var hashoffset = br.ReadUInt32(); var FileCount = br.ReadUInt32(); Files = new BSAFileEntry[FileCount]; var dataoffset = 12 + hashoffset + FileCount * 8; var fnameOffset1 = 12 + FileCount * 8; var fnameOffset2 = 12 + FileCount * 12; for (var i = 0; i < FileCount; i++) { br.BaseStream.Position = 12 + i * 8; var size = br.ReadUInt32(); var offset = br.ReadUInt32() + dataoffset; br.BaseStream.Position = fnameOffset1 + i * 4; br.BaseStream.Position = br.ReadInt32() + fnameOffset2; sb.Length = 0; while (true) { var b = br.ReadChar(); if (b == '\0') { break; } sb.Append(b); } Files[i] = new BSAFileEntry(sb.ToString(), offset, size); } } else { var version = br.ReadInt32(); if (version != 0x67 && version != 0x68) { if (MessageBox.Show("This BSA archive has an unknown version number.\n" + "Attempt to open anyway?", "Warning", MessageBoxButtons.YesNo) != DialogResult.Yes) { br.Close(); return; } } br.BaseStream.Position += 4; var flags = br.ReadUInt32(); Compressed = (flags & 0x004) > 0; if ((flags & 0x100) > 0 && version == 0x68) { ContainsFileNameBlobs = true; } else { ContainsFileNameBlobs = false; } var FolderCount = br.ReadInt32(); var FileCount = br.ReadInt32(); br.BaseStream.Position += 12; Files = new BSAFileEntry[FileCount]; var numfiles = new int[FolderCount]; br.BaseStream.Position += 8; for (var i = 0; i < FolderCount; i++) { numfiles[i] = br.ReadInt32(); br.BaseStream.Position += 12; } br.BaseStream.Position -= 8; var filecount = 0; for (var i = 0; i < FolderCount; i++) { int k = br.ReadByte(); while (--k > 0) { sb.Append(br.ReadChar()); } br.BaseStream.Position++; var folder = sb.ToString(); for (var j = 0; j < numfiles[i]; j++) { br.BaseStream.Position += 8; var size = br.ReadUInt32(); var comp = Compressed; if ((size & (1 << 30)) != 0) { comp = !comp; size ^= 1 << 30; } Files[filecount++] = new BSAFileEntry(comp, folder, br.ReadUInt32(), size); } sb.Length = 0; } for (var i = 0; i < FileCount; i++) { while (true) { var c = br.ReadChar(); if (c == '\0') { break; } sb.Append(c); } Files[i].FileName = sb.ToString(); sb.Length = 0; } } } catch (Exception ex) { if (br != null) { br.Close(); } br = null; MessageBox.Show("An error occured trying to open the archive.\n" + ex.Message); return; } tvFolders.Nodes.Add(Path.GetFileNameWithoutExtension(path)); tvFolders.Nodes[0].Nodes.Add("empty"); if (tvFolders.Nodes[0].IsExpanded) { tvFolders.Nodes[0].Collapse(); } tbSearch.Text = ""; UpdateFileList(); bOpen.Text = "Close"; bExtract.Enabled = true; ArchiveOpen = true; bExtractAll.Enabled = true; bPreview.Enabled = true; }