mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-11-29 13:42:11 +00:00
Tweaked gamecard code.
Modified gamecard handle retrieval and storage area mounting. Added gamecard status codes.
This commit is contained in:
parent
95d5bda83a
commit
6bee2c5d20
4 changed files with 48 additions and 48 deletions
|
@ -129,7 +129,7 @@ static void gamecardFreeInfo(void);
|
||||||
|
|
||||||
static bool gamecardReadSecurityInformation(void);
|
static bool gamecardReadSecurityInformation(void);
|
||||||
|
|
||||||
static bool gamecardGetHandle(void);
|
static bool gamecardGetHandleAndStorage(u32 partition);
|
||||||
NX_INLINE void gamecardCloseHandle(void);
|
NX_INLINE void gamecardCloseHandle(void);
|
||||||
|
|
||||||
static bool gamecardOpenStorageArea(u8 area);
|
static bool gamecardOpenStorageArea(u8 area);
|
||||||
|
@ -262,12 +262,12 @@ UEvent *gamecardGetStatusChangeUserEvent(void)
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gamecardIsReady(void)
|
u8 gamecardGetStatus(void)
|
||||||
{
|
{
|
||||||
mutexLock(&g_gamecardMutex);
|
mutexLock(&g_gamecardMutex);
|
||||||
bool ret = (g_gameCardInserted && g_gameCardInfoLoaded);
|
u8 status = (g_gameCardInserted ? (g_gameCardInfoLoaded ? GameCardStatus_InsertedAndInfoLoaded : GameCardStatus_InsertedAndInfoNotLoaded) : GameCardStatus_NotInserted);
|
||||||
mutexUnlock(&g_gamecardMutex);
|
mutexUnlock(&g_gamecardMutex);
|
||||||
return ret;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gamecardReadStorage(void *out, u64 read_size, u64 offset)
|
bool gamecardReadStorage(void *out, u64 read_size, u64 offset)
|
||||||
|
@ -527,7 +527,7 @@ static int gamecardDetectionThreadFunc(void *arg)
|
||||||
Waiter exit_event_waiter = waiterForUEvent(&g_gameCardDetectionThreadExitEvent);
|
Waiter exit_event_waiter = waiterForUEvent(&g_gameCardDetectionThreadExitEvent);
|
||||||
|
|
||||||
/* Retrieve initial gamecard insertion status. */
|
/* Retrieve initial gamecard insertion status. */
|
||||||
/* Load gamecard info right away if a gamecard is inserted. */
|
/* Load gamecard info right away if a gamecard is inserted, then signal the user mode gamecard status change event. */
|
||||||
g_gameCardInserted = gamecardIsInserted();
|
g_gameCardInserted = gamecardIsInserted();
|
||||||
if (g_gameCardInserted) gamecardLoadInfo();
|
if (g_gameCardInserted) gamecardLoadInfo();
|
||||||
ueventSignal(&g_gameCardStatusChangeEvent);
|
ueventSignal(&g_gameCardStatusChangeEvent);
|
||||||
|
@ -559,6 +559,7 @@ static int gamecardDetectionThreadFunc(void *arg)
|
||||||
|
|
||||||
mutexUnlock(&g_gamecardMutex);
|
mutexUnlock(&g_gamecardMutex);
|
||||||
|
|
||||||
|
/* Signal user mode gamecard status change event. */
|
||||||
ueventSignal(&g_gameCardStatusChangeEvent);
|
ueventSignal(&g_gameCardStatusChangeEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,49 +816,51 @@ static bool gamecardReadSecurityInformation(void)
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool gamecardGetHandle(void)
|
static bool gamecardGetHandleAndStorage(u32 partition)
|
||||||
{
|
{
|
||||||
if (!g_gameCardInserted)
|
if (!g_gameCardInserted || partition > 1)
|
||||||
{
|
{
|
||||||
LOGFILE("Gamecard not inserted!");
|
LOGFILE("Invalid parameters!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result rc1 = 0, rc2 = 0;
|
Result rc1 = 0, rc2 = 0;
|
||||||
FsStorage tmp_storage = {0};
|
|
||||||
|
|
||||||
/* 10 tries. */
|
/* 10 tries. */
|
||||||
for(u8 i = 0; i < 10; i++)
|
for(u8 i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
/* First try to open a gamecard storage area using the current gamecard handle. */
|
/* 100 ms wait in case there was an error in the previous loop. */
|
||||||
rc1 = fsOpenGameCardStorage(&tmp_storage, &g_gameCardHandle, 0);
|
if (R_FAILED(rc1) || R_FAILED(rc2)) svcSleepThread(100000000);
|
||||||
if (R_SUCCEEDED(rc1))
|
|
||||||
|
/* First, let's try to retrieve a gamecard handle. */
|
||||||
|
/* This can return 0x140A02 if the "nogc" patch is enabled by the running CFW. */
|
||||||
|
rc1 = fsDeviceOperatorGetGameCardHandle(&g_deviceOperator, &g_gameCardHandle);
|
||||||
|
if (R_FAILED(rc1))
|
||||||
{
|
{
|
||||||
fsStorageClose(&tmp_storage);
|
LOGFILE("fsDeviceOperatorGetGameCardHandle failed on try #%u! (0x%08X).", i + 1, rc1);
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the previous call failed, we may have an invalid handle, so let's close the current one and try to retrieve a new one. */
|
/* If the previous call succeeded, let's try to open the desired gamecard storage area. */
|
||||||
gamecardCloseHandle();
|
rc2 = fsOpenGameCardStorage(&g_gameCardStorage, &g_gameCardHandle, partition);
|
||||||
rc2 = fsDeviceOperatorGetGameCardHandle(&g_deviceOperator, &g_gameCardHandle);
|
if (R_FAILED(rc2))
|
||||||
|
{
|
||||||
|
gamecardCloseHandle(); /* Close invalid gamecard handle. */
|
||||||
|
LOGFILE("fsOpenGameCardStorage failed to open %s storage area on try #%u! (0x%08X).", GAMECARD_STORAGE_AREA_NAME(partition + 1), i + 1, rc2);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we got up to this point, both a valid gamecard handle and a valid storage area handle are guaranteed. */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (R_FAILED(rc1) || R_FAILED(rc2))
|
return (R_SUCCEEDED(rc1) && R_SUCCEEDED(rc2));
|
||||||
{
|
|
||||||
/* Close leftover gamecard handle. */
|
|
||||||
gamecardCloseHandle();
|
|
||||||
|
|
||||||
if (R_FAILED(rc1)) LOGFILE("fsOpenGameCardStorage failed! (0x%08X).", rc1);
|
|
||||||
if (R_FAILED(rc2)) LOGFILE("fsDeviceOperatorGetGameCardHandle failed! (0x%08X).", rc2);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NX_INLINE void gamecardCloseHandle(void)
|
NX_INLINE void gamecardCloseHandle(void)
|
||||||
{
|
{
|
||||||
|
/* I need to find a way to properly close a gamecard handle... */
|
||||||
|
if (!g_gameCardHandle.value) return;
|
||||||
svcCloseHandle(g_gameCardHandle.value);
|
svcCloseHandle(g_gameCardHandle.value);
|
||||||
g_gameCardHandle.value = 0;
|
g_gameCardHandle.value = 0;
|
||||||
}
|
}
|
||||||
|
@ -870,29 +873,20 @@ static bool gamecardOpenStorageArea(u8 area)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return right away if a valid handle has already been retrieved and the desired gamecard storage area is currently open. */
|
||||||
if (g_gameCardHandle.value && serviceIsActive(&(g_gameCardStorage.s)) && g_gameCardStorageCurrentArea == area) return true;
|
if (g_gameCardHandle.value && serviceIsActive(&(g_gameCardStorage.s)) && g_gameCardStorageCurrentArea == area) return true;
|
||||||
|
|
||||||
|
/* Close both gamecard handle and open storage area. */
|
||||||
gamecardCloseStorageArea();
|
gamecardCloseStorageArea();
|
||||||
|
|
||||||
Result rc = 0;
|
/* Retrieve both a new gamecard handle and a storage area handle. */
|
||||||
u32 partition = (area - 1); /* Zero-based index. */
|
if (!gamecardGetHandleAndStorage(area - 1)) /* Zero-based index. */
|
||||||
|
|
||||||
/* Retrieve a new gamecard handle. */
|
|
||||||
if (!gamecardGetHandle())
|
|
||||||
{
|
{
|
||||||
LOGFILE("Failed to retrieve gamecard handle!");
|
LOGFILE("Failed to retrieve gamecard handle and storage area handle!");
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open storage area. */
|
|
||||||
rc = fsOpenGameCardStorage(&g_gameCardStorage, &g_gameCardHandle, partition);
|
|
||||||
if (R_FAILED(rc))
|
|
||||||
{
|
|
||||||
LOGFILE("fsOpenGameCardStorage failed to open %s storage area! (0x%08X).", GAMECARD_STORAGE_AREA_NAME(area), rc);
|
|
||||||
gamecardCloseHandle();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update current gamecard storage area. */
|
||||||
g_gameCardStorageCurrentArea = area;
|
g_gameCardStorageCurrentArea = area;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -177,6 +177,12 @@ typedef struct {
|
||||||
GameCardHeaderEncryptedArea encrypted_area;
|
GameCardHeaderEncryptedArea encrypted_area;
|
||||||
} GameCardHeader;
|
} GameCardHeader;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GameCardStatus_NotInserted = 0,
|
||||||
|
GameCardStatus_InsertedAndInfoNotLoaded = 1, ///< Most likely related to the "nogc" patch being enabled. Means nothing at all can be done with the inserted gamecard.
|
||||||
|
GameCardStatus_InsertedAndInfoLoaded = 2
|
||||||
|
} GameCardStatus;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GameCardHashFileSystemPartitionType_Root = 0,
|
GameCardHashFileSystemPartitionType_Root = 0,
|
||||||
GameCardHashFileSystemPartitionType_Update = 1,
|
GameCardHashFileSystemPartitionType_Update = 1,
|
||||||
|
@ -198,9 +204,8 @@ void gamecardExit(void);
|
||||||
/// If the gamecard interface hasn't been initialized, this returns NULL.
|
/// If the gamecard interface hasn't been initialized, this returns NULL.
|
||||||
UEvent *gamecardGetStatusChangeUserEvent(void);
|
UEvent *gamecardGetStatusChangeUserEvent(void);
|
||||||
|
|
||||||
/// Used to check if a gamecard has been inserted and if info could be loaded from it (e.g. physical storage access is possible).
|
/// Returns the current GameCardStatus value.
|
||||||
/// If this call returns false, it pretty much means nothing can be done with the inserted gamecard.
|
u8 gamecardGetStatus(void);
|
||||||
bool gamecardIsReady(void);
|
|
||||||
|
|
||||||
/// Used to read data from the inserted gamecard.
|
/// Used to read data from the inserted gamecard.
|
||||||
/// All required handles, changes between normal <-> secure storage areas and proper offset calculations are managed internally.
|
/// All required handles, changes between normal <-> secure storage areas and proper offset calculations are managed internally.
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "fatfs/ff.h"
|
#include "fatfs/ff.h"
|
||||||
|
|
||||||
|
#define LOGFILE_PATH "./nxdumptool.log"
|
||||||
|
|
||||||
/* Global variables. */
|
/* Global variables. */
|
||||||
|
|
||||||
static bool g_resourcesInitialized = false;
|
static bool g_resourcesInitialized = false;
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
|
||||||
#define APP_BASE_PATH "sdmc:/switch/nxdumptool/"
|
#define APP_BASE_PATH "sdmc:/switch/nxdumptool/"
|
||||||
#define LOGFILE_PATH APP_BASE_PATH "nxdumptool.log"
|
|
||||||
|
|
||||||
#define MEMBER_SIZE(type, member) sizeof(((type*)NULL)->member)
|
#define MEMBER_SIZE(type, member) sizeof(((type*)NULL)->member)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue