mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-01-01 14:20:08 +01:00
* Add PUP loader * Add .tar loader and update .pup loader * Add extract method + offset to TAR loader Also adds error checking + operator bool overload * Add firmware decryption keys to key vault * Initial seperation of SELFDecrypter This seperates SELFDecrypter into itself and SCEDecrypter. SCEDecrypter contains the logic to decrypt any file with an SCE Header. SELFDecrypter inherits from SCEDecrypter and contains the code specifically to do with ELF. DecryptData could be deduplicated more. * Add "Install Firmware" option to tools menu * SCEDecrypter: put each segment in own file Also, const-correctness, adjusted buffer size and better error handling * More SELFDecrypter refactoring * Compile fix * Add messageboxes to firmware install * Add progress bar to firmware install
124 lines
2.9 KiB
C++
124 lines
2.9 KiB
C++
#include "stdafx.h"
|
|
|
|
#include "TAR.h"
|
|
|
|
#include <cmath>
|
|
#include <cstdlib>
|
|
|
|
tar_object::tar_object(const fs::file& file, size_t offset) : m_file(file), initial_offset(offset)
|
|
{
|
|
m_file.seek(initial_offset);
|
|
largest_offset = initial_offset;
|
|
}
|
|
|
|
TARHeader tar_object::read_header(u64 offset)
|
|
{
|
|
m_file.seek(offset);
|
|
TARHeader header;
|
|
m_file.read(header);
|
|
return header;
|
|
}
|
|
|
|
int octalToDecimal(int octalNumber)
|
|
{
|
|
int decimalNumber = 0, i = 0, rem;
|
|
while (octalNumber != 0)
|
|
{
|
|
rem = octalNumber % 10;
|
|
octalNumber /= 10;
|
|
decimalNumber += rem * pow(8, i);
|
|
++i;
|
|
}
|
|
return decimalNumber;
|
|
}
|
|
|
|
std::vector<std::string> tar_object::get_filenames()
|
|
{
|
|
if (!isValid) return std::vector<std::string>();
|
|
|
|
std::vector<std::string> vec;
|
|
get_file("");
|
|
for (auto it = m_map.cbegin(); it != m_map.cend(); ++it)
|
|
{
|
|
vec.push_back(it->first);
|
|
}
|
|
return vec;
|
|
}
|
|
|
|
fs::file tar_object::get_file(std::string path)
|
|
{
|
|
if (!isValid || !m_file) return fs::file();
|
|
|
|
auto it = m_map.find(path);
|
|
if (it != m_map.end())
|
|
{
|
|
TARHeader header = read_header(it->second);
|
|
int size = octalToDecimal(atoi(header.size));
|
|
std::vector<u8> buf(size);
|
|
m_file.read(buf, size);
|
|
int offset = ((m_file.pos() - initial_offset + 512 - 1) & ~(512 - 1)) + initial_offset; // Always keep the offset aligned to 512 bytes + the initial offset.
|
|
m_file.seek(offset);
|
|
return fs::make_stream(std::move(buf));
|
|
}
|
|
else //continue scanning from last file entered
|
|
{
|
|
while (m_file.pos() < m_file.size()) {
|
|
TARHeader header = read_header(largest_offset);
|
|
if (!isValid) return fs::file();
|
|
|
|
if (std::string(header.magic).find("ustar") != std::string::npos)
|
|
m_map[header.name] = largest_offset;
|
|
|
|
int size = octalToDecimal(atoi(header.size));
|
|
if (path.compare(header.name) == 0) { //path is equal, read file and advance offset to start of next block
|
|
std::vector<u8> buf(size);
|
|
m_file.read(buf, size);
|
|
int offset = ((m_file.pos() - initial_offset + 512 - 1) & ~(512 - 1)) + initial_offset;
|
|
m_file.seek(offset);
|
|
largest_offset = offset;
|
|
|
|
return fs::make_stream(std::move(buf));
|
|
}
|
|
else { // just advance offset to next block
|
|
m_file.seek(size, fs::seek_mode::seek_cur);
|
|
int offset = ((m_file.pos() - initial_offset + 512 - 1) & ~(512 - 1)) + initial_offset;
|
|
m_file.seek(offset);
|
|
largest_offset = offset;
|
|
}
|
|
}
|
|
|
|
return fs::file();
|
|
}
|
|
}
|
|
|
|
bool tar_object::extract(std::string path)
|
|
{
|
|
if (!isValid || !m_file) return false;
|
|
|
|
get_file(""); //Make sure we have scanned all files
|
|
for (auto iter : m_map)
|
|
{
|
|
TARHeader header = read_header(iter.second);
|
|
if (std::string(header.name).empty()) continue;
|
|
|
|
switch (header.filetype) {
|
|
case '0':
|
|
{
|
|
fs::file file(header.name, fs::rewrite);
|
|
file.write(get_file(header.name).to_vector<u8>());
|
|
break;
|
|
}
|
|
|
|
case '5':
|
|
{
|
|
fs::create_dir(path + header.name);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
LOG_ERROR(GENERAL,"Tar loader: unknown file type: "+header.filetype);
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
} |