C++ is a general-purpose programming language created by Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significantly over time, and modern C++ now has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation. It is almost always implemented as a compiled language, and many vendors provide C++ compilers, including the Free Software Foundation, LLVM, Microsoft, Intel, Oracle, and IBM, so it is available on many platforms.

* fix XCI installation if card was inserted prior
* fix double expression call on ASSERT_OK failure
* fix compatibility with latest libnx master to build with usb:ds changes for 11.0.0+
* remove unused functions
This commit is contained in:
Luis Scheurenbrand 2020-12-12 02:46:33 +01:00 committed by HookedBehemoth
parent c1a9658313
commit 3f7b8497db
18 changed files with 78 additions and 435 deletions

View File

@ -54,16 +54,21 @@ ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
CFLAGS := -g -Wall -O2 -ffunction-sections \ CFLAGS := -g -Wall -O2 -ffunction-sections \
$(ARCH) $(DEFINES) $(ARCH) $(DEFINES)
CFLAGS += `curl-config --cflags`
CFLAGS += `sdl2-config --cflags` `freetype-config --cflags`
CFLAGS += $(INCLUDE) -D__SWITCH__ -Wall -Werror #-D__DEBUG__ -DNXLINK_DEBUG CFLAGS += $(INCLUDE) -D__SWITCH__ -Wall #-Werror -D__DEBUG__ -DNXLINK_DEBUG
CXXFLAGS := $(CFLAGS) -fno-rtti -std=gnu++17 -Wall -Werror CXXFLAGS := $(CFLAGS) -fno-rtti -std=gnu++17
ASFLAGS := -g $(ARCH) ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS := -lcurl -lz -lmbedtls -lmbedcrypto -lmbedx509 -lminizip -lnx -lstdc++fs -lzzip -lpu -lfreetype -lSDL2_mixer -lopusfile -lopus -lmodplug -lmpg123 -lvorbisidec -lSDL2 -lc -logg -lSDL2_ttf -lSDL2_gfx -lSDL2_image -lwebp -lpng -ljpeg `sdl2-config --libs` `freetype-config --libs` -lzstd LIBS := `curl-config --libs` # Networking
LIBS += -lSDL2_mixer -lopusfile -lopus -lmodplug -lmpg123 -lvorbisidec -logg # Audio
LIBS += -lpu -lSDL2_gfx -lSDL2_image -lwebp -lpng -ljpeg `sdl2-config --libs` `freetype-config --libs` # Graphics
LIBS += -lmbedtls -lmbedcrypto -lminizip -lzstd # Memes
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing # list of directories containing libraries, this must be the top level containing

View File

@ -22,21 +22,9 @@ SOFTWARE.
#pragma once #pragma once
#include <switch/services/ncm.h> #include <switch/types.h>
typedef struct { Result esInitialize(void);
u8 c[0x10]; void esExit(void);
} RightsId;
Result esInitialize(); Result esImportTicket(void const *tikBuf, size_t tikSize, void const *certBuf, size_t certSize);
void esExit();
Service* esGetServiceSession();
Result esImportTicket(void const *tikBuf, size_t tikSize, void const *certBuf, size_t certSize); //1
Result esDeleteTicket(const RightsId *rightsIdBuf, size_t bufSize); //3
Result esGetTitleKey(const RightsId *rightsId, u8 *outBuf, size_t bufSize); //8
Result esCountCommonTicket(u32 *numTickets); //9
Result esCountPersonalizedTicket(u32 *numTickets); // 10
Result esListCommonTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize);
Result esListPersonalizedTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize);
Result esGetCommonTicketData(u64 *unkOut, void *outBuf1, size_t bufSize1, const RightsId* rightsId);

View File

