mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 05:47:56 -07:00
Merge pull request #3324 from lioncash/alloc
DiscIO: Get rid of a few explicit deletes
This commit is contained in:
commit
49cd777fce
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -26,35 +27,26 @@ namespace DiscIO
|
|||||||
|
|
||||||
void SectorReader::SetSectorSize(int blocksize)
|
void SectorReader::SetSectorSize(int blocksize)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < CACHE_SIZE; i++)
|
for (auto& cache_entry : m_cache)
|
||||||
{
|
cache_entry.resize(blocksize);
|
||||||
m_cache[i] = new u8[blocksize];
|
|
||||||
m_cache_tags[i] = (u64)(s64) - 1;
|
m_cache_tags.fill(std::numeric_limits<u64>::max());
|
||||||
}
|
|
||||||
m_blocksize = blocksize;
|
m_blocksize = blocksize;
|
||||||
}
|
}
|
||||||
|
|
||||||
SectorReader::~SectorReader()
|
SectorReader::~SectorReader()
|
||||||
{
|
{
|
||||||
for (u8*& block : m_cache)
|
|
||||||
{
|
|
||||||
delete [] block;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const u8 *SectorReader::GetBlockData(u64 block_num)
|
const std::vector<u8>& SectorReader::GetBlockData(u64 block_num)
|
||||||
{
|
{
|
||||||
// TODO : Expand usage of the cache to more than one block :P
|
// TODO : Expand usage of the cache to more than one block :P
|
||||||
if (m_cache_tags[0] == block_num)
|
if (m_cache_tags[0] == block_num)
|
||||||
{
|
|
||||||
return m_cache[0];
|
return m_cache[0];
|
||||||
}
|
|
||||||
else
|
GetBlock(block_num, m_cache[0].data());
|
||||||
{
|
m_cache_tags[0] = block_num;
|
||||||
GetBlock(block_num, m_cache[0]);
|
return m_cache[0];
|
||||||
m_cache_tags[0] = block_num;
|
|
||||||
return m_cache[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SectorReader::Read(u64 offset, u64 size, u8* out_ptr)
|
bool SectorReader::Read(u64 offset, u64 size, u8* out_ptr)
|
||||||
@ -78,22 +70,20 @@ bool SectorReader::Read(u64 offset, u64 size, u8* out_ptr)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const u8* data = GetBlockData(block);
|
const std::vector<u8>& data = GetBlockData(block);
|
||||||
if (!data)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
u32 toCopy = m_blocksize - positionInBlock;
|
u32 to_copy = m_blocksize - positionInBlock;
|
||||||
if (toCopy >= remain)
|
if (to_copy >= remain)
|
||||||
{
|
{
|
||||||
// Yay, we are done!
|
// Yay, we are done!
|
||||||
memcpy(out_ptr, data + positionInBlock, (size_t)remain);
|
std::copy(data.begin() + positionInBlock, data.begin() + positionInBlock + remain, out_ptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(out_ptr, data + positionInBlock, toCopy);
|
std::copy(data.begin() + positionInBlock, data.begin() + positionInBlock + to_copy, out_ptr);
|
||||||
out_ptr += toCopy;
|
out_ptr += to_copy;
|
||||||
remain -= toCopy;
|
remain -= to_copy;
|
||||||
positionInBlock = 0;
|
positionInBlock = 0;
|
||||||
block++;
|
block++;
|
||||||
}
|
}
|
||||||
@ -102,14 +92,14 @@ bool SectorReader::Read(u64 offset, u64 size, u8* out_ptr)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SectorReader::ReadMultipleAlignedBlocks(u64 block_num, u64 num_blocks, u8 *out_ptr)
|
bool SectorReader::ReadMultipleAlignedBlocks(u64 block_num, u64 num_blocks, u8* out_ptr)
|
||||||
{
|
{
|
||||||
for (u64 i = 0; i < num_blocks; i++)
|
for (u64 i = 0; i < num_blocks; i++)
|
||||||
{
|
{
|
||||||
const u8 *data = GetBlockData(block_num + i);
|
const std::vector<u8>& data = GetBlockData(block_num + i);
|
||||||
if (!data)
|
const u64 offset = i * m_blocksize;
|
||||||
return false;
|
|
||||||
memcpy(out_ptr + i * m_blocksize, data, m_blocksize);
|
std::copy(data.begin(), data.end(), out_ptr + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// detect whether the file is a compressed blob, or just a big hunk of data, or a drive, and
|
// detect whether the file is a compressed blob, or just a big hunk of data, or a drive, and
|
||||||
// automatically do the right thing.
|
// automatically do the right thing.
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
@ -57,8 +58,6 @@ class SectorReader : public IBlobReader
|
|||||||
public:
|
public:
|
||||||
virtual ~SectorReader();
|
virtual ~SectorReader();
|
||||||
|
|
||||||
// A pointer returned by GetBlockData is invalidated as soon as GetBlockData, Read, or ReadMultipleAlignedBlocks is called again.
|
|
||||||
const u8 *GetBlockData(u64 block_num);
|
|
||||||
bool Read(u64 offset, u64 size, u8 *out_ptr) override;
|
bool Read(u64 offset, u64 size, u8 *out_ptr) override;
|
||||||
friend class DriveReader;
|
friend class DriveReader;
|
||||||
|
|
||||||
@ -69,10 +68,13 @@ protected:
|
|||||||
virtual bool ReadMultipleAlignedBlocks(u64 block_num, u64 num_blocks, u8 *out_ptr);
|
virtual bool ReadMultipleAlignedBlocks(u64 block_num, u64 num_blocks, u8 *out_ptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// A reference returned by GetBlockData is invalidated as soon as GetBlockData, Read, or ReadMultipleAlignedBlocks is called again.
|
||||||
|
const std::vector<u8>& GetBlockData(u64 block_num);
|
||||||
|
|
||||||
enum { CACHE_SIZE = 32 };
|
enum { CACHE_SIZE = 32 };
|
||||||
int m_blocksize;
|
int m_blocksize;
|
||||||
u8* m_cache[CACHE_SIZE];
|
std::array<std::vector<u8>, CACHE_SIZE> m_cache;
|
||||||
u64 m_cache_tags[CACHE_SIZE];
|
std::array<u64, CACHE_SIZE> m_cache_tags;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Factory function - examines the path to choose the right type of IBlobReader, and returns one.
|
// Factory function - examines the path to choose the right type of IBlobReader, and returns one.
|
||||||
|
@ -39,10 +39,10 @@ CompressedBlobReader::CompressedBlobReader(const std::string& filename) : m_file
|
|||||||
SetSectorSize(m_header.block_size);
|
SetSectorSize(m_header.block_size);
|
||||||
|
|
||||||
// cache block pointers and hashes
|
// cache block pointers and hashes
|
||||||
m_block_pointers = new u64[m_header.num_blocks];
|
m_block_pointers.resize(m_header.num_blocks);
|
||||||
m_file.ReadArray(m_block_pointers, m_header.num_blocks);
|
m_file.ReadArray(m_block_pointers.data(), m_header.num_blocks);
|
||||||
m_hashes = new u32[m_header.num_blocks];
|
m_hashes.resize(m_header.num_blocks);
|
||||||
m_file.ReadArray(m_hashes, m_header.num_blocks);
|
m_file.ReadArray(m_hashes.data(), m_header.num_blocks);
|
||||||
|
|
||||||
m_data_offset = (sizeof(CompressedBlobHeader))
|
m_data_offset = (sizeof(CompressedBlobHeader))
|
||||||
+ (sizeof(u64)) * m_header.num_blocks // skip block pointers
|
+ (sizeof(u64)) * m_header.num_blocks // skip block pointers
|
||||||
@ -50,9 +50,8 @@ CompressedBlobReader::CompressedBlobReader(const std::string& filename) : m_file
|
|||||||
|
|
||||||
// A compressed block is never ever longer than a decompressed block, so just header.block_size should be fine.
|
// A compressed block is never ever longer than a decompressed block, so just header.block_size should be fine.
|
||||||
// I still add some safety margin.
|
// I still add some safety margin.
|
||||||
m_zlib_buffer_size = m_header.block_size + 64;
|
const u32 zlib_buffer_size = m_header.block_size + 64;
|
||||||
m_zlib_buffer = new u8[m_zlib_buffer_size];
|
m_zlib_buffer.resize(zlib_buffer_size);
|
||||||
memset(m_zlib_buffer, 0, m_zlib_buffer_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<CompressedBlobReader> CompressedBlobReader::Create(const std::string& filename)
|
std::unique_ptr<CompressedBlobReader> CompressedBlobReader::Create(const std::string& filename)
|
||||||
@ -65,9 +64,6 @@ std::unique_ptr<CompressedBlobReader> CompressedBlobReader::Create(const std::st
|
|||||||
|
|
||||||
CompressedBlobReader::~CompressedBlobReader()
|
CompressedBlobReader::~CompressedBlobReader()
|
||||||
{
|
{
|
||||||
delete [] m_zlib_buffer;
|
|
||||||
delete [] m_block_pointers;
|
|
||||||
delete [] m_hashes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IMPORTANT: Calling this function invalidates all earlier pointers gotten from this function.
|
// IMPORTANT: Calling this function invalidates all earlier pointers gotten from this function.
|
||||||
@ -98,16 +94,13 @@ void CompressedBlobReader::GetBlock(u64 block_num, u8 *out_ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// clear unused part of zlib buffer. maybe this can be deleted when it works fully.
|
// clear unused part of zlib buffer. maybe this can be deleted when it works fully.
|
||||||
memset(m_zlib_buffer + comp_block_size, 0, m_zlib_buffer_size - comp_block_size);
|
memset(&m_zlib_buffer[comp_block_size], 0, m_zlib_buffer.size() - comp_block_size);
|
||||||
|
|
||||||
m_file.Seek(offset, SEEK_SET);
|
m_file.Seek(offset, SEEK_SET);
|
||||||
m_file.ReadBytes(m_zlib_buffer, comp_block_size);
|
m_file.ReadBytes(m_zlib_buffer.data(), comp_block_size);
|
||||||
|
|
||||||
u8* source = m_zlib_buffer;
|
|
||||||
u8* dest = out_ptr;
|
|
||||||
|
|
||||||
// First, check hash.
|
// First, check hash.
|
||||||
u32 block_hash = HashAdler32(source, comp_block_size);
|
u32 block_hash = HashAdler32(m_zlib_buffer.data(), comp_block_size);
|
||||||
if (block_hash != m_hashes[block_num])
|
if (block_hash != m_hashes[block_num])
|
||||||
PanicAlertT("The disc image \"%s\" is corrupt.\n"
|
PanicAlertT("The disc image \"%s\" is corrupt.\n"
|
||||||
"Hash of block %" PRIu64 " is %08x instead of %08x.",
|
"Hash of block %" PRIu64 " is %08x instead of %08x.",
|
||||||
@ -116,19 +109,18 @@ void CompressedBlobReader::GetBlock(u64 block_num, u8 *out_ptr)
|
|||||||
|
|
||||||
if (uncompressed)
|
if (uncompressed)
|
||||||
{
|
{
|
||||||
memcpy(dest, source, comp_block_size);
|
std::copy(m_zlib_buffer.begin(), m_zlib_buffer.begin() + comp_block_size, out_ptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
z_stream z;
|
z_stream z = {};
|
||||||
memset(&z, 0, sizeof(z));
|
z.next_in = m_zlib_buffer.data();
|
||||||
z.next_in = source;
|
|
||||||
z.avail_in = comp_block_size;
|
z.avail_in = comp_block_size;
|
||||||
if (z.avail_in > m_header.block_size)
|
if (z.avail_in > m_header.block_size)
|
||||||
{
|
{
|
||||||
PanicAlert("We have a problem");
|
PanicAlert("We have a problem");
|
||||||
}
|
}
|
||||||
z.next_out = dest;
|
z.next_out = out_ptr;
|
||||||
z.avail_out = m_header.block_size;
|
z.avail_out = m_header.block_size;
|
||||||
inflateInit(&z);
|
inflateInit(&z);
|
||||||
int status = inflate(&z, Z_FULL_FLUSH);
|
int status = inflate(&z, Z_FULL_FLUSH);
|
||||||
@ -201,10 +193,10 @@ bool CompressFileToBlob(const std::string& infile, const std::string& outfile, u
|
|||||||
// round upwards!
|
// round upwards!
|
||||||
header.num_blocks = (u32)((header.data_size + (block_size - 1)) / block_size);
|
header.num_blocks = (u32)((header.data_size + (block_size - 1)) / block_size);
|
||||||
|
|
||||||
u64* offsets = new u64[header.num_blocks];
|
std::vector<u64> offsets(header.num_blocks);
|
||||||
u32* hashes = new u32[header.num_blocks];
|
std::vector<u32> hashes(header.num_blocks);
|
||||||
u8* out_buf = new u8[block_size];
|
std::vector<u8> out_buf(block_size);
|
||||||
u8* in_buf = new u8[block_size];
|
std::vector<u8> in_buf(block_size);
|
||||||
|
|
||||||
// seek past the header (we will write it at the end)
|
// seek past the header (we will write it at the end)
|
||||||
f.Seek(sizeof(CompressedBlobHeader), SEEK_CUR);
|
f.Seek(sizeof(CompressedBlobHeader), SEEK_CUR);
|
||||||
@ -240,16 +232,16 @@ bool CompressFileToBlob(const std::string& infile, const std::string& outfile, u
|
|||||||
|
|
||||||
size_t read_bytes;
|
size_t read_bytes;
|
||||||
if (scrubbing)
|
if (scrubbing)
|
||||||
read_bytes = DiscScrubber::GetNextBlock(inf, in_buf);
|
read_bytes = DiscScrubber::GetNextBlock(inf, in_buf.data());
|
||||||
else
|
else
|
||||||
inf.ReadArray(in_buf, header.block_size, &read_bytes);
|
inf.ReadArray(in_buf.data(), header.block_size, &read_bytes);
|
||||||
if (read_bytes < header.block_size)
|
if (read_bytes < header.block_size)
|
||||||
std::fill(in_buf + read_bytes, in_buf + header.block_size, 0);
|
std::fill(in_buf.begin() + read_bytes, in_buf.begin() + header.block_size, 0);
|
||||||
|
|
||||||
int retval = deflateReset(&z);
|
int retval = deflateReset(&z);
|
||||||
z.next_in = in_buf;
|
z.next_in = in_buf.data();
|
||||||
z.avail_in = header.block_size;
|
z.avail_in = header.block_size;
|
||||||
z.next_out = out_buf;
|
z.next_out = out_buf.data();
|
||||||
z.avail_out = block_size;
|
z.avail_out = block_size;
|
||||||
|
|
||||||
if (retval != Z_OK)
|
if (retval != Z_OK)
|
||||||
@ -268,7 +260,7 @@ bool CompressFileToBlob(const std::string& infile, const std::string& outfile, u
|
|||||||
{
|
{
|
||||||
//PanicAlert("%i %i Store %i", i*block_size, position, comp_size);
|
//PanicAlert("%i %i Store %i", i*block_size, position, comp_size);
|
||||||
// let's store uncompressed
|
// let's store uncompressed
|
||||||
write_buf = in_buf;
|
write_buf = in_buf.data();
|
||||||
offsets[i] |= 0x8000000000000000ULL;
|
offsets[i] |= 0x8000000000000000ULL;
|
||||||
write_size = block_size;
|
write_size = block_size;
|
||||||
num_stored++;
|
num_stored++;
|
||||||
@ -277,7 +269,7 @@ bool CompressFileToBlob(const std::string& infile, const std::string& outfile, u
|
|||||||
{
|
{
|
||||||
// let's store compressed
|
// let's store compressed
|
||||||
//PanicAlert("Comp %i to %i", block_size, comp_size);
|
//PanicAlert("Comp %i to %i", block_size, comp_size);
|
||||||
write_buf = out_buf;
|
write_buf = out_buf.data();
|
||||||
write_size = comp_size;
|
write_size = comp_size;
|
||||||
num_compressed++;
|
num_compressed++;
|
||||||
}
|
}
|
||||||
@ -310,16 +302,11 @@ bool CompressFileToBlob(const std::string& infile, const std::string& outfile, u
|
|||||||
// Okay, go back and fill in headers
|
// Okay, go back and fill in headers
|
||||||
f.Seek(0, SEEK_SET);
|
f.Seek(0, SEEK_SET);
|
||||||
f.WriteArray(&header, 1);
|
f.WriteArray(&header, 1);
|
||||||
f.WriteArray(offsets, header.num_blocks);
|
f.WriteArray(offsets.data(), header.num_blocks);
|
||||||
f.WriteArray(hashes, header.num_blocks);
|
f.WriteArray(hashes.data(), header.num_blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
delete[] in_buf;
|
|
||||||
delete[] out_buf;
|
|
||||||
delete[] offsets;
|
|
||||||
delete[] hashes;
|
|
||||||
|
|
||||||
deflateEnd(&z);
|
deflateEnd(&z);
|
||||||
DiscScrubber::Cleanup();
|
DiscScrubber::Cleanup();
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/FileUtil.h"
|
#include "Common/FileUtil.h"
|
||||||
@ -59,13 +60,12 @@ private:
|
|||||||
CompressedBlobReader(const std::string& filename);
|
CompressedBlobReader(const std::string& filename);
|
||||||
|
|
||||||
CompressedBlobHeader m_header;
|
CompressedBlobHeader m_header;
|
||||||
u64* m_block_pointers;
|
std::vector<u64> m_block_pointers;
|
||||||
u32* m_hashes;
|
std::vector<u32> m_hashes;
|
||||||
int m_data_offset;
|
int m_data_offset;
|
||||||
File::IOFile m_file;
|
File::IOFile m_file;
|
||||||
u64 m_file_size;
|
u64 m_file_size;
|
||||||
u8* m_zlib_buffer;
|
std::vector<u8> m_zlib_buffer;
|
||||||
int m_zlib_buffer_size;
|
|
||||||
std::string m_file_name;
|
std::string m_file_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
// Licensed under GPLv2+
|
// Licensed under GPLv2+
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/FileUtil.h"
|
#include "Common/FileUtil.h"
|
||||||
@ -33,16 +35,14 @@ DriveReader::DriveReader(const std::string& drive)
|
|||||||
// Do a test read to make sure everything is OK, since it seems you can get
|
// Do a test read to make sure everything is OK, since it seems you can get
|
||||||
// handles to empty drives.
|
// handles to empty drives.
|
||||||
DWORD not_used;
|
DWORD not_used;
|
||||||
u8 *buffer = new u8[m_blocksize];
|
std::vector<u8> buffer(m_blocksize);
|
||||||
if (!ReadFile(m_disc_handle, buffer, m_blocksize, (LPDWORD)¬_used, nullptr))
|
if (!ReadFile(m_disc_handle, buffer.data(), m_blocksize, ¬_used, nullptr))
|
||||||
{
|
{
|
||||||
delete [] buffer;
|
|
||||||
// OK, something is wrong.
|
// OK, something is wrong.
|
||||||
CloseHandle(m_disc_handle);
|
CloseHandle(m_disc_handle);
|
||||||
m_disc_handle = INVALID_HANDLE_VALUE;
|
m_disc_handle = INVALID_HANDLE_VALUE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
delete [] buffer;
|
|
||||||
|
|
||||||
#ifdef _LOCKDRIVE // Do we want to lock the drive?
|
#ifdef _LOCKDRIVE // Do we want to lock the drive?
|
||||||
// Lock the compact disc in the CD-ROM drive to prevent accidental
|
// Lock the compact disc in the CD-ROM drive to prevent accidental
|
||||||
@ -97,32 +97,33 @@ std::unique_ptr<DriveReader> DriveReader::Create(const std::string& drive)
|
|||||||
|
|
||||||
void DriveReader::GetBlock(u64 block_num, u8* out_ptr)
|
void DriveReader::GetBlock(u64 block_num, u8* out_ptr)
|
||||||
{
|
{
|
||||||
u8* const lpSector = new u8[m_blocksize];
|
std::vector<u8> sector(m_blocksize);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
u32 NotUsed;
|
|
||||||
u64 offset = m_blocksize * block_num;
|
u64 offset = m_blocksize * block_num;
|
||||||
LONG off_low = (LONG)offset & 0xFFFFFFFF;
|
LONG off_low = (LONG)offset & 0xFFFFFFFF;
|
||||||
LONG off_high = (LONG)(offset >> 32);
|
LONG off_high = (LONG)(offset >> 32);
|
||||||
|
DWORD not_used;
|
||||||
SetFilePointer(m_disc_handle, off_low, &off_high, FILE_BEGIN);
|
SetFilePointer(m_disc_handle, off_low, &off_high, FILE_BEGIN);
|
||||||
if (!ReadFile(m_disc_handle, lpSector, m_blocksize, (LPDWORD)&NotUsed, nullptr))
|
if (!ReadFile(m_disc_handle, sector.data(), m_blocksize, ¬_used, nullptr))
|
||||||
PanicAlertT("Disc Read Error");
|
PanicAlertT("Disc Read Error");
|
||||||
#else
|
#else
|
||||||
m_file.Seek(m_blocksize * block_num, SEEK_SET);
|
m_file.Seek(m_blocksize * block_num, SEEK_SET);
|
||||||
m_file.ReadBytes(lpSector, m_blocksize);
|
m_file.ReadBytes(sector.data(), m_blocksize);
|
||||||
#endif
|
#endif
|
||||||
memcpy(out_ptr, lpSector, m_blocksize);
|
|
||||||
delete[] lpSector;
|
std::copy(sector.begin(), sector.end(), out_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DriveReader::ReadMultipleAlignedBlocks(u64 block_num, u64 num_blocks, u8* out_ptr)
|
bool DriveReader::ReadMultipleAlignedBlocks(u64 block_num, u64 num_blocks, u8* out_ptr)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
u32 NotUsed;
|
|
||||||
u64 offset = m_blocksize * block_num;
|
u64 offset = m_blocksize * block_num;
|
||||||
LONG off_low = (LONG)offset & 0xFFFFFFFF;
|
LONG off_low = (LONG)offset & 0xFFFFFFFF;
|
||||||
LONG off_high = (LONG)(offset >> 32);
|
LONG off_high = (LONG)(offset >> 32);
|
||||||
|
DWORD not_used;
|
||||||
SetFilePointer(m_disc_handle, off_low, &off_high, FILE_BEGIN);
|
SetFilePointer(m_disc_handle, off_low, &off_high, FILE_BEGIN);
|
||||||
if (!ReadFile(m_disc_handle, out_ptr, (DWORD)(m_blocksize * num_blocks), (LPDWORD)&NotUsed, nullptr))
|
if (!ReadFile(m_disc_handle, out_ptr, (DWORD)(m_blocksize * num_blocks), ¬_used, nullptr))
|
||||||
{
|
{
|
||||||
PanicAlertT("Disc Read Error");
|
PanicAlertT("Disc Read Error");
|
||||||
return false;
|
return false;
|
||||||
|
@ -28,11 +28,10 @@ public:
|
|||||||
u64 GetDataSize() const override { return m_size; }
|
u64 GetDataSize() const override { return m_size; }
|
||||||
u64 GetRawSize() const override { return m_size; }
|
u64 GetRawSize() const override { return m_size; }
|
||||||
|
|
||||||
bool ReadMultipleAlignedBlocks(u64 block_num, u64 num_blocks, u8 *out_ptr) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DriveReader(const std::string& drive);
|
DriveReader(const std::string& drive);
|
||||||
void GetBlock(u64 block_num, u8 *out_ptr) override;
|
void GetBlock(u64 block_num, u8 *out_ptr) override;
|
||||||
|
bool ReadMultipleAlignedBlocks(u64 block_num, u64 num_blocks, u8* out_ptr) override;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
HANDLE m_disc_handle;
|
HANDLE m_disc_handle;
|
||||||
|
@ -29,7 +29,7 @@ CVolumeDirectory::CVolumeDirectory(const std::string& _rDirectory, bool _bIsWii,
|
|||||||
: m_totalNameSize(0)
|
: m_totalNameSize(0)
|
||||||
, m_dataStartAddress(-1)
|
, m_dataStartAddress(-1)
|
||||||
, m_diskHeader(DISKHEADERINFO_ADDRESS)
|
, m_diskHeader(DISKHEADERINFO_ADDRESS)
|
||||||
, m_diskHeaderInfo(new SDiskHeaderInfo())
|
, m_diskHeaderInfo(std::make_unique<SDiskHeaderInfo>())
|
||||||
, m_fst_address(0)
|
, m_fst_address(0)
|
||||||
, m_dol_address(0)
|
, m_dol_address(0)
|
||||||
{
|
{
|
||||||
|
@ -30,14 +30,12 @@ namespace DiscIO
|
|||||||
CVolumeWiiCrypted::CVolumeWiiCrypted(std::unique_ptr<IBlobReader> reader, u64 _VolumeOffset,
|
CVolumeWiiCrypted::CVolumeWiiCrypted(std::unique_ptr<IBlobReader> reader, u64 _VolumeOffset,
|
||||||
const unsigned char* _pVolumeKey)
|
const unsigned char* _pVolumeKey)
|
||||||
: m_pReader(std::move(reader)),
|
: m_pReader(std::move(reader)),
|
||||||
m_AES_ctx(new mbedtls_aes_context),
|
m_AES_ctx(std::make_unique<mbedtls_aes_context>()),
|
||||||
m_pBuffer(nullptr),
|
|
||||||
m_VolumeOffset(_VolumeOffset),
|
m_VolumeOffset(_VolumeOffset),
|
||||||
m_dataOffset(0x20000),
|
m_dataOffset(0x20000),
|
||||||
m_LastDecryptedBlockOffset(-1)
|
m_LastDecryptedBlockOffset(-1)
|
||||||
{
|
{
|
||||||
mbedtls_aes_setkey_dec(m_AES_ctx.get(), _pVolumeKey, 128);
|
mbedtls_aes_setkey_dec(m_AES_ctx.get(), _pVolumeKey, 128);
|
||||||
m_pBuffer = new u8[s_block_total_size];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CVolumeWiiCrypted::ChangePartition(u64 offset)
|
bool CVolumeWiiCrypted::ChangePartition(u64 offset)
|
||||||
@ -53,8 +51,6 @@ bool CVolumeWiiCrypted::ChangePartition(u64 offset)
|
|||||||
|
|
||||||
CVolumeWiiCrypted::~CVolumeWiiCrypted()
|
CVolumeWiiCrypted::~CVolumeWiiCrypted()
|
||||||
{
|
{
|
||||||
delete[] m_pBuffer;
|
|
||||||
m_pBuffer = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CVolumeWiiCrypted::Read(u64 _ReadOffset, u64 _Length, u8* _pBuffer, bool decrypt) const
|
bool CVolumeWiiCrypted::Read(u64 _ReadOffset, u64 _Length, u8* _pBuffer, bool decrypt) const
|
||||||
@ -67,6 +63,7 @@ bool CVolumeWiiCrypted::Read(u64 _ReadOffset, u64 _Length, u8* _pBuffer, bool de
|
|||||||
|
|
||||||
FileMon::FindFilename(_ReadOffset);
|
FileMon::FindFilename(_ReadOffset);
|
||||||
|
|
||||||
|
std::vector<u8> read_buffer(s_block_total_size);
|
||||||
while (_Length > 0)
|
while (_Length > 0)
|
||||||
{
|
{
|
||||||
// Calculate block offset
|
// Calculate block offset
|
||||||
@ -76,15 +73,15 @@ bool CVolumeWiiCrypted::Read(u64 _ReadOffset, u64 _Length, u8* _pBuffer, bool de
|
|||||||
if (m_LastDecryptedBlockOffset != Block)
|
if (m_LastDecryptedBlockOffset != Block)
|
||||||
{
|
{
|
||||||
// Read the current block
|
// Read the current block
|
||||||
if (!m_pReader->Read(m_VolumeOffset + m_dataOffset + Block * s_block_total_size, s_block_total_size, m_pBuffer))
|
if (!m_pReader->Read(m_VolumeOffset + m_dataOffset + Block * s_block_total_size, s_block_total_size, read_buffer.data()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Decrypt the block's data.
|
// Decrypt the block's data.
|
||||||
// 0x3D0 - 0x3DF in m_pBuffer will be overwritten,
|
// 0x3D0 - 0x3DF in m_pBuffer will be overwritten,
|
||||||
// but that won't affect anything, because we won't
|
// but that won't affect anything, because we won't
|
||||||
// use the content of m_pBuffer anymore after this
|
// use the content of m_pBuffer anymore after this
|
||||||
mbedtls_aes_crypt_cbc(m_AES_ctx.get(), MBEDTLS_AES_DECRYPT, s_block_data_size, m_pBuffer + 0x3D0,
|
mbedtls_aes_crypt_cbc(m_AES_ctx.get(), MBEDTLS_AES_DECRYPT, s_block_data_size, &read_buffer[0x3D0],
|
||||||
m_pBuffer + s_block_header_size, m_LastDecryptedBlock);
|
&read_buffer[s_block_header_size], m_LastDecryptedBlock);
|
||||||
m_LastDecryptedBlockOffset = Block;
|
m_LastDecryptedBlockOffset = Block;
|
||||||
|
|
||||||
// The only thing we currently use from the 0x000 - 0x3FF part
|
// The only thing we currently use from the 0x000 - 0x3FF part
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
|
||||||
#include <mbedtls/aes.h>
|
#include <mbedtls/aes.h>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
@ -46,8 +45,6 @@ public:
|
|||||||
u64 GetSize() const override;
|
u64 GetSize() const override;
|
||||||
u64 GetRawSize() const override;
|
u64 GetRawSize() const override;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const unsigned int s_block_header_size = 0x0400;
|
static const unsigned int s_block_header_size = 0x0400;
|
||||||
static const unsigned int s_block_data_size = 0x7C00;
|
static const unsigned int s_block_data_size = 0x7C00;
|
||||||
@ -56,8 +53,6 @@ private:
|
|||||||
std::unique_ptr<IBlobReader> m_pReader;
|
std::unique_ptr<IBlobReader> m_pReader;
|
||||||
std::unique_ptr<mbedtls_aes_context> m_AES_ctx;
|
std::unique_ptr<mbedtls_aes_context> m_AES_ctx;
|
||||||
|
|
||||||
u8* m_pBuffer;
|
|
||||||
|
|
||||||
u64 m_VolumeOffset;
|
u64 m_VolumeOffset;
|
||||||
u64 m_dataOffset;
|
u64 m_dataOffset;
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ static inline u64 align(u64 value, u64 bounds)
|
|||||||
}
|
}
|
||||||
|
|
||||||
WbfsFileReader::WbfsFileReader(const std::string& filename)
|
WbfsFileReader::WbfsFileReader(const std::string& filename)
|
||||||
: m_total_files(0), m_size(0), m_wlba_table(nullptr), m_good(true)
|
: m_total_files(0), m_size(0), m_good(true)
|
||||||
{
|
{
|
||||||
if (filename.length() < 4 || !OpenFiles(filename) || !ReadHeader())
|
if (filename.length() < 4 || !OpenFiles(filename) || !ReadHeader())
|
||||||
{
|
{
|
||||||
@ -37,19 +37,15 @@ WbfsFileReader::WbfsFileReader(const std::string& filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Grab disc info (assume slot 0, checked in ReadHeader())
|
// Grab disc info (assume slot 0, checked in ReadHeader())
|
||||||
m_wlba_table = new u16[m_blocks_per_disc];
|
m_wlba_table.resize(m_blocks_per_disc);
|
||||||
m_files[0]->file.Seek(m_hd_sector_size + WII_DISC_HEADER_SIZE /*+ i * m_disc_info_size*/, SEEK_SET);
|
m_files[0]->file.Seek(m_hd_sector_size + WII_DISC_HEADER_SIZE /*+ i * m_disc_info_size*/, SEEK_SET);
|
||||||
m_files[0]->file.ReadBytes(m_wlba_table, m_blocks_per_disc * sizeof(u16));
|
m_files[0]->file.ReadBytes(m_wlba_table.data(), m_blocks_per_disc * sizeof(u16));
|
||||||
for (size_t i = 0; i < m_blocks_per_disc; i++)
|
for (size_t i = 0; i < m_blocks_per_disc; i++)
|
||||||
m_wlba_table[i] = Common::swap16(m_wlba_table[i]);
|
m_wlba_table[i] = Common::swap16(m_wlba_table[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
WbfsFileReader::~WbfsFileReader()
|
WbfsFileReader::~WbfsFileReader()
|
||||||
{
|
{
|
||||||
for (file_entry* entry : m_files)
|
|
||||||
delete entry;
|
|
||||||
|
|
||||||
delete[] m_wlba_table;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 WbfsFileReader::GetDataSize() const
|
u64 WbfsFileReader::GetDataSize() const
|
||||||
@ -63,7 +59,7 @@ bool WbfsFileReader::OpenFiles(const std::string& filename)
|
|||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
file_entry* new_entry = new file_entry;
|
auto new_entry = std::make_unique<file_entry>();
|
||||||
|
|
||||||
// Replace last character with index (e.g. wbfs = wbf1)
|
// Replace last character with index (e.g. wbfs = wbf1)
|
||||||
std::string path = filename;
|
std::string path = filename;
|
||||||
@ -74,8 +70,7 @@ bool WbfsFileReader::OpenFiles(const std::string& filename)
|
|||||||
|
|
||||||
if (!new_entry->file.Open(path, "rb"))
|
if (!new_entry->file.Open(path, "rb"))
|
||||||
{
|
{
|
||||||
delete new_entry;
|
return m_total_files != 0;
|
||||||
return 0 != m_total_files;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
new_entry->base_address = m_size;
|
new_entry->base_address = m_size;
|
||||||
@ -83,7 +78,7 @@ bool WbfsFileReader::OpenFiles(const std::string& filename)
|
|||||||
m_size += new_entry->size;
|
m_size += new_entry->size;
|
||||||
|
|
||||||
m_total_files++;
|
m_total_files++;
|
||||||
m_files.push_back(new_entry);
|
m_files.emplace_back(std::move(new_entry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ private:
|
|||||||
u64 size;
|
u64 size;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<file_entry*> m_files;
|
std::vector<std::unique_ptr<file_entry>> m_files;
|
||||||
|
|
||||||
u32 m_total_files;
|
u32 m_total_files;
|
||||||
u64 m_size;
|
u64 m_size;
|
||||||
@ -71,7 +71,7 @@ private:
|
|||||||
} m_header;
|
} m_header;
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
u16* m_wlba_table;
|
std::vector<u16> m_wlba_table;
|
||||||
u64 m_blocks_per_disc;
|
u64 m_blocks_per_disc;
|
||||||
|
|
||||||
bool m_good;
|
bool m_good;
|
||||||
|
Loading…
Reference in New Issue
Block a user