mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-01-31 03:45:38 +00:00
Merge pull request #1938 from stenzek/file-offset-64
CDImagePBP: Use 64-bit file functions
This commit is contained in:
commit
6ce5330d75
|
@ -251,6 +251,13 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
|
|
||||||
|
# Enable large file support on Linux 32-bit platforms.
|
||||||
|
# Android is deliberately ommitted here as it didn't support 64-bit ops on files until Android 7/N.
|
||||||
|
if((LINUX OR FREEBSD) AND (${CPU_ARCH} STREQUAL "x86" OR ${CPU_ARCH} STREQUAL "aarch32"))
|
||||||
|
add_definitions("-D_FILE_OFFSET_BITS=64")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
# Recursively include the source tree.
|
# Recursively include the source tree.
|
||||||
enable_testing()
|
enable_testing()
|
||||||
add_subdirectory(dep)
|
add_subdirectory(dep)
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
Log_SetChannel(CDImagePBP);
|
Log_SetChannel(CDImagePBP);
|
||||||
|
|
||||||
using namespace PBP;
|
using namespace PBP;
|
||||||
|
using FileSystem::FSeek64;
|
||||||
|
using FileSystem::FTell64;
|
||||||
|
|
||||||
class CDImagePBP final : public CDImage
|
class CDImagePBP final : public CDImage
|
||||||
{
|
{
|
||||||
|
@ -58,7 +60,7 @@ private:
|
||||||
bool IsValidEboot(Common::Error* error);
|
bool IsValidEboot(Common::Error* error);
|
||||||
|
|
||||||
bool InitDecompressionStream();
|
bool InitDecompressionStream();
|
||||||
bool DecompressBlock(BlockInfo block_info);
|
bool DecompressBlock(const BlockInfo& block_info);
|
||||||
|
|
||||||
bool OpenDisc(u32 index, Common::Error* error);
|
bool OpenDisc(u32 index, Common::Error* error);
|
||||||
|
|
||||||
|
@ -129,13 +131,13 @@ bool CDImagePBP::LoadPBPHeader()
|
||||||
if (!m_file)
|
if (!m_file)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (fseek(m_file, 0, SEEK_END) != 0)
|
if (FSeek64(m_file, 0, SEEK_END) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (ftell(m_file) < 0)
|
if (FTell64(m_file) < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (fseek(m_file, 0, SEEK_SET) != 0)
|
if (FSeek64(m_file, 0, SEEK_SET) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (fread(&m_pbp_header, sizeof(PBPHeader), 1, m_file) != 1)
|
if (fread(&m_pbp_header, sizeof(PBPHeader), 1, m_file) != 1)
|
||||||
|
@ -159,7 +161,7 @@ bool CDImagePBP::LoadPBPHeader()
|
||||||
|
|
||||||
bool CDImagePBP::LoadSFOHeader()
|
bool CDImagePBP::LoadSFOHeader()
|
||||||
{
|
{
|
||||||
if (fseek(m_file, m_pbp_header.param_sfo_offset, SEEK_SET) != 0)
|
if (FSeek64(m_file, m_pbp_header.param_sfo_offset, SEEK_SET) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (fread(&m_sfo_header, sizeof(SFOHeader), 1, m_file) != 1)
|
if (fread(&m_sfo_header, sizeof(SFOHeader), 1, m_file) != 1)
|
||||||
|
@ -183,7 +185,7 @@ bool CDImagePBP::LoadSFOIndexTable()
|
||||||
m_sfo_index_table.clear();
|
m_sfo_index_table.clear();
|
||||||
m_sfo_index_table.resize(m_sfo_header.num_table_entries);
|
m_sfo_index_table.resize(m_sfo_header.num_table_entries);
|
||||||
|
|
||||||
if (fseek(m_file, m_pbp_header.param_sfo_offset + sizeof(m_sfo_header), SEEK_SET) != 0)
|
if (FSeek64(m_file, m_pbp_header.param_sfo_offset + sizeof(m_sfo_header), SEEK_SET) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (fread(m_sfo_index_table.data(), sizeof(SFOIndexTableEntry), m_sfo_header.num_table_entries, m_file) !=
|
if (fread(m_sfo_index_table.data(), sizeof(SFOIndexTableEntry), m_sfo_header.num_table_entries, m_file) !=
|
||||||
|
@ -209,7 +211,7 @@ bool CDImagePBP::LoadSFOTable()
|
||||||
u32 abs_data_offset =
|
u32 abs_data_offset =
|
||||||
m_pbp_header.param_sfo_offset + m_sfo_header.data_table_offset + m_sfo_index_table[i].data_offset;
|
m_pbp_header.param_sfo_offset + m_sfo_header.data_table_offset + m_sfo_index_table[i].data_offset;
|
||||||
|
|
||||||
if (fseek(m_file, abs_key_offset, SEEK_SET) != 0)
|
if (FSeek64(m_file, abs_key_offset, SEEK_SET) != 0)
|
||||||
{
|
{
|
||||||
Log_ErrorPrintf("Failed seek to key for SFO table entry %zu", i);
|
Log_ErrorPrintf("Failed seek to key for SFO table entry %zu", i);
|
||||||
return false;
|
return false;
|
||||||
|
@ -223,7 +225,7 @@ bool CDImagePBP::LoadSFOTable()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fseek(m_file, abs_data_offset, SEEK_SET) != 0)
|
if (FSeek64(m_file, abs_data_offset, SEEK_SET) != 0)
|
||||||
{
|
{
|
||||||
Log_ErrorPrintf("Failed seek to data for SFO table entry %zu", i);
|
Log_ErrorPrintf("Failed seek to data for SFO table entry %zu", i);
|
||||||
return false;
|
return false;
|
||||||
|
@ -381,7 +383,7 @@ bool CDImagePBP::Open(const char* filename, Common::Error* error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start parsing ISO stuff
|
// Start parsing ISO stuff
|
||||||
if (fseek(m_file, m_pbp_header.data_psar_offset, SEEK_SET) != 0)
|
if (FSeek64(m_file, m_pbp_header.data_psar_offset, SEEK_SET) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check "PSTITLEIMG000000" for multi-disc
|
// Check "PSTITLEIMG000000" for multi-disc
|
||||||
|
@ -395,7 +397,7 @@ bool CDImagePBP::Open(const char* filename, Common::Error* error)
|
||||||
// of 0. There are also some disc hashes, a serial (from one of the discs, but used as an identifier for the entire
|
// of 0. There are also some disc hashes, a serial (from one of the discs, but used as an identifier for the entire
|
||||||
// "title image" header), and some other offsets, but we don't really need to check those
|
// "title image" header), and some other offsets, but we don't really need to check those
|
||||||
|
|
||||||
if (fseek(m_file, m_pbp_header.data_psar_offset + 0x200, SEEK_SET) != 0)
|
if (FSeek64(m_file, m_pbp_header.data_psar_offset + 0x200, SEEK_SET) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
u32 disc_table[DISC_TABLE_NUM_ENTRIES] = {};
|
u32 disc_table[DISC_TABLE_NUM_ENTRIES] = {};
|
||||||
|
@ -454,7 +456,7 @@ bool CDImagePBP::OpenDisc(u32 index, Common::Error* error)
|
||||||
|
|
||||||
// Go to ISO header
|
// Go to ISO header
|
||||||
const u32 iso_header_start = m_disc_offsets[index];
|
const u32 iso_header_start = m_disc_offsets[index];
|
||||||
if (fseek(m_file, iso_header_start, SEEK_SET) != 0)
|
if (FSeek64(m_file, iso_header_start, SEEK_SET) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
char iso_header_magic[12] = {};
|
char iso_header_magic[12] = {};
|
||||||
|
@ -469,7 +471,7 @@ bool CDImagePBP::OpenDisc(u32 index, Common::Error* error)
|
||||||
|
|
||||||
// Ignore encrypted files
|
// Ignore encrypted files
|
||||||
u32 pgd_magic;
|
u32 pgd_magic;
|
||||||
if (fseek(m_file, iso_header_start + 0x400, SEEK_SET) != 0)
|
if (FSeek64(m_file, iso_header_start + 0x400, SEEK_SET) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (fread(&pgd_magic, sizeof(pgd_magic), 1, m_file) != 1)
|
if (fread(&pgd_magic, sizeof(pgd_magic), 1, m_file) != 1)
|
||||||
|
@ -485,7 +487,7 @@ bool CDImagePBP::OpenDisc(u32 index, Common::Error* error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read in the TOC
|
// Read in the TOC
|
||||||
if (fseek(m_file, iso_header_start + 0x800, SEEK_SET) != 0)
|
if (FSeek64(m_file, iso_header_start + 0x800, SEEK_SET) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (u32 i = 0; i < TOC_NUM_ENTRIES; i++)
|
for (u32 i = 0; i < TOC_NUM_ENTRIES; i++)
|
||||||
|
@ -498,7 +500,7 @@ bool CDImagePBP::OpenDisc(u32 index, Common::Error* error)
|
||||||
// for both data and audio
|
// for both data and audio
|
||||||
|
|
||||||
// Get the offset of the compressed iso
|
// Get the offset of the compressed iso
|
||||||
if (fseek(m_file, iso_header_start + 0xBFC, SEEK_SET) != 0)
|
if (FSeek64(m_file, iso_header_start + 0xBFC, SEEK_SET) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
u32 iso_offset;
|
u32 iso_offset;
|
||||||
|
@ -506,7 +508,7 @@ bool CDImagePBP::OpenDisc(u32 index, Common::Error* error)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Generate block info table
|
// Generate block info table
|
||||||
if (fseek(m_file, iso_header_start + 0x4000, SEEK_SET) != 0)
|
if (FSeek64(m_file, iso_header_start + 0x4000, SEEK_SET) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (u32 i = 0; i < BLOCK_TABLE_NUM_ENTRIES; i++)
|
for (u32 i = 0; i < BLOCK_TABLE_NUM_ENTRIES; i++)
|
||||||
|
@ -708,9 +710,9 @@ bool CDImagePBP::InitDecompressionStream()
|
||||||
return ret == Z_OK;
|
return ret == Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDImagePBP::DecompressBlock(BlockInfo block_info)
|
bool CDImagePBP::DecompressBlock(const BlockInfo& block_info)
|
||||||
{
|
{
|
||||||
if (fseek(m_file, block_info.offset, SEEK_SET) != 0)
|
if (FSeek64(m_file, block_info.offset, SEEK_SET) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_compressed_block.resize(block_info.size);
|
m_compressed_block.resize(block_info.size);
|
||||||
|
|
|
@ -500,6 +500,31 @@ std::FILE* OpenCFile(const char* filename, const char* mode)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FSeek64(std::FILE* fp, s64 offset, int whence)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return _fseeki64(fp, offset, whence);
|
||||||
|
#else
|
||||||
|
// Prevent truncation on platforms which don't have a 64-bit off_t (Android 32-bit).
|
||||||
|
if constexpr (sizeof(off_t) != sizeof(s64))
|
||||||
|
{
|
||||||
|
if (offset < std::numeric_limits<off_t>::min() || offset > std::numeric_limits<off_t>::max())
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fseeko(fp, static_cast<off_t>(offset), whence);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 FTell64(std::FILE* fp)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return static_cast<s64>(_ftelli64(fp));
|
||||||
|
#else
|
||||||
|
return static_cast<s64>(ftello(fp));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<std::vector<u8>> ReadBinaryFile(const char* filename)
|
std::optional<std::vector<u8>> ReadBinaryFile(const char* filename)
|
||||||
{
|
{
|
||||||
ManagedCFilePtr fp = OpenManagedCFile(filename, "rb");
|
ManagedCFilePtr fp = OpenManagedCFile(filename, "rb");
|
||||||
|
|
|
@ -183,6 +183,8 @@ std::unique_ptr<ByteStream> OpenFile(const char* FileName, u32 Flags);
|
||||||
using ManagedCFilePtr = std::unique_ptr<std::FILE, void (*)(std::FILE*)>;
|
using ManagedCFilePtr = std::unique_ptr<std::FILE, void (*)(std::FILE*)>;
|
||||||
ManagedCFilePtr OpenManagedCFile(const char* filename, const char* mode);
|
ManagedCFilePtr OpenManagedCFile(const char* filename, const char* mode);
|
||||||
std::FILE* OpenCFile(const char* filename, const char* mode);
|
std::FILE* OpenCFile(const char* filename, const char* mode);
|
||||||
|
int FSeek64(std::FILE* fp, s64 offset, int whence);
|
||||||
|
s64 FTell64(std::FILE* fp);
|
||||||
|
|
||||||
std::optional<std::vector<u8>> ReadBinaryFile(const char* filename);
|
std::optional<std::vector<u8>> ReadBinaryFile(const char* filename);
|
||||||
std::optional<std::vector<u8>> ReadBinaryFile(std::FILE* fp);
|
std::optional<std::vector<u8>> ReadBinaryFile(std::FILE* fp);
|
||||||
|
|
Loading…
Reference in a new issue