@ -25,29 +25,18 @@ SOFTWARE.
#include <switch/services/ns.h> #include <switch/services/ns.h>
#include <switch/services/ncm.h> #include <switch/services/ncm.h>
typedef struct { typedef enum {
u64 titleID; NsApplicationRecordType_Installed = 0x3,
u64 unk; NsApplicationRecordType_GamecardMissing = 0x5,
u64 size; NsApplicationRecordType_Archived = 0xB,
} PACKED ApplicationRecord; } NsApplicationRecordType;
typedef struct { typedef struct {
NcmContentMetaKey metaRecord; NcmContentMetaKey metaRecord;
u64 storageId; u64 storageId;
} PACKED ContentStorageRecord; } ContentStorageRecord;
Result nsextInitialize(void); Result nsextInitialize(void);
void nsextExit(void); void nsextExit(void);
Result nsPushApplicationRecord(u64 title_id, u8 last_modified_event, ContentStorageRecord *content_records_buf, size_t buf_size); Result nsPushApplicationRecord(u64 application_id, NsApplicationRecordType last_modified_event, ContentStorageRecord *content_records, u32 count);
Result nsListApplicationRecordContentMeta(u64 offset, u64 titleID, void *out_buf, size_t out_buf_size, u32 *entries_read_out);
Result nsDeleteApplicationRecord(u64 titleID);
Result nsLaunchApplication(u64 titleID);
Result nsPushLaunchVersion(u64 titleID, u32 version);
Result nsDisableApplicationAutoUpdate(u64 titleID);
Result nsGetContentMetaStorage(const NcmContentMetaKey *record, u8 *out);
Result nsBeginInstallApplication(u64 tid, u32 unk, u8 storageId);
Result nsInvalidateAllApplicationControlCache(void);
Result nsInvalidateApplicationControlCache(u64 tid);
Result nsCheckApplicationLaunchRights(u64 tid);
Result nsGetApplicationContentPath(u64 titleId, u8 type, char *outBuf, size_t bufSize);

View File

