2018-05-15 17:00:19 +01:00
|
|
|
#pragma once
|
|
|
|
|
2018-06-21 07:42:46 +01:00
|
|
|
#ifndef __UTIL_H__
|
|
|
|
#define __UTIL_H__
|
|
|
|
|
2018-05-15 17:00:19 +01:00
|
|
|
#include <switch.h>
|
2019-06-05 23:44:18 +01:00
|
|
|
#include "nca.h"
|
2018-07-21 06:56:00 +01:00
|
|
|
|
2019-09-15 03:45:27 +01:00
|
|
|
#define APP_BASE_PATH "sdmc:/switch/"
|
|
|
|
#define NXDUMPTOOL_BASE_PATH APP_BASE_PATH "nxdumptool/"
|
|
|
|
#define XCI_DUMP_PATH NXDUMPTOOL_BASE_PATH "XCI/"
|
|
|
|
#define NSP_DUMP_PATH NXDUMPTOOL_BASE_PATH "NSP/"
|
|
|
|
#define HFS0_DUMP_PATH NXDUMPTOOL_BASE_PATH "HFS0/"
|
|
|
|
#define EXEFS_DUMP_PATH NXDUMPTOOL_BASE_PATH "ExeFS/"
|
|
|
|
#define ROMFS_DUMP_PATH NXDUMPTOOL_BASE_PATH "RomFS/"
|
|
|
|
#define CERT_DUMP_PATH NXDUMPTOOL_BASE_PATH "Certificate/"
|
2019-06-09 02:36:21 +01:00
|
|
|
|
2019-05-01 21:24:13 +01:00
|
|
|
#define KiB (1024.0)
|
|
|
|
#define MiB (1024.0 * KiB)
|
|
|
|
#define GiB (1024.0 * MiB)
|
2018-07-21 06:56:00 +01:00
|
|
|
|
2019-08-17 11:33:50 +01:00
|
|
|
#define NAME_BUF_LEN 4096
|
2018-07-21 06:56:00 +01:00
|
|
|
|
2019-05-01 21:24:13 +01:00
|
|
|
#define SOCK_BUFFERSIZE 65536
|
2018-06-21 07:42:46 +01:00
|
|
|
|
2019-09-15 03:45:27 +01:00
|
|
|
#define DUMP_BUFFER_SIZE (u64)0x100000 // 1 MiB (1048576 bytes)
|
|
|
|
|
|
|
|
#define NCA_CTR_BUFFER_SIZE DUMP_BUFFER_SIZE // 1 MiB (1048576 bytes)
|
|
|
|
|
|
|
|
#define NSP_XML_BUFFER_SIZE (u64)0xA00000 // 10 MiB (10485760 bytes)
|
|
|
|
|
2019-05-01 21:24:13 +01:00
|
|
|
#define META_DB_REGULAR_APPLICATION 0x80
|
2019-06-05 23:44:18 +01:00
|
|
|
#define META_DB_PATCH 0x81
|
|
|
|
#define META_DB_ADDON 0x82
|
|
|
|
|
|
|
|
#define APPLICATION_PATCH_BITMASK (u64)0x800
|
|
|
|
#define APPLICATION_ADDON_BITMASK (u64)0xFFFFFFFFFFFF0000
|
2018-06-21 07:42:46 +01:00
|
|
|
|
2019-06-09 02:36:21 +01:00
|
|
|
#define FILENAME_LENGTH 512
|
2019-06-05 23:44:18 +01:00
|
|
|
#define FILENAME_MAX_CNT 20000
|
2019-06-09 02:36:21 +01:00
|
|
|
#define FILENAME_BUFFER_SIZE (FILENAME_LENGTH * FILENAME_MAX_CNT) // 10000 KiB
|
2019-05-01 21:24:13 +01:00
|
|
|
|
|
|
|
#define NACP_APPNAME_LEN 0x200
|
|
|
|
#define NACP_AUTHOR_LEN 0x100
|
|
|
|
#define VERSION_STR_LEN 0x40
|
|
|
|
|
2019-06-09 02:36:21 +01:00
|
|
|
#define GAMECARD_WAIT_TIME 3 // 3 seconds
|
2019-05-01 21:24:13 +01:00
|
|
|
|
|
|
|
#define GAMECARD_HEADER_SIZE 0x200
|
|
|
|
#define GAMECARD_SIZE_ADDR 0x10D
|
|
|
|
#define GAMECARD_DATAEND_ADDR 0x118
|
|
|
|
|
2019-06-28 21:13:54 +01:00
|
|
|
#define GAMECARD_ECC_BLOCK_SIZE (u64)0x200 // 512 bytes
|
|
|
|
#define GAMECARD_ECC_DATA_SIZE (u64)0x24 // 36 bytes
|
|
|
|
|
2019-05-01 21:24:13 +01:00
|
|
|
#define HFS0_OFFSET_ADDR 0x130
|
|
|
|
#define HFS0_SIZE_ADDR 0x138
|
2019-06-09 02:36:21 +01:00
|
|
|
#define HFS0_MAGIC (u32)0x48465330 // "HFS0"
|
2019-05-01 21:24:13 +01:00
|
|
|
#define HFS0_FILE_COUNT_ADDR 0x04
|
|
|
|
#define HFS0_STR_TABLE_SIZE_ADDR 0x08
|
|
|
|
#define HFS0_ENTRY_TABLE_ADDR 0x10
|
|
|
|
|
|
|
|
#define MEDIA_UNIT_SIZE 0x200
|
|
|
|
|
2019-06-09 02:36:21 +01:00
|
|
|
#define GAMECARD_TYPE1_PARTITION_CNT 3 // "update" (0), "normal" (1), "update" (2)
|
|
|
|
#define GAMECARD_TYPE2_PARTITION_CNT 4 // "update" (0), "logo" (1), "normal" (2), "update" (3)
|
2019-05-01 21:24:13 +01:00
|
|
|
#define GAMECARD_TYPE(x) ((x) == GAMECARD_TYPE1_PARTITION_CNT ? "Type 0x01" : ((x) == GAMECARD_TYPE2_PARTITION_CNT ? "Type 0x02" : "Unknown"))
|
|
|
|
#define GAMECARD_TYPE1_PART_NAMES(x) ((x) == 0 ? "Update" : ((x) == 1 ? "Normal" : ((x) == 2 ? "Secure" : "Unknown")))
|
|
|
|
#define GAMECARD_TYPE2_PART_NAMES(x) ((x) == 0 ? "Update" : ((x) == 1 ? "Logo" : ((x) == 2 ? "Normal" : ((x) == 3 ? "Secure" : "Unknown"))))
|
|
|
|
#define GAMECARD_PARTITION_NAME(x, y) ((x) == GAMECARD_TYPE1_PARTITION_CNT ? GAMECARD_TYPE1_PART_NAMES(y) : ((x) == GAMECARD_TYPE2_PARTITION_CNT ? GAMECARD_TYPE2_PART_NAMES(y) : "Unknown"))
|
|
|
|
|
|
|
|
#define HFS0_TO_ISTORAGE_IDX(x, y) ((x) == GAMECARD_TYPE1_PARTITION_CNT ? ((y) < 2 ? 0 : 1) : ((y) < 3 ? 0 : 1))
|
|
|
|
|
|
|
|
#define GAMECARD_SIZE_1GiB (u64)0x40000000
|
|
|
|
#define GAMECARD_SIZE_2GiB (u64)0x80000000
|
|
|
|
#define GAMECARD_SIZE_4GiB (u64)0x100000000
|
|
|
|
#define GAMECARD_SIZE_8GiB (u64)0x200000000
|
|
|
|
#define GAMECARD_SIZE_16GiB (u64)0x400000000
|
|
|
|
#define GAMECARD_SIZE_32GiB (u64)0x800000000
|
|
|
|
|
|
|
|
/* Reference: https://switchbrew.org/wiki/Title_list */
|
|
|
|
#define GAMECARD_UPDATE_TITLEID (u64)0x0100000000000816
|
|
|
|
|
2019-06-05 23:44:18 +01:00
|
|
|
#define NACP_ICON_SQUARE_DIMENSION 256
|
|
|
|
#define NACP_ICON_DOWNSCALED 96
|
|
|
|
|
2019-05-01 21:24:13 +01:00
|
|
|
#define bswap_32(a) ((((a) << 24) & 0xff000000) | (((a) << 8) & 0xff0000) | (((a) >> 8) & 0xff00) | (((a) >> 24) & 0xff))
|
|
|
|
#define round_up(x, y) ((x) + (((y) - ((x) % (y))) % (y))) // Aligns 'x' bytes to a 'y' bytes boundary
|
|
|
|
|
2019-06-09 02:36:21 +01:00
|
|
|
#define ORPHAN_ENTRY_TYPE_PATCH 1
|
|
|
|
#define ORPHAN_ENTRY_TYPE_ADDON 2
|
|
|
|
|
2019-06-05 23:44:18 +01:00
|
|
|
typedef struct {
|
2019-05-01 21:24:13 +01:00
|
|
|
u64 file_offset;
|
|
|
|
u64 file_size;
|
|
|
|
u32 filename_offset;
|
|
|
|
u32 hashed_region_size;
|
|
|
|
u64 reserved;
|
|
|
|
u8 hashed_region_sha256[0x20];
|
|
|
|
} PACKED hfs0_entry_table;
|
|
|
|
|
|
|
|
typedef struct {
|
2019-06-05 23:44:18 +01:00
|
|
|
int line_offset;
|
|
|
|
u64 totalSize;
|
|
|
|
char totalSizeStr[32];
|
|
|
|
u64 curOffset;
|
|
|
|
char curOffsetStr[32];
|
|
|
|
u8 progress;
|
|
|
|
u64 start;
|
|
|
|
u64 now;
|
|
|
|
u64 remainingTime;
|
|
|
|
char etaInfo[32];
|
|
|
|
double lastSpeed;
|
|
|
|
double averageSpeed;
|
2019-08-15 06:21:51 +01:00
|
|
|
u32 cancelBtnState;
|
|
|
|
u32 cancelBtnStatePrev;
|
|
|
|
u64 cancelStartTmr;
|
|
|
|
u64 cancelEndTmr;
|
2019-06-05 23:44:18 +01:00
|
|
|
} PACKED progress_ctx_t;
|
2019-04-21 17:27:33 +01:00
|
|
|
|
2019-09-15 03:45:27 +01:00
|
|
|
typedef enum {
|
|
|
|
ROMFS_TYPE_APP = 0,
|
|
|
|
ROMFS_TYPE_PATCH,
|
|
|
|
ROMFS_TYPE_ADDON
|
|
|
|
} selectedRomFsType;
|
|
|
|
|
2019-06-09 02:36:21 +01:00
|
|
|
typedef struct {
|
|
|
|
u32 index;
|
|
|
|
u8 type; // 1 = Patch, 2 = AddOn
|
|
|
|
} PACKED orphan_patch_addon_entry;
|
|
|
|
|
2019-04-21 17:27:33 +01:00
|
|
|
bool isGameCardInserted();
|
|
|
|
|
|
|
|
void fsGameCardDetectionThreadFunc(void *arg);
|
2018-06-21 07:42:46 +01:00
|
|
|
|
2019-06-28 21:13:54 +01:00
|
|
|
bool isServiceRunning(const char *serviceName);
|
|
|
|
|
|
|
|
bool checkSxOsServices();
|
|
|
|
|
2018-06-21 07:42:46 +01:00
|
|
|
void delay(u8 seconds);
|
|
|
|
|
2019-06-05 23:44:18 +01:00
|
|
|
void formatETAString(u64 curTime, char *output, u32 outSize);
|
|
|
|
|
2019-06-09 02:36:21 +01:00
|
|
|
void initExeFsContext();
|
2019-04-21 17:27:33 +01:00
|
|
|
|
2019-06-09 02:36:21 +01:00
|
|
|
void freeExeFsContext();
|
2019-05-01 21:24:13 +01:00
|
|
|
|
2019-06-05 23:44:18 +01:00
|
|
|
void initRomFsContext();
|
|
|
|
|
|
|
|
void freeRomFsContext();
|
|
|
|
|
2019-06-28 21:13:54 +01:00
|
|
|
void initBktrContext();
|
|
|
|
|
|
|
|
void freeBktrContext();
|
|
|
|
|
2019-06-09 02:36:21 +01:00
|
|
|
void freeGlobalData();
|
2019-05-01 21:24:13 +01:00
|
|
|
|
2019-09-15 03:45:27 +01:00
|
|
|
bool loadTitlesFromSdCardAndEmmc(u8 titleType);
|
2019-06-28 21:13:54 +01:00
|
|
|
|
2019-09-15 03:45:27 +01:00
|
|
|
void freeTitlesFromSdCardAndEmmc(u8 titleType);
|
2019-06-28 21:13:54 +01:00
|
|
|
|
2019-06-09 02:36:21 +01:00
|
|
|
void convertTitleVersionToDecimal(u32 version, char *versionBuf, size_t versionBufSize);
|
|
|
|
|
|
|
|
void removeIllegalCharacters(char *name);
|
|
|
|
|
|
|
|
void createOutputDirectories();
|
|
|
|
|
|
|
|
void strtrim(char *str);
|
|
|
|
|
|
|
|
void loadTitleInfo();
|
2019-04-21 17:27:33 +01:00
|
|
|
|
2019-06-05 23:44:18 +01:00
|
|
|
bool getHfs0EntryDetails(u8 *hfs0Header, u64 hfs0HeaderOffset, u64 hfs0HeaderSize, u32 num_entries, u32 entry_idx, bool isRoot, u32 partitionIndex, u64 *out_offset, u64 *out_size);
|
2019-05-01 21:24:13 +01:00
|
|
|
|
|
|
|
bool getPartitionHfs0Header(u32 partition);
|
|
|
|
|
|
|
|
bool getHfs0FileList(u32 partition);
|
|
|
|
|
2019-06-09 02:36:21 +01:00
|
|
|
bool getPartitionHfs0FileByName(FsStorage *gameCardStorage, const char *filename, u8 *outBuf, u64 outBufSize);
|
|
|
|
|
|
|
|
bool calculateExeFsExtractedDataSize(u64 *out);
|
2018-06-21 07:42:46 +01:00
|
|
|
|
2019-06-28 21:13:54 +01:00
|
|
|
bool calculateRomFsFullExtractedSize(bool usePatch, u64 *out);
|
2018-06-21 07:42:46 +01:00
|
|
|
|
2019-06-28 21:13:54 +01:00
|
|
|
bool calculateRomFsExtractedDirSize(u32 dir_offset, bool usePatch, u64 *out);
|
|
|
|
|
2019-09-15 03:45:27 +01:00
|
|
|
bool readNcaExeFsSection(u32 titleIndex, bool usePatch);
|
|
|
|
|
|
|
|
bool readNcaRomFsSection(u32 titleIndex, selectedRomFsType curRomFsType);
|
2019-06-09 02:36:21 +01:00
|
|
|
|
|
|
|
bool getExeFsFileList();
|
2019-05-01 21:24:13 +01:00
|
|
|
|
2019-06-28 21:13:54 +01:00
|
|
|
bool getRomFsFileList(u32 dir_offset, bool usePatch);
|
2018-06-21 07:42:46 +01:00
|
|
|
|
2019-06-05 23:44:18 +01:00
|
|
|
int getSdCardFreeSpace(u64 *out);
|
2019-05-01 21:24:13 +01:00
|
|
|
|
2019-06-05 23:44:18 +01:00
|
|
|
void convertSize(u64 size, char *out, int bufsize);
|
|
|
|
|
2019-06-09 02:36:21 +01:00
|
|
|
void addStringToFilenameBuffer(const char *string, char **nextFilename);
|
|
|
|
|
2019-06-28 21:13:54 +01:00
|
|
|
char *generateFullDumpName();
|
2019-05-01 21:24:13 +01:00
|
|
|
|
2019-06-05 23:44:18 +01:00
|
|
|
char *generateNSPDumpName(nspDumpType selectedNspDumpType, u32 titleIndex);
|
2019-05-01 21:24:13 +01:00
|
|
|
|
2019-06-20 04:56:14 +01:00
|
|
|
void retrieveDescriptionForPatchOrAddOn(u64 titleID, u32 version, bool addOn, bool addAppName, const char *prefix, char *outBuf, size_t outBufSize);
|
2019-05-01 21:24:13 +01:00
|
|
|
|
2019-06-09 02:36:21 +01:00
|
|
|
bool checkOrphanPatchOrAddOn(bool addOn);
|
|
|
|
|
|
|
|
void generateOrphanPatchOrAddOnList();
|
|
|
|
|
|
|
|
bool checkIfBaseApplicationHasPatchOrAddOn(u32 appIndex, bool addOn);
|
|
|
|
|
2019-06-20 04:56:14 +01:00
|
|
|
bool checkIfPatchOrAddOnBelongsToBaseApplication(u32 titleIndex, u32 appIndex, bool addOn);
|
2019-06-09 02:36:21 +01:00
|
|
|
|
|
|
|
u32 retrieveFirstPatchOrAddOnIndexFromBaseApplication(u32 appIndex, bool addOn);
|
|
|
|
|
2019-06-20 04:56:14 +01:00
|
|
|
u32 retrievePreviousPatchOrAddOnIndexFromBaseApplication(u32 startTitleIndex, u32 appIndex, bool addOn);
|
|
|
|
|
|
|
|
u32 retrieveNextPatchOrAddOnIndexFromBaseApplication(u32 startTitleIndex, u32 appIndex, bool addOn);
|
|
|
|
|
2019-09-15 03:45:27 +01:00
|
|
|
u32 retrieveLastPatchOrAddOnIndexFromBaseApplication(u32 appIndex, bool addOn);
|
|
|
|
|
2019-06-05 23:44:18 +01:00
|
|
|
void waitForButtonPress();
|
2019-05-01 21:24:13 +01:00
|
|
|
|
2019-06-05 23:44:18 +01:00
|
|
|
void printProgressBar(progress_ctx_t *progressCtx, bool calcData, u64 chunkSize);
|
2019-05-01 21:24:13 +01:00
|
|
|
|
2019-06-05 23:44:18 +01:00
|
|
|
void setProgressBarError(progress_ctx_t *progressCtx);
|
|
|
|
|
2019-08-15 06:21:51 +01:00
|
|
|
bool cancelProcessCheck(progress_ctx_t *progressCtx);
|
|
|
|
|
2019-06-05 23:44:18 +01:00
|
|
|
void convertDataToHexString(const u8 *data, const u32 dataSize, char *outBuf, const u32 outBufSize);
|
2019-05-01 21:24:13 +01:00
|
|
|
|
2019-06-20 04:56:14 +01:00
|
|
|
bool checkIfFileExists(const char *path);
|
|
|
|
|
|
|
|
bool yesNoPrompt(const char *message);
|
|
|
|
|
2019-06-28 21:13:54 +01:00
|
|
|
bool checkIfDumpedXciContainsCertificate(const char *xciPath);
|
|
|
|
|
2019-06-20 04:56:14 +01:00
|
|
|
bool checkIfDumpedNspContainsConsoleData(const char *nspPath);
|
|
|
|
|
2019-08-15 06:21:51 +01:00
|
|
|
void removeDirectoryWithVerbose(const char *path, const char *msg);
|
2019-04-21 17:27:33 +01:00
|
|
|
|
2018-06-30 07:37:42 +01:00
|
|
|
void gameCardDumpNSWDBCheck(u32 crc);
|
|
|
|
|
|
|
|
void updateNSWDBXml();
|
|
|
|
|
|
|
|
void updateApplication();
|
|
|
|
|
2018-06-21 07:42:46 +01:00
|
|
|
#endif
|