1
0
Fork 0
mirror of https://github.com/DarkMatterCore/nxdumptool.git synced 2024-11-22 18:26:39 +00:00

Some fixes and corrections.

* Fixed building using latest libnx commit + recently added pacman packages (switch-libxml2 and switch-libjson-c).
* Removed ncm-related code because libnx now includes what's needed by the application.
* Cleaned up the fs-srv service additional functions.
* Mounted partition filesystems are now properly closed.
* Changed some output text.
This commit is contained in:
Pablo Curiel 2018-07-21 01:56:00 -04:00
parent 3364f062b2
commit 01a3ebe477
10 changed files with 54 additions and 291 deletions

View file

@ -33,7 +33,7 @@ include $(DEVKITPRO)/libnx/switch_rules
VERSION_MAJOR := 1
VERSION_MINOR := 0
VERSION_MICRO := 5
VERSION_MICRO := 6
APP_TITLE := gcdumptool
APP_AUTHOR := MCMrARM, DarkMatterCore
@ -56,8 +56,8 @@ CFLAGS := -g -Wall -O2 -ffunction-sections \
$(ARCH) $(DEFINES)
CFLAGS += $(INCLUDE) -D__SWITCH__ -D__LINUX_ERRNO_EXTENSIONS__
CFLAGS += `aarch64-none-elf-pkg-config libxml-2.0 --cflags`
CFLAGS += `aarch64-none-elf-pkg-config zlib --cflags`
CFLAGS += `aarch64-none-elf-pkg-config libxml-2.0 --cflags`
CFLAGS += `aarch64-none-elf-pkg-config json-c --cflags`
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
@ -65,7 +65,7 @@ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS := -lcurl -lz -lnx -ljson-c -lxml2 -lm
LIBS := -lcurl -lxml2 -lz -lnx -ljson-c -lm
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing

View file

@ -1529,6 +1529,8 @@ bool dumpPartitionData(FsDeviceOperator* fsOperator, u32 partition)
snprintf(strbuf, sizeof(strbuf) / sizeof(strbuf[0]), "fsdevMountDevice failed! (%d)", ret);
uiDrawString(strbuf, 0, breaks * 8, 255, 0, 0);
}
fsFsClose(&fs);
} else {
snprintf(strbuf, sizeof(strbuf) / sizeof(strbuf[0]), "Failed to open partition #%u filesystem!", partition);
uiDrawString(strbuf, 0, breaks * 8, 255, 0, 0);
@ -1539,17 +1541,16 @@ bool dumpPartitionData(FsDeviceOperator* fsOperator, u32 partition)
return success;
}
bool mountViewPartition(FsDeviceOperator *fsOperator, u32 partition)
bool mountViewPartition(FsDeviceOperator *fsOperator, FsFileSystem *out, u32 partition)
{
FsFileSystem fs;
int ret;
bool success = false;
workaroundPartitionZeroAccess(fsOperator);
if (openPartitionFs(&fs, fsOperator, partition))
if (openPartitionFs(out, fsOperator, partition))
{
ret = fsdevMountDevice("view", fs);
ret = fsdevMountDevice("view", *out);
if (ret != -1)
{
//snprintf(strbuf, sizeof(strbuf) / sizeof(strbuf[0]), "fsdevMountDevice succeeded: %d", ret);
@ -1558,6 +1559,7 @@ bool mountViewPartition(FsDeviceOperator *fsOperator, u32 partition)
success = true;
} else {
fsFsClose(out);
snprintf(strbuf, sizeof(strbuf) / sizeof(strbuf[0]), "fsdevMountDevice failed! (%d)", ret);
uiDrawString(strbuf, 0, breaks * 8, 255, 0, 0);
}

View file

@ -83,7 +83,7 @@ bool copyDirectory(const char* source, const char* dest, bool doSplitting);
void removeDirectory(const char *path);
bool getDirectorySize(const char *path, u64 *out_size);
bool dumpPartitionData(FsDeviceOperator* fsOperator, u32 partition);
bool mountViewPartition(FsDeviceOperator *fsOperator, u32 partition);
bool mountViewPartition(FsDeviceOperator *fsOperator, FsFileSystem *out, u32 partition);
bool dumpGameCertificate(FsDeviceOperator *fsOperator);
#endif

View file

@ -15,7 +15,7 @@ Result fsOpenGameCardStorage(FsStorage* out, u32 handle, u32 partition)
u64 cmd_id;
u32 handle;
u32 partition;
} PACKED *raw;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
@ -54,7 +54,7 @@ Result fsOpenGameCardFileSystem(FsFileSystem* out, u32 handle, u32 partition)
u64 cmd_id;
u32 handle;
u32 partition;
} PACKED *raw;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
@ -198,40 +198,3 @@ Result fsDeviceOperatorUpdatePartitionInfo(FsDeviceOperator* d, u32 handle, u32*
return rc;
}
// FsStorage
Result fsStorageGetSize(FsStorage* s, u64* out)
{
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 4;
Result rc = serviceIpcDispatch(&s->s);
if (R_SUCCEEDED(rc))
{
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
u64 size;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) *out = resp->size;
}
return rc;
}