@ -24,16 +24,27 @@ SOFTWARE.
#include <cstring> #include <cstring>
#include <stdexcept> #include <stdexcept>
#include <stdio.h> #include <cstdio>
#include "util/debug.h"
#define ASSERT_OK(res_expr, desc) \
({ \
const auto tmp_rc = (res_expr); \
if (R_FAILED(tmp_rc)) { \
char msg[256] = {}; std::snprintf(msg, 256-1, "%s:%u: %s. Error code: 0x%08x\n", __func__, __LINE__, desc, tmp_rc); \
throw std::runtime_error(msg); \
} \
})
#define THROW_FORMAT(format, ...) \
({ \
char error_prefix[512] = {}; std::snprintf(error_prefix, 256-1, "%s:%u: ", __func__, __LINE__); \
char formatted_msg[256] = {}; std::snprintf(formatted_msg, 256-1, format, ##__VA_ARGS__); \
std::strncat(error_prefix, formatted_msg, 512-1); throw std::runtime_error(error_prefix); \
})
#define ASSERT_OK(rc_out, desc) if (R_FAILED(rc_out)) { char msg[256] = {0}; snprintf(msg, 256-1, "%s:%u: %s. Error code: 0x%08x\n", __func__, __LINE__, desc, rc_out); throw std::runtime_error(msg); }
#define THROW_FORMAT(format, ...) { char error_prefix[512] = {0}; snprintf(error_prefix, 256-1, "%s:%u: ", __func__, __LINE__);\
char formatted_msg[256] = {0}; snprintf(formatted_msg, 256-1, format, ##__VA_ARGS__);\
strncat(error_prefix, formatted_msg, 512-1); throw std::runtime_error(error_prefix); }
#ifdef NXLINK_DEBUG #ifdef NXLINK_DEBUG
#define LOG_DEBUG(format, ...) { printf("%s:%u: ", __func__, __LINE__); printf(format, ##__VA_ARGS__); } #define LOG_DEBUG(format, ...) { std::printf("%s:%u: ", __func__, __LINE__); std::printf(format, ##__VA_ARGS__); }
#else #else
#define LOG_DEBUG(format, ...) ; #define LOG_DEBUG(format, ...) ;
#endif #endif

View File

@ -29,8 +29,8 @@ SOFTWARE.
namespace tin::util namespace tin::util
{ {
u64 GetRightsIdTid(RightsId rightsId); u64 GetRightsIdTid(FsRightsId rightsId);
u64 GetRightsIdKeyGen(RightsId rightsId); u64 GetRightsIdKeyGen(FsRightsId rightsId);
std::string GetNcaIdString(const NcmContentId& ncaId); std::string GetNcaIdString(const NcmContentId& ncaId);
NcmContentId GetNcaIdFromString(std::string ncaIdStr); NcmContentId GetNcaIdFromString(std::string ncaIdStr);

View File

@ -19,7 +19,7 @@ namespace inst::util {
std::string getDriveFileName(std::string fileId); std::string getDriveFileName(std::string fileId);
std::vector<uint32_t> setClockSpeed(int deviceToClock, uint32_t clockSpeed); std::vector<uint32_t> setClockSpeed(int deviceToClock, uint32_t clockSpeed);
std::string getIPAddress(); std::string getIPAddress();
int getUsbState(); bool usbIsConnected();
void playAudio(std::string audioPath); void playAudio(std::string audioPath);
std::vector<std::string> checkForAppUpdate(); std::vector<std::string> checkForAppUpdate();
} }

View File

@ -69,56 +69,15 @@ namespace tin::install
void Install::InstallApplicationRecord(int i) void Install::InstallApplicationRecord(int i)
{ {
Result rc = 0; const u64 baseTitleId = tin::util::GetBaseTitleId(this->GetTitleId(i), this->GetContentMetaType(i));
std::vector<ContentStorageRecord> storageRecords;
u64 baseTitleId = tin::util::GetBaseTitleId(this->GetTitleId(i), this->GetContentMetaType(i));
s32 contentMetaCount = 0;
LOG_DEBUG("Base title Id: 0x%lx", baseTitleId);
// TODO: Make custom error with result code field
// 0x410: The record doesn't already exist
if (R_FAILED(rc = nsCountApplicationContentMeta(baseTitleId, &contentMetaCount)) && rc != 0x410)
{
THROW_FORMAT("Failed to count application content meta");
}
rc = 0;
LOG_DEBUG("Content meta count: %u\n", contentMetaCount);
// Obtain any existing app record content meta and append it to our vector
if (contentMetaCount > 0)
{
storageRecords.resize(contentMetaCount);
size_t contentStorageBufSize = contentMetaCount * sizeof(ContentStorageRecord);
auto contentStorageBuf = std::make_unique<ContentStorageRecord[]>(contentMetaCount);
u32 entriesRead;
ASSERT_OK(nsListApplicationRecordContentMeta(0, baseTitleId, contentStorageBuf.get(), contentStorageBufSize, &entriesRead), "Failed to list application record content meta");
if ((s32)entriesRead != contentMetaCount)
{
THROW_FORMAT("Mismatch between entries read and content meta count");
}
memcpy(storageRecords.data(), contentStorageBuf.get(), contentStorageBufSize);
}
// Add our new content meta // Add our new content meta
ContentStorageRecord storageRecord; ContentStorageRecord storageRecord;
storageRecord.metaRecord = m_contentMeta[i].GetContentMetaKey(); storageRecord.metaRecord = m_contentMeta[i].GetContentMetaKey();
storageRecord.storageId = m_destStorageId; storageRecord.storageId = m_destStorageId;
storageRecords.push_back(storageRecord);
// Replace the existing application records with our own
try
{
nsDeleteApplicationRecord(baseTitleId);
}
catch (...) {}
LOG_DEBUG("Pushing application record...\n"); LOG_DEBUG("Pushing application record...\n");
ASSERT_OK(nsPushApplicationRecord(baseTitleId, 0x3, storageRecords.data(), storageRecords.size() * sizeof(ContentStorageRecord)), "Failed to push application record"); ASSERT_OK(nsPushApplicationRecord(baseTitleId, NsApplicationRecordType_Installed, &storageRecord, 1), "Failed to push application record");
} }
// Validate and obtain all data needed for install // Validate and obtain all data needed for install

View File

@ -56,7 +56,7 @@ namespace tin::install::nsp
const PFS0FileEntry* NSP::GetFileEntry(unsigned int index) const PFS0FileEntry* NSP::GetFileEntry(unsigned int index)
{ {
if (index >= this->GetBaseHeader()->numFiles) if (index >= this->GetBaseHeader()->numFiles)
THROW_FORMAT("File entry index is out of bounds\n") THROW_FORMAT("File entry index is out of bounds\n");
size_t fileEntryOffset = sizeof(PFS0BaseHeader) + index * sizeof(PFS0FileEntry); size_t fileEntryOffset = sizeof(PFS0BaseHeader) + index * sizeof(PFS0FileEntry);

View File

@ -109,7 +109,7 @@ namespace tin::install::xci
const HFS0FileEntry* XCI::GetFileEntry(unsigned int index) const HFS0FileEntry* XCI::GetFileEntry(unsigned int index)
{ {
if (index >= this->GetSecureHeader()->numFiles) if (index >= this->GetSecureHeader()->numFiles)
THROW_FORMAT("File entry index is out of bounds\n") THROW_FORMAT("File entry index is out of bounds\n");
return hfs0GetFileEntry(this->GetSecureHeader(), index); return hfs0GetFileEntry(this->GetSecureHeader(), index);
} }

View File

@ -25,24 +25,17 @@ SOFTWARE.
#include <string.h> #include <string.h>
#include <switch.h> #include <switch.h>
#include "service_guard.h"
static Service g_esSrv; static Service g_esSrv;
NX_GENERATE_SERVICE_GUARD(es); Result esInitialize(void) {
Result _esInitialize() {
return smGetService(&g_esSrv, "es"); return smGetService(&g_esSrv, "es");
} }
void _esCleanup() { void esExit(void) {
serviceClose(&g_esSrv); serviceClose(&g_esSrv);
} }
Service* esGetServiceSession() {
return &g_esSrv;
}
Result esImportTicket(void const *tikBuf, size_t tikSize, void const *certBuf, size_t certSize) { Result esImportTicket(void const *tikBuf, size_t tikSize, void const *certBuf, size_t certSize) {
return serviceDispatch(&g_esSrv, 1, return serviceDispatch(&g_esSrv, 1,
.buffer_attrs = { .buffer_attrs = {
@ -55,91 +48,3 @@ Result esImportTicket(void const *tikBuf, size_t tikSize, void const *certBuf, s
}, },
); );
} }
Result esDeleteTicket(const RightsId *rightsIdBuf, size_t bufSize) {
return serviceDispatch(&g_esSrv, 3,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
.buffers = { { rightsIdBuf, bufSize }, },
);
}
Result esGetTitleKey(const RightsId *rightsId, u8 *outBuf, size_t bufSize) {
struct {
RightsId rights_Id;
u32 key_generation;
} in;
memcpy(&in.rights_Id, rightsId, sizeof(RightsId));
in.key_generation = 0;
return serviceDispatchIn(&g_esSrv, 8, in,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { outBuf, bufSize } },
);
}
Result esCountCommonTicket(u32 *numTickets) {
struct {
u32 num_tickets;
} out;
Result rc = serviceDispatchOut(&g_esSrv, 9, out);
if (R_SUCCEEDED(rc) && numTickets) *numTickets = out.num_tickets;
return rc;
}
Result esCountPersonalizedTicket(u32 *numTickets) {
struct {
u32 num_tickets;
} out;
Result rc = serviceDispatchOut(&g_esSrv, 10, out);
if (R_SUCCEEDED(rc) && numTickets) *numTickets = out.num_tickets;
return rc;
}
Result esListCommonTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize) {
struct {
u32 num_rights_ids_written;
} out;
Result rc = serviceDispatchInOut(&g_esSrv, 11, *numRightsIdsWritten, out,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { outBuf, bufSize } },
);
if (R_SUCCEEDED(rc) && numRightsIdsWritten) *numRightsIdsWritten = out.num_rights_ids_written;
return rc;
}
Result esListPersonalizedTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize) {
struct {
u32 num_rights_ids_written;
} out;
Result rc = serviceDispatchInOut(&g_esSrv, 12, *numRightsIdsWritten, out,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { outBuf, bufSize } },
);
if (R_SUCCEEDED(rc) && numRightsIdsWritten) *numRightsIdsWritten = out.num_rights_ids_written;
return rc;
}
Result esGetCommonTicketData(u64 *unkOut, void *outBuf1, size_t bufSize1, const RightsId* rightsId) {
struct {
RightsId rights_id;
} in;
memcpy(&in.rights_id, rightsId, sizeof(RightsId));
struct {
u64 unk;
} out;
Result rc = serviceDispatchInOut(&g_esSrv, 16, in, out,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { outBuf1, bufSize1 } },
);
return rc;
}

