From 931dff6125445561b74c23156c93cf5c6f9ca50d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 26 Jan 2020 10:18:41 -0800 Subject: [PATCH] Core: Future proof CSO support a bit. For CSO versions >= 2, respect the header size field and uncompressed frame size behavior. This will allow more options for future files, like adding a field for the CRC or otherwise. --- Core/FileSystems/BlockDevices.cpp | 40 +++++++++++++------------------ Core/FileSystems/BlockDevices.h | 1 + 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/Core/FileSystems/BlockDevices.cpp b/Core/FileSystems/BlockDevices.cpp index f5ac8f926473..0826cafed6d0 100644 --- a/Core/FileSystems/BlockDevices.cpp +++ b/Core/FileSystems/BlockDevices.cpp @@ -134,18 +134,11 @@ CISOFileBlockDevice::CISOFileBlockDevice(FileLoader *fileLoader) CISO_H hdr; size_t readSize = fileLoader->ReadAt(0, sizeof(CISO_H), 1, &hdr); - if (readSize != 1 || memcmp(hdr.magic, "CISO", 4) != 0) - { + if (readSize != 1 || memcmp(hdr.magic, "CISO", 4) != 0) { WARN_LOG(LOADER, "Invalid CSO!"); } - else - { - VERBOSE_LOG(LOADER, "Valid CSO!"); - } - if (hdr.ver > 1) - { - ERROR_LOG(LOADER, "CSO version too high!"); - //ARGH! + if (hdr.ver > 1) { + WARN_LOG(LOADER, "CSO version too high!"); } frameSize = hdr.block_size; @@ -174,10 +167,11 @@ CISOFileBlockDevice::CISOFileBlockDevice(FileLoader *fileLoader) zlibBufferFrame = numFrames; const u32 indexSize = numFrames + 1; + const size_t headerEnd = hdr.ver > 1 ? (size_t)hdr.header_size : sizeof(hdr); #if COMMON_LITTLE_ENDIAN index = new u32[indexSize]; - if (fileLoader->ReadAt(sizeof(hdr), sizeof(u32), indexSize, index) != indexSize) { + if (fileLoader->ReadAt(headerEnd, sizeof(u32), indexSize, index) != indexSize) { NotifyReadError(); memset(index, 0, indexSize * sizeof(u32)); } @@ -185,7 +179,7 @@ CISOFileBlockDevice::CISOFileBlockDevice(FileLoader *fileLoader) index = new u32[indexSize]; u32_le *indexTemp = new u32_le[indexSize]; - if (fileLoader->ReadAt(sizeof(hdr), sizeof(u32), indexSize, indexTemp) != indexSize) { + if (fileLoader->ReadAt(headerEnd, sizeof(u32), indexSize, indexTemp) != indexSize) { NotifyReadError(); memset(indexTemp, 0, indexSize * sizeof(u32_le)); } @@ -196,6 +190,8 @@ CISOFileBlockDevice::CISOFileBlockDevice(FileLoader *fileLoader) delete[] indexTemp; #endif + ver_ = hdr.ver; + // Double check that the CSO is not truncated. In most cases, this will be the exact size. u64 fileSize = fileLoader->FileSize(); u64 lastIndexPos = index[indexSize - 1] & 0x7FFFFFFF; @@ -216,8 +212,7 @@ CISOFileBlockDevice::~CISOFileBlockDevice() bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached) { FileLoader::Flags flags = uncached ? FileLoader::Flags::HINT_UNCACHED : FileLoader::Flags::NONE; - if ((u32)blockNumber >= numBlocks) - { + if ((u32)blockNumber >= numBlocks) { memset(outPtr, 0, GetBlockSize()); return false; } @@ -233,20 +228,19 @@ bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached) const size_t compressedReadSize = (size_t)(compressedReadEnd - compressedReadPos); const u32 compressedOffset = (blockNumber & ((1 << blockShift) - 1)) * GetBlockSize(); - const int plain = idx & 0x80000000; - if (plain) - { + bool plain = (idx & 0x80000000) != 0; + if (ver_ >= 2) { + // CSO v2+ requires blocks be uncompressed if large enough to be. High bit means other things. + plain = compressedReadSize >= frameSize; + } + if (plain) { int readSize = (u32)fileLoader_->ReadAt(compressedReadPos + compressedOffset, 1, GetBlockSize(), outPtr, flags); if (readSize < GetBlockSize()) memset(outPtr + readSize, 0, GetBlockSize() - readSize); - } - else if (zlibBufferFrame == frameNumber) - { + } else if (zlibBufferFrame == frameNumber) { // We already have it. Just apply the offset and copy. memcpy(outPtr, zlibBuffer + compressedOffset, GetBlockSize()); - } - else - { + } else { const u32 readSize = (u32)fileLoader_->ReadAt(compressedReadPos, 1, compressedReadSize, readBuffer, flags); z.zalloc = Z_NULL; diff --git a/Core/FileSystems/BlockDevices.h b/Core/FileSystems/BlockDevices.h index e3b9dc280bb0..6e17aaa4eafe 100644 --- a/Core/FileSystems/BlockDevices.h +++ b/Core/FileSystems/BlockDevices.h @@ -72,6 +72,7 @@ class CISOFileBlockDevice : public BlockDevice { u32 frameSize; u32 numBlocks; u32 numFrames; + int ver_; };