View file

@ -4,7 +4,6 @@
#include <memory.h>
#include "dumper.h"
#include "ncmext.h"
#include "ui.h"
#include "util.h"

View file

@ -1,170 +0,0 @@
#include <switch/arm/atomics.h>
#include <switch/kernel/ipc.h>
#include <stdlib.h>
#include <string.h>
#include "ncmext.h"
static Service g_ncm;
static u64 g_refCnt;
// IContentManager
Result ncmInitialize(void)
{
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_ncm)) return 0;
Result rc = smGetService(&g_ncm, "ncm");
return rc;
}
void ncmExit(void)
{
if (atomicDecrement64(&g_refCnt) == 0) serviceClose(&g_ncm);
}
Result ncmGetContentMetaDatabase(ncmContentMetaDatabase *out, FsStorageId storage_id)
{
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u8 storage_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 5;
raw->storage_id = storage_id;
Result rc = serviceIpcDispatch(&g_ncm);
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;
}
Result ncmOpenContentMetaDatabase(FsStorageId storage_id)
{
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u8 storage_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 11;
raw->storage_id = storage_id;
Result rc = serviceIpcDispatch(&g_ncm);
if (R_SUCCEEDED(rc))
{
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
} *resp = r.Raw;
rc = resp->result;
}
return rc;
}
Result ncmCloseContentMetaDatabase(FsStorageId storage_id)
{
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u8 storage_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 12;
raw->storage_id = storage_id;
Result rc = serviceIpcDispatch(&g_ncm);
if (R_SUCCEEDED(rc))
{
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
} *resp = r.Raw;
rc = resp->result;
}
return rc;
}
// IContentMetaDatabase
Result ncmMetaDatabaseListApplication(ncmContentMetaDatabase *md, ncmApplicationMetaKey *buffer, size_t size, u8 filter)
{
IpcCommand c;
ipcInitialize(&c);
ipcAddRecvBuffer(&c, buffer, size, BufferType_Normal);
struct {
u64 magic;
u64 cmd_id;
u8 filter;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 7;
raw->filter = filter;
Result rc = serviceIpcDispatch(&md->s);
if (R_SUCCEEDED(rc))
{
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
} *resp = r.Raw;
rc = resp->result;
}
return rc;
}

View file

@ -1,36 +0,0 @@
#pragma once
#ifndef __NCMEXT_H__
#define __NCMEXT_H__
#include <switch/types.h>
#include <switch/services/fs.h>
typedef struct {
Service s;
} ncmContentMetaDatabase;
typedef struct {
u64 titleID;
u32 titleVersion;
u8 type;
u8 unk1;
u16 unk2;
} ncmContentMetaKey;
typedef struct {
ncmContentMetaKey meta_record;
u64 base_title_id;
} ncmApplicationMetaKey;
// IContentManager
Result ncmInitialize(void);
void ncmExit(void);
Result ncmGetContentMetaDatabase(ncmContentMetaDatabase *out, FsStorageId storage_id);
Result ncmOpenContentMetaDatabase(FsStorageId storage_id);
Result ncmCloseContentMetaDatabase(FsStorageId storage_id);
// IContentMetaDatabase
Result ncmMetaDatabaseListApplication(ncmContentMetaDatabase *md, ncmApplicationMetaKey *buffer, size_t size, u8 filter);
#endif

View file

