示例#1
0
    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;
    }
示例#2
0
文件: BSABrowser.cs 项目: vjmira/fomm
        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;
        }