View File

@ -22,176 +22,38 @@ SOFTWARE.
#include "nx/ipc/ns_ext.h" #include "nx/ipc/ns_ext.h"
#include <stdio.h>
#include <string.h>
#include <switch.h> #include <switch.h>
#include "service_guard.h"
static Service g_nsAppManSrv, g_nsGetterSrv; Service g_nsAppManSrv;
static Result _nsextGetSession(Service* srv, Service* srv_out, u32 cmd_id); Result nsextInitialize(void) {
Result rc = nsInitialize();
NX_GENERATE_SERVICE_GUARD(nsext); if (R_SUCCEEDED(rc)) {
if(hosversionBefore(3,0,0)) {
Result _nsextInitialize(void) { g_nsAppManSrv = *nsGetServiceSession_ApplicationManagerInterface();
Result rc=0; } else {
rc = nsGetApplicationManagerInterface(&g_nsAppManSrv);
if(hosversionBefore(3,0,0)) }
return smGetService(&g_nsAppManSrv, "ns:am"); }
rc = smGetService(&g_nsGetterSrv, "ns:am2");//TODO: Support the other services?(Only useful when ns:am2 isn't accessible)
if (R_FAILED(rc)) return rc;
rc = _nsextGetSession(&g_nsGetterSrv, &g_nsAppManSrv, 7996);
if (R_FAILED(rc)) serviceClose(&g_nsGetterSrv);
return rc; return rc;
} }
void _nsextCleanup(void) { void nsextExit(void) {
if(hosversionAtLeast(3,0,0))
serviceClose(&g_nsAppManSrv); serviceClose(&g_nsAppManSrv);
if(hosversionBefore(3,0,0)) return; nsExit();
serviceClose(&g_nsGetterSrv);
} }
static Result _nsextGetSession(Service* srv, Service* srv_out, u32 cmd_id) { Result nsPushApplicationRecord(u64 application_id, NsApplicationRecordType last_modified_event, ContentStorageRecord *content_records, u32 count) {
return serviceDispatch(srv, cmd_id,
.out_num_objects = 1,
.out_objects = srv_out,
);
}
Result nsPushApplicationRecord(u64 title_id, u8 last_modified_event, ContentStorageRecord *content_records_buf, size_t buf_size) {
struct { struct {
u8 last_modified_event; u8 last_modified_event;
u8 padding[0x7]; u64 application_id;
u64 title_id; } in = { last_modified_event, application_id };
} in = { last_modified_event, {0}, title_id };
return serviceDispatchIn(&g_nsAppManSrv, 16, in, return serviceDispatchIn(&g_nsAppManSrv, 16, in,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In }, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
.buffers = { { content_records_buf, buf_size } }); .buffers = { { content_records, count * sizeof(*content_records) }
} });
Result nsListApplicationRecordContentMeta(u64 offset, u64 titleID, void *out_buf, size_t out_buf_size, u32 *entries_read_out) {
struct {
u64 offset;
u64 titleID;
} in = { offset, titleID };
struct {
u32 entries_read;
} out;
Result rc = serviceDispatchInOut(&g_nsAppManSrv, 17, in, out,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { out_buf, out_buf_size } });
if (R_SUCCEEDED(rc) && entries_read_out) *entries_read_out = out.entries_read;
return rc;
}
Result nsDeleteApplicationRecord(u64 titleID) {
struct {
u64 titleID;
} in = { titleID };
return serviceDispatchIn(&g_nsAppManSrv, 27, in);
}
Result nsLaunchApplication(u64 titleID) {
struct {
u64 titleID;
} in = { titleID };
return serviceDispatchIn(&g_nsAppManSrv, 19, in);
}
Result nsPushLaunchVersion(u64 titleID, u32 version) {
struct {
u64 titleID;
u32 version;
u32 padding;
} in = { titleID, version, 0 };
return serviceDispatchIn(&g_nsAppManSrv, 36, in);
}
Result nsGetContentMetaStorage(const NcmContentMetaKey *record, u8 *storageOut) {
struct {
NcmContentMetaKey metaRecord;
} in;
memcpy(&in.metaRecord, record, sizeof(NcmContentMetaKey));
struct {
u8 out;
} out;
Result rc = serviceDispatchInOut(&g_nsAppManSrv, 606, in, out);
if (R_SUCCEEDED(rc) && storageOut) *storageOut = out.out;
return rc;
}
Result nsBeginInstallApplication(u64 tid, u32 unk, u8 storageId) {
struct {
u32 storageId;
u32 unk;
u64 tid;
} in = { storageId, unk, tid };
return serviceDispatchIn(&g_nsAppManSrv, 26, in);
}
Result nsInvalidateAllApplicationControlCache(void) {
return serviceDispatch(&g_nsAppManSrv, 401);
}
Result nsInvalidateApplicationControlCache(u64 tid) {
struct {
u64 tid;
} in = { tid };
return serviceDispatchIn(&g_nsAppManSrv, 404, in);
}
Result nsCheckApplicationLaunchRights(u64 tid) {
struct {
u64 tid;
} in = { tid };
return serviceDispatchIn(&g_nsAppManSrv, 39, in);
}
Result nsGetApplicationContentPath(u64 tid, u8 type, char *out, size_t buf_size) {
struct {
u8 padding[0x7];
u8 type;
u64 tid;
} in = { {0}, type, tid };
return serviceDispatchIn(&g_nsAppManSrv, 21, in,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { out, buf_size } }
);
}
Result nsDisableApplicationAutoUpdate(u64 titleID) {
struct {
u64 title_id;
} in = { titleID };
return serviceDispatchIn(&g_nsAppManSrv, 903, in);
} }

