mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-12-23 17:06:02 +00:00
Browse files from the update partition
This commit is contained in:
parent
18e0170bcb
commit
7a47bf55e3
7 changed files with 163 additions and 78 deletions
|
@ -10,11 +10,25 @@ void workaroundPartitionZeroAccess(FsDeviceOperator* fsOperator) {
|
||||||
if (R_FAILED(fsDeviceOperatorGetGameCardHandle(fsOperator, &handle)))
|
if (R_FAILED(fsDeviceOperatorGetGameCardHandle(fsOperator, &handle)))
|
||||||
return;
|
return;
|
||||||
FsStorage gameCardStorage;
|
FsStorage gameCardStorage;
|
||||||
if (R_FAILED(fsOpenGameCard(&gameCardStorage, handle, 0)))
|
if (R_FAILED(fsOpenGameCardStorage(&gameCardStorage, handle, 0)))
|
||||||
return;
|
return;
|
||||||
fsStorageClose(&gameCardStorage);
|
fsStorageClose(&gameCardStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool openPartitionFs(FsFileSystem* ret, FsDeviceOperator* fsOperator, u32 partition) {
|
||||||
|
u32 handle;
|
||||||
|
if (R_FAILED(fsDeviceOperatorGetGameCardHandle(fsOperator, &handle))) {
|
||||||
|
printf("GetGameCardHandle failed\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Result result;
|
||||||
|
if (R_FAILED(result = fsMountGameCard(ret, handle, partition))) {
|
||||||
|
printf("MountGameCard failed %x\n", result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
printf("Opened card\n");
|
||||||
|
}
|
||||||
|
|
||||||
bool dumpPartitionRaw(FsDeviceOperator* fsOperator, u32 partition) {
|
bool dumpPartitionRaw(FsDeviceOperator* fsOperator, u32 partition) {
|
||||||
u32 handle;
|
u32 handle;
|
||||||
if (R_FAILED(fsDeviceOperatorGetGameCardHandle(fsOperator, &handle))) {
|
if (R_FAILED(fsDeviceOperatorGetGameCardHandle(fsOperator, &handle))) {
|
||||||
|
@ -32,7 +46,7 @@ bool dumpPartitionRaw(FsDeviceOperator* fsOperator, u32 partition) {
|
||||||
|
|
||||||
FsStorage gameCardStorage;
|
FsStorage gameCardStorage;
|
||||||
Result result;
|
Result result;
|
||||||
if (R_FAILED(result = fsOpenGameCard(&gameCardStorage, handle, partition))) {
|
if (R_FAILED(result = fsOpenGameCardStorage(&gameCardStorage, handle, partition))) {
|
||||||
printf("MountGameCard failed %x\n", result);
|
printf("MountGameCard failed %x\n", result);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,4 +3,5 @@
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
|
||||||
void workaroundPartitionZeroAccess(FsDeviceOperator* fsOperator);
|
void workaroundPartitionZeroAccess(FsDeviceOperator* fsOperator);
|
||||||
|
bool openPartitionFs(FsFileSystem* ret, FsDeviceOperator* fsOperator, u32 partition);
|
||||||
bool dumpPartitionRaw(FsDeviceOperator* fsOperator, u32 partition);
|
bool dumpPartitionRaw(FsDeviceOperator* fsOperator, u32 partition);
|
77
source/filebrowser.c
Normal file
77
source/filebrowser.c
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#include "filebrowser.h"
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void openMainMenu();
|
||||||
|
|
||||||
|
MenuItem* currentFileListBuf;
|
||||||
|
|
||||||
|
void freeCurrentFileListBuf() {
|
||||||
|
MenuItem* ptr = currentFileListBuf;
|
||||||
|
while (ptr != NULL) {
|
||||||
|
free(ptr->text);
|
||||||
|
if (ptr->userdata != NULL)
|
||||||
|
free(ptr->userdata);
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
free(currentFileListBuf);
|
||||||
|
}
|
||||||
|
void exitFileList() {
|
||||||
|
freeCurrentFileListBuf();
|
||||||
|
openMainMenu();
|
||||||
|
}
|
||||||
|
char* getParentDir(const char* path) {
|
||||||
|
char* ptr = strrchr(path, '/');
|
||||||
|
if (ptr == NULL || ptr == path) // not found or first character
|
||||||
|
return NULL;
|
||||||
|
char* retval = (char*) malloc(ptr - path + 1);
|
||||||
|
memcpy(retval, path, ptr - path);
|
||||||
|
retval[ptr - path] = '\0';
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
char* pathJoin(const char* p1, const char* p2) {
|
||||||
|
size_t p1s = strlen(p1);
|
||||||
|
if (p1s == 0)
|
||||||
|
return strdup(p2);
|
||||||
|
size_t p2s = strlen(p2);
|
||||||
|
char* retval = (char*) malloc(p1s + 1 + p2s + 1);
|
||||||
|
memcpy(retval, p1, p1s);
|
||||||
|
retval[p1s] = '/';
|
||||||
|
memcpy(&retval[p1s + 1], p2, p2s + 1); // copy with null terminator
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
void printFilesInDir(const char* path) {
|
||||||
|
int maxMenuItemCount = 48;
|
||||||
|
MenuItem* buf = (MenuItem*) malloc(sizeof(MenuItem) * (maxMenuItemCount + 1));
|
||||||
|
currentFileListBuf = buf;
|
||||||
|
DIR* dir = opendir(path);
|
||||||
|
struct dirent* ent;
|
||||||
|
int bufi = 0;
|
||||||
|
char* parentDir = getParentDir(path);
|
||||||
|
if (parentDir != NULL) {
|
||||||
|
buf[bufi].userdata = parentDir;
|
||||||
|
buf[bufi].text = strdup("..");
|
||||||
|
buf[bufi].callback = printFilesInDirMenuItem;
|
||||||
|
bufi++;
|
||||||
|
}
|
||||||
|
while ((ent = readdir(dir)) != NULL) {
|
||||||
|
if (ent->d_type == DT_DIR) {
|
||||||
|
buf[bufi].text = pathJoin(ent->d_name, "");
|
||||||
|
buf[bufi].userdata = pathJoin(path, ent->d_name);
|
||||||
|
buf[bufi].callback = printFilesInDirMenuItem;
|
||||||
|
} else {
|
||||||
|
buf[bufi].text = strdup(ent->d_name);
|
||||||
|
buf[bufi].userdata = buf[bufi].callback = NULL;
|
||||||
|
}
|
||||||
|
if (++bufi >= maxMenuItemCount)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buf[bufi].text = NULL;
|
||||||
|
closedir(dir);
|
||||||
|
menuSetCurrent(buf, exitFileList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printFilesInDirMenuItem(MenuItem* item) {
|
||||||
|
printFilesInDir(item->userdata);
|
||||||
|
}
|
6
source/filebrowser.h
Normal file
6
source/filebrowser.h
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "menu.h"
|
||||||
|
|
||||||
|
void printFilesInDir(const char* path);
|
||||||
|
void printFilesInDirMenuItem(MenuItem* item);
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
|
|
||||||
// IFileSystemProxy
|
// IFileSystemProxy
|
||||||
Result fsOpenGameCard(FsStorage* out, u32 handle, u32 partition) {
|
Result fsOpenGameCardStorage(FsStorage* out, u32 handle, u32 partition) {
|
||||||
IpcCommand c;
|
IpcCommand c;
|
||||||
ipcInitialize(&c);
|
ipcInitialize(&c);
|
||||||
|
|
||||||
|
@ -42,6 +42,44 @@ Result fsOpenGameCard(FsStorage* out, u32 handle, u32 partition) {
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
Result fsMountGameCard(FsFileSystem* out, u32 handle, u32 partition) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
u32 handle;
|
||||||
|
u32 partition;
|
||||||
|
} PACKED *raw;
|
||||||
|
|
||||||
|
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||||
|
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = 31;
|
||||||
|
raw->handle = handle;
|
||||||
|
raw->partition = partition;
|
||||||
|
|
||||||
|
Result rc = serviceIpcDispatch(fsGetServiceSession());
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcParsedCommand r;
|
||||||
|
ipcParse(&r);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
} *resp = r.Raw;
|
||||||
|
|
||||||
|
rc = resp->result;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
serviceCreate(&out->s, r.Handles[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// IDeviceOperator
|
// IDeviceOperator
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include <switch/services/fs.h>
|
#include <switch/services/fs.h>
|
||||||
|
|
||||||
// IFileSystemProxy
|
// IFileSystemProxy
|
||||||
Result fsOpenGameCard(FsStorage* out, u32 handle, u32 partition);
|
Result fsOpenGameCardStorage(FsStorage* out, u32 handle, u32 partition);
|
||||||
|
Result fsMountGameCard(FsFileSystem* out, u32 handle, u32 partition);
|
||||||
|
|
||||||
|
|
||||||
// IDeviceOperator
|
// IDeviceOperator
|
||||||
|
|
|
@ -2,17 +2,19 @@
|
||||||
|
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <dirent.h>
|
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "dumper.h"
|
#include "dumper.h"
|
||||||
#include "ccolor.h"
|
#include "ccolor.h"
|
||||||
|
#include "filebrowser.h"
|
||||||
|
|
||||||
FsDeviceOperator fsOperatorInstance;
|
FsDeviceOperator fsOperatorInstance;
|
||||||
|
|
||||||
bool shouldExit = false;
|
bool shouldExit = false;
|
||||||
bool shouldWaitForAnyButton = false;
|
bool shouldWaitForAnyButton = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void menuExit() {
|
void menuExit() {
|
||||||
shouldExit = true;
|
shouldExit = true;
|
||||||
}
|
}
|
||||||
|
@ -34,85 +36,32 @@ void dumpPartitionZero(MenuItem* item) {
|
||||||
menuWaitForAnyButton();
|
menuWaitForAnyButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
void printFilesInDirMenuItem(MenuItem* item);
|
void viewPartitionZero() {
|
||||||
|
startOperation("Mount Partition 0 (SysUpdate)");
|
||||||
|
workaroundPartitionZeroAccess(&fsOperatorInstance);
|
||||||
|
FsFileSystem fs;
|
||||||
|
if (!openPartitionFs(&fs, &fsOperatorInstance, 0)) {
|
||||||
|
menuWaitForAnyButton();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fsdevMountDevice("test", fs) == -1) {
|
||||||
|
printf("fsdevMountDevice failed\n");
|
||||||
|
menuWaitForAnyButton();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printFilesInDir("test:/");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MenuItem mainMenu[] = {
|
MenuItem mainMenu[] = {
|
||||||
{ .text = "Raw Dump Partition 0 (SysUpdate)", .callback = dumpPartitionZero },
|
{ .text = "Raw Dump Partition 0 (SysUpdate)", .callback = dumpPartitionZero },
|
||||||
{ .text = "Print files on SD Card", .callback = printFilesInDirMenuItem, .userdata = "/" },
|
{ .text = "View files on Game Card (SysUpdate)", .callback = viewPartitionZero },
|
||||||
{ .text = NULL }
|
{ .text = NULL }
|
||||||
};
|
};
|
||||||
|
void openMainMenu() {
|
||||||
|
|
||||||
MenuItem* currentFileListBuf;
|
|
||||||
|
|
||||||
void freeCurrentFileListBuf() {
|
|
||||||
MenuItem* ptr = currentFileListBuf;
|
|
||||||
while (ptr != NULL) {
|
|
||||||
free(ptr->text);
|
|
||||||
if (ptr->userdata != NULL)
|
|
||||||
free(ptr->userdata);
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
free(currentFileListBuf);
|
|
||||||
}
|
|
||||||
void exitFileList() {
|
|
||||||
freeCurrentFileListBuf();
|
|
||||||
menuSetCurrent(mainMenu, menuExit);
|
menuSetCurrent(mainMenu, menuExit);
|
||||||
}
|
}
|
||||||
char* getParentDir(const char* path) {
|
|
||||||
char* ptr = strrchr(path, '/');
|
|
||||||
if (ptr == NULL || ptr == path) // not found or first character
|
|
||||||
return NULL;
|
|
||||||
char* retval = (char*) malloc(ptr - path + 1);
|
|
||||||
memcpy(retval, path, ptr - path);
|
|
||||||
retval[ptr - path] = '\0';
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
char* pathJoin(const char* p1, const char* p2) {
|
|
||||||
size_t p1s = strlen(p1);
|
|
||||||
if (p1s == 0)
|
|
||||||
return strdup(p2);
|
|
||||||
size_t p2s = strlen(p2);
|
|
||||||
char* retval = (char*) malloc(p1s + 1 + p2s + 1);
|
|
||||||
memcpy(retval, p1, p1s);
|
|
||||||
retval[p1s] = '/';
|
|
||||||
memcpy(&retval[p1s + 1], p2, p2s + 1); // copy with null terminator
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
void printFilesInDir(const char* path) {
|
|
||||||
int maxMenuItemCount = 48;
|
|
||||||
MenuItem* buf = (MenuItem*) malloc(sizeof(MenuItem) * (maxMenuItemCount + 1));
|
|
||||||
currentFileListBuf = buf;
|
|
||||||
DIR* dir = opendir(path);
|
|
||||||
struct dirent* ent;
|
|
||||||
int bufi = 0;
|
|
||||||
char* parentDir = getParentDir(path);
|
|
||||||
if (parentDir != NULL) {
|
|
||||||
buf[bufi].userdata = parentDir;
|
|
||||||
buf[bufi].text = strdup("..");
|
|
||||||
buf[bufi].callback = printFilesInDirMenuItem;
|
|
||||||
bufi++;
|
|
||||||
}
|
|
||||||
while ((ent = readdir(dir)) != NULL) {
|
|
||||||
if (ent->d_type == DT_DIR) {
|
|
||||||
buf[bufi].text = pathJoin(ent->d_name, "");
|
|
||||||
buf[bufi].userdata = pathJoin(path, ent->d_name);
|
|
||||||
buf[bufi].callback = printFilesInDirMenuItem;
|
|
||||||
} else {
|
|
||||||
buf[bufi].text = strdup(ent->d_name);
|
|
||||||
buf[bufi].userdata = buf[bufi].callback = NULL;
|
|
||||||
}
|
|
||||||
if (++bufi >= maxMenuItemCount)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
buf[bufi].text = NULL;
|
|
||||||
closedir(dir);
|
|
||||||
menuSetCurrent(buf, exitFileList);
|
|
||||||
}
|
|
||||||
|
|
||||||
void printFilesInDirMenuItem(MenuItem* item) {
|
|
||||||
printFilesInDir(item->userdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
@ -123,8 +72,7 @@ int main(int argc, char **argv) {
|
||||||
printf("Failed to open device operator\n");
|
printf("Failed to open device operator\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
openMainMenu();
|
||||||
menuSetCurrent(mainMenu, menuExit);
|
|
||||||
|
|
||||||
while(appletMainLoop())
|
while(appletMainLoop())
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue