Replace (u8*) with (void*) where applicable

... also changes sector0x96 workaround to OTP encrypt method
This commit is contained in:
d0k3 2017-06-01 15:11:41 +02:00
parent c9abc77348
commit 7bbaf17b42
35 changed files with 159 additions and 152 deletions

View File

@ -7,7 +7,7 @@ static u32 mount_state = 0;
static char mount_path[256] = { 0 };
int ReadImageBytes(u8* buffer, u64 offset, u64 count) {
int ReadImageBytes(void* buffer, u64 offset, u64 count) {
UINT bytes_read;
UINT ret;
if (!count) return -1;
@ -20,7 +20,7 @@ int ReadImageBytes(u8* buffer, u64 offset, u64 count) {
return (ret != 0) ? (int) ret : (bytes_read != count) ? -1 : 0;
}
int WriteImageBytes(const u8* buffer, u64 offset, u64 count) {
int WriteImageBytes(const void* buffer, u64 offset, u64 count) {
UINT bytes_written;
UINT ret;
if (!count) return -1;
@ -31,11 +31,11 @@ int WriteImageBytes(const u8* buffer, u64 offset, u64 count) {
return (ret != 0) ? (int) ret : (bytes_written != count) ? -1 : 0;
}
int ReadImageSectors(u8* buffer, u32 sector, u32 count) {
int ReadImageSectors(void* buffer, u32 sector, u32 count) {
return ReadImageBytes(buffer, sector * 0x200, count * 0x200);
}
int WriteImageSectors(const u8* buffer, u32 sector, u32 count) {
int WriteImageSectors(const void* buffer, u32 sector, u32 count) {
return WriteImageBytes(buffer, sector * 0x200, count * 0x200);
}

View File

@ -3,10 +3,10 @@
#include "common.h"
#include "filetype.h"
int ReadImageBytes(u8* buffer, u64 offset, u64 count);
int WriteImageBytes(const u8* buffer, u64 offset, u64 count);
int ReadImageSectors(u8* buffer, u32 sector, u32 count);
int WriteImageSectors(const u8* buffer, u32 sector, u32 count);
int ReadImageBytes(void* buffer, u64 offset, u64 count);
int WriteImageBytes(const void* buffer, u64 offset, u64 count);
int ReadImageSectors(void* buffer, u32 sector, u32 count);
int WriteImageSectors(const void* buffer, u32 sector, u32 count);
int SyncImage(void);
u64 GetMountSize(void);

View File

@ -4,7 +4,7 @@
static u8* ramdrv_buffer = NULL;
static u32 ramdrv_size = 0;
int ReadRamDriveSectors(u8* buffer, u32 sector, u32 count) {
int ReadRamDriveSectors(void* buffer, u32 sector, u32 count) {
u64 offset = sector * 0x200;
u64 btr = count * 0x200;
if (!ramdrv_buffer) return -1;
@ -12,7 +12,7 @@ int ReadRamDriveSectors(u8* buffer, u32 sector, u32 count) {
memcpy(buffer, ramdrv_buffer + offset, btr);
return 0;
}
int WriteRamDriveSectors(const u8* buffer, u32 sector, u32 count) {
int WriteRamDriveSectors(const void* buffer, u32 sector, u32 count) {
u64 offset = sector * 0x200;
u64 btw = count * 0x200;
if (!ramdrv_buffer) return -1;
@ -28,4 +28,4 @@ u64 GetRamDriveSize(void) {
void InitRamDrive(void) {
ramdrv_buffer = RAMDRV_BUFFER;
ramdrv_size = (IS_O3DS || IS_SIGHAX) ? RAMDRV_SIZE_O3DS : RAMDRV_SIZE_N3DS;
}
}

View File

@ -2,7 +2,7 @@
#include "common.h"
int ReadRamDriveSectors(u8* buffer, u32 sector, u32 count);
int WriteRamDriveSectors(const u8* buffer, u32 sector, u32 count);
int ReadRamDriveSectors(void* buffer, u32 sector, u32 count);
int WriteRamDriveSectors(const void* buffer, u32 sector, u32 count);
u64 GetRamDriveSize(void);
void InitRamDrive(void);

View File

@ -101,9 +101,7 @@ u32 IdentifyFileType(const char* path) {
return BIN_KEYDB; // key database
} else if ((sscanf(fname, "slot%02lXKey", &id) == 1) && (strncasecmp(ext, "bin", 4) == 0) && (fsize = 16) && (id < 0x40)) {
return BIN_LEGKEY; // legacy key file
} else if ((strncasecmp(fname, OTP_NAME, sizeof(OTP_NAME)) == 0) ||
(strncasecmp(fname, OTP_BIG_NAME, sizeof(OTP_BIG_NAME)) == 0) ||
(strncasecmp(fname, SEEDDB_NAME, sizeof(SEEDDB_NAME)) == 0) ||
} else if ((strncasecmp(fname, SEEDDB_NAME, sizeof(SEEDDB_NAME)) == 0) ||
(strncasecmp(fname, SECTOR_NAME, sizeof(SECTOR_NAME)) == 0) ||
(strncasecmp(fname, SECRET_NAME, sizeof(SECRET_NAME)) == 0)) {
return BIN_SUPPORT; // known support file (so launching is not offered)

View File

@ -51,11 +51,11 @@ u32 CheckBossEncrypted(BossHeader* boss) {
}
// on the fly de-/encryptor for BOSS
u32 CryptBoss(u8* data, u32 offset, u32 size, BossHeader* boss) {
u32 CryptBoss(void* data, u32 offset, u32 size, BossHeader* boss) {
// check data area (encrypted area starts @0x28)
if (offset + size < 0x28) return 0;
else if (offset < 0x28) {
data += 0x28 - offset;
data = ((u8*)data + 0x28 - offset);
size -= 0x28 - offset;
offset = 0x28;
}
@ -71,7 +71,7 @@ u32 CryptBoss(u8* data, u32 offset, u32 size, BossHeader* boss) {
}
// on the fly de-/encryptor for BOSS - sequential
u32 CryptBossSequential(u8* data, u32 offset, u32 size) {
u32 CryptBossSequential(void* data, u32 offset, u32 size) {
// warning: this will only work for sequential processing
// unexpected results otherwise
static BossHeader boss = { 0 };

View File

@ -40,5 +40,5 @@ typedef struct {
u32 ValidateBossHeader(BossHeader* header, u32 fsize);
u32 GetBossPayloadHashHeader(u8* header, BossHeader* boss);
u32 CheckBossEncrypted(BossHeader* boss);
u32 CryptBoss(u8* data, u32 offset, u32 size, BossHeader* boss);
u32 CryptBossSequential(u8* data, u32 offset, u32 size);
u32 CryptBoss(void* data, u32 offset, u32 size, BossHeader* boss);
u32 CryptBossSequential(void* data, u32 offset, u32 size);

View File

@ -107,7 +107,7 @@ u32 BuildCiaHeader(CiaHeader* header) {
return 0;
}
u32 DecryptCiaContentSequential(u8* data, u32 size, u8* ctr, const u8* titlekey) {
u32 DecryptCiaContentSequential(void* data, u32 size, u8* ctr, const u8* titlekey) {
// WARNING: size and offset of data have to be a multiple of 16
u8 tik[16] __attribute__((aligned(32)));
u32 mode = AES_CNT_TITLEKEY_DECRYPT_MODE;
@ -118,7 +118,7 @@ u32 DecryptCiaContentSequential(u8* data, u32 size, u8* ctr, const u8* titlekey)
return 0;
}
u32 EncryptCiaContentSequential(u8* data, u32 size, u8* ctr, const u8* titlekey) {
u32 EncryptCiaContentSequential(void* data, u32 size, u8* ctr, const u8* titlekey) {
// WARNING: size and offset of data have to be a multiple of 16
u8 tik[16] __attribute__((aligned(32)));
u32 mode = AES_CNT_TITLEKEY_ENCRYPT_MODE;

View File

@ -68,5 +68,5 @@ u32 BuildCiaCert(u8* ciacert);
u32 BuildCiaMeta(CiaMeta* meta, void* exthdr, void* smdh);
u32 BuildCiaHeader(CiaHeader* header);
u32 DecryptCiaContentSequential(u8* data, u32 size, u8* ctr, const u8* titlekey);
u32 EncryptCiaContentSequential(u8* data, u32 size, u8* ctr, const u8* titlekey);
u32 DecryptCiaContentSequential(void* data, u32 size, u8* ctr, const u8* titlekey);
u32 EncryptCiaContentSequential(void* data, u32 size, u8* ctr, const u8* titlekey);

View File

@ -120,7 +120,7 @@ u32 SetupArm9BinaryCrypto(FirmA9LHeader* header) {
return 0;
}
u32 DecryptArm9Binary(u8* data, u32 offset, u32 size, FirmA9LHeader* a9l) {
u32 DecryptArm9Binary(void* data, u32 offset, u32 size, FirmA9LHeader* a9l) {
// offset == offset inside ARM9 binary
// ARM9 binary begins 0x800 byte after the ARM9 loader header
@ -137,7 +137,7 @@ u32 DecryptArm9Binary(u8* data, u32 offset, u32 size, FirmA9LHeader* a9l) {
return 0;
}
u32 DecryptFirm(u8* data, u32 offset, u32 size, FirmHeader* firm, FirmA9LHeader* a9l) {
u32 DecryptFirm(void* data, u32 offset, u32 size, FirmHeader* firm, FirmA9LHeader* a9l) {
// ARM9 binary size / offset
FirmSectionHeader* arm9s = FindFirmArm9Section(firm);
u32 offset_arm9bin = arm9s->offset + ARM9BIN_OFFSET;
@ -153,20 +153,21 @@ u32 DecryptFirm(u8* data, u32 offset, u32 size, FirmHeader* firm, FirmA9LHeader*
return 0; // section not in data
// determine data / offset / size
u8* data_i = data;
u8* data8 = (u8*)data;
u8* data_i = data8;
u32 offset_i = 0;
u32 size_i = size_arm9bin;
if (offset_arm9bin < offset)
offset_i = offset - offset_arm9bin;
else data_i = data + (offset_arm9bin - offset);
else data_i = data8 + (offset_arm9bin - offset);
size_i = size_arm9bin - offset_i;
if (size_i > size - (data_i - data))
size_i = size - (data_i - data);
if (size_i > size - (data_i - data8))
size_i = size - (data_i - data8);
return DecryptArm9Binary(data_i, offset_i, size_i, a9l);
}
u32 DecryptFirmSequential(u8* data, u32 offset, u32 size) {
u32 DecryptFirmSequential(void* data, u32 offset, u32 size) {
// warning: this will only work for sequential processing
// unexpected results otherwise
static FirmHeader firm = { 0 };
@ -189,7 +190,7 @@ u32 DecryptFirmSequential(u8* data, u32 offset, u32 size) {
// fetch ARM9 loader header from data
if (arm9s && !a9lptr && (offset <= arm9s->offset) &&
((offset + size) >= arm9s->offset + sizeof(FirmA9LHeader))) {
memcpy(&a9l, data + arm9s->offset - offset, sizeof(FirmA9LHeader));
memcpy(&a9l, (u8*)data + arm9s->offset - offset, sizeof(FirmA9LHeader));
a9lptr = (ValidateFirmA9LHeader(&a9l) == 0) ? &a9l : NULL;
}

View File

@ -49,6 +49,6 @@ u32 GetArm9BinarySize(FirmA9LHeader* a9l);
u32 SetupArm9BinaryCrypto(FirmA9LHeader* header);
u32 DecryptA9LHeader(FirmA9LHeader* header);
u32 DecryptFirm(u8* data, u32 offset, u32 size, FirmHeader* firm, FirmA9LHeader* a9l);
u32 DecryptArm9Binary(u8* data, u32 offset, u32 size, FirmA9LHeader* a9l);
u32 DecryptFirmSequential(u8* data, u32 offset, u32 size);
u32 DecryptFirm(void* data, u32 offset, u32 size, FirmHeader* firm, FirmA9LHeader* a9l);
u32 DecryptArm9Binary(void* data, u32 offset, u32 size, FirmA9LHeader* a9l);
u32 DecryptFirmSequential(void* data, u32 offset, u32 size);

View File

@ -208,7 +208,7 @@ u32 SetupNcchCrypto(NcchHeader* ncch, u16 crypt_to) {
return res_from | res_to;
}
u32 CryptNcchSection(u8* data, u32 offset_data, u32 size_data, u32 offset_section, u32 size_section,
u32 CryptNcchSection(void* data, u32 offset_data, u32 size_data, u32 offset_section, u32 size_section,
u32 offset_ctr, NcchHeader* ncch, u32 snum, u16 crypt_to, u32 keyid) {
u16 crypt_from = NCCH_GET_CRYPTO(ncch);
const u32 mode = AES_CNT_CTRNAND_MODE;
@ -221,15 +221,16 @@ u32 CryptNcchSection(u8* data, u32 offset_data, u32 size_data, u32 offset_sectio
}
// determine data / offset / size
u8* data_i = data;
u8* data8 = (u8*)data;
u8* data_i = data8;
u32 offset_i = 0;
u32 size_i = size_section;
if (offset_section < offset_data)
offset_i = offset_data - offset_section;
else data_i = data + (offset_section - offset_data);
else data_i = data8 + (offset_section - offset_data);
size_i = size_section - offset_i;
if (size_i > size_data - (data_i - data))
size_i = size_data - (data_i - data);
if (size_i > size_data - (data_i - data8))
size_i = size_data - (data_i - data8);
// actual decryption stuff
u8 ctr[16];
@ -247,7 +248,7 @@ u32 CryptNcchSection(u8* data, u32 offset_data, u32 size_data, u32 offset_sectio
}
// on the fly de-/encryptor for NCCH
u32 CryptNcch(u8* data, u32 offset, u32 size, NcchHeader* ncch, ExeFsHeader* exefs, u16 crypt_to) {
u32 CryptNcch(void* data, u32 offset, u32 size, NcchHeader* ncch, ExeFsHeader* exefs, u16 crypt_to) {
const u32 offset_flag3 = 0x188 + 3;
const u32 offset_flag7 = 0x188 + 7;
u16 crypt_from = NCCH_GET_CRYPTO(ncch);
@ -258,10 +259,10 @@ u32 CryptNcch(u8* data, u32 offset, u32 size, NcchHeader* ncch, ExeFsHeader* exe
// ncch flags handling
if ((offset <= offset_flag3) && (offset + size > offset_flag3))
data[offset_flag3 - offset] = (crypt_to >> 8);
((u8*)data)[offset_flag3 - offset] = (crypt_to >> 8);
if ((offset <= offset_flag7) && (offset + size > offset_flag7)) {
data[offset_flag7 - offset] &= ~(0x01|0x20|0x04);
data[offset_flag7 - offset] |= (crypt_to & (0x01|0x20|0x04));
((u8*)data)[offset_flag7 - offset] &= ~(0x01|0x20|0x04);
((u8*)data)[offset_flag7 - offset] |= (crypt_to & (0x01|0x20|0x04));
}
// exthdr handling
@ -301,7 +302,7 @@ u32 CryptNcch(u8* data, u32 offset, u32 size, NcchHeader* ncch, ExeFsHeader* exe
}
// on the fly de- / encryptor for NCCH - sequential
u32 CryptNcchSequential(u8* data, u32 offset, u32 size, u16 crypt_to) {
u32 CryptNcchSequential(void* data, u32 offset, u32 size, u16 crypt_to) {
// warning: this will only work for sequential processing
// unexpected results otherwise
static NcchHeader ncch = { 0 };
@ -324,7 +325,7 @@ u32 CryptNcchSequential(u8* data, u32 offset, u32 size, u16 crypt_to) {
u32 offset_exefs = ncchptr->offset_exefs * NCCH_MEDIA_UNIT;
if ((offset <= offset_exefs) &&
((offset + size) >= offset_exefs + sizeof(ExeFsHeader))) {
memcpy(&exefs, data + offset_exefs - offset, sizeof(ExeFsHeader));
memcpy(&exefs, (u8*)data + offset_exefs - offset, sizeof(ExeFsHeader));
if ((NCCH_ENCRYPTED(ncchptr)) &&
(DecryptNcch((u8*) &exefs, offset_exefs, sizeof(ExeFsHeader), ncchptr, NULL) != 0))
return 1;
@ -336,9 +337,9 @@ u32 CryptNcchSequential(u8* data, u32 offset, u32 size, u16 crypt_to) {
return CryptNcch(data, offset, size, ncchptr, exefsptr, crypt_to);
}
u32 SetNcchSdFlag(u8* data) { // data must be at least 0x600 byte and start with NCCH header
NcchHeader* ncch = (NcchHeader*) (void*) data;
NcchExtHeader* exthdr = (NcchExtHeader*) (void*) (data + NCCH_EXTHDR_OFFSET);
u32 SetNcchSdFlag(void* data) { // data must be at least 0x600 byte and start with NCCH header
NcchHeader* ncch = (NcchHeader*) data;
NcchExtHeader* exthdr = (NcchExtHeader*) (void*) ((u8*)data + NCCH_EXTHDR_OFFSET);
NcchExtHeader exthdr_dec;
if ((ValidateNcchHeader(ncch) != 0) || (!ncch->size_exthdr))

View File

@ -91,8 +91,8 @@ typedef struct {
u32 ValidateNcchHeader(NcchHeader* header);
u32 SetNcchKey(NcchHeader* ncch, u16 crypto, u32 keyid);
u32 SetupNcchCrypto(NcchHeader* ncch, u16 crypt_to);
u32 CryptNcch(u8* data, u32 offset, u32 size, NcchHeader* ncch, ExeFsHeader* exefs, u16 crypto);
u32 CryptNcchSequential(u8* data, u32 offset, u32 size, u16 crypto);
u32 SetNcchSdFlag(u8* data);
u32 CryptNcch(void* data, u32 offset, u32 size, NcchHeader* ncch, ExeFsHeader* exefs, u16 crypto);
u32 CryptNcchSequential(void* data, u32 offset, u32 size, u16 crypto);
u32 SetNcchSdFlag(void* data);
u32 AddSeedToDb(SeedInfo* seed_info, SeedInfoEntry* seed_entry);

View File

@ -40,7 +40,7 @@ u32 FixNcchInfoEntry(NcchInfoEntry* entry, u32 version) {
return 0;
}
u32 BuildNcchInfoXorpad(u8* buffer, NcchInfoEntry* entry, u32 size, u32 offset) {
u32 BuildNcchInfoXorpad(void* buffer, NcchInfoEntry* entry, u32 size, u32 offset) {
// set NCCH key
// build faux NCCH header from entry
NcchHeader ncch = { 0 };

View File

@ -27,4 +27,4 @@ typedef struct {
u32 GetNcchInfoVersion(NcchInfoHeader* info);
u32 FixNcchInfoEntry(NcchInfoEntry* entry, u32 version);
u32 BuildNcchInfoXorpad(u8* buffer, NcchInfoEntry* entry, u32 size, u32 offset);
u32 BuildNcchInfoXorpad(void* buffer, NcchInfoEntry* entry, u32 size, u32 offset);

View File

@ -35,7 +35,7 @@ u64 GetNcsdTrimmedSize(NcsdHeader* header) {
}
// on the fly decryptor for NCSD
u32 CryptNcsdSequential(u8* data, u32 offset_data, u32 size_data, u16 crypto) {
u32 CryptNcsdSequential(void* data, u32 offset_data, u32 size_data, u16 crypto) {
// warning: this will only work for sequential processing
static NcsdHeader ncsd;
@ -54,15 +54,16 @@ u32 CryptNcsdSequential(u8* data, u32 offset_data, u32 size_data, u16 crypto) {
continue; // section not in data
}
// determine data / offset / size
u8* data_i = data;
u8* data8 = (u8*)data;
u8* data_i = data8;
u32 offset_i = 0;
u32 size_i = size_p;
if (offset_p < offset_data)
offset_i = offset_data - offset_p;
else data_i = data + (offset_p - offset_data);
else data_i = data8 + (offset_p - offset_data);
size_i = size_p - offset_i;
if (size_i > size_data - (data_i - data))
size_i = size_data - (data_i - data);
if (size_i > size_data - (data_i - data8))
size_i = size_data - (data_i - data8);
// decrypt ncch segment
if (CryptNcchSequential(data_i, offset_i, size_i, crypto) != 0)
return 1;

View File

@ -38,4 +38,4 @@ typedef struct {
u32 ValidateNcsdHeader(NcsdHeader* header);
u64 GetNcsdTrimmedSize(NcsdHeader* header);
u32 CryptNcsdSequential(u8* data, u32 offset_data, u32 size_data, u16 crypto);
u32 CryptNcsdSequential(void* data, u32 offset_data, u32 size_data, u16 crypto);

View File

@ -125,14 +125,15 @@ u32 InitCardRead(CartData* cdata) {
return 0;
}
u32 ReadCartSectors(u8* buffer, u32 sector, u32 count, CartData* cdata) {
u32 ReadCartSectors(void* buffer, u32 sector, u32 count, CartData* cdata) {
u8* buffer8 = (u8*) buffer;
if (!CART_INSERTED) return 1;
// header
u32 header_sectors = (cdata->cart_type & CART_CTR) ? 0x4000/0x200 : 0x8000/0x200;
if (sector < header_sectors) {
u32 header_count = (sector + count > header_sectors) ? header_sectors - sector : count;
memcpy(buffer, cdata->header + (sector * 0x200), header_count * 0x200);
buffer += header_count * 0x200;
memcpy(buffer8, cdata->header + (sector * 0x200), header_count * 0x200);
buffer8 += header_count * 0x200;
sector += header_count;
count -= header_count;
}
@ -141,19 +142,19 @@ u32 ReadCartSectors(u8* buffer, u32 sector, u32 count, CartData* cdata) {
if (cdata->cart_type & CART_CTR) {
Cart_Dummy();
Cart_Dummy();
CTR_CmdReadData(sector, 0x200, count, buffer);
CTR_CmdReadData(sector, 0x200, count, buffer8);
// overwrite the card2 savegame with 0xFF
u32 card2_offset = getle32(cdata->header + 0x200);
if ((card2_offset != 0xFFFFFFFF) &&
(card2_offset >= cdata->data_size) &&
(sector + count > card2_offset)) {
if (sector > card2_offset)
memset(buffer, 0xFF, (count * 0x200));
else memset(buffer + (card2_offset - sector) * 0x200, 0xFF,
memset(buffer8, 0xFF, (count * 0x200));
else memset(buffer8 + (card2_offset - sector) * 0x200, 0xFF,
(count - (card2_offset - sector)) * 0x200);
}
} else if (cdata->cart_type & CART_NTR) {
u8* buff = buffer;
u8* buff = buffer8;
u32 off = sector * 0x200;
for (u32 i = 0; i < count; i++, off += 0x200, buff += 0x200)
NTR_CmdReadData(off, buff);
@ -162,49 +163,50 @@ u32 ReadCartSectors(u8* buffer, u32 sector, u32 count, CartData* cdata) {
((sector+count) * 0x200 > cdata->arm9i_rom_offset) &&
(sector * 0x200 < cdata->arm9i_rom_offset + MODC_AREA_SIZE)) {
u32 arm9i_rom_offset = cdata->arm9i_rom_offset;
u8* buffer_arm9i = buffer;
u8* buffer_arm9i = buffer8;
u32 offset_i = 0;
u32 size_i = MODC_AREA_SIZE;
if (arm9i_rom_offset < (sector * 0x200))
offset_i = (sector * 0x200) - arm9i_rom_offset;
else buffer_arm9i = buffer + (arm9i_rom_offset - (sector * 0x200));
else buffer_arm9i = buffer8 + (arm9i_rom_offset - (sector * 0x200));
size_i = MODC_AREA_SIZE - offset_i;
if (size_i > (count * 0x200) - (buffer_arm9i - buffer))
size_i = (count * 0x200) - (buffer_arm9i - buffer);
if (size_i > (count * 0x200) - (buffer_arm9i - buffer8))
size_i = (count * 0x200) - (buffer_arm9i - buffer8);
if (size_i) memcpy(buffer_arm9i, cdata->twl_header + 0x4000 + offset_i, size_i);
}
} else return 1;
return 0;
}
u32 ReadCartBytes(u8* buffer, u64 offset, u64 count, CartData* cdata) {
u32 ReadCartBytes(void* buffer, u64 offset, u64 count, CartData* cdata) {
if (!(offset % 0x200) && !(count % 0x200)) { // aligned data -> simple case
// simple wrapper function for ReadCartSectors(...)
return ReadCartSectors(buffer, offset / 0x200, count / 0x200, cdata);
} else { // misaligned data -> -___-
u8* buffer8 = (u8*) buffer;
u8 l_buffer[0x200];
if (offset % 0x200) { // handle misaligned offset
u32 offset_fix = 0x200 - (offset % 0x200);
if (ReadCartSectors(l_buffer, offset / 0x200, 1, cdata) != 0) return 1;
memcpy(buffer, l_buffer + 0x200 - offset_fix, min(offset_fix, count));
memcpy(buffer8, l_buffer + 0x200 - offset_fix, min(offset_fix, count));
if (count <= offset_fix) return 0;
offset += offset_fix;
buffer += offset_fix;
buffer8 += offset_fix;
count -= offset_fix;
} // offset is now aligned and part of the data is read
if (count >= 0x200) { // otherwise this is misaligned and will be handled below
if (ReadCartSectors(buffer, offset / 0x200, count / 0x200, cdata) != 0) return 1;
if (ReadCartSectors(buffer8, offset / 0x200, count / 0x200, cdata) != 0) return 1;
}
if (count % 0x200) { // handle misaligned count
u32 count_fix = count % 0x200;
if (ReadCartSectors(l_buffer, (offset + count) / 0x200, 1, cdata) != 0) return 1;
memcpy(buffer + count - count_fix, l_buffer, count_fix);
memcpy(buffer8 + count - count_fix, l_buffer, count_fix);
}
return 0;
}
}
u32 ReadCartPrivateHeader(u8* buffer, u64 offset, u64 count, CartData* cdata) {
u32 ReadCartPrivateHeader(void* buffer, u64 offset, u64 count, CartData* cdata) {
if (!(cdata->cart_type & CART_CTR)) return 1;
if (offset < PRIV_HDR_SIZE) {
u8* priv_hdr = cdata->header + 0x4000;

View File

@ -22,6 +22,6 @@ typedef struct {
u32 GetCartName(char* name, CartData* cdata);
u32 InitCardRead(CartData* cdata);
u32 ReadCartSectors(u8* buffer, u32 sector, u32 count, CartData* cdata);
u32 ReadCartBytes(u8* buffer, u64 offset, u64 count, CartData* cdata);
u32 ReadCartPrivateHeader(u8* buffer, u64 offset, u64 count, CartData* cdata);
u32 ReadCartSectors(void* buffer, u32 sector, u32 count, CartData* cdata);
u32 ReadCartBytes(void* buffer, u64 offset, u64 count, CartData* cdata);
u32 ReadCartPrivateHeader(void* buffer, u64 offset, u64 count, CartData* cdata);

View File

@ -112,20 +112,22 @@ bool InitNandCrypto(void)
} else if (IS_A9LH) { // for a9lh
// store the current SHA256 from register
memcpy(OtpSha256, (void*) REG_SHAHASH, 32);
} else {
// load hash via keys?
const char* base[] = { INPUT_PATHS };
char path[64];
u8 otp[0x100];
for (u32 i = 0; i < 2 * (sizeof(base)/sizeof(char*)); i++) {
snprintf(path, 64, "%s/%s", base[i/2], (i%2) ? OTP_BIG_NAME : OTP_NAME);
if (FileGetData(path, otp, 0x100, 0) == 0x100) {
sha_quick(OtpSha256, otp, 0x90, SHA256_MODE);
break;
}
}
if (!CheckSector0x96Crypto()) { // if all else fails...
u8 __attribute__((aligned(32))) otp0x90[0x90];
u8 __attribute__((aligned(32))) otp_key[0x10];
u8 __attribute__((aligned(32))) otp_iv[0x10];
memcpy(otp0x90, (u8*) 0x01FFB800, 0x90);
if ((LoadKeyFromFile(otp_key, 0x11, 'N', "OTP") == 0) &&
((LoadKeyFromFile(otp_iv, 0x11, 'I', "IVOTP") == 0) ||
(LoadKeyFromFile(otp_iv, 0x11, 'I', "OTP") == 0))) {
setup_aeskey(0x11, otp_key);
use_aeskey(0x11);
cbc_encrypt(otp0x90, otp0x90, 0x90 / 0x10, AES_CNT_TITLEKEY_ENCRYPT_MODE, otp_iv);
sha_quick(OtpSha256, otp0x90, 0x90, SHA256_MODE);
}
}
// part #1: Get NAND CID, set up TWL/CTR counter
u32 NandCid[4];
u8 shasum[32];
@ -205,7 +207,7 @@ bool CheckSector0x96Crypto(void)
return (sha_cmp(KEY95_SHA256, buffer, 16, SHA256_MODE) == 0);
}
void CryptNand(u8* buffer, u32 sector, u32 count, u32 keyslot)
void CryptNand(void* buffer, u32 sector, u32 count, u32 keyslot)
{
u32 mode = (keyslot != 0x03) ? AES_CNT_CTRNAND_MODE : AES_CNT_TWLNAND_MODE; // somewhat hacky
u8 ctr[16] __attribute__((aligned(32)));
@ -220,7 +222,7 @@ void CryptNand(u8* buffer, u32 sector, u32 count, u32 keyslot)
ctr_decrypt((void*) buffer, (void*) buffer, blocks, mode, ctr);
}
void CryptSector0x96(u8* buffer, bool encrypt)
void CryptSector0x96(void* buffer, bool encrypt)
{
u32 mode = encrypt ? AES_CNT_ECB_ENCRYPT_MODE : AES_CNT_ECB_DECRYPT_MODE;
@ -233,67 +235,69 @@ void CryptSector0x96(u8* buffer, bool encrypt)
ecb_decrypt((void*) buffer, (void*) buffer, 0x200 / AES_BLOCK_SIZE, mode);
}
int ReadNandBytes(u8* buffer, u64 offset, u64 count, u32 keyslot, u32 nand_src)
int ReadNandBytes(void* buffer, u64 offset, u64 count, u32 keyslot, u32 nand_src)
{
if (!(offset % 0x200) && !(count % 0x200)) { // aligned data -> simple case
// simple wrapper function for ReadNandSectors(...)
return ReadNandSectors(buffer, offset / 0x200, count / 0x200, keyslot, nand_src);
} else { // misaligned data -> -___-
u8* buffer8 = (u8*) buffer;
u8 l_buffer[0x200];
int errorcode = 0;
if (offset % 0x200) { // handle misaligned offset
u32 offset_fix = 0x200 - (offset % 0x200);
errorcode = ReadNandSectors(l_buffer, offset / 0x200, 1, keyslot, nand_src);
if (errorcode != 0) return errorcode;
memcpy(buffer, l_buffer + 0x200 - offset_fix, min(offset_fix, count));
memcpy(buffer8, l_buffer + 0x200 - offset_fix, min(offset_fix, count));
if (count <= offset_fix) return 0;
offset += offset_fix;
buffer += offset_fix;
buffer8 += offset_fix;
count -= offset_fix;
} // offset is now aligned and part of the data is read
if (count >= 0x200) { // otherwise this is misaligned and will be handled below
errorcode = ReadNandSectors(buffer, offset / 0x200, count / 0x200, keyslot, nand_src);
errorcode = ReadNandSectors(buffer8, offset / 0x200, count / 0x200, keyslot, nand_src);
if (errorcode != 0) return errorcode;
}
if (count % 0x200) { // handle misaligned count
u32 count_fix = count % 0x200;
errorcode = ReadNandSectors(l_buffer, (offset + count) / 0x200, 1, keyslot, nand_src);
if (errorcode != 0) return errorcode;
memcpy(buffer + count - count_fix, l_buffer, count_fix);
memcpy(buffer8 + count - count_fix, l_buffer, count_fix);
}
return errorcode;
}
}
int WriteNandBytes(const u8* buffer, u64 offset, u64 count, u32 keyslot, u32 nand_dst)
int WriteNandBytes(const void* buffer, u64 offset, u64 count, u32 keyslot, u32 nand_dst)
{
if (!(offset % 0x200) && !(count % 0x200)) { // aligned data -> simple case
// simple wrapper function for WriteNandSectors(...)
return WriteNandSectors(buffer, offset / 0x200, count / 0x200, keyslot, nand_dst);
} else { // misaligned data -> -___-
u8* buffer8 = (u8*) buffer8;
u8 l_buffer[0x200];
int errorcode = 0;
if (offset % 0x200) { // handle misaligned offset
u32 offset_fix = 0x200 - (offset % 0x200);
errorcode = ReadNandSectors(l_buffer, offset / 0x200, 1, keyslot, nand_dst);
if (errorcode != 0) return errorcode;
memcpy(l_buffer + 0x200 - offset_fix, buffer, min(offset_fix, count));
memcpy(l_buffer + 0x200 - offset_fix, buffer8, min(offset_fix, count));
errorcode = WriteNandSectors((const u8*) l_buffer, offset / 0x200, 1, keyslot, nand_dst);
if (errorcode != 0) return errorcode;
if (count <= offset_fix) return 0;
offset += offset_fix;
buffer += offset_fix;
buffer8 += offset_fix;
count -= offset_fix;
} // offset is now aligned and part of the data is written
if (count >= 0x200) { // otherwise this is misaligned and will be handled below
errorcode = WriteNandSectors(buffer, offset / 0x200, count / 0x200, keyslot, nand_dst);
errorcode = WriteNandSectors(buffer8, offset / 0x200, count / 0x200, keyslot, nand_dst);
if (errorcode != 0) return errorcode;
}
if (count % 0x200) { // handle misaligned count
u32 count_fix = count % 0x200;
errorcode = ReadNandSectors(l_buffer, (offset + count) / 0x200, 1, keyslot, nand_dst);
if (errorcode != 0) return errorcode;
memcpy(l_buffer, buffer + count - count_fix, count_fix);
memcpy(l_buffer, buffer8 + count - count_fix, count_fix);
errorcode = WriteNandSectors((const u8*) l_buffer, (offset + count) / 0x200, 1, keyslot, nand_dst);
if (errorcode != 0) return errorcode;
}
@ -301,43 +305,45 @@ int WriteNandBytes(const u8* buffer, u64 offset, u64 count, u32 keyslot, u32 nan
}
}
int ReadNandSectors(u8* buffer, u32 sector, u32 count, u32 keyslot, u32 nand_src)
{
int ReadNandSectors(void* buffer, u32 sector, u32 count, u32 keyslot, u32 nand_src)
{
u8* buffer8 = (u8*) buffer;
if (!count) return 0; // <--- just to be safe
if (nand_src == NAND_EMUNAND) { // EmuNAND
int errorcode = 0;
if ((sector == 0) && (emunand_base_sector % 0x200000 == 0)) { // GW EmuNAND header handling
errorcode = sdmmc_sdcard_readsectors(emunand_base_sector + getMMCDevice(0)->total_size, 1, buffer);
if ((keyslot < 0x40) && (keyslot != 0x11) && !errorcode) CryptNand(buffer, 0, 1, keyslot);
errorcode = sdmmc_sdcard_readsectors(emunand_base_sector + getMMCDevice(0)->total_size, 1, buffer8);
if ((keyslot < 0x40) && (keyslot != 0x11) && !errorcode) CryptNand(buffer8, 0, 1, keyslot);
sector = 1;
count--;
buffer += 0x200;
buffer8 += 0x200;
}
errorcode = (!errorcode && count) ? sdmmc_sdcard_readsectors(emunand_base_sector + sector, count, buffer) : errorcode;
errorcode = (!errorcode && count) ? sdmmc_sdcard_readsectors(emunand_base_sector + sector, count, buffer8) : errorcode;
if (errorcode) return errorcode;
} else if (nand_src == NAND_IMGNAND) { // ImgNAND
int errorcode = ReadImageSectors(buffer, sector, count);
int errorcode = ReadImageSectors(buffer8, sector, count);
if (errorcode) return errorcode;
} else if (nand_src == NAND_SYSNAND) { // SysNAND
int errorcode = sdmmc_nand_readsectors(sector, count, buffer);
int errorcode = sdmmc_nand_readsectors(sector, count, buffer8);
if (errorcode) return errorcode;
} else if (nand_src == NAND_ZERONAND) { // zero NAND (good for XORpads)
memset(buffer, 0, count * 0x200);
memset(buffer8, 0, count * 0x200);
} else {
return -1;
}
if ((keyslot == 0x11) && (sector == SECTOR_SECRET)) CryptSector0x96(buffer, false);
else if (keyslot < 0x40) CryptNand(buffer, sector, count, keyslot);
if ((keyslot == 0x11) && (sector == SECTOR_SECRET)) CryptSector0x96(buffer8, false);
else if (keyslot < 0x40) CryptNand(buffer8, sector, count, keyslot);
return 0;
}
int WriteNandSectors(const u8* buffer, u32 sector, u32 count, u32 keyslot, u32 nand_dst)
int WriteNandSectors(const void* buffer, u32 sector, u32 count, u32 keyslot, u32 nand_dst)
{
u8* buffer8 = (u8*) buffer;
// buffer must not be changed, so this is a little complicated
for (u32 s = 0; s < count; s += (NAND_BUFFER_SIZE / 0x200)) {
u32 pcount = min((NAND_BUFFER_SIZE/0x200), (count - s));
memcpy(NAND_BUFFER, buffer + (s*0x200), pcount * 0x200);
memcpy(NAND_BUFFER, buffer8 + (s*0x200), pcount * 0x200);
if ((keyslot == 0x11) && (sector == SECTOR_SECRET)) CryptSector0x96(NAND_BUFFER, true);
else if (keyslot < 0x40) CryptNand(NAND_BUFFER, sector + s, pcount, keyslot);
if (nand_dst == NAND_EMUNAND) {

View File

@ -14,8 +14,6 @@
// filenames for sector 0x96
#define SECTOR_NAME "sector0x96.bin"
#define SECRET_NAME "secret_sector.bin"
#define OTP_NAME "otp.bin"
#define OTP_BIG_NAME "otp0x108.bin"
// 0x110...0x118 in the NAND NCSD header
// see: https://www.3dbrew.org/wiki/NCSD#NCSD_header
@ -66,12 +64,12 @@ bool InitNandCrypto(void);
bool CheckSlot0x05Crypto(void);
bool CheckSector0x96Crypto(void);
void CryptNand(u8* buffer, u32 sector, u32 count, u32 keyslot);
void CryptSector0x96(u8* buffer, bool encrypt);
int ReadNandBytes(u8* buffer, u64 offset, u64 count, u32 keyslot, u32 nand_src);
int WriteNandBytes(const u8* buffer, u64 offset, u64 count, u32 keyslot, u32 nand_dst);
int ReadNandSectors(u8* buffer, u32 sector, u32 count, u32 keyslot, u32 src);
int WriteNandSectors(const u8* buffer, u32 sector, u32 count, u32 keyslot, u32 dest);
void CryptNand(void* buffer, u32 sector, u32 count, u32 keyslot);
void CryptSector0x96(void* buffer, bool encrypt);
int ReadNandBytes(void* buffer, u64 offset, u64 count, u32 keyslot, u32 nand_src);
int WriteNandBytes(const void* buffer, u64 offset, u64 count, u32 keyslot, u32 nand_dst);
int ReadNandSectors(void* buffer, u32 sector, u32 count, u32 keyslot, u32 src);
int WriteNandSectors(const void* buffer, u32 sector, u32 count, u32 keyslot, u32 dest);
u32 ValidateNandNcsdHeader(NandNcsdHeader* header);
u32 GetNandNcsdMinSizeSectors(NandNcsdHeader* ncsd);

View File

@ -53,7 +53,7 @@ bool ReadVCartDir(VirtualFile* vfile, VirtualDir* vdir) {
return false;
}
int ReadVCartFile(const VirtualFile* vfile, u8* buffer, u64 offset, u64 count) {
int ReadVCartFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count) {
u32 foffset = vfile->offset + offset;
if (vfile->flags & VFLAG_PRIV_HDR)
return ReadCartPrivateHeader(buffer, foffset, count, cdata);

View File

@ -5,6 +5,6 @@
u32 InitVCartDrive(void);
bool ReadVCartDir(VirtualFile* vfile, VirtualDir* vdir);
int ReadVCartFile(const VirtualFile* vfile, u8* buffer, u64 offset, u64 count);
// int WriteVCartFile(const VirtualFile* vfile, const u8* buffer, u64 offset, u64 count); // no writes
int ReadVCartFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count);
// int WriteVCartFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count); // no writes
u64 GetVCartDriveSize(void);

View File

@ -80,7 +80,7 @@ static ExeFsHeader* exefs = (ExeFsHeader*) (void*) (VGAME_BUFFER + 0x1FE00); //
static u8* romfslv3 = (u8*) (VGAME_BUFFER + 0x20000); // 1920kB reserved
static RomFsLv3Index lv3idx;
int ReadFirmImageBytes(u8* buffer, u64 offset, u64 count) {
int ReadFirmImageBytes(void* buffer, u64 offset, u64 count) {
int ret = ReadImageBytes(buffer, offset, count);
if ((offset_a9bin == (u64) -1) || (ret != 0)) return ret;
if (DecryptFirm(buffer, offset, count, firm, a9l) != 0)
@ -88,7 +88,7 @@ int ReadFirmImageBytes(u8* buffer, u64 offset, u64 count) {
return 0;
}
int ReadNcchImageBytes(u8* buffer, u64 offset, u64 count) {
int ReadNcchImageBytes(void* buffer, u64 offset, u64 count) {
int ret = (offset_a9bin == (u64) - 1) ? ReadImageBytes(buffer, offset, count) :
ReadFirmImageBytes(buffer, offset, count);
if ((offset_ncch == (u64) -1) || (ret != 0)) return ret;
@ -685,7 +685,7 @@ bool ReadVGameDir(VirtualFile* vfile, VirtualDir* vdir) {
return false;
}
int ReadVGameFile(const VirtualFile* vfile, u8* buffer, u64 offset, u64 count) {
int ReadVGameFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count) {
u32 vfoffset = vfile->offset;
if (vfile->flags & VFLAG_LV3) {
RomFsLv3FileMeta* lv3file;

View File

@ -9,8 +9,8 @@ u32 CheckVGameDrive(void);
bool OpenVGameDir(VirtualDir* vdir, VirtualFile* ventry);
bool ReadVGameDir(VirtualFile* vfile, VirtualDir* vdir);
int ReadVGameFile(const VirtualFile* vfile, u8* buffer, u64 offset, u64 count);
// int WriteVGameFile(const VirtualFile* vfile, const u8* buffer, u64 offset, u64 count); // writing is not enabled
int ReadVGameFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count);
// int WriteVGameFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count); // writing is not enabled
bool FindVirtualFileInLv3Dir(VirtualFile* vfile, const VirtualDir* vdir, const char* name);
bool GetVGameLv3Filename(char* name, const VirtualFile* vfile, u32 n_chars);

View File

@ -169,7 +169,7 @@ bool GetVirtualFilename(char* name, const VirtualFile* vfile, u32 n_chars) {
return true;
}
int ReadVirtualFile(const VirtualFile* vfile, u8* buffer, u64 offset, u64 count, u32* bytes_read) {
int ReadVirtualFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count, u32* bytes_read) {
// basic check of offset / count
if (offset >= vfile->size)
return 0;
@ -194,7 +194,7 @@ int ReadVirtualFile(const VirtualFile* vfile, u8* buffer, u64 offset, u64 count,
return -1;
}
int WriteVirtualFile(const VirtualFile* vfile, const u8* buffer, u64 offset, u64 count, u32* bytes_written) {
int WriteVirtualFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count, u32* bytes_written) {
// basic check of offset / count
if (offset >= vfile->size)
return 0;

View File

@ -58,7 +58,7 @@ bool GetVirtualDirContents(DirStruct* contents, char* fpath, int fnsize, const c
bool GetVirtualFilename(char* name, const VirtualFile* vfile, u32 n_chars);
int ReadVirtualFile(const VirtualFile* vfile, u8* buffer, u64 offset, u64 count, u32* bytes_read);
int WriteVirtualFile(const VirtualFile* vfile, const u8* buffer, u64 offset, u64 count, u32* bytes_written);
int ReadVirtualFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count, u32* bytes_read);
int WriteVirtualFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count, u32* bytes_written);
u64 GetVirtualDriveSize(const char* path);

View File

@ -57,7 +57,7 @@ bool ReadVKeyDbDir(VirtualFile* vfile, VirtualDir* vdir) {
return false;
}
int ReadVKeyDbFile(const VirtualFile* vfile, u8* buffer, u64 offset, u64 count) {
int ReadVKeyDbFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count) {
AesKeyInfo* key_entry = key_info + (vfile->offset / sizeof(AesKeyInfo));
memcpy(buffer, key_entry->key + offset, count);
return 0;

View File

@ -7,6 +7,6 @@ u32 InitVKeyDbDrive(void);
u32 CheckVKeyDbDrive(void);
bool ReadVKeyDbDir(VirtualFile* vfile, VirtualDir* vdir);
int ReadVKeyDbFile(const VirtualFile* vfile, u8* buffer, u64 offset, u64 count);
// int WriteVKeyDbFile(const VirtualFile* vfile, const u8* buffer, u64 offset, u64 count); // no writing
int ReadVKeyDbFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count);
// int WriteVKeyDbFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count); // no writing
u64 GetVKeyDbDriveSize(void);

View File

@ -69,7 +69,7 @@ bool ReadVMemDir(VirtualFile* vfile, VirtualDir* vdir) { // uses a generic vdir
return false;
}
int ReadVMemFile(const VirtualFile* vfile, u8* buffer, u64 offset, u64 count) {
int ReadVMemFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count) {
if ((vfile->flags & VFLAG_OTP) && (vfile->keyslot == 0x11)) {
u8 __attribute__((aligned(32))) otp_local[vfile->size];
u8 __attribute__((aligned(32))) otp_iv[0x10];
@ -86,7 +86,7 @@ int ReadVMemFile(const VirtualFile* vfile, u8* buffer, u64 offset, u64 count) {
return 0;
}
int WriteVMemFile(const VirtualFile* vfile, const u8* buffer, u64 offset, u64 count) {
int WriteVMemFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count) {
if (vfile->flags & (VFLAG_OTP|VFLAG_BOOT9|VFLAG_BOOT11)) {
return 1; // not writable / writes blocked
} else {

View File

@ -4,5 +4,5 @@
#include "virtual.h"
bool ReadVMemDir(VirtualFile* vfile, VirtualDir* vdir);
int ReadVMemFile(const VirtualFile* vfile, u8* buffer, u64 offset, u64 count);
int WriteVMemFile(const VirtualFile* vfile, const u8* buffer, u64 offset, u64 count);
int ReadVMemFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count);
int WriteVMemFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count);

View File

@ -108,12 +108,12 @@ bool ReadVNandDir(VirtualFile* vfile, VirtualDir* vdir) { // uses a generic vdir
return false;
}
int ReadVNandFile(const VirtualFile* vfile, u8* buffer, u64 offset, u64 count) {
int ReadVNandFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count) {
u32 nand_src = vfile->flags & (VRT_SYSNAND|VRT_EMUNAND|VRT_IMGNAND|VRT_XORPAD);
return ReadNandBytes(buffer, vfile->offset + offset, count, vfile->keyslot, nand_src);
}
int WriteVNandFile(const VirtualFile* vfile, const u8* buffer, u64 offset, u64 count) {
int WriteVNandFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count) {
u32 nand_dst = vfile->flags & (VRT_SYSNAND|VRT_EMUNAND|VRT_IMGNAND|VRT_XORPAD);
int res = WriteNandBytes(buffer, vfile->offset + offset, count, vfile->keyslot, nand_dst);
if ((res == 0) && (vfile->flags & VFLAG_GBA_VC)) res = FixAgbSaveCmac(nand_dst);

View File

@ -5,6 +5,6 @@
bool CheckVNandDrive(u32 nand_src);
bool ReadVNandDir(VirtualFile* vfile, VirtualDir* vdir);
int ReadVNandFile(const VirtualFile* vfile, u8* buffer, u64 offset, u64 count);
int WriteVNandFile(const VirtualFile* vfile, const u8* buffer, u64 offset, u64 count);
int ReadVNandFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count);
int WriteVNandFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count);
u64 GetVNandDriveSize(u32 nand_src);

View File

@ -130,7 +130,7 @@ bool ReadVTickDbDir(VirtualFile* vfile, VirtualDir* vdir) {
return false;
}
int ReadVTickDbFile(const VirtualFile* vfile, u8* buffer, u64 offset, u64 count) {
int ReadVTickDbFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count) {
u64 foffset = vfile->offset + offset;
return (ReadImageBytes(buffer, foffset, count) == 0) ? 0 : 1;
}

View File

@ -7,6 +7,6 @@ u32 InitVTickDbDrive(void);
u32 CheckVTickDbDrive(void);
bool ReadVTickDbDir(VirtualFile* vfile, VirtualDir* vdir);
int ReadVTickDbFile(const VirtualFile* vfile, u8* buffer, u64 offset, u64 count);
// int WriteVTickDbFile(const VirtualFile* vfile, const u8* buffer, u64 offset, u64 count); // no writing
int ReadVTickDbFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count);
// int WriteVTickDbFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count); // no writing
u64 GetVTickDbDriveSize(void);