View File

@ -1,74 +0,0 @@
/*
Copyright (c) 2017-2018 Adubbz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#pragma once
#include <switch.h>
typedef struct ServiceGuard {
Mutex mutex;
u32 refCount;
} ServiceGuard;
NX_INLINE bool serviceGuardBeginInit(ServiceGuard* g)
{
mutexLock(&g->mutex);
return (g->refCount++) == 0;
}
NX_INLINE Result serviceGuardEndInit(ServiceGuard* g, Result rc, void (*cleanupFunc)(void))
{
if (R_FAILED(rc)) {
cleanupFunc();
--g->refCount;
}
mutexUnlock(&g->mutex);
return rc;
}
NX_INLINE void serviceGuardExit(ServiceGuard* g, void (*cleanupFunc)(void))
{
mutexLock(&g->mutex);
if (g->refCount && (--g->refCount) == 0)
cleanupFunc();
mutexUnlock(&g->mutex);
}
#define NX_GENERATE_SERVICE_GUARD_PARAMS(name, _paramdecl, _parampass) \
\
static ServiceGuard g_##name##Guard; \
NX_INLINE Result _##name##Initialize _paramdecl; \
static void _##name##Cleanup(void); \
\
Result name##Initialize _paramdecl \
{ \
Result rc = 0; \
if (serviceGuardBeginInit(&g_##name##Guard)) \
rc = _##name##Initialize _parampass; \
return serviceGuardEndInit(&g_##name##Guard, rc, _##name##Cleanup); \
} \
\
void name##Exit(void) \
{ \
serviceGuardExit(&g_##name##Guard, _##name##Cleanup); \
}
#define NX_GENERATE_SERVICE_GUARD(name) NX_GENERATE_SERVICE_GUARD_PARAMS(name, (void), ())

View File

@ -115,7 +115,7 @@ namespace inst::ui {
inst::config::setConfig(); inst::config::setConfig();
} }
} }
if (inst::util::getUsbState() == 5) mainApp->usbinstPage->startUsb(); if (inst::util::usbIsConnected()) mainApp->usbinstPage->startUsb();
else mainApp->CreateShowDialog("main.usb.error.title"_lang, "main.usb.error.desc"_lang, {"common.ok"_lang}, false); else mainApp->CreateShowDialog("main.usb.error.title"_lang, "main.usb.error.desc"_lang, {"common.ok"_lang}, false);
} }

View File

@ -66,7 +66,7 @@ namespace usbInstStuff {
u64 kDown = hidKeysDown(CONTROLLER_P1_AUTO); u64 kDown = hidKeysDown(CONTROLLER_P1_AUTO);
if (kDown & KEY_B) return {}; if (kDown & KEY_B) return {};
if (kDown & KEY_X) inst::ui::mainApp->CreateShowDialog("inst.usb.help.title"_lang, "inst.usb.help.desc"_lang, {"common.ok"_lang}, true); if (kDown & KEY_X) inst::ui::mainApp->CreateShowDialog("inst.usb.help.title"_lang, "inst.usb.help.desc"_lang, {"common.ok"_lang}, true);
if (inst::util::getUsbState() != 5) return {}; if (!inst::util::usbIsConnected()) return {};
} }
if (header.magic != 0x304C5554) return {}; if (header.magic != 0x304C5554) return {};

View File

@ -1,8 +1,8 @@
#include "util/crypto.hpp" #include "util/crypto.hpp"
#include <stdexcept>
#include <string.h> #include <string.h>
#include <mbedtls/bignum.h> #include <mbedtls/bignum.h>
#include <stdexcept>
#include "util/error.hpp"
void Crypto::calculateMGF1andXOR(unsigned char* data, size_t data_size, const void* source, size_t source_size) { void Crypto::calculateMGF1andXOR(unsigned char* data, size_t data_size, const void* source, size_t source_size) {
unsigned char h_buf[RSA_2048_BYTES] = {0}; unsigned char h_buf[RSA_2048_BYTES] = {0};
@ -46,7 +46,7 @@ bool Crypto::rsa2048PssVerify(const void *data, size_t len, const unsigned char
mbedtls_mpi_exp_mod(&message_mpi, &signature_mpi, &e_mpi, &modulus_mpi, NULL); mbedtls_mpi_exp_mod(&message_mpi, &signature_mpi, &e_mpi, &modulus_mpi, NULL);
if (mbedtls_mpi_write_binary(&message_mpi, m_buf, RSA_2048_BYTES) != 0) { if (mbedtls_mpi_write_binary(&message_mpi, m_buf, RSA_2048_BYTES) != 0) {
THROW_FORMAT("Failed to export exponentiated RSA message!"); throw std::runtime_error("Failed to export exponentiated RSA message!");
} }
mbedtls_mpi_free(&signature_mpi); mbedtls_mpi_free(&signature_mpi);

View File

@ -27,12 +27,12 @@ SOFTWARE.
namespace tin::util namespace tin::util
{ {
u64 GetRightsIdTid(RightsId rightsId) u64 GetRightsIdTid(FsRightsId rightsId)
{ {
return __bswap64(*(u64 *)rightsId.c); return __bswap64(*(u64 *)rightsId.c);
} }
u64 GetRightsIdKeyGen(RightsId rightsId) u64 GetRightsIdKeyGen(FsRightsId rightsId)
{ {
return __bswap64(*(u64 *)(rightsId.c + 8)); return __bswap64(*(u64 *)(rightsId.c + 8));
} }

View File

@ -38,7 +38,6 @@ namespace inst::util {
void initInstallServices() { void initInstallServices() {
ncmInitialize(); ncmInitialize();
nsInitialize();
nsextInitialize(); nsextInitialize();
esInitialize(); esInitialize();
splCryptoInitialize(); splCryptoInitialize();
@ -47,7 +46,6 @@ namespace inst::util {
void deinitInstallServices() { void deinitInstallServices() {
ncmExit(); ncmExit();
nsExit();
nsextExit(); nsextExit();
esExit(); esExit();
splCryptoExit(); splCryptoExit();
@ -266,10 +264,10 @@ namespace inst::util {
return inet_ntoa(addr); return inet_ntoa(addr);
} }
int getUsbState() { bool usbIsConnected() {
u32 usbState = 0; UsbState state = UsbState_Detached;
usbDsGetState(&usbState); usbDsGetState(&state);
return usbState; return state == UsbState_Configured;
} }
void playAudio(std::string audioPath) { void playAudio(std::string audioPath) {