Advertisement
Thatoneham

Untitled

Oct 10th, 2024
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.16 KB | Source Code | 0 0
  1. /*
  2. Giga Entergram .arc extractor
  3. Copyright (C) 2024  rahcchi (https://github.com/rahcchi)
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program.  If not, see <http://www.gnu.org/licenses/>.
  14. */
  15.  
  16. #include <iostream>
  17. #include <vector>
  18. #include <fstream>
  19. #include <cstring>   // For memcpy and memset
  20. #include <cstdio>    // For sprintf
  21. #include <cstdlib>   // For setlocale
  22. #include <sys/stat.h> // For stat() to check file existence
  23.  
  24. #ifdef _WIN32
  25.     #include <direct.h>  // For _mkdir on Windows
  26.     #define mkdir(F, A) _mkdir(F)  // Redefine mkdir for Windows compatibility
  27. #endif
  28.  
  29. // Function to check if a file exists
  30. bool file_exists(const char* filename) {
  31.     struct stat buffer;
  32.     return (stat(filename, &buffer) == 0);
  33. }
  34.  
  35. // Struct for archive header
  36. typedef struct header {
  37.     uint32_t unk;
  38.     uint32_t file_number;
  39. } header;
  40.  
  41. // Struct for individual file entry in the archive
  42. typedef struct entry_header {
  43.     char file_name[64];
  44.     uint32_t size;
  45.     uint32_t offset;
  46. } entry_header;
  47.  
  48. // Template function to extract data of a given type (T) from a byte array
  49. template<typename T>
  50. T get(const uint8_t* data, int offset) {
  51.     return *(T*)&data[offset];  // Cast the data at offset to type T
  52. }
  53.  
  54. int main(int argc, char* argv[]) {
  55.     // Set locale to support file names with special characters
  56.     setlocale(LC_ALL, "");
  57.  
  58.     // Check if input file is provided and exists
  59.     if (argc < 2 || !file_exists(argv[1])) {
  60.         std::cerr << "Usage: " << argv[0] << " <input.arc>" << std::endl;
  61.         return -1;
  62.     }
  63.  
  64.     // Read the file into a byte vector
  65.     std::vector<uint8_t> filedata;
  66.     std::ifstream is(argv[1], std::ios::binary);
  67.    
  68.     // Get the file size
  69.     is.seekg(0, std::ios_base::end);
  70.     std::size_t filesize = is.tellg();
  71.     is.seekg(0, std::ios_base::beg);
  72.  
  73.     // Resize the vector to fit the file data
  74.     filedata.resize(filesize);
  75.     is.read(reinterpret_cast<char*>(&filedata[0]), static_cast<std::streamsize>(filesize));
  76.     is.close();
  77.  
  78.     // Initialize offset and read the archive header
  79.     int global_offset = 0;
  80.     header file;
  81.     file.unk = get<uint32_t>(filedata.data(), global_offset);
  82.     global_offset += sizeof(uint32_t);
  83.     file.file_number = get<uint32_t>(filedata.data(), global_offset);
  84.     global_offset += sizeof(uint32_t);
  85.  
  86.     // Read file entries from the archive
  87.     std::vector<entry_header> files;
  88.     for (uint32_t i = 0; i < file.file_number; i++) {
  89.         entry_header f;
  90.         memcpy(&f.file_name, filedata.data() + global_offset, 64);  // Copy file name
  91.         global_offset += 64;
  92.         f.size = get<uint32_t>(filedata.data(), global_offset);     // Read file size
  93.         global_offset += sizeof(uint32_t);
  94.         f.offset = get<uint32_t>(filedata.data(), global_offset);   // Read file offset
  95.         global_offset += sizeof(uint32_t);
  96.         files.push_back(f);
  97.     }
  98.  
  99.     // Output number of files found
  100.     printf("FOUND %d FILES\n", file.file_number);
  101.  
  102.     // Create output directory
  103.     mkdir("out", 0777);  // On Windows, this uses _mkdir
  104.  
  105.     // Extract each file
  106.     for (size_t i = 0; i < files.size(); i++) {
  107.         char buffer[256];
  108.         memset(buffer, 0, 256);
  109.         sprintf(buffer, "./out/%s", files[i].file_name);  // Define output path
  110.  
  111.         // Open the file for writing
  112.         FILE* f = fopen(buffer, "wb");
  113.         if (f != NULL) {
  114.             fwrite(filedata.data() + files[i].offset, files[i].size, 1, f);
  115.             fclose(f);
  116.             printf("EXTRACTED %s\n", files[i].file_name);
  117.         } else {
  118.             printf("FAILED TO EXTRACT %s\n", files[i].file_name);
  119.         }
  120.     }
  121.  
  122.     return 0;
  123. }
  124.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement