home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 5257 / source.7z / x_afs.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2012-03-05  |  3.4 KB  |  117 lines

  1. #include "xentax.h"
  2. #include "x_file.h"
  3. #include "x_afs.h"
  4.  
  5. struct AFSITEM {
  6.  uint32 offset;
  7.  uint32 size;
  8. };
  9.  
  10. bool ExtractAFS(const char* filename)
  11. {
  12.  // extract filename information
  13.  if(!filename || !strlen(filename)) return error("Invalid filename.");
  14.  std::string fname = GetShortFilename(filename);
  15.  std::string fname_noext = GetShortFilenameWithoutExtension(filename);
  16.  std::string pname = GetPathnameFromFilename(filename);
  17.  
  18.  // open file
  19.  std::ifstream ifile(filename, std::ios::binary);
  20.  if(!ifile) return error("Failed to open file.");
  21.  
  22.  // read magic
  23.  uint32 magic = LE_read_uint32(ifile);
  24.  if(ifile.fail()) return error("Read failure.");
  25.  if(magic != 0x00534641) return error("Expecting AFS.");
  26.  
  27.  // read header
  28.  uint32 head01 = LE_read_uint32(ifile); // number of files
  29.  uint32 head02 = LE_read_uint32(ifile); // 0x800
  30.  uint32 head03 = LE_read_uint32(ifile); // start?
  31.  
  32.  // move to start
  33.  ifile.seekg(0x10);
  34.  if(ifile.fail()) return error("Seek failure.");
  35.  
  36.  // build list of AFS items
  37.  std::deque<AFSITEM> itemlist;
  38.  for(uint32 i = 0; i < head01; i++) {
  39.      uint32 p1 = LE_read_uint32(ifile);
  40.      uint32 p2 = LE_read_uint32(ifile);
  41.      AFSITEM item = { p1, p2 };
  42.      itemlist.push_back(item);
  43.     }
  44.  
  45.  // filename data
  46.  std::map<std::string, uint32> namemap;
  47.  std::deque<std::string> filelist;
  48.  
  49.  // move to last AFS item
  50.  ifile.seekg(itemlist.back().offset);
  51.  if(ifile.fail()) return error("Seek failure.");
  52.  
  53.  // now let's try to read filenames
  54.  for(uint32 i = 0; i < head01; i++)
  55.     {
  56.      // read filename
  57.      char buffer[0x20];
  58.      memset(buffer, 0, 0x20);
  59.      ifile.read(&buffer[0], 0x20);
  60.      std::cout << buffer << std::endl;
  61.      LE_read_uint32(ifile);
  62.      LE_read_uint16(ifile);
  63.      LE_read_uint16(ifile);
  64.      LE_read_uint16(ifile);
  65.      LE_read_uint16(ifile);
  66.      LE_read_uint16(ifile);
  67.      LE_read_uint16(ifile);
  68.  
  69.      // save filename
  70.      std::map<std::string, uint32>::iterator iter = namemap.find(buffer);
  71.      if(iter == namemap.end()) {
  72.         namemap.insert(std::map<std::string, uint32>::value_type(buffer, 0));
  73.         filelist.push_back(buffer);
  74.        }
  75.      else {
  76.         std::stringstream ss;
  77.         ss << buffer << "." << std::setfill('0') << std::setw(3) << iter->second;
  78.         filelist.push_back(ss.str());
  79.         iter->second++;
  80.        }
  81.     }
  82.  
  83.  // create subdirectory
  84.  std::stringstream savepath;
  85.  savepath << pname << fname_noext << "\\";
  86.  CreateDirectoryA(savepath.str().c_str(), NULL);
  87.  
  88.  // now let's try to save files
  89.  for(uint32 i = 0; i < head01; i++)
  90.     {
  91.      // move to AFS item
  92.      ifile.seekg(itemlist[i].offset);
  93.      if(ifile.fail()) return error("Seek failure.");
  94.  
  95.      if(itemlist[i].size)
  96.        {
  97.         // create file
  98.         std::stringstream ss;
  99.         ss << savepath.str() << filelist[i];
  100.         std::ofstream ofile(ss.str().c_str(), std::ios::binary);
  101.         if(!ofile) return error("Failed to create output file.");
  102.  
  103.         std::cout << "Saving " << ss.str() << " at " << itemlist[i].size << " bytes." << std::endl;
  104.         
  105.         // read file
  106.         boost::shared_array<char> data(new char[itemlist[i].size]);
  107.         ifile.read(data.get(), itemlist[i].size);
  108.         if(ifile.fail()) return error("Read failure.");
  109.  
  110.         // save file
  111.         ofile.write(data.get(), itemlist[i].size);
  112.         if(ofile.fail()) return error("Write failure.");
  113.        }
  114.     }
  115.  
  116.  return true;
  117. }