diff --git a/include/arm9/partitions.h b/include/arm9/partitions.h index ddf43b7..444a173 100644 --- a/include/arm9/partitions.h +++ b/include/arm9/partitions.h @@ -40,4 +40,5 @@ bool partitionGetSectorOffset(size_t index, size_t *offset); bool partitionSetKeyslot(size_t index, u8 keyslot); bool partitionGetKeyslot(size_t index, u8 *keyslot); +bool partitionGetInfo(size_t index, partitionStruct *info); void partitionsReset(void); diff --git a/include/fs.h b/include/fs.h index 5ca3206..b08af76 100644 --- a/include/fs.h +++ b/include/fs.h @@ -64,6 +64,7 @@ s32 fMount(FsDrive drive); s32 fUnmount(FsDrive drive); s32 fGetFree(FsDrive drive, u64 *size); +u32 fGetDeviceSize(FsDevice dev); s32 fPrepareRawAccess(FsDevice dev); s32 fFinalizeRawAccess(DevHandle handle); s32 fCreateDeviceBuffer(u32 size); @@ -86,3 +87,5 @@ s32 fMkdir(const char *const path); s32 fRename(const char *const old, const char *const new); s32 fUnlink(const char *const path); +s32 fVerifyNandImage(const char *const path); +s32 fSetNandProtection(bool protect); diff --git a/source/arm9/dev.c b/source/arm9/dev.c index 61aba3a..0860185 100644 --- a/source/arm9/dev.c +++ b/source/arm9/dev.c @@ -279,7 +279,7 @@ // Check "NCSD" magic if(header.magic != 0x4453434E) return false; - // Collect partition infos... + // Collect partition info... for(int i = 0; i < MAX_PARTITIONS; i++) { u8 type = header.partFsType[i]; diff --git a/source/arm9/fs.c b/source/arm9/fs.c index 57d31fa..08b7131 100644 --- a/source/arm9/fs.c +++ b/source/arm9/fs.c @@ -22,6 +22,8 @@ #include "util.h" #include "fs.h" #include "arm9/dev.h" +#include "arm9/ncsd.h" +#include "arm9/partitions.h" #include "fatfs/ff.h" @@ -32,6 +34,12 @@ size_t dataSize; } DevBuf; +typedef struct +{ + size_t sector; + size_t count; +} ProtNandRegion; + static const DevHandle devHandleMagic = 0x42424296; @@ -52,10 +60,17 @@ static DevBuf devBuf; +static ProtNandRegion protNandRegions[MAX_PARTITIONS + 1] = {0}; +static size_t numProtNandRegions; static bool isFileHandleValid(s32 handle); +static inline bool isNandProtected() +{ + return numProtNandRegions != 0; +} + s32 fMount(FsDrive drive) { if((u32)drive >= FS_MAX_DRIVES) return -30; @@ -100,6 +115,23 @@ else return -res; } +u32 fGetDeviceSize(FsDevice dev) +{ + switch(dev) + { + case FS_DEVICE_SDMC: + return dev_sdcard->get_sector_count(); + break; + case FS_DEVICE_NAND: + return dev_rawnand->get_sector_count(); + break; + default: + break; + } + + return 0; +} + s32 fPrepareRawAccess(FsDevice dev) { if((u32)dev >= FS_MAX_DEVICES) return -30; @@ -183,7 +215,7 @@ s32 fCreateDeviceBuffer(u32 size) { - if(!size || size > 0x40000) return -30; + if(!size || size > 0x80000) return -30; if(devBuf.mem) return -31; if(!devBufAllocate(&devBuf, size)) @@ -575,3 +607,48 @@ if(res == FR_OK) return res; else return -res; } + +s32 fVerifyNandImage(const char *const path) +{ + //NCSD_header header; + + // TODO + (void) path; + + return FR_OK; +} + +s32 fSetNandProtection(bool protect) +{ + partitionStruct partInfo; + + if(protect == isNandProtected()) // nothing to do here + return FR_OK; + + if(protect) + { + protNandRegions[0].sector = 0x96; + protNandRegions[0].count = 1; + numProtNandRegions = 1; + + for(size_t i=0; i < arrayEntries(protNandRegions) - 1; i++) + { + if(partitionGetInfo(i, &partInfo)) + { + if(partInfo.type == 3) // is firmware? + { + protNandRegions[numProtNandRegions].sector = partInfo.sector; + protNandRegions[numProtNandRegions].count = partInfo.count; + numProtNandRegions++; + } + } + } + } + else + { + numProtNandRegions = 0; + } + + return FR_OK; +} + diff --git a/source/arm9/partitions.c b/source/arm9/partitions.c index 4a0fa6d..dacdfdc 100644 --- a/source/arm9/partitions.c +++ b/source/arm9/partitions.c @@ -153,6 +153,19 @@ return true; } +bool partitionGetInfo(size_t index, partitionStruct *info) +{ + if(index >= MAX_PARTITIONS) + { + memset(info, 0, sizeof(*info)); + return false; + } + + memcpy(info, &partitions[index], sizeof(*info)); + + return true; +} + void partitionsReset(void) { numPartitions = 0;