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

  1. #include "xentax.h"
  2. #include "x_findfile.h"
  3. #include "x_file.h"
  4.  
  5. std::string GetModulePathname(void)
  6. {
  7.  // get filename
  8.  char filename[MAX_PATH];
  9.  GetModuleFileNameA(NULL, filename, MAX_PATH);
  10.  
  11.  // make path from filename
  12.  char c_drive[MAX_PATH];
  13.  char c_path[MAX_PATH];
  14.  _splitpath(filename, c_drive, c_path, nullptr, nullptr);
  15.  std::string temp(c_drive);
  16.  temp += c_path;
  17.  
  18.  // set pathname
  19.  char buffer[MAX_PATH];
  20.  strcpy_s(&buffer[0], MAX_PATH, temp.c_str());
  21.  return std::string(buffer);
  22. }
  23.  
  24. std::string GetShortFilename(const std::string& filename)
  25. {
  26.  // validate
  27.  if(!filename.length()) return std::string();
  28.  
  29.  // extract components
  30.  char c_param1[MAX_PATH];
  31.  char c_param2[MAX_PATH];
  32.  char c_param3[MAX_PATH];
  33.  char c_param4[MAX_PATH];
  34.  
  35.  // extract components
  36.  c_param1[0] = '\0';
  37.  c_param2[0] = '\0';
  38.  c_param3[0] = '\0';
  39.  c_param4[0] = '\0';
  40.  _splitpath(filename.c_str(), c_param1, c_param2, c_param3, c_param4); 
  41.  
  42.  // return name + extension
  43.  std::string retval(c_param3);
  44.  retval += c_param4;
  45.  return retval;
  46. }
  47.  
  48. std::string GetShortFilenameWithoutExtension(const std::string& filename)
  49. {
  50.  // validate
  51.  if(!filename.length()) return std::string();
  52.  
  53.  // extract components
  54.  char c_param1[MAX_PATH];
  55.  char c_param2[MAX_PATH];
  56.  char c_param3[MAX_PATH];
  57.  char c_param4[MAX_PATH];
  58.  
  59.  // extract components
  60.  c_param1[0] = '\0';
  61.  c_param2[0] = '\0';
  62.  c_param3[0] = '\0';
  63.  c_param4[0] = '\0';
  64.  _splitpath(filename.c_str(), c_param1, c_param2, c_param3, c_param4); 
  65.  
  66.  // return name + extension
  67.  std::string retval(c_param3);
  68.  return retval;
  69. }
  70.  
  71. std::string GetPathnameFromFilename(const std::string& filename)
  72. {
  73.  // validate
  74.  if(!filename.length()) return std::string();
  75.  
  76.  // extract components
  77.  char c_param1[MAX_PATH];
  78.  char c_param2[MAX_PATH];
  79.  char c_param3[MAX_PATH];
  80.  char c_param4[MAX_PATH];
  81.  
  82.  // extract components
  83.  c_param1[0] = '\0';
  84.  c_param2[0] = '\0';
  85.  c_param3[0] = '\0';
  86.  c_param4[0] = '\0';
  87.  _splitpath(filename.c_str(), c_param1, c_param2, c_param3, c_param4); 
  88.  
  89.  // return name + extension
  90.  std::string retval(c_param1);
  91.  retval += c_param2;
  92.  return retval;
  93. }
  94.  
  95. std::string GetExtensionFromFilename(const std::string& filename)
  96. {
  97.  // validate
  98.  if(!filename.length()) return std::string();
  99.  
  100.  // extract components
  101.  char c_param1[MAX_PATH];
  102.  char c_param2[MAX_PATH];
  103.  char c_param3[MAX_PATH];
  104.  char c_param4[MAX_PATH];
  105.  
  106.  // extract components
  107.  c_param1[0] = '\0';
  108.  c_param2[0] = '\0';
  109.  c_param3[0] = '\0';
  110.  c_param4[0] = '\0';
  111.  _splitpath(filename.c_str(), c_param1, c_param2, c_param3, c_param4); 
  112.  
  113.  // return name + extension
  114.  //strlwr(c_param4);
  115.  return std::string(c_param4);
  116. }
  117.  
  118. bool HasExtension(const std::string& filename, const std::string& extension)
  119. {
  120.  std::string test = GetExtensionFromFilename(filename);
  121.  return (strcmpi(test.c_str(), extension.c_str()) == 0);
  122. }
  123.  
  124. bool BuildFilenameList(std::deque<std::string>& namelist, const char* fext)
  125. {
  126.  // get path of application
  127.  char c_rootname[MAX_PATH];
  128.  GetModuleFileNameA(0, c_rootname, MAX_PATH);
  129.  
  130.  // split the pathname
  131.  char c_drive[1024];
  132.  char c_dir[1024];
  133.  _splitpath(c_rootname, c_drive, c_dir, nullptr, nullptr);
  134.  //strlwr(c_drive);
  135.  //strlwr(c_dir);
  136.  
  137.  // build pathname
  138.  std::string s_rootname(c_drive);
  139.  s_rootname += std::string(c_dir);
  140.  
  141.  // build directory list
  142.  std::deque<std::string> templist;
  143.  templist.insert(templist.end(), s_rootname);
  144.  
  145.  size_t i = 0;
  146.  for(;;)
  147.     {
  148.      // get wildcard
  149.      find_file file;
  150.      std::string path(templist[i]);
  151.      path += "*.*";
  152.      file.find(path.c_str());
  153.      if(!file) return error("Could not build wildcard path.");
  154.  
  155.      // insert directories
  156.      if(file.is_directory() && !file.is_dots() && !file.is_system()) {
  157.         std::string path(templist[i]);
  158.         path += std::string(file.filename());
  159.         path += std::string("\\");
  160.         templist.insert(templist.end(), path);
  161.        }
  162.  
  163.      while(file.next()) {
  164.         if(file.is_directory() && !file.is_dots() && !file.is_system()) {
  165.            std::string path(templist[i]);
  166.            path += std::string(file.filename());
  167.            path += std::string("\\");
  168.            templist.insert(templist.end(), path);
  169.           }
  170.        }
  171.  
  172.      file.close();
  173.  
  174.      // update index
  175.      if(++i == templist.size())
  176.         break;
  177.     }
  178.  
  179.  // transfer directories with EXT files
  180.  std::deque<std::string> rootlist;
  181.  for(size_t i = 0; i < templist.size(); i++)
  182.     {
  183.      find_file file;
  184.      bool added = false;
  185.      std::string path(templist[i]);
  186.      path += "*";
  187.      path += ".";
  188.      path += fext;
  189.      if(file.find(path.c_str()) && !file.is_directory()) {
  190.         rootlist.insert(rootlist.end(), templist[i]);
  191.         added = true;
  192.        }
  193.     }
  194.  
  195.  // erase the temporary list
  196.  templist.erase(templist.begin(), templist.end());
  197.  if(rootlist.empty()) return error("No files found in current directory or subdirectories.");
  198.  
  199.  // build namelist
  200.  namelist.clear();
  201.  for(size_t i = 0; i < rootlist.size(); i++)
  202.     {
  203.      // clear templist
  204.      find_file file;
  205.      templist.erase(templist.begin(), templist.end());
  206.  
  207.      // add EXT files
  208.      std::string path(rootlist[i]);
  209.      path += "*";
  210.      path += ".";
  211.      path += fext;
  212.      if(file.find(path.c_str())) {
  213.         std::string temp(rootlist[i]);
  214.         temp += file.filename();
  215.         templist.insert(templist.end(), temp);
  216.        }
  217.      while(file.next()) {
  218.         std::string temp(rootlist[i]);
  219.         temp += file.filename();
  220.         templist.insert(templist.end(), temp);
  221.        }
  222.  
  223.      // sort temporary list and append to the namelist
  224.      if(templist.size()) {
  225.         std::sort(templist.begin(), templist.end());
  226.         namelist.insert(namelist.end(), templist.begin(), templist.end());
  227.        }
  228.     }
  229.  
  230.  // must have something in namelist
  231.  templist.erase(templist.begin(), templist.end());
  232.  if(!namelist.size()) return error("No files found in root directory or subdirectories.");
  233.  
  234.  return true;
  235. }
  236.  
  237. bool BuildFilenameList(std::deque<std::string>& namelist, const char* fext, const char* rootname)
  238. {
  239.  // get path of application
  240.  char c_rootname[MAX_PATH];
  241.  memmove(c_rootname, rootname, strlen(rootname) + 1);
  242.  
  243.  // add "." to extension
  244.  std::string extension;
  245.  if(fext[0] != '.') extension += ".";
  246.  extension += fext;
  247.  
  248.  // split the pathname
  249.  char c_drive[1024];
  250.  char c_dir[1024];
  251.  _splitpath(c_rootname, c_drive, c_dir, nullptr, nullptr);
  252.  //strlwr(c_drive);
  253.  //strlwr(c_dir);
  254.  
  255.  // build pathname
  256.  std::string s_rootname(c_drive);
  257.  s_rootname += std::string(c_dir);
  258.  
  259.  // build directory list
  260.  std::deque<std::string> templist;
  261.  templist.insert(templist.end(), s_rootname);
  262.  
  263.  size_t i = 0;
  264.  for(;;)
  265.     {
  266.      // get wildcard
  267.      find_file file;
  268.      std::string path(templist[i]);
  269.      path += "*.*";
  270.      file.find(path.c_str());
  271.      if(!file) return error("Could not build wildcard path.");
  272.  
  273.      // insert directories
  274.      if(file.is_directory() && !file.is_dots() && !file.is_system()) {
  275.         std::string path(templist[i]);
  276.         path += std::string(file.filename());
  277.         path += std::string("\\");
  278.         templist.insert(templist.end(), path);
  279.        }
  280.  
  281.      while(file.next()) {
  282.         if(file.is_directory() && !file.is_dots() && !file.is_system()) {
  283.            std::string path(templist[i]);
  284.            path += std::string(file.filename());
  285.            path += std::string("\\");
  286.            templist.insert(templist.end(), path);
  287.           }
  288.        }
  289.  
  290.      file.close();
  291.  
  292.      // update index
  293.      if(++i == templist.size())
  294.         break;
  295.     }
  296.  
  297.  // transfer directories with EXT files
  298.  std::deque<std::string> rootlist;
  299.  for(size_t i = 0; i < templist.size(); i++)
  300.     {
  301.      find_file file;
  302.      bool added = false;
  303.      std::string path(templist[i]);
  304.      path += "*";
  305.      path += extension;
  306.      if(file.find(path.c_str()) && !file.is_directory()) {
  307.         rootlist.insert(rootlist.end(), templist[i]);
  308.         added = true;
  309.        }
  310.     }
  311.  
  312.  // erase the temporary list
  313.  templist.erase(templist.begin(), templist.end());
  314.  if(rootlist.empty()) return error("No files found in current directory or subdirectories.");
  315.  
  316.  // build namelist
  317.  namelist.clear();
  318.  for(size_t i = 0; i < rootlist.size(); i++)
  319.     {
  320.      // clear templist
  321.      find_file file;
  322.      templist.erase(templist.begin(), templist.end());
  323.  
  324.      // add files
  325.      std::string path(rootlist[i]);
  326.      path += "*";
  327.      path += extension;
  328.      if(file.find(path.c_str())) {
  329.         std::string temp(rootlist[i]);
  330.         temp += file.filename();
  331.         if(!file.is_directory())
  332.            if(!strcmpi(extension.c_str(), GetExtensionFromFilename(temp).c_str()))
  333.               templist.insert(templist.end(), temp);
  334.        }
  335.      while(file.next()) {
  336.         std::string temp(rootlist[i]);
  337.         temp += file.filename();
  338.         if(!file.is_directory())
  339.            if(!strcmpi(extension.c_str(), GetExtensionFromFilename(temp).c_str()))
  340.               templist.insert(templist.end(), temp);
  341.        }
  342.  
  343.      // sort temporary list and append to the namelist
  344.      if(templist.size()) {
  345.         std::sort(templist.begin(), templist.end());
  346.         namelist.insert(namelist.end(), templist.begin(), templist.end());
  347.        }
  348.     }
  349.  
  350.  // must have something in namelist
  351.  templist.erase(templist.begin(), templist.end());
  352.  if(!namelist.size()) return error("No files found in root directory or subdirectories.");
  353.  
  354.  return true;
  355. }
  356.  
  357. bool SearchFileForSignature(std::ifstream& ifile, const char* signature, size_t sigsize, std::deque<uint64>& offsets)
  358. {
  359.  // validation
  360.  if(!ifile.is_open()) return false;
  361.  if(!signature || !sigsize) return false;
  362.  if(offsets.size()) offsets.clear();
  363.  
  364.  // get filesize
  365.  ifile.seekg(0, std::ios::end);
  366.  uint64 filesize = ifile.tellg();
  367.  ifile.seekg(0, std::ios::beg);
  368.  
  369.  // read buffer properties
  370.  const uint32 maxbuffersize = 32*1024*1024;
  371.  uint32 buffersize = (filesize < (uint64)maxbuffersize ? (uint32)filesize : maxbuffersize);
  372.  boost::shared_array<char> buffer(new char[buffersize]);
  373.  
  374.  // boyer-moore-horspool properties
  375.  boost::shared_array<unsigned char> table(new unsigned char[256]);
  376.  for(uint32 i = 0; i < 256; i++) table[i] = sigsize;
  377.  uint32 p_len = sigsize;
  378.  const unsigned char* p_str = reinterpret_cast<const unsigned char*>(signature);
  379.  for(uint32 i = 0; i < p_len - 1; i++) table[p_str[i]] = p_len - i - 1;
  380.  
  381.  // search properties
  382.  uint64 bytes_read = 0;
  383.  uint64 bytes_left = filesize;
  384.  uint64 start = 0;
  385.  
  386.  // search
  387.  while(bytes_read < filesize)
  388.       {
  389.        // search partial buffer
  390.        if(bytes_left < buffersize)
  391.          {
  392.           // read data
  393.           ifile.read(buffer.get(), bytes_left);
  394.           if(ifile.fail()) return false;
  395.  
  396.           // resume search?
  397.  
  398.           // boyer-moore-horspool properties
  399.           uint32 s_len = (uint32)bytes_left;
  400.           const unsigned char* s_str = reinterpret_cast<const unsigned char*>(buffer.get());          
  401.  
  402.           // boyer-moore-horspool search
  403.           size_t j = 0;
  404.           while(j <= (s_len - p_len)) {
  405.                 unsigned char c = s_str[j + p_len - 1];
  406.                 if(p_str[p_len - 1] == c && memcmp(p_str, s_str + j, p_len - 1) == 0) offsets.push_back(bytes_read + j);
  407.                 j += table[c];
  408.                }
  409.  
  410.           // adjust search properties
  411.           bytes_read = bytes_read + bytes_left;
  412.           bytes_left = 0;
  413.          }
  414.        // search full buffer
  415.        else
  416.          {
  417.           // read data
  418.           ifile.read(buffer.get(), buffersize);
  419.           if(ifile.fail()) return false;
  420.  
  421.           // resume search?
  422.  
  423.           // boyer-moore-horspool properties
  424.           size_t s_len = buffersize;
  425.           const unsigned char* s_str = reinterpret_cast<const unsigned char*>(buffer.get());          
  426.  
  427.           // boyer-moore-horspool search
  428.           size_t j = 0;
  429.           while(j <= (s_len - p_len)) {
  430.                 unsigned char c = s_str[j + p_len - 1];
  431.                 if(p_str[p_len - 1] == c && memcmp(p_str, s_str + j, p_len - 1) == 0) offsets.push_back(bytes_read + j);
  432.                 j += table[c];
  433.                }
  434.  
  435.           // adjust search properties
  436.           bytes_read = bytes_read + buffersize;
  437.           bytes_left = bytes_left - buffersize;
  438.          }
  439.       }
  440.  
  441.  return true;
  442. }
  443.  
  444. bool SearchFileForSignature(std::ifstream& ifile, const char* signature, size_t sigsize, size_t alignment, std::deque<uint64>& offsets)
  445. {
  446.  // validation
  447.  if(!ifile.is_open()) return false;
  448.  if(!signature || !sigsize) return false;
  449.  if(offsets.size()) offsets.clear();
  450.  
  451.  // get filesize
  452.  ifile.seekg(0, std::ios::end);
  453.  uint64 filesize = ifile.tellg();
  454.  ifile.seekg(0, std::ios::beg);
  455.  
  456.  // read buffer properties
  457.  const uint32 maxbuffersize = 32*1024*1024;
  458.  uint32 buffersize = (filesize < (uint64)maxbuffersize ? (uint32)filesize : maxbuffersize);
  459.  boost::shared_array<char> buffer(new char[buffersize]);
  460.  
  461.  // boyer-moore-horspool properties
  462.  boost::shared_array<unsigned char> table(new unsigned char[256]);
  463.  for(uint32 i = 0; i < 256; i++) table[i] = sigsize;
  464.  uint32 p_len = sigsize;
  465.  const unsigned char* p_str = reinterpret_cast<const unsigned char*>(signature);
  466.  for(uint32 i = 0; i < p_len - 1; i++) table[p_str[i]] = p_len - i - 1;
  467.  
  468.  // search properties
  469.  uint64 bytes_read = 0;
  470.  uint64 bytes_left = filesize;
  471.  uint64 start = 0;
  472.  
  473.  // search
  474.  while(bytes_read < filesize)
  475.       {
  476.        // search partial buffer
  477.        if(bytes_left < buffersize)
  478.          {
  479.           // read data
  480.           ifile.read(buffer.get(), bytes_left);
  481.           if(ifile.fail()) return false;
  482.  
  483.           // resume search?
  484.  
  485.           // boyer-moore-horspool properties
  486.           uint32 s_len = (uint32)bytes_left;
  487.           const unsigned char* s_str = reinterpret_cast<const unsigned char*>(buffer.get());          
  488.  
  489.           // boyer-moore-horspool search
  490.           size_t j = 0;
  491.           while(j <= (s_len - p_len)) {
  492.                 unsigned char c = s_str[j + p_len - 1];
  493.                 if(p_str[p_len - 1] == c && memcmp(p_str, s_str + j, p_len - 1) == 0)
  494.                    if(!((bytes_read + j) % alignment)) offsets.push_back(bytes_read + j);
  495.                 j += table[c];
  496.                }
  497.  
  498.           // adjust search properties
  499.           bytes_read = bytes_read + bytes_left;
  500.           bytes_left = 0;
  501.          }
  502.        // search full buffer
  503.        else
  504.          {
  505.           // read data
  506.           ifile.read(buffer.get(), buffersize);
  507.           if(ifile.fail()) return false;
  508.  
  509.           // resume search?
  510.  
  511.           // boyer-moore-horspool properties
  512.           size_t s_len = buffersize;
  513.           const unsigned char* s_str = reinterpret_cast<const unsigned char*>(buffer.get());          
  514.  
  515.           // boyer-moore-horspool search
  516.           size_t j = 0;
  517.           while(j <= (s_len - p_len)) {
  518.                 unsigned char c = s_str[j + p_len - 1];
  519.                 if(p_str[p_len - 1] == c && memcmp(p_str, s_str + j, p_len - 1) == 0)
  520.                   if(!((bytes_read + j) % alignment)) offsets.push_back(bytes_read + j);
  521.                 j += table[c];
  522.                }
  523.  
  524.           // adjust search properties
  525.           bytes_read = bytes_read + buffersize;
  526.           bytes_left = bytes_left - buffersize;
  527.          }
  528.       }
  529.  
  530.  return true;
  531. }