@ -35,6 +35,8 @@ static bool isFat32 = false, dumpCert = false, trimDump = false, calcCrc = true;
static u32 selectedOption;
static FsFileSystem fs;
static char statusMessage[2048] = {'\0'};
static int statusMessageFadeout = 0;
@ -60,14 +62,14 @@ static int filenamesCount = 0;
static UIState uiState;
static const char *appHeadline = "Nintendo Switch Game Card Dump Tool v" APP_VERSION ".\nOriginal code by MCMrARM.\nAdditional modifications by DarkMatterCore.\n\n";
static const char *appControls = "[D-Pad / Analog Stick] Move | [A] Select | [B] Back | [+] Exit";
static const char *appControls = "[D-Pad / Analog Sticks] Move | [A] Select | [B] Back | [+] Exit";
static const char *mainMenuItems[] = { "Full XCI Dump", "Raw Partition Dump", "Partition Data Dump", "View Game Card Files", "Dump Game Card Certificate", "Update nswdb.com XML database", "Update application (not working at this moment)" };
static const char *mainMenuItems[] = { "Full XCI dump", "Raw partition dump", "Partition data dump", "View game card files", "Dump game card certificate", "Update NSWDB.COM XML database", "Update application (not working at this moment)" };
static const char *xciDumpMenuItems[] = { "Start XCI dump process", "Split output dump (FAT32 support): ", "Dump certificate: ", "Trim output dump: ", "CRC32 checksum calculation + dump verification: " };
static const char *partitionDumpType1MenuItems[] = { "Dump Partition 0 (Update)", "Dump Partition 1 (Normal)", "Dump Partition 2 (Secure)" };
static const char *partitionDumpType2MenuItems[] = { "Dump Partition 0 (Update)", "Dump Partition 1 (Logo)", "Dump Partition 2 (Normal)", "Dump Partition 3 (Secure)" };
static const char *viewGameCardFsType1MenuItems[] = { "View Files from Partition 0 (Update)", "View Files from Partition 1 (Normal)", "View Files from Partition 2 (Secure)" };
static const char *viewGameCardFsType2MenuItems[] = { "View Files from Partition 0 (Update)", "View Files from Partition 1 (Logo)", "View Files from Partition 2 (Normal)", "View Files from Partition 3 (Secure)" };
static const char *partitionDumpType1MenuItems[] = { "Dump partition 0 (Update)", "Dump partition 1 (Normal)", "Dump partition 2 (Secure)" };
static const char *partitionDumpType2MenuItems[] = { "Dump partition 0 (Update)", "Dump partition 1 (Logo)", "Dump partition 2 (Normal)", "Dump partition 3 (Secure)" };
static const char *viewGameCardFsType1MenuItems[] = { "View files from partition 0 (Update)", "View files from partition 1 (Normal)", "View files from partition 2 (Secure)" };
static const char *viewGameCardFsType2MenuItems[] = { "View files from partition 0 (Update)", "View files from partition 1 (Logo)", "View files from partition 2 (Normal)", "View files from partition 3 (Secure)" };
static unsigned char asciiData[128][8] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x3E, 0x41, 0x55, 0x41, 0x55, 0x49, 0x3E},
@ -294,8 +296,6 @@ void uiInit()
void uiDeinit()
{
if (filenameBuffer) free(filenameBuffer);
if (uiState == stateViewGameCardFsBrowser) fsdevUnmountDevice("view");
}
void uiSetState(UIState state)
@ -342,7 +342,16 @@ UIResult uiLoop(u32 keysDown)
if (uiState == stateMainMenu || uiState == stateXciDumpMenu || uiState == stateRawPartitionDumpMenu || uiState == statePartitionDataDumpMenu || uiState == stateViewGameCardFsMenu || uiState == stateViewGameCardFsBrowser)
{
// Exit
if (keysDown & KEY_PLUS) return resultExit;
if (keysDown & KEY_PLUS)
{
if (uiState == stateViewGameCardFsBrowser)
{
fsdevUnmountDevice("view");
fsFsClose(&fs);
}
return resultExit;
}
uiDrawString(appControls, 0, breaks * 8, 255, 255, 255);
breaks += 2;
@ -395,7 +404,7 @@ UIResult uiLoop(u32 keysDown)
if (strlen(gameCardUpdateVersionStr))
{
breaks++;
snprintf(titlebuf, sizeof(titlebuf) / sizeof(titlebuf[0]), "Game Card FW Version: %s", gameCardUpdateVersionStr);
snprintf(titlebuf, sizeof(titlebuf) / sizeof(titlebuf[0]), "Bundled FW update: %s", gameCardUpdateVersionStr);
uiDrawString(titlebuf, 0, breaks * 8, 0, 255, 0);
}
} else {
@ -410,7 +419,7 @@ UIResult uiLoop(u32 keysDown)
if (strlen(gameCardUpdateVersionStr))
{
breaks++;
snprintf(titlebuf, sizeof(titlebuf) / sizeof(titlebuf[0]), "Game Card FW Version: %s", gameCardUpdateVersionStr);
snprintf(titlebuf, sizeof(titlebuf) / sizeof(titlebuf[0]), "Bundled FW Update: %s", gameCardUpdateVersionStr);
uiDrawString(titlebuf, 0, breaks * 8, 0, 255, 0);
breaks++;
@ -722,6 +731,7 @@ UIResult uiLoop(u32 keysDown)
if (!strcmp(currentDirectory, "view:/") && strlen(currentDirectory) == 6)
{
fsdevUnmountDevice("view");
fsFsClose(&fs);
res = resultShowViewGameCardFsMenu;
} else {
@ -807,7 +817,7 @@ UIResult uiLoop(u32 keysDown)
uiDrawString((hfs0_partition_cnt == GAMECARD_TYPE1_PARTITION_CNT ? viewGameCardFsType1MenuItems[selectedOption] : viewGameCardFsType1MenuItems[selectedOption]), 0, breaks * 8, 115, 115, 255);
breaks += 2;
if (mountViewPartition(&fsOperatorInstance, selectedOption))
if (mountViewPartition(&fsOperatorInstance, &fs, selectedOption))
{
enterDirectory("view:/");

View file

@ -9,6 +9,7 @@
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/socket.h>
#include <switch/services/ncm.h>
#include <switch/services/ns.h>
#include <libxml2/libxml/globals.h>
#include <libxml2/libxml/xpath.h>
@ -17,7 +18,6 @@
#include "dumper.h"
#include "fsext.h"
#include "ncmext.h"
#include "ui.h"
#include "util.h"
@ -77,38 +77,30 @@ bool getGameCardTitleIDAndVersion(u64 *titleID, u32 *version)
bool success = false;
Result result;
ncmContentMetaDatabase ncmDb;
NcmContentMetaDatabase ncmDb;
ncmApplicationMetaKey *appList = (ncmApplicationMetaKey*)malloc(sizeof(ncmApplicationMetaKey));
NcmApplicationContentMetaKey *appList = (NcmApplicationContentMetaKey*)malloc(sizeof(NcmApplicationContentMetaKey));
if (appList)
{
memset(appList, 0, sizeof(ncmApplicationMetaKey));
memset(appList, 0, sizeof(NcmApplicationContentMetaKey));
if (R_SUCCEEDED(result = ncmOpenContentMetaDatabase(FsStorageId_GameCard)))
if (R_SUCCEEDED(result = ncmOpenContentMetaDatabase(FsStorageId_GameCard, &ncmDb)))
{
if (R_SUCCEEDED(result = ncmGetContentMetaDatabase(&ncmDb, FsStorageId_GameCard)))
if (R_SUCCEEDED(result = ncmContentMetaDatabaseListApplication(&ncmDb, META_DATABASE_FILTER, appList, sizeof(NcmApplicationContentMetaKey), NULL, NULL)))
{
if (R_SUCCEEDED(result = ncmMetaDatabaseListApplication(&ncmDb, appList, sizeof(ncmApplicationMetaKey), 0)))
{
*titleID = appList->meta_record.titleID;
*version = appList->meta_record.titleVersion;
success = true;
} else {
uiStatusMsg("getGameCardTitleIDAndVersion: MetaDatabaseListApplication failed! (0x%08X)", result);
}
*titleID = appList->metaRecord.titleId;
*version = appList->metaRecord.version;
success = true;
} else {
uiStatusMsg("getGameCardTitleIDAndVersion: GetContentMetaDatabase failed! (0x%08X)", result);
uiStatusMsg("getGameCardTitleIDAndVersion: ncmContentMetaDatabaseListApplication failed! (0x%08X)", result);
}
} else {
uiStatusMsg("getGameCardTitleIDAndVersion: OpenContentMetaDatabase failed! (0x%08X)", result);
uiStatusMsg("getGameCardTitleIDAndVersion: ncmOpenContentMetaDatabase failed! (0x%08X)", result);
}
// Seems to cause problems
//if (R_FAILED(result = ncmCloseContentMetaDatabase(FsStorageId_GameCard))) uiStatusMsg("getGameCardTitleIDAndVersion: CloseContentMetaDatabase failed! (0x%08X)", result);
free(appList);
} else {
uiStatusMsg("getGameCardTitleIDAndVersion: Unable to allocate memory for the NCM service operations.");
uiStatusMsg("getGameCardTitleIDAndVersion: Unable to allocate memory for the ncm service operations.");
}
return success;
@ -147,7 +139,6 @@ bool getGameCardControlNacp(u64 titleID, char *nameBuf, int nameBufSize, char *a
{
strncpy(nameBuf, langentry->name, nameBufSize - 1);
strncpy(authorBuf, langentry->author, authorBufSize - 1);
success = true;
} else {
uiStatusMsg("getGameCardControlNacp: GetLanguageEntry failed! (0x%08X)", result);
@ -161,7 +152,7 @@ bool getGameCardControlNacp(u64 titleID, char *nameBuf, int nameBufSize, char *a
free(buf);
} else {
uiStatusMsg("getGameCardControlNacp: Unable to allocate memory for the NS service operations.");
uiStatusMsg("getGameCardControlNacp: Unable to allocate memory for the ns service operations.");
}
return success;

View file

@ -5,9 +5,13 @@
#include <switch.h>
#define APP_VERSION "1.0.5"
#define NAME_BUF_LEN 4096
#define SOCK_BUFFERSIZE 65536
#define APP_VERSION "1.0.6"
#define NAME_BUF_LEN 4096
#define SOCK_BUFFERSIZE 65536
#define META_DATABASE_FILTER 0x80 // Regular Application
bool isGameCardInserted(FsDeviceOperator* o);