1
0
Fork 0
mirror of https://github.com/DarkMatterCore/nxdumptool.git synced 2024-12-27 02:46:02 +00:00

Tweaked gamecard code.

Modified gamecard handle retrieval and storage area mounting. Added gamecard status codes.
This commit is contained in:
Pablo Curiel 2020-07-17 01:01:31 -04:00
parent 95d5bda83a
commit 6bee2c5d20
4 changed files with 48 additions and 48 deletions

View file

@ -129,7 +129,7 @@ static void gamecardFreeInfo(void);
static bool gamecardReadSecurityInformation(void);
static bool gamecardGetHandle(void);
static bool gamecardGetHandleAndStorage(u32 partition);
NX_INLINE void gamecardCloseHandle(void);
static bool gamecardOpenStorageArea(u8 area);
@ -262,12 +262,12 @@ UEvent *gamecardGetStatusChangeUserEvent(void)
return event;
}
bool gamecardIsReady(void)
u8 gamecardGetStatus(void)
{
mutexLock(&g_gamecardMutex);
bool ret = (g_gameCardInserted && g_gameCardInfoLoaded);
u8 status = (g_gameCardInserted ? (g_gameCardInfoLoaded ? GameCardStatus_InsertedAndInfoLoaded : GameCardStatus_InsertedAndInfoNotLoaded) : GameCardStatus_NotInserted);
mutexUnlock(&g_gamecardMutex);
return ret;
return status;
}
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);
/* 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();
if (g_gameCardInserted) gamecardLoadInfo();
ueventSignal(&g_gameCardStatusChangeEvent);
@ -559,6 +559,7 @@ static int gamecardDetectionThreadFunc(void *arg)
mutexUnlock(&g_gamecardMutex);
/* Signal user mode gamecard status change event. */
ueventSignal(&g_gameCardStatusChangeEvent);
}
@ -815,49 +816,51 @@ static bool gamecardReadSecurityInformation(void)
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;
}
Result rc1 = 0, rc2 = 0;
FsStorage tmp_storage = {0};
/* 10 tries. */
for(u8 i = 0; i < 10; i++)
{
/* First try to open a gamecard storage area using the current gamecard handle. */
rc1 = fsOpenGameCardStorage(&tmp_storage, &g_gameCardHandle, 0);
if (R_SUCCEEDED(rc1))
/* 100 ms wait in case there was an error in the previous loop. */
if (R_FAILED(rc1) || R_FAILED(rc2)) svcSleepThread(100000000);
/* 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);
break;
LOGFILE("fsDeviceOperatorGetGameCardHandle failed on try #%u! (0x%08X).", i + 1, rc1);
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. */
gamecardCloseHandle();
rc2 = fsDeviceOperatorGetGameCardHandle(&g_deviceOperator, &g_gameCardHandle);
/* If the previous call succeeded, let's try to open the desired gamecard storage area. */
rc2 = fsOpenGameCardStorage(&g_gameCardStorage, &g_gameCardHandle, partition);
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))
{
/* 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;
return (R_SUCCEEDED(rc1) && R_SUCCEEDED(rc2));
}
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);
g_gameCardHandle.value = 0;
}
@ -870,29 +873,20 @@ static bool gamecardOpenStorageArea(u8 area)
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;
/* Close both gamecard handle and open storage area. */
gamecardCloseStorageArea();
Result rc = 0;
u32 partition = (area - 1); /* Zero-based index. */
/* Retrieve a new gamecard handle. */
if (!gamecardGetHandle())
/* Retrieve both a new gamecard handle and a storage area handle. */
if (!gamecardGetHandleAndStorage(area - 1)) /* Zero-based index. */
{
LOGFILE("Failed to retrieve gamecard 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();
LOGFILE("Failed to retrieve gamecard handle and storage area handle!");
return false;
}
/* Update current gamecard storage area. */
g_gameCardStorageCurrentArea = area;
return true;

View file

@ -177,6 +177,12 @@ typedef struct {
GameCardHeaderEncryptedArea encrypted_area;
} 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 {
GameCardHashFileSystemPartitionType_Root = 0,
GameCardHashFileSystemPartitionType_Update = 1,
@ -198,9 +204,8 @@ void gamecardExit(void);
/// If the gamecard interface hasn't been initialized, this returns NULL.
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).
/// If this call returns false, it pretty much means nothing can be done with the inserted gamecard.
bool gamecardIsReady(void);
/// Returns the current GameCardStatus value.
u8 gamecardGetStatus(void);
/// Used to read data from the inserted gamecard.
/// All required handles, changes between normal <-> secure storage areas and proper offset calculations are managed internally.

View file

@ -29,6 +29,8 @@
#include "usb.h"
#include "fatfs/ff.h"
#define LOGFILE_PATH "./nxdumptool.log"
/* Global variables. */
static bool g_resourcesInitialized = false;

View file

@ -38,7 +38,6 @@
#include <switch.h>
#define APP_BASE_PATH "sdmc:/switch/nxdumptool/"
#define LOGFILE_PATH APP_BASE_PATH "nxdumptool.log"
#define MEMBER_SIZE(type, member) sizeof(((type*)NULL)->member)