forked from Mirror/GodMode9
124 lines
3.5 KiB
C
124 lines
3.5 KiB
C
#include "vvram.h"
|
|
#include "vram0.h"
|
|
|
|
|
|
bool SplitTarFName(char* tar_fname, char** dir, char** name) {
|
|
u32 len = strnlen(tar_fname, 100 + 1);
|
|
if (!len || (len == 101)) return false;
|
|
|
|
// remove trailing slash
|
|
if (tar_fname[len-1] == '/') tar_fname[--len] = '\0';
|
|
|
|
// find last slash
|
|
char* slash = strrchr(tar_fname, '/');
|
|
|
|
// relative root dir entry
|
|
if (!slash) {
|
|
*name = tar_fname;
|
|
*dir = NULL;
|
|
} else {
|
|
*slash = '\0';
|
|
*name = slash + 1;
|
|
*dir = tar_fname;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CheckVVramDrive(void) {
|
|
return CheckVram0Tar();
|
|
}
|
|
|
|
bool ReadVVramDir(VirtualFile* vfile, VirtualDir* vdir) {
|
|
vfile->name[0] = '\0';
|
|
vfile->flags = VFLAG_READONLY;
|
|
vfile->keyslot = 0xFF;
|
|
|
|
|
|
// get current dir name
|
|
char curr_dir[100 + 1];
|
|
if (vdir->offset == (u64) -1) return false; // end of the dir?
|
|
else if (!vdir->offset) *curr_dir = '\0'; // relative root?
|
|
else {
|
|
// vdir->offset is offset of dir entry + 0x200
|
|
TarHeader* tar = (TarHeader*) OffsetVTarEntry(vdir->offset - 0x200);
|
|
strncpy(curr_dir, tar->fname, 100);
|
|
u32 len = strnlen(curr_dir, 100 + 1);
|
|
if (len == 101) return false; // path error
|
|
if (curr_dir[len-1] == '/') curr_dir[len-1] = '\0';
|
|
}
|
|
|
|
|
|
// using vdir index to signify the position limits us to 1TiB TARs
|
|
void* tardata = NULL;
|
|
if (vdir->index < 0) tardata = FirstVTarEntry();
|
|
else tardata = NextVTarEntry(OffsetVTarEntry(vdir->index << 9));
|
|
|
|
if (tardata) do {
|
|
TarHeader* tar = (TarHeader*) tardata;
|
|
char tar_fname[100 + 1];
|
|
char *name, *dir;
|
|
|
|
strncpy(tar_fname, tar->fname, 100);
|
|
if (!SplitTarFName(tar_fname, &dir, &name)) return false;
|
|
if ((!dir && !*curr_dir) || (dir && (strncmp(dir, curr_dir, 100) == 0))) break;
|
|
} while ((tardata = NextVTarEntry(tardata)));
|
|
|
|
// match found?
|
|
if (tardata) {
|
|
u64 fsize;
|
|
bool is_dir;
|
|
void* fdata = GetVTarFileInfo(tardata, NULL, &fsize, &is_dir);
|
|
|
|
vfile->offset = (u32) fdata - VRAM0_OFFSET;
|
|
vfile->size = fsize;
|
|
if (is_dir) vfile->flags |= VFLAG_DIR;
|
|
|
|
vdir->index = (vfile->offset >> 9) - 1;
|
|
} else { // not found
|
|
vdir->offset = (u64) -1;
|
|
return false;
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
int ReadVVramFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count) {
|
|
if (vfile->flags & VFLAG_DIR) return -1;
|
|
void* fdata = (u8*) VRAM0_OFFSET + vfile->offset;
|
|
|
|
// range checks in virtual.c
|
|
memcpy(buffer, (u8*) fdata + offset, count);
|
|
return 0;
|
|
}
|
|
|
|
bool GetVVramFilename(char* name, const VirtualFile* vfile) {
|
|
void* tardata = OffsetVTarEntry(vfile->offset - 0x200);
|
|
TarHeader* tar = (TarHeader*) tardata;
|
|
char tar_fname[100 + 1];
|
|
char *name_tmp, *dir;
|
|
|
|
strncpy(tar_fname, tar->fname, 100);
|
|
if (!SplitTarFName(tar_fname, &dir, &name_tmp)) return false;
|
|
strncpy(name, name_tmp, 100);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool MatchVVramFilename(const char* name, const VirtualFile* vfile) {
|
|
void* tardata = OffsetVTarEntry(vfile->offset - 0x200);
|
|
TarHeader* tar = (TarHeader*) tardata;
|
|
char tar_fname[100 + 1];
|
|
char *name_tmp, *dir;
|
|
|
|
strncpy(tar_fname, tar->fname, 100);
|
|
if (!SplitTarFName(tar_fname, &dir, &name_tmp)) return false;
|
|
return (strncasecmp(name, name_tmp, 100) == 0);
|
|
}
|
|
|
|
u64 GetVVramDriveSize(void) {
|
|
return VRAM0_LIMIT;
|
|
}
|