add basic error messages for internal sphaira errors.
This commit is contained in:
@@ -174,6 +174,7 @@ enum {
|
|||||||
Module_Npln = 321,
|
Module_Npln = 321,
|
||||||
Module_Tspm = 499,
|
Module_Tspm = 499,
|
||||||
Module_Devmenu = 500,
|
Module_Devmenu = 500,
|
||||||
|
Module_Sphaira = 505,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SvcError {
|
enum SvcError {
|
||||||
@@ -494,7 +495,274 @@ enum NcmError {
|
|||||||
NcmError_WriteToReadOnlyContentStorage = 0x17C05,
|
NcmError_WriteToReadOnlyContentStorage = 0x17C05,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define R_SUCCEED() return 0
|
enum class SphairaResult : Result {
|
||||||
|
TransferCancelled,
|
||||||
|
StreamBadSeek,
|
||||||
|
|
||||||
|
FsTooManyEntries,
|
||||||
|
FsNewPathTooLarge,
|
||||||
|
FsInvalidType,
|
||||||
|
FsEmpty,
|
||||||
|
FsAlreadyRoot,
|
||||||
|
FsNoCurrentPath,
|
||||||
|
FsBrokenCurrentPath,
|
||||||
|
FsIndexOutOfBounds,
|
||||||
|
FsFsNotActive,
|
||||||
|
FsNewPathEmpty,
|
||||||
|
FsLoadingCancelled,
|
||||||
|
FsBrokenRoot,
|
||||||
|
FsUnknownStdioError,
|
||||||
|
FsReadOnly,
|
||||||
|
FsNotActive,
|
||||||
|
FsFailedStdioStat,
|
||||||
|
FsFailedStdioOpendir,
|
||||||
|
|
||||||
|
NroBadMagic,
|
||||||
|
NroBadSize,
|
||||||
|
|
||||||
|
AppFailedMusicDownload,
|
||||||
|
CurlFailedEasyInit,
|
||||||
|
DumpFailedNetworkUpload,
|
||||||
|
|
||||||
|
UnzOpen2_64,
|
||||||
|
UnzGetGlobalInfo64,
|
||||||
|
UnzLocateFile,
|
||||||
|
UnzGoToFirstFile,
|
||||||
|
UnzGoToNextFile,
|
||||||
|
UnzOpenCurrentFile,
|
||||||
|
UnzGetCurrentFileInfo64,
|
||||||
|
UnzReadCurrentFile,
|
||||||
|
|
||||||
|
ZipOpen2_64,
|
||||||
|
ZipOpenNewFileInZip,
|
||||||
|
ZipWriteInFileInZip,
|
||||||
|
|
||||||
|
FileBrowserFailedUpload,
|
||||||
|
FileBrowserDirNotDaybreak,
|
||||||
|
|
||||||
|
AppstoreFailedZipDownload,
|
||||||
|
AppstoreFailedMd5,
|
||||||
|
AppstoreFailedParseManifest,
|
||||||
|
|
||||||
|
GameBadReadForDump,
|
||||||
|
GameEmptyMetaEntries,
|
||||||
|
GameMultipleKeysFound,
|
||||||
|
GameNoNspEntriesBuilt,
|
||||||
|
|
||||||
|
KeyMissingNcaKeyArea,
|
||||||
|
KeyMissingTitleKek,
|
||||||
|
KeyMissingMasterKey,
|
||||||
|
KeyFailedDecyptETicketDeviceKey,
|
||||||
|
|
||||||
|
NcaFailedNcaHeaderHashVerify,
|
||||||
|
NcaBadSigKeyGen,
|
||||||
|
|
||||||
|
GcBadReadForDump,
|
||||||
|
GcEmptyGamecard,
|
||||||
|
GcBadXciMagic,
|
||||||
|
GcBadXciRomSize,
|
||||||
|
GcFailedToGetSecurityInfo,
|
||||||
|
|
||||||
|
GhdlEmptyAsset,
|
||||||
|
GhdlFailedToDownloadAsset,
|
||||||
|
GhdlFailedToDownloadAssetJson,
|
||||||
|
|
||||||
|
ThemezerFailedToDownloadThemeMeta,
|
||||||
|
ThemezerFailedToDownloadTheme,
|
||||||
|
|
||||||
|
MainFailedToDownloadUpdate,
|
||||||
|
|
||||||
|
UsbDsBadDeviceSpeed,
|
||||||
|
|
||||||
|
NspBadMagic,
|
||||||
|
XciBadMagic,
|
||||||
|
|
||||||
|
EsBadTitleKeyType,
|
||||||
|
EsPersonalisedTicketDeviceIdMissmatch,
|
||||||
|
EsFailedDecryptPersonalisedTicket,
|
||||||
|
EsBadDecryptedPersonalisedTicketSize,
|
||||||
|
|
||||||
|
OwoBadArgs,
|
||||||
|
|
||||||
|
UsbCancelled,
|
||||||
|
UsbBadMagic,
|
||||||
|
UsbBadVersion,
|
||||||
|
UsbBadCount,
|
||||||
|
UsbBadTransferSize,
|
||||||
|
UsbBadTotalSize,
|
||||||
|
|
||||||
|
UsbUploadBadMagic,
|
||||||
|
UsbUploadExit,
|
||||||
|
UsbUploadBadCount,
|
||||||
|
UsbUploadBadTransferSize,
|
||||||
|
UsbUploadBadTotalSize,
|
||||||
|
UsbUploadBadCommand,
|
||||||
|
|
||||||
|
// unkown container for the source provided.
|
||||||
|
YatiContainerNotFound,
|
||||||
|
// nca required by the cnmt but not found in collection.
|
||||||
|
YatiNcaNotFound,
|
||||||
|
YatiInvalidNcaReadSize,
|
||||||
|
YatiInvalidNcaSigKeyGen,
|
||||||
|
YatiInvalidNcaMagic,
|
||||||
|
YatiInvalidNcaSignature0,
|
||||||
|
YatiInvalidNcaSignature1,
|
||||||
|
// invalid sha256 over the entire nca.
|
||||||
|
YatiInvalidNcaSha256,
|
||||||
|
// section could not be found.
|
||||||
|
YatiNczSectionNotFound,
|
||||||
|
// section count == 0.
|
||||||
|
YatiInvalidNczSectionCount,
|
||||||
|
// block could not be found.
|
||||||
|
YatiNczBlockNotFound,
|
||||||
|
// block version != 2.
|
||||||
|
YatiInvalidNczBlockVersion,
|
||||||
|
// block type != 1.
|
||||||
|
YatiInvalidNczBlockType,
|
||||||
|
// block count == 0.
|
||||||
|
YatiInvalidNczBlockTotal,
|
||||||
|
// block size exponent < 14 || > 32.
|
||||||
|
YatiInvalidNczBlockSizeExponent,
|
||||||
|
// zstd error while decompressing ncz.
|
||||||
|
YatiInvalidNczZstdError,
|
||||||
|
// nca has rights_id but matching ticket wasn't found.
|
||||||
|
YatiTicketNotFound,
|
||||||
|
// found ticket has missmatching rights_id from it's name.
|
||||||
|
YatiInvalidTicketBadRightsId,
|
||||||
|
YatiInvalidTicketVersion,
|
||||||
|
YatiInvalidTicketKeyType,
|
||||||
|
YatiInvalidTicketKeyRevision,
|
||||||
|
// cert not found for the ticket.
|
||||||
|
YatiCertNotFound,
|
||||||
|
// unable to fetch header from ncm database.
|
||||||
|
YatiNcmDbCorruptHeader,
|
||||||
|
// unable to total infos from ncm database.
|
||||||
|
YatiNcmDbCorruptInfos,
|
||||||
|
|
||||||
|
// found ticket has missmatching rights_id from it's name.
|
||||||
|
TicketInvalidTicketBadRightsId,
|
||||||
|
TicketInvalidTicketVersion,
|
||||||
|
TicketInvalidTicketKeyType,
|
||||||
|
TicketInvalidTicketKeyRevision,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAKE_SPHAIRA_RESULT_ENUM(x) Result_##x = MAKERESULT(Module_Sphaira, (Result)SphairaResult::x)
|
||||||
|
|
||||||
|
enum : Result {
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(TransferCancelled),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(StreamBadSeek),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsTooManyEntries),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsNewPathTooLarge),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsInvalidType),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsEmpty),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsAlreadyRoot),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsNoCurrentPath),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsBrokenCurrentPath),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsIndexOutOfBounds),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsFsNotActive),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsNewPathEmpty),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsLoadingCancelled),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsBrokenRoot),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsUnknownStdioError),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsReadOnly),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsNotActive),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsFailedStdioStat),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FsFailedStdioOpendir),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(NroBadMagic),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(NroBadSize),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(AppFailedMusicDownload),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(CurlFailedEasyInit),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(DumpFailedNetworkUpload),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UnzOpen2_64),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UnzGetGlobalInfo64),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UnzLocateFile),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UnzGoToFirstFile),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UnzGoToNextFile),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UnzOpenCurrentFile),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UnzGetCurrentFileInfo64),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UnzReadCurrentFile),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(ZipOpen2_64),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(ZipOpenNewFileInZip),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(ZipWriteInFileInZip),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FileBrowserFailedUpload),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(FileBrowserDirNotDaybreak),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(AppstoreFailedZipDownload),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(AppstoreFailedMd5),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(AppstoreFailedParseManifest),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(GameBadReadForDump),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(GameEmptyMetaEntries),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(GameMultipleKeysFound),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(GameNoNspEntriesBuilt),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(KeyMissingNcaKeyArea),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(KeyMissingTitleKek),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(KeyMissingMasterKey),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(KeyFailedDecyptETicketDeviceKey),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(NcaFailedNcaHeaderHashVerify),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(NcaBadSigKeyGen),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(GcBadReadForDump),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(GcEmptyGamecard),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(GcBadXciMagic),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(GcBadXciRomSize),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(GcFailedToGetSecurityInfo),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(GhdlEmptyAsset),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(GhdlFailedToDownloadAsset),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(GhdlFailedToDownloadAssetJson),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(ThemezerFailedToDownloadThemeMeta),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(ThemezerFailedToDownloadTheme),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(MainFailedToDownloadUpdate),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UsbDsBadDeviceSpeed),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(NspBadMagic),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(XciBadMagic),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(EsBadTitleKeyType),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(EsPersonalisedTicketDeviceIdMissmatch),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(EsFailedDecryptPersonalisedTicket),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(EsBadDecryptedPersonalisedTicketSize),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(OwoBadArgs),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UsbCancelled),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UsbBadMagic),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UsbBadVersion),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UsbBadCount),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UsbBadTransferSize),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UsbBadTotalSize),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UsbUploadBadMagic),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UsbUploadExit),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UsbUploadBadCount),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UsbUploadBadTransferSize),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UsbUploadBadTotalSize),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(UsbUploadBadCommand),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiContainerNotFound),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiNcaNotFound),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiInvalidNcaReadSize),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiInvalidNcaSigKeyGen),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiInvalidNcaMagic),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiInvalidNcaSignature0),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiInvalidNcaSignature1),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiInvalidNcaSha256),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiNczSectionNotFound),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiInvalidNczSectionCount),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiNczBlockNotFound),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiInvalidNczBlockVersion),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiInvalidNczBlockType),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiInvalidNczBlockTotal),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiInvalidNczBlockSizeExponent),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiInvalidNczZstdError),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiTicketNotFound),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiInvalidTicketBadRightsId),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiInvalidTicketVersion),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiInvalidTicketKeyType),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiInvalidTicketKeyRevision),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiCertNotFound),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiNcmDbCorruptHeader),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(YatiNcmDbCorruptInfos),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(TicketInvalidTicketBadRightsId),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(TicketInvalidTicketVersion),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(TicketInvalidTicketKeyType),
|
||||||
|
MAKE_SPHAIRA_RESULT_ENUM(TicketInvalidTicketKeyRevision),
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef MAKE_SPHAIRA_RESULT_ENUM
|
||||||
|
|
||||||
|
#define R_SUCCEED() return (Result)0
|
||||||
|
|
||||||
#define R_THROW(_rc) return _rc
|
#define R_THROW(_rc) return _rc
|
||||||
|
|
||||||
@@ -521,8 +789,8 @@ enum NcmError {
|
|||||||
#define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __COUNTER__)
|
#define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __COUNTER__)
|
||||||
|
|
||||||
#define ON_SCOPE_EXIT(_f) std::experimental::scope_exit ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE_){[&] { _f; }};
|
#define ON_SCOPE_EXIT(_f) std::experimental::scope_exit ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE_){[&] { _f; }};
|
||||||
#define ON_SCOPE_FAIL(_f) std::experimental::scope_exit ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE_){[&] { if (R_FAILED(rc)) { _f; } }};
|
// #define ON_SCOPE_FAIL(_f) std::experimental::scope_exit ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE_){[&] { if (R_FAILED(rc)) { _f; } }};
|
||||||
#define ON_SCOPE_SUCCESS(_f) std::experimental::scope_exit ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE_){[&] { if (R_SUCCEEDED(rc)) { _f; } }};
|
// #define ON_SCOPE_SUCCESS(_f) std::experimental::scope_exit ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE_){[&] { if (R_SUCCEEDED(rc)) { _f; } }};
|
||||||
|
|
||||||
// threading helpers.
|
// threading helpers.
|
||||||
#define PRIO_PREEMPTIVE 0x3B
|
#define PRIO_PREEMPTIVE 0x3B
|
||||||
|
|||||||
@@ -261,22 +261,6 @@ Result FileGetSizeAndTimestamp(fs::Fs* fs, const FsPath& path, FsTimeStampRaw* t
|
|||||||
Result IsDirEmpty(fs::Fs* m_fs, const fs::FsPath& path, bool* out);
|
Result IsDirEmpty(fs::Fs* m_fs, const fs::FsPath& path, bool* out);
|
||||||
|
|
||||||
struct Fs {
|
struct Fs {
|
||||||
static constexpr inline u32 FsModule = 505;
|
|
||||||
static constexpr inline Result ResultTooManyEntries = MAKERESULT(FsModule, 1);
|
|
||||||
static constexpr inline Result ResultNewPathTooLarge = MAKERESULT(FsModule, 2);
|
|
||||||
static constexpr inline Result ResultInvalidType = MAKERESULT(FsModule, 3);
|
|
||||||
static constexpr inline Result ResultEmpty = MAKERESULT(FsModule, 4);
|
|
||||||
static constexpr inline Result ResultAlreadyRoot = MAKERESULT(FsModule, 5);
|
|
||||||
static constexpr inline Result ResultNoCurrentPath = MAKERESULT(FsModule, 6);
|
|
||||||
static constexpr inline Result ResultBrokenCurrentPath = MAKERESULT(FsModule, 7);
|
|
||||||
static constexpr inline Result ResultIndexOutOfBounds = MAKERESULT(FsModule, 8);
|
|
||||||
static constexpr inline Result ResultFsNotActive = MAKERESULT(FsModule, 9);
|
|
||||||
static constexpr inline Result ResultNewPathEmpty = MAKERESULT(FsModule, 10);
|
|
||||||
static constexpr inline Result ResultLoadingCancelled = MAKERESULT(FsModule, 11);
|
|
||||||
static constexpr inline Result ResultBrokenRoot = MAKERESULT(FsModule, 12);
|
|
||||||
static constexpr inline Result ResultUnknownStdioError = MAKERESULT(FsModule, 13);
|
|
||||||
static constexpr inline Result ResultReadOnly = MAKERESULT(FsModule, 14);
|
|
||||||
|
|
||||||
Fs(bool ignore_read_only = true) : m_ignore_read_only{ignore_read_only} {}
|
Fs(bool ignore_read_only = true) : m_ignore_read_only{ignore_read_only} {}
|
||||||
virtual ~Fs() = default;
|
virtual ~Fs() = default;
|
||||||
|
|
||||||
|
|||||||
@@ -20,17 +20,6 @@ struct OwoConfig {
|
|||||||
std::vector<u8> program_nca{};
|
std::vector<u8> program_nca{};
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
Module_Owo = 424,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum OwoError {
|
|
||||||
OwoError_BadArgs = MAKERESULT(Module_Owo, 1),
|
|
||||||
};
|
|
||||||
|
|
||||||
// fwd
|
|
||||||
// struct ui::ProgressBox;
|
|
||||||
|
|
||||||
auto install_forwarder(OwoConfig& config, NcmStorageId storage_id) -> Result;
|
auto install_forwarder(OwoConfig& config, NcmStorageId storage_id) -> Result;
|
||||||
auto install_forwarder(ui::ProgressBox* pbox, OwoConfig& config, NcmStorageId storage_id) -> Result;
|
auto install_forwarder(ui::ProgressBox* pbox, OwoConfig& config, NcmStorageId storage_id) -> Result;
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
std::optional<Result> m_code{};
|
std::optional<Result> m_code{};
|
||||||
std::string m_message{};
|
std::string m_message{};
|
||||||
|
std::string m_code_message{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sphaira::ui
|
} // namespace sphaira::ui
|
||||||
|
|||||||
@@ -8,12 +8,6 @@
|
|||||||
namespace sphaira::usb {
|
namespace sphaira::usb {
|
||||||
|
|
||||||
struct Base {
|
struct Base {
|
||||||
enum { USBModule = 523 };
|
|
||||||
|
|
||||||
enum : Result {
|
|
||||||
Result_Cancelled = MAKERESULT(USBModule, 100),
|
|
||||||
};
|
|
||||||
|
|
||||||
Base(u64 transfer_timeout);
|
Base(u64 transfer_timeout);
|
||||||
virtual ~Base();
|
virtual ~Base();
|
||||||
|
|
||||||
|
|||||||
@@ -10,17 +10,6 @@
|
|||||||
namespace sphaira::usb::upload {
|
namespace sphaira::usb::upload {
|
||||||
|
|
||||||
struct Usb {
|
struct Usb {
|
||||||
enum { USBModule = 523 };
|
|
||||||
|
|
||||||
enum : Result {
|
|
||||||
Result_BadMagic = MAKERESULT(USBModule, 0),
|
|
||||||
Result_Exit = MAKERESULT(USBModule, 1),
|
|
||||||
Result_BadCount = MAKERESULT(USBModule, 2),
|
|
||||||
Result_BadTransferSize = MAKERESULT(USBModule, 3),
|
|
||||||
Result_BadTotalSize = MAKERESULT(USBModule, 4),
|
|
||||||
Result_BadCommand = MAKERESULT(USBModule, 4),
|
|
||||||
};
|
|
||||||
|
|
||||||
Usb(u64 transfer_timeout);
|
Usb(u64 transfer_timeout);
|
||||||
virtual ~Usb();
|
virtual ~Usb();
|
||||||
|
|
||||||
|
|||||||
@@ -46,19 +46,19 @@ struct Keys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto GetNcaKeyArea(KeyEntry* out, u8 key, u8 index) const -> Result {
|
auto GetNcaKeyArea(KeyEntry* out, u8 key, u8 index) const -> Result {
|
||||||
R_UNLESS(HasNcaKeyArea(key, index), 0x1);
|
R_UNLESS(HasNcaKeyArea(key, index), Result_KeyMissingNcaKeyArea);
|
||||||
*out = key_area_key[index][FixKey(key)];
|
*out = key_area_key[index][FixKey(key)];
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto GetTitleKek(KeyEntry* out, u8 key) const -> Result {
|
auto GetTitleKek(KeyEntry* out, u8 key) const -> Result {
|
||||||
R_UNLESS(HasTitleKek(key), 0x1);
|
R_UNLESS(HasTitleKek(key), Result_KeyMissingTitleKek);
|
||||||
*out = titlekek[FixKey(key)];
|
*out = titlekek[FixKey(key)];
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto GetMasterKey(KeyEntry* out, u8 key) const -> Result {
|
auto GetMasterKey(KeyEntry* out, u8 key) const -> Result {
|
||||||
R_UNLESS(HasMasterKey(key), 0x1);
|
R_UNLESS(HasMasterKey(key), Result_KeyMissingMasterKey);
|
||||||
*out = master_key[FixKey(key)];
|
*out = master_key[FixKey(key)];
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,16 +11,6 @@
|
|||||||
namespace sphaira::yati::source {
|
namespace sphaira::yati::source {
|
||||||
|
|
||||||
struct Usb final : Base {
|
struct Usb final : Base {
|
||||||
enum { USBModule = 508 };
|
|
||||||
|
|
||||||
enum : Result {
|
|
||||||
Result_BadMagic = MAKERESULT(USBModule, 0),
|
|
||||||
Result_BadVersion = MAKERESULT(USBModule, 1),
|
|
||||||
Result_BadCount = MAKERESULT(USBModule, 2),
|
|
||||||
Result_BadTransferSize = MAKERESULT(USBModule, 3),
|
|
||||||
Result_BadTotalSize = MAKERESULT(USBModule, 4),
|
|
||||||
};
|
|
||||||
|
|
||||||
Usb(u64 transfer_timeout);
|
Usb(u64 transfer_timeout);
|
||||||
~Usb();
|
~Usb();
|
||||||
|
|
||||||
|
|||||||
@@ -16,67 +16,6 @@
|
|||||||
|
|
||||||
namespace sphaira::yati {
|
namespace sphaira::yati {
|
||||||
|
|
||||||
enum { YatiModule = 506 };
|
|
||||||
|
|
||||||
/*
|
|
||||||
Improving compression ratio via block splitting is now enabled by default for high compression levels (16+).
|
|
||||||
The amount of benefit varies depending on the workload.
|
|
||||||
Compressing archives comprised of heavily differing files will see more improvement than compression of single files that don’t
|
|
||||||
vary much entropically (like text files/enwik). At levels 16+, we observe no measurable regression to compression speed.
|
|
||||||
|
|
||||||
The block splitter can be forcibly enabled on lower compression levels as well with the advanced parameter ZSTD_c_splitBlocks.
|
|
||||||
When forcibly enabled at lower levels, speed regressions can become more notable.
|
|
||||||
Additionally, since more compressed blocks may be produced, decompression speed on these blobs may also see small regressions.
|
|
||||||
*/
|
|
||||||
enum : Result {
|
|
||||||
// unkown container for the source provided.
|
|
||||||
Result_ContainerNotFound = MAKERESULT(YatiModule, 10),
|
|
||||||
Result_Cancelled = MAKERESULT(YatiModule, 11),
|
|
||||||
|
|
||||||
// nca required by the cnmt but not found in collection.
|
|
||||||
Result_NcaNotFound = MAKERESULT(YatiModule, 30),
|
|
||||||
Result_InvalidNcaReadSize = MAKERESULT(YatiModule, 31),
|
|
||||||
Result_InvalidNcaSigKeyGen = MAKERESULT(YatiModule, 32),
|
|
||||||
Result_InvalidNcaMagic = MAKERESULT(YatiModule, 33),
|
|
||||||
Result_InvalidNcaSignature0 = MAKERESULT(YatiModule, 34),
|
|
||||||
Result_InvalidNcaSignature1 = MAKERESULT(YatiModule, 35),
|
|
||||||
// invalid sha256 over the entire nca.
|
|
||||||
Result_InvalidNcaSha256 = MAKERESULT(YatiModule, 36),
|
|
||||||
|
|
||||||
// section could not be found.
|
|
||||||
Result_NczSectionNotFound = MAKERESULT(YatiModule, 50),
|
|
||||||
// section count == 0.
|
|
||||||
Result_InvalidNczSectionCount = MAKERESULT(YatiModule, 51),
|
|
||||||
// block could not be found.
|
|
||||||
Result_NczBlockNotFound = MAKERESULT(YatiModule, 52),
|
|
||||||
// block version != 2.
|
|
||||||
Result_InvalidNczBlockVersion = MAKERESULT(YatiModule, 53),
|
|
||||||
// block type != 1.
|
|
||||||
Result_InvalidNczBlockType = MAKERESULT(YatiModule, 54),
|
|
||||||
// block count == 0.
|
|
||||||
Result_InvalidNczBlockTotal = MAKERESULT(YatiModule, 55),
|
|
||||||
// block size exponent < 14 || > 32.
|
|
||||||
Result_InvalidNczBlockSizeExponent = MAKERESULT(YatiModule, 56),
|
|
||||||
// zstd error while decompressing ncz.
|
|
||||||
Result_InvalidNczZstdError = MAKERESULT(YatiModule, 57),
|
|
||||||
|
|
||||||
// nca has rights_id but matching ticket wasn't found.
|
|
||||||
Result_TicketNotFound = MAKERESULT(YatiModule, 70),
|
|
||||||
// found ticket has missmatching rights_id from it's name.
|
|
||||||
Result_InvalidTicketBadRightsId = MAKERESULT(YatiModule, 71),
|
|
||||||
Result_InvalidTicketVersion = MAKERESULT(YatiModule, 72),
|
|
||||||
Result_InvalidTicketKeyType = MAKERESULT(YatiModule, 73),
|
|
||||||
Result_InvalidTicketKeyRevision = MAKERESULT(YatiModule, 74),
|
|
||||||
|
|
||||||
// cert not found for the ticket.
|
|
||||||
Result_CertNotFound = MAKERESULT(YatiModule, 90),
|
|
||||||
|
|
||||||
// unable to fetch header from ncm database.
|
|
||||||
Result_NcmDbCorruptHeader = MAKERESULT(YatiModule, 110),
|
|
||||||
// unable to total infos from ncm database.
|
|
||||||
Result_NcmDbCorruptInfos = MAKERESULT(YatiModule, 111),
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
bool sd_card_install{};
|
bool sd_card_install{};
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ constexpr const u8 DEFAULT_IMAGE_DATA[]{
|
|||||||
};
|
};
|
||||||
|
|
||||||
void download_default_music() {
|
void download_default_music() {
|
||||||
App::Push(std::make_shared<ui::ProgressBox>(0, "Downloading "_i18n, "default_music.bfstm", [](auto pbox){
|
App::Push(std::make_shared<ui::ProgressBox>(0, "Downloading "_i18n, "default_music.bfstm", [](auto pbox) -> Result {
|
||||||
const auto result = curl::Api().ToFile(
|
const auto result = curl::Api().ToFile(
|
||||||
curl::Url{DEFAULT_MUSIC_URL},
|
curl::Url{DEFAULT_MUSIC_URL},
|
||||||
curl::Path{DEFAULT_MUSIC_PATH},
|
curl::Path{DEFAULT_MUSIC_PATH},
|
||||||
@@ -59,7 +59,7 @@ void download_default_music() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
R_THROW(0x1);
|
R_THROW(Result_AppFailedMusicDownload);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ private:
|
|||||||
struct ThreadEntry {
|
struct ThreadEntry {
|
||||||
auto Create() -> Result {
|
auto Create() -> Result {
|
||||||
m_curl = curl_easy_init();
|
m_curl = curl_easy_init();
|
||||||
R_UNLESS(m_curl != nullptr, 0x1);
|
R_UNLESS(m_curl != nullptr, Result_CurlFailedEasyInit);
|
||||||
|
|
||||||
ueventCreate(&m_uevent, true);
|
ueventCreate(&m_uevent, true);
|
||||||
R_TRY(threadCreate(&m_thread, ThreadFunc, this, nullptr, 1024*32, THREAD_PRIO, THREAD_CORE));
|
R_TRY(threadCreate(&m_thread, ThreadFunc, this, nullptr, 1024*32, THREAD_PRIO, THREAD_CORE));
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ Result DumpToUsbS2S(ui::ProgressBox* pbox, BaseSource* source, std::span<const f
|
|||||||
log_write("skipped polling for exit command\n");
|
log_write("skipped polling for exit command\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == usb->Result_Exit) {
|
if (rc == Result_UsbUploadExit) {
|
||||||
log_write("got exit command\n");
|
log_write("got exit command\n");
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
@@ -303,7 +303,7 @@ Result DumpToNetwork(ui::ProgressBox* pbox, const location::Entry& loc, BaseSour
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
R_UNLESS(result.success, 0x1);
|
R_UNLESS(result.success, Result_DumpFailedNetworkUpload);
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -110,19 +110,19 @@ FsPath AppendPath(const FsPath& root_path, const FsPath& _file_path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result CreateFile(FsFileSystem* fs, const FsPath& path, u64 size, u32 option, bool ignore_read_only) {
|
Result CreateFile(FsFileSystem* fs, const FsPath& path, u64 size, u32 option, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only_root(path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only_root(path), Result_FsReadOnly);
|
||||||
|
|
||||||
return fsFsCreateFile(fs, path, size, option);
|
return fsFsCreateFile(fs, path, size, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateDirectory(FsFileSystem* fs, const FsPath& path, bool ignore_read_only) {
|
Result CreateDirectory(FsFileSystem* fs, const FsPath& path, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only_root(path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only_root(path), Result_FsReadOnly);
|
||||||
|
|
||||||
return fsFsCreateDirectory(fs, path);
|
return fsFsCreateDirectory(fs, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateDirectoryRecursively(FsFileSystem* fs, const FsPath& _path, bool ignore_read_only) {
|
Result CreateDirectoryRecursively(FsFileSystem* fs, const FsPath& _path, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only_root(_path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only_root(_path), Result_FsReadOnly);
|
||||||
|
|
||||||
// try and create the directory / see if it already exists before the loop.
|
// try and create the directory / see if it already exists before the loop.
|
||||||
Result rc;
|
Result rc;
|
||||||
@@ -170,7 +170,7 @@ Result CreateDirectoryRecursively(FsFileSystem* fs, const FsPath& _path, bool ig
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result CreateDirectoryRecursivelyWithPath(FsFileSystem* fs, const FsPath& _path, bool ignore_read_only) {
|
Result CreateDirectoryRecursivelyWithPath(FsFileSystem* fs, const FsPath& _path, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only_root(_path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only_root(_path), Result_FsReadOnly);
|
||||||
|
|
||||||
// strip file name form path.
|
// strip file name form path.
|
||||||
const auto last_slash = std::strrchr(_path, '/');
|
const auto last_slash = std::strrchr(_path, '/');
|
||||||
@@ -184,32 +184,32 @@ Result CreateDirectoryRecursivelyWithPath(FsFileSystem* fs, const FsPath& _path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result DeleteFile(FsFileSystem* fs, const FsPath& path, bool ignore_read_only) {
|
Result DeleteFile(FsFileSystem* fs, const FsPath& path, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(path), Result_FsReadOnly);
|
||||||
return fsFsDeleteFile(fs, path);
|
return fsFsDeleteFile(fs, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeleteDirectory(FsFileSystem* fs, const FsPath& path, bool ignore_read_only) {
|
Result DeleteDirectory(FsFileSystem* fs, const FsPath& path, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(path), Result_FsReadOnly);
|
||||||
|
|
||||||
return fsFsDeleteDirectory(fs, path);
|
return fsFsDeleteDirectory(fs, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeleteDirectoryRecursively(FsFileSystem* fs, const FsPath& path, bool ignore_read_only) {
|
Result DeleteDirectoryRecursively(FsFileSystem* fs, const FsPath& path, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(path), Result_FsReadOnly);
|
||||||
|
|
||||||
return fsFsDeleteDirectoryRecursively(fs, path);
|
return fsFsDeleteDirectoryRecursively(fs, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RenameFile(FsFileSystem* fs, const FsPath& src, const FsPath& dst, bool ignore_read_only) {
|
Result RenameFile(FsFileSystem* fs, const FsPath& src, const FsPath& dst, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(src), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(src), Result_FsReadOnly);
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(dst), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(dst), Result_FsReadOnly);
|
||||||
|
|
||||||
return fsFsRenameFile(fs, src, dst);
|
return fsFsRenameFile(fs, src, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RenameDirectory(FsFileSystem* fs, const FsPath& src, const FsPath& dst, bool ignore_read_only) {
|
Result RenameDirectory(FsFileSystem* fs, const FsPath& src, const FsPath& dst, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(src), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(src), Result_FsReadOnly);
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(dst), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(dst), Result_FsReadOnly);
|
||||||
|
|
||||||
return fsFsRenameDirectory(fs, src, dst);
|
return fsFsRenameDirectory(fs, src, dst);
|
||||||
}
|
}
|
||||||
@@ -259,7 +259,7 @@ Result read_entire_file(FsFileSystem* _fs, const FsPath& path, std::vector<u8>&
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result write_entire_file(FsFileSystem* _fs, const FsPath& path, const std::vector<u8>& in, bool ignore_read_only) {
|
Result write_entire_file(FsFileSystem* _fs, const FsPath& path, const std::vector<u8>& in, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(path), Result_FsReadOnly);
|
||||||
|
|
||||||
FsNative fs{_fs, false, ignore_read_only};
|
FsNative fs{_fs, false, ignore_read_only};
|
||||||
R_TRY(fs.GetFsOpenResult());
|
R_TRY(fs.GetFsOpenResult());
|
||||||
@@ -279,7 +279,7 @@ Result write_entire_file(FsFileSystem* _fs, const FsPath& path, const std::vecto
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result copy_entire_file(FsFileSystem* fs, const FsPath& dst, const FsPath& src, bool ignore_read_only) {
|
Result copy_entire_file(FsFileSystem* fs, const FsPath& dst, const FsPath& src, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(dst), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(dst), Result_FsReadOnly);
|
||||||
|
|
||||||
std::vector<u8> data;
|
std::vector<u8> data;
|
||||||
R_TRY(read_entire_file(fs, src, data));
|
R_TRY(read_entire_file(fs, src, data));
|
||||||
@@ -287,7 +287,7 @@ Result copy_entire_file(FsFileSystem* fs, const FsPath& dst, const FsPath& src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result CreateFile(const FsPath& path, u64 size, u32 option, bool ignore_read_only) {
|
Result CreateFile(const FsPath& path, u64 size, u32 option, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only_root(path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only_root(path), Result_FsReadOnly);
|
||||||
|
|
||||||
auto fd = open(path, O_WRONLY | O_CREAT, DEFFILEMODE);
|
auto fd = open(path, O_WRONLY | O_CREAT, DEFFILEMODE);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
@@ -296,19 +296,19 @@ Result CreateFile(const FsPath& path, u64 size, u32 option, bool ignore_read_onl
|
|||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(fsdevGetLastResult());
|
R_TRY(fsdevGetLastResult());
|
||||||
return Fs::ResultUnknownStdioError;
|
return Result_FsUnknownStdioError;
|
||||||
}
|
}
|
||||||
ON_SCOPE_EXIT(close(fd));
|
ON_SCOPE_EXIT(close(fd));
|
||||||
|
|
||||||
if (size) {
|
if (size) {
|
||||||
R_UNLESS(!ftruncate(fd, size), Fs::ResultUnknownStdioError);
|
R_UNLESS(!ftruncate(fd, size), Result_FsUnknownStdioError);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateDirectory(const FsPath& path, bool ignore_read_only) {
|
Result CreateDirectory(const FsPath& path, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only_root(path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only_root(path), Result_FsReadOnly);
|
||||||
|
|
||||||
if (mkdir(path, ACCESSPERMS)) {
|
if (mkdir(path, ACCESSPERMS)) {
|
||||||
if (errno == EEXIST) {
|
if (errno == EEXIST) {
|
||||||
@@ -316,46 +316,46 @@ Result CreateDirectory(const FsPath& path, bool ignore_read_only) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(fsdevGetLastResult());
|
R_TRY(fsdevGetLastResult());
|
||||||
return Fs::ResultUnknownStdioError;
|
return Result_FsUnknownStdioError;
|
||||||
}
|
}
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateDirectoryRecursively(const FsPath& path, bool ignore_read_only) {
|
Result CreateDirectoryRecursively(const FsPath& path, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only_root(path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only_root(path), Result_FsReadOnly);
|
||||||
|
|
||||||
return CreateDirectoryRecursively(nullptr, path, ignore_read_only);
|
return CreateDirectoryRecursively(nullptr, path, ignore_read_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateDirectoryRecursivelyWithPath(const FsPath& path, bool ignore_read_only) {
|
Result CreateDirectoryRecursivelyWithPath(const FsPath& path, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only_root(path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only_root(path), Result_FsReadOnly);
|
||||||
|
|
||||||
return CreateDirectoryRecursivelyWithPath(nullptr, path, ignore_read_only);
|
return CreateDirectoryRecursivelyWithPath(nullptr, path, ignore_read_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeleteFile(const FsPath& path, bool ignore_read_only) {
|
Result DeleteFile(const FsPath& path, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(path), Result_FsReadOnly);
|
||||||
|
|
||||||
if (unlink(path)) {
|
if (unlink(path)) {
|
||||||
R_TRY(fsdevGetLastResult());
|
R_TRY(fsdevGetLastResult());
|
||||||
return Fs::ResultUnknownStdioError;
|
return Result_FsUnknownStdioError;
|
||||||
}
|
}
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeleteDirectory(const FsPath& path, bool ignore_read_only) {
|
Result DeleteDirectory(const FsPath& path, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(path), Result_FsReadOnly);
|
||||||
|
|
||||||
if (rmdir(path)) {
|
if (rmdir(path)) {
|
||||||
R_TRY(fsdevGetLastResult());
|
R_TRY(fsdevGetLastResult());
|
||||||
return Fs::ResultUnknownStdioError;
|
return Result_FsUnknownStdioError;
|
||||||
}
|
}
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ftw / ntfw isn't found by linker...
|
// ftw / ntfw isn't found by linker...
|
||||||
Result DeleteDirectoryRecursively(const FsPath& path, bool ignore_read_only) {
|
Result DeleteDirectoryRecursively(const FsPath& path, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(path), Result_FsReadOnly);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// const auto unlink_cb = [](const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) -> int {
|
// const auto unlink_cb = [](const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) -> int {
|
||||||
@@ -366,7 +366,7 @@ Result DeleteDirectoryRecursively(const FsPath& path, bool ignore_read_only) {
|
|||||||
// if (nftw(path, unlink_cb, 16, FTW_DEPTH)) {
|
// if (nftw(path, unlink_cb, 16, FTW_DEPTH)) {
|
||||||
if (ftw(path, unlink_cb, 16)) {
|
if (ftw(path, unlink_cb, 16)) {
|
||||||
R_TRY(fsdevGetLastResult());
|
R_TRY(fsdevGetLastResult());
|
||||||
return Fs::ResultUnknownStdioError;
|
return Result_FsUnknownStdioError;
|
||||||
}
|
}
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
#else
|
#else
|
||||||
@@ -375,19 +375,19 @@ Result DeleteDirectoryRecursively(const FsPath& path, bool ignore_read_only) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result RenameFile(const FsPath& src, const FsPath& dst, bool ignore_read_only) {
|
Result RenameFile(const FsPath& src, const FsPath& dst, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(src), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(src), Result_FsReadOnly);
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(dst), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(dst), Result_FsReadOnly);
|
||||||
|
|
||||||
if (rename(src, dst)) {
|
if (rename(src, dst)) {
|
||||||
R_TRY(fsdevGetLastResult());
|
R_TRY(fsdevGetLastResult());
|
||||||
return Fs::ResultUnknownStdioError;
|
return Result_FsUnknownStdioError;
|
||||||
}
|
}
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RenameDirectory(const FsPath& src, const FsPath& dst, bool ignore_read_only) {
|
Result RenameDirectory(const FsPath& src, const FsPath& dst, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(src), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(src), Result_FsReadOnly);
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(dst), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(dst), Result_FsReadOnly);
|
||||||
|
|
||||||
return RenameFile(src, dst, ignore_read_only);
|
return RenameFile(src, dst, ignore_read_only);
|
||||||
}
|
}
|
||||||
@@ -396,7 +396,7 @@ Result GetEntryType(const FsPath& path, FsDirEntryType* out) {
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(path, &st)) {
|
if (stat(path, &st)) {
|
||||||
R_TRY(fsdevGetLastResult());
|
R_TRY(fsdevGetLastResult());
|
||||||
return Fs::ResultUnknownStdioError;
|
return Result_FsUnknownStdioError;
|
||||||
}
|
}
|
||||||
*out = S_ISREG(st.st_mode) ? FsDirEntryType_File : FsDirEntryType_Dir;
|
*out = S_ISREG(st.st_mode) ? FsDirEntryType_File : FsDirEntryType_Dir;
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
@@ -406,7 +406,7 @@ Result GetFileTimeStampRaw(const FsPath& path, FsTimeStampRaw *out) {
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(path, &st)) {
|
if (stat(path, &st)) {
|
||||||
R_TRY(fsdevGetLastResult());
|
R_TRY(fsdevGetLastResult());
|
||||||
return Fs::ResultUnknownStdioError;
|
return Result_FsUnknownStdioError;
|
||||||
}
|
}
|
||||||
|
|
||||||
out->is_valid = true;
|
out->is_valid = true;
|
||||||
@@ -446,7 +446,7 @@ Result read_entire_file(const FsPath& path, std::vector<u8>& out) {
|
|||||||
auto f = std::fopen(path, "rb");
|
auto f = std::fopen(path, "rb");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
R_TRY(fsdevGetLastResult());
|
R_TRY(fsdevGetLastResult());
|
||||||
return Fs::ResultUnknownStdioError;
|
return Result_FsUnknownStdioError;
|
||||||
}
|
}
|
||||||
ON_SCOPE_EXIT(std::fclose(f));
|
ON_SCOPE_EXIT(std::fclose(f));
|
||||||
|
|
||||||
@@ -461,12 +461,12 @@ Result read_entire_file(const FsPath& path, std::vector<u8>& out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result write_entire_file(const FsPath& path, const std::vector<u8>& in, bool ignore_read_only) {
|
Result write_entire_file(const FsPath& path, const std::vector<u8>& in, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(path), Result_FsReadOnly);
|
||||||
|
|
||||||
auto f = std::fopen(path, "wb");
|
auto f = std::fopen(path, "wb");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
R_TRY(fsdevGetLastResult());
|
R_TRY(fsdevGetLastResult());
|
||||||
return Fs::ResultUnknownStdioError;
|
return Result_FsUnknownStdioError;
|
||||||
}
|
}
|
||||||
ON_SCOPE_EXIT(std::fclose(f));
|
ON_SCOPE_EXIT(std::fclose(f));
|
||||||
|
|
||||||
@@ -475,7 +475,7 @@ Result write_entire_file(const FsPath& path, const std::vector<u8>& in, bool ign
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result copy_entire_file(const FsPath& dst, const FsPath& src, bool ignore_read_only) {
|
Result copy_entire_file(const FsPath& dst, const FsPath& src, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(dst), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(dst), Result_FsReadOnly);
|
||||||
|
|
||||||
std::vector<u8> data;
|
std::vector<u8> data;
|
||||||
R_TRY(read_entire_file(src, data));
|
R_TRY(read_entire_file(src, data));
|
||||||
@@ -499,7 +499,7 @@ Result OpenFile(fs::Fs* fs, const fs::FsPath& path, u32 mode, File* f) {
|
|||||||
f->m_stdio = std::fopen(path, "rb+");
|
f->m_stdio = std::fopen(path, "rb+");
|
||||||
}
|
}
|
||||||
|
|
||||||
R_UNLESS(f->m_stdio, Fs::ResultUnknownStdioError);
|
R_UNLESS(f->m_stdio, Result_FsUnknownStdioError);
|
||||||
std::strcpy(f->m_path, path);
|
std::strcpy(f->m_path, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,7 +512,7 @@ File::~File() {
|
|||||||
|
|
||||||
Result File::Read( s64 off, void* buf, u64 read_size, u32 option, u64* bytes_read) {
|
Result File::Read( s64 off, void* buf, u64 read_size, u32 option, u64* bytes_read) {
|
||||||
*bytes_read = 0;
|
*bytes_read = 0;
|
||||||
R_UNLESS(m_fs, 0x1);
|
R_UNLESS(m_fs, Result_FsNotActive);
|
||||||
|
|
||||||
if (m_fs->IsNative()) {
|
if (m_fs->IsNative()) {
|
||||||
R_TRY(fsFileRead(&m_native, off, buf, read_size, option, bytes_read));
|
R_TRY(fsFileRead(&m_native, off, buf, read_size, option, bytes_read));
|
||||||
@@ -527,7 +527,7 @@ Result File::Read( s64 off, void* buf, u64 read_size, u32 option, u64* bytes_rea
|
|||||||
// if we read less bytes than expected, check if there was an error (ignoring eof).
|
// if we read less bytes than expected, check if there was an error (ignoring eof).
|
||||||
if (*bytes_read < read_size) {
|
if (*bytes_read < read_size) {
|
||||||
if (!std::feof(m_stdio) && std::ferror(m_stdio)) {
|
if (!std::feof(m_stdio) && std::ferror(m_stdio)) {
|
||||||
R_THROW(Fs::ResultUnknownStdioError);
|
R_THROW(Result_FsUnknownStdioError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,7 +538,7 @@ Result File::Read( s64 off, void* buf, u64 read_size, u32 option, u64* bytes_rea
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result File::Write(s64 off, const void* buf, u64 write_size, u32 option) {
|
Result File::Write(s64 off, const void* buf, u64 write_size, u32 option) {
|
||||||
R_UNLESS(m_fs, 0x1);
|
R_UNLESS(m_fs, Result_FsNotActive);
|
||||||
|
|
||||||
if (m_fs->IsNative()) {
|
if (m_fs->IsNative()) {
|
||||||
R_TRY(fsFileWrite(&m_native, off, buf, write_size, option));
|
R_TRY(fsFileWrite(&m_native, off, buf, write_size, option));
|
||||||
@@ -551,7 +551,7 @@ Result File::Write(s64 off, const void* buf, u64 write_size, u32 option) {
|
|||||||
|
|
||||||
const auto result = std::fwrite(buf, 1, write_size, m_stdio);
|
const auto result = std::fwrite(buf, 1, write_size, m_stdio);
|
||||||
// log_write("[FS] fwrite res: %zu vs %zu\n", result, write_size);
|
// log_write("[FS] fwrite res: %zu vs %zu\n", result, write_size);
|
||||||
R_UNLESS(result == write_size, Fs::ResultUnknownStdioError);
|
R_UNLESS(result == write_size, Result_FsUnknownStdioError);
|
||||||
|
|
||||||
m_stdio_off += write_size;
|
m_stdio_off += write_size;
|
||||||
}
|
}
|
||||||
@@ -560,21 +560,21 @@ Result File::Write(s64 off, const void* buf, u64 write_size, u32 option) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result File::SetSize(s64 sz) {
|
Result File::SetSize(s64 sz) {
|
||||||
R_UNLESS(m_fs, 0x1);
|
R_UNLESS(m_fs, Result_FsNotActive);
|
||||||
|
|
||||||
if (m_fs->IsNative()) {
|
if (m_fs->IsNative()) {
|
||||||
R_TRY(fsFileSetSize(&m_native, sz));
|
R_TRY(fsFileSetSize(&m_native, sz));
|
||||||
} else {
|
} else {
|
||||||
const auto fd = fileno(m_stdio);
|
const auto fd = fileno(m_stdio);
|
||||||
R_UNLESS(fd > 0, Fs::ResultUnknownStdioError);
|
R_UNLESS(fd > 0, Result_FsUnknownStdioError);
|
||||||
R_UNLESS(!ftruncate(fd, sz), Fs::ResultUnknownStdioError);
|
R_UNLESS(!ftruncate(fd, sz), Result_FsUnknownStdioError);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result File::GetSize(s64* out) {
|
Result File::GetSize(s64* out) {
|
||||||
R_UNLESS(m_fs, 0x1);
|
R_UNLESS(m_fs, Result_FsNotActive);
|
||||||
|
|
||||||
if (m_fs->IsNative()) {
|
if (m_fs->IsNative()) {
|
||||||
R_TRY(fsFileGetSize(&m_native, out));
|
R_TRY(fsFileGetSize(&m_native, out));
|
||||||
@@ -588,7 +588,7 @@ Result File::GetSize(s64* out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!did_stat) {
|
if (!did_stat) {
|
||||||
R_UNLESS(!lstat(m_path, &st), Fs::ResultUnknownStdioError);
|
R_UNLESS(!lstat(m_path, &st), Result_FsUnknownStdioError);
|
||||||
}
|
}
|
||||||
|
|
||||||
*out = st.st_size;
|
*out = st.st_size;
|
||||||
@@ -624,7 +624,7 @@ Result OpenDirectory(fs::Fs* fs, const fs::FsPath& path, u32 mode, Dir* d) {
|
|||||||
R_TRY(fsFsOpenDirectory(&fs->m_fs, path, mode, &d->m_native));
|
R_TRY(fsFsOpenDirectory(&fs->m_fs, path, mode, &d->m_native));
|
||||||
} else {
|
} else {
|
||||||
d->m_stdio = opendir(path);
|
d->m_stdio = opendir(path);
|
||||||
R_UNLESS(d->m_stdio, Fs::ResultUnknownStdioError);
|
R_UNLESS(d->m_stdio, Result_FsUnknownStdioError);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
@@ -683,7 +683,7 @@ Dir::~Dir() {
|
|||||||
|
|
||||||
Result Dir::GetEntryCount(s64* out) {
|
Result Dir::GetEntryCount(s64* out) {
|
||||||
*out = 0;
|
*out = 0;
|
||||||
R_UNLESS(m_fs, 0x1);
|
R_UNLESS(m_fs, Result_FsNotActive);
|
||||||
|
|
||||||
if (m_fs->IsNative()) {
|
if (m_fs->IsNative()) {
|
||||||
R_TRY(fsDirGetEntryCount(&m_native, out));
|
R_TRY(fsDirGetEntryCount(&m_native, out));
|
||||||
@@ -704,7 +704,7 @@ Result Dir::GetEntryCount(s64* out) {
|
|||||||
|
|
||||||
Result Dir::ReadAll(std::vector<FsDirectoryEntry>& buf) {
|
Result Dir::ReadAll(std::vector<FsDirectoryEntry>& buf) {
|
||||||
buf.clear();
|
buf.clear();
|
||||||
R_UNLESS(m_fs, 0x1);
|
R_UNLESS(m_fs, Result_FsNotActive);
|
||||||
|
|
||||||
if (m_fs->IsNative()) {
|
if (m_fs->IsNative()) {
|
||||||
s64 count;
|
s64 count;
|
||||||
@@ -779,7 +779,7 @@ Result FileGetSizeAndTimestamp(fs::Fs* m_fs, const FsPath& path, FsTimeStampRaw*
|
|||||||
R_TRY(f.GetSize(size));
|
R_TRY(f.GetSize(size));
|
||||||
} else {
|
} else {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
R_UNLESS(!lstat(path, &st), 0x1);
|
R_UNLESS(!lstat(path, &st), Result_FsFailedStdioStat);
|
||||||
|
|
||||||
ts->is_valid = true;
|
ts->is_valid = true;
|
||||||
ts->created = st.st_ctim.tv_sec;
|
ts->created = st.st_ctim.tv_sec;
|
||||||
@@ -802,7 +802,7 @@ Result IsDirEmpty(fs::Fs* m_fs, const fs::FsPath& path, bool* out) {
|
|||||||
*out = !count;
|
*out = !count;
|
||||||
} else {
|
} else {
|
||||||
auto dir = opendir(path);
|
auto dir = opendir(path);
|
||||||
R_UNLESS(dir, 0x1);
|
R_UNLESS(dir, Result_FsFailedStdioOpendir);
|
||||||
ON_SCOPE_EXIT(closedir(dir));
|
ON_SCOPE_EXIT(closedir(dir));
|
||||||
|
|
||||||
while (auto d = readdir(dir)) {
|
while (auto d = readdir(dir)) {
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ Result Hash(ui::ProgressBox* pbox, Type type, std::shared_ptr<BaseSource> source
|
|||||||
case Type::Sha1: return Hash(pbox, std::make_unique<HashSha1>(), source, out);
|
case Type::Sha1: return Hash(pbox, std::make_unique<HashSha1>(), source, out);
|
||||||
case Type::Sha256: return Hash(pbox, std::make_unique<HashSha256>(), source, out);
|
case Type::Sha256: return Hash(pbox, std::make_unique<HashSha256>(), source, out);
|
||||||
}
|
}
|
||||||
R_THROW(0x1);
|
std::unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Hash(ui::ProgressBox* pbox, Type type, fs::Fs* fs, const fs::FsPath& path, std::string& out) {
|
Result Hash(ui::ProgressBox* pbox, Type type, fs::Fs* fs, const fs::FsPath& path, std::string& out) {
|
||||||
|
|||||||
@@ -13,15 +13,6 @@
|
|||||||
namespace sphaira {
|
namespace sphaira {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
enum {
|
|
||||||
Module_Nro = 421,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum NroError {
|
|
||||||
NroError_BadMagic = MAKERESULT(Module_Nro, 1),
|
|
||||||
NroError_BadSize = MAKERESULT(Module_Nro, 2),
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NroData {
|
struct NroData {
|
||||||
NroStart start;
|
NroStart start;
|
||||||
NroHeader header;
|
NroHeader header;
|
||||||
@@ -47,11 +38,11 @@ auto nro_parse_internal(fs::Fs* fs, const fs::FsPath& path, NroEntry& entry) ->
|
|||||||
NroData data;
|
NroData data;
|
||||||
u64 bytes_read;
|
u64 bytes_read;
|
||||||
R_TRY(f.Read(0, &data, sizeof(data), FsReadOption_None, &bytes_read));
|
R_TRY(f.Read(0, &data, sizeof(data), FsReadOption_None, &bytes_read));
|
||||||
R_UNLESS(data.header.magic == NROHEADER_MAGIC, NroError_BadMagic);
|
R_UNLESS(data.header.magic == NROHEADER_MAGIC, Result_NroBadMagic);
|
||||||
|
|
||||||
NroAssetHeader asset;
|
NroAssetHeader asset;
|
||||||
R_TRY(f.Read(data.header.size, &asset, sizeof(asset), FsReadOption_None, &bytes_read));
|
R_TRY(f.Read(data.header.size, &asset, sizeof(asset), FsReadOption_None, &bytes_read));
|
||||||
// R_UNLESS(asset.magic == NROASSETHEADER_MAGIC, NroError_BadMagic);
|
// R_UNLESS(asset.magic == NROASSETHEADER_MAGIC, Result_NroBadMagic);
|
||||||
|
|
||||||
// we can avoid a GetSize() call by calculating the size manually.
|
// we can avoid a GetSize() call by calculating the size manually.
|
||||||
entry.size = data.header.size;
|
entry.size = data.header.size;
|
||||||
@@ -192,10 +183,10 @@ auto launch_internal(const std::string& path, const std::string& argv) -> Result
|
|||||||
|
|
||||||
auto nro_verify(std::span<const u8> data) -> Result {
|
auto nro_verify(std::span<const u8> data) -> Result {
|
||||||
NroData nro;
|
NroData nro;
|
||||||
R_UNLESS(data.size() >= sizeof(nro), NroError_BadSize);
|
R_UNLESS(data.size() >= sizeof(nro), Result_NroBadSize);
|
||||||
|
|
||||||
memcpy(&nro, data.data(), sizeof(nro));
|
memcpy(&nro, data.data(), sizeof(nro));
|
||||||
R_UNLESS(nro.header.magic == NROHEADER_MAGIC, NroError_BadMagic);
|
R_UNLESS(nro.header.magic == NROHEADER_MAGIC, Result_NroBadMagic);
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
@@ -243,9 +234,9 @@ auto nro_get_nacp(const fs::FsPath& path, NacpStruct& nacp) -> Result {
|
|||||||
R_TRY(fs.OpenFile(path, FsOpenMode_Read, &f));
|
R_TRY(fs.OpenFile(path, FsOpenMode_Read, &f));
|
||||||
|
|
||||||
R_TRY(f.Read(0, &data, sizeof(data), FsReadOption_None, &bytes_read));
|
R_TRY(f.Read(0, &data, sizeof(data), FsReadOption_None, &bytes_read));
|
||||||
R_UNLESS(data.header.magic == NROHEADER_MAGIC, NroError_BadMagic);
|
R_UNLESS(data.header.magic == NROHEADER_MAGIC, Result_NroBadMagic);
|
||||||
R_TRY(f.Read(data.header.size, &asset, sizeof(asset), FsReadOption_None, &bytes_read));
|
R_TRY(f.Read(data.header.size, &asset, sizeof(asset), FsReadOption_None, &bytes_read));
|
||||||
R_UNLESS(asset.magic == NROASSETHEADER_MAGIC, NroError_BadMagic);
|
R_UNLESS(asset.magic == NROASSETHEADER_MAGIC, Result_NroBadMagic);
|
||||||
R_TRY(f.Read(data.header.size + asset.nacp.offset, &nacp, sizeof(nacp), FsReadOption_None, &bytes_read));
|
R_TRY(f.Read(data.header.size + asset.nacp.offset, &nacp, sizeof(nacp), FsReadOption_None, &bytes_read));
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
|
|||||||
@@ -842,7 +842,7 @@ auto install_forwader_internal(ui::ProgressBox* pbox, OwoConfig& config, NcmStor
|
|||||||
pbox->SetTitle(config.name);
|
pbox->SetTitle(config.name);
|
||||||
pbox->SetImageDataConst(config.icon);
|
pbox->SetImageDataConst(config.icon);
|
||||||
|
|
||||||
R_UNLESS(!config.nro_path.empty(), OwoError_BadArgs);
|
R_UNLESS(!config.nro_path.empty(), Result_OwoBadArgs);
|
||||||
// R_UNLESS(!config.icon.empty(), OwoError_BadArgs);
|
// R_UNLESS(!config.icon.empty(), OwoError_BadArgs);
|
||||||
|
|
||||||
R_TRY(splCryptoInitialize());
|
R_TRY(splCryptoInitialize());
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ ThreadData::ThreadData(ui::ProgressBox* _pbox, s64 size, ReadCallback _rfunc, Wr
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto ThreadData::GetResults() -> Result {
|
auto ThreadData::GetResults() -> Result {
|
||||||
R_UNLESS(!pbox->ShouldExit(), 0x1);
|
R_UNLESS(!pbox->ShouldExit(), Result_TransferCancelled);
|
||||||
R_TRY(read_result);
|
R_TRY(read_result);
|
||||||
R_TRY(write_result);
|
R_TRY(write_result);
|
||||||
R_TRY(pull_result);
|
R_TRY(pull_result);
|
||||||
@@ -458,7 +458,7 @@ Result TransferUnzip(ui::ProgressBox* pbox, void* zfile, fs::Fs* fs, const fs::F
|
|||||||
const auto result = unzReadCurrentFile(zfile, data, size);
|
const auto result = unzReadCurrentFile(zfile, data, size);
|
||||||
if (result <= 0) {
|
if (result <= 0) {
|
||||||
log_write("failed to read zip file: %s %d\n", path.s, result);
|
log_write("failed to read zip file: %s %d\n", path.s, result);
|
||||||
R_THROW(0x1);
|
R_THROW(Result_UnzReadCurrentFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crc32) {
|
if (crc32) {
|
||||||
@@ -502,7 +502,7 @@ Result TransferZip(ui::ProgressBox* pbox, void* zfile, fs::Fs* fs, const fs::FsP
|
|||||||
[&](const void* data, s64 off, s64 size) -> Result {
|
[&](const void* data, s64 off, s64 size) -> Result {
|
||||||
if (ZIP_OK != zipWriteInFileInZip(zfile, data, size)) {
|
if (ZIP_OK != zipWriteInFileInZip(zfile, data, size)) {
|
||||||
log_write("failed to write zip file: %s\n", path.s);
|
log_write("failed to write zip file: %s\n", path.s);
|
||||||
R_THROW(0x1);
|
R_THROW(Result_ZipWriteInFileInZip);
|
||||||
}
|
}
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
},
|
},
|
||||||
@@ -513,11 +513,11 @@ Result TransferZip(ui::ProgressBox* pbox, void* zfile, fs::Fs* fs, const fs::FsP
|
|||||||
Result TransferUnzipAll(ui::ProgressBox* pbox, void* zfile, fs::Fs* fs, const fs::FsPath& base_path, UnzipAllFilter filter) {
|
Result TransferUnzipAll(ui::ProgressBox* pbox, void* zfile, fs::Fs* fs, const fs::FsPath& base_path, UnzipAllFilter filter) {
|
||||||
unz_global_info64 ginfo;
|
unz_global_info64 ginfo;
|
||||||
if (UNZ_OK != unzGetGlobalInfo64(zfile, &ginfo)) {
|
if (UNZ_OK != unzGetGlobalInfo64(zfile, &ginfo)) {
|
||||||
R_THROW(0x1);
|
R_THROW(Result_UnzGetGlobalInfo64);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNZ_OK != unzGoToFirstFile(zfile)) {
|
if (UNZ_OK != unzGoToFirstFile(zfile)) {
|
||||||
R_THROW(0x1);
|
R_THROW(Result_UnzGoToFirstFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s64 i = 0; i < ginfo.number_entry; i++) {
|
for (s64 i = 0; i < ginfo.number_entry; i++) {
|
||||||
@@ -526,13 +526,13 @@ Result TransferUnzipAll(ui::ProgressBox* pbox, void* zfile, fs::Fs* fs, const fs
|
|||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
if (UNZ_OK != unzGoToNextFile(zfile)) {
|
if (UNZ_OK != unzGoToNextFile(zfile)) {
|
||||||
log_write("failed to unzGoToNextFile\n");
|
log_write("failed to unzGoToNextFile\n");
|
||||||
R_THROW(0x1);
|
R_THROW(Result_UnzGoToNextFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNZ_OK != unzOpenCurrentFile(zfile)) {
|
if (UNZ_OK != unzOpenCurrentFile(zfile)) {
|
||||||
log_write("failed to open current file\n");
|
log_write("failed to open current file\n");
|
||||||
R_THROW(0x1);
|
R_THROW(Result_UnzOpenCurrentFile);
|
||||||
}
|
}
|
||||||
ON_SCOPE_EXIT(unzCloseCurrentFile(zfile));
|
ON_SCOPE_EXIT(unzCloseCurrentFile(zfile));
|
||||||
|
|
||||||
@@ -540,7 +540,7 @@ Result TransferUnzipAll(ui::ProgressBox* pbox, void* zfile, fs::Fs* fs, const fs
|
|||||||
fs::FsPath name;
|
fs::FsPath name;
|
||||||
if (UNZ_OK != unzGetCurrentFileInfo64(zfile, &info, name, sizeof(name), 0, 0, 0, 0)) {
|
if (UNZ_OK != unzGetCurrentFileInfo64(zfile, &info, name, sizeof(name), 0, 0, 0, 0)) {
|
||||||
log_write("failed to get current info\n");
|
log_write("failed to get current info\n");
|
||||||
R_THROW(0x1);
|
R_THROW(Result_UnzGetCurrentFileInfo64);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we should skip this file.
|
// check if we should skip this file.
|
||||||
@@ -572,7 +572,7 @@ Result TransferUnzipAll(ui::ProgressBox* pbox, const fs::FsPath& zip_out, fs::Fs
|
|||||||
mz::FileFuncStdio(&file_func);
|
mz::FileFuncStdio(&file_func);
|
||||||
|
|
||||||
auto zfile = unzOpen2_64(zip_out, &file_func);
|
auto zfile = unzOpen2_64(zip_out, &file_func);
|
||||||
R_UNLESS(zfile, 0x1);
|
R_UNLESS(zfile, Result_UnzOpen2_64);
|
||||||
ON_SCOPE_EXIT(unzClose(zfile));
|
ON_SCOPE_EXIT(unzClose(zfile));
|
||||||
|
|
||||||
return TransferUnzipAll(pbox, zfile, fs, base_path, filter);
|
return TransferUnzipAll(pbox, zfile, fs, base_path, filter);
|
||||||
|
|||||||
@@ -4,6 +4,129 @@
|
|||||||
#include "i18n.hpp"
|
#include "i18n.hpp"
|
||||||
|
|
||||||
namespace sphaira::ui {
|
namespace sphaira::ui {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
auto GetCodeMessage(Result rc) -> const char* {
|
||||||
|
switch (rc) {
|
||||||
|
case FsError_PathNotFound: return "FsError_PathNotFound";
|
||||||
|
case FsError_PathAlreadyExists: return "FsError_PathAlreadyExists";
|
||||||
|
case FsError_TargetLocked: return "FsError_TargetLocked";
|
||||||
|
|
||||||
|
case Result_TransferCancelled: return "SphairaError_TransferCancelled";
|
||||||
|
case Result_StreamBadSeek: return "SphairaError_StreamBadSeek";
|
||||||
|
case Result_FsTooManyEntries: return "SphairaError_FsTooManyEntries";
|
||||||
|
case Result_FsNewPathTooLarge: return "SphairaError_FsNewPathTooLarge";
|
||||||
|
case Result_FsInvalidType: return "SphairaError_FsInvalidType";
|
||||||
|
case Result_FsEmpty: return "SphairaError_FsEmpty";
|
||||||
|
case Result_FsAlreadyRoot: return "SphairaError_FsAlreadyRoot";
|
||||||
|
case Result_FsNoCurrentPath: return "SphairaError_FsNoCurrentPath";
|
||||||
|
case Result_FsBrokenCurrentPath: return "SphairaError_FsBrokenCurrentPath";
|
||||||
|
case Result_FsIndexOutOfBounds: return "SphairaError_FsIndexOutOfBounds";
|
||||||
|
case Result_FsFsNotActive: return "SphairaError_FsFsNotActive";
|
||||||
|
case Result_FsNewPathEmpty: return "SphairaError_FsNewPathEmpty";
|
||||||
|
case Result_FsLoadingCancelled: return "SphairaError_FsLoadingCancelled";
|
||||||
|
case Result_FsBrokenRoot: return "SphairaError_FsBrokenRoot";
|
||||||
|
case Result_FsUnknownStdioError: return "SphairaError_FsUnknownStdioError";
|
||||||
|
case Result_FsReadOnly: return "SphairaError_FsReadOnly";
|
||||||
|
case Result_FsNotActive: return "SphairaError_FsNotActive";
|
||||||
|
case Result_FsFailedStdioStat: return "SphairaError_FsFailedStdioStat";
|
||||||
|
case Result_FsFailedStdioOpendir: return "SphairaError_FsFailedStdioOpendir";
|
||||||
|
case Result_NroBadMagic: return "SphairaError_NroBadMagic";
|
||||||
|
case Result_NroBadSize: return "SphairaError_NroBadSize";
|
||||||
|
case Result_AppFailedMusicDownload: return "SphairaError_AppFailedMusicDownload";
|
||||||
|
case Result_CurlFailedEasyInit: return "SphairaError_CurlFailedEasyInit";
|
||||||
|
case Result_DumpFailedNetworkUpload: return "SphairaError_DumpFailedNetworkUpload";
|
||||||
|
case Result_UnzOpen2_64: return "SphairaError_UnzOpen2_64";
|
||||||
|
case Result_UnzGetGlobalInfo64: return "SphairaError_UnzGetGlobalInfo64";
|
||||||
|
case Result_UnzLocateFile: return "SphairaError_UnzLocateFile";
|
||||||
|
case Result_UnzGoToFirstFile: return "SphairaError_UnzGoToFirstFile";
|
||||||
|
case Result_UnzGoToNextFile: return "SphairaError_UnzGoToNextFile";
|
||||||
|
case Result_UnzOpenCurrentFile: return "SphairaError_UnzOpenCurrentFile";
|
||||||
|
case Result_UnzGetCurrentFileInfo64: return "SphairaError_UnzGetCurrentFileInfo64";
|
||||||
|
case Result_UnzReadCurrentFile: return "SphairaError_UnzReadCurrentFile";
|
||||||
|
case Result_ZipOpen2_64: return "SphairaError_ZipOpen2_64";
|
||||||
|
case Result_ZipOpenNewFileInZip: return "SphairaError_ZipOpenNewFileInZip";
|
||||||
|
case Result_ZipWriteInFileInZip: return "SphairaError_ZipWriteInFileInZip";
|
||||||
|
case Result_FileBrowserFailedUpload: return "SphairaError_FileBrowserFailedUpload";
|
||||||
|
case Result_FileBrowserDirNotDaybreak: return "SphairaError_FileBrowserDirNotDaybreak";
|
||||||
|
case Result_AppstoreFailedZipDownload: return "SphairaError_AppstoreFailedZipDownload";
|
||||||
|
case Result_AppstoreFailedMd5: return "SphairaError_AppstoreFailedMd5";
|
||||||
|
case Result_AppstoreFailedParseManifest: return "SphairaError_AppstoreFailedParseManifest";
|
||||||
|
case Result_GameBadReadForDump: return "SphairaError_GameBadReadForDump";
|
||||||
|
case Result_GameEmptyMetaEntries: return "SphairaError_GameEmptyMetaEntries";
|
||||||
|
case Result_GameMultipleKeysFound: return "SphairaError_GameMultipleKeysFound";
|
||||||
|
case Result_GameNoNspEntriesBuilt: return "SphairaError_GameNoNspEntriesBuilt";
|
||||||
|
case Result_KeyMissingNcaKeyArea: return "SphairaError_KeyMissingNcaKeyArea";
|
||||||
|
case Result_KeyMissingTitleKek: return "SphairaError_KeyMissingTitleKek";
|
||||||
|
case Result_KeyMissingMasterKey: return "SphairaError_KeyMissingMasterKey";
|
||||||
|
case Result_KeyFailedDecyptETicketDeviceKey: return "SphairaError_KeyFailedDecyptETicketDeviceKey";
|
||||||
|
case Result_NcaFailedNcaHeaderHashVerify: return "SphairaError_NcaFailedNcaHeaderHashVerify";
|
||||||
|
case Result_NcaBadSigKeyGen: return "SphairaError_NcaBadSigKeyGen";
|
||||||
|
case Result_GcBadReadForDump: return "SphairaError_GcBadReadForDump";
|
||||||
|
case Result_GcEmptyGamecard: return "SphairaError_GcEmptyGamecard";
|
||||||
|
case Result_GcBadXciMagic: return "SphairaError_GcBadXciMagic";
|
||||||
|
case Result_GcBadXciRomSize: return "SphairaError_GcBadXciRomSize";
|
||||||
|
case Result_GcFailedToGetSecurityInfo: return "SphairaError_GcFailedToGetSecurityInfo";
|
||||||
|
case Result_GhdlEmptyAsset: return "SphairaError_GhdlEmptyAsset";
|
||||||
|
case Result_GhdlFailedToDownloadAsset: return "SphairaError_GhdlFailedToDownloadAsset";
|
||||||
|
case Result_GhdlFailedToDownloadAssetJson: return "SphairaError_GhdlFailedToDownloadAssetJson";
|
||||||
|
case Result_ThemezerFailedToDownloadThemeMeta: return "SphairaError_ThemezerFailedToDownloadThemeMeta";
|
||||||
|
case Result_ThemezerFailedToDownloadTheme: return "SphairaError_ThemezerFailedToDownloadTheme";
|
||||||
|
case Result_MainFailedToDownloadUpdate: return "SphairaError_MainFailedToDownloadUpdate";
|
||||||
|
case Result_UsbDsBadDeviceSpeed: return "SphairaError_UsbDsBadDeviceSpeed";
|
||||||
|
case Result_NspBadMagic: return "SphairaError_NspBadMagic";
|
||||||
|
case Result_XciBadMagic: return "SphairaError_XciBadMagic";
|
||||||
|
case Result_EsBadTitleKeyType: return "SphairaError_EsBadTitleKeyType";
|
||||||
|
case Result_EsPersonalisedTicketDeviceIdMissmatch: return "SphairaError_EsPersonalisedTicketDeviceIdMissmatch";
|
||||||
|
case Result_EsFailedDecryptPersonalisedTicket: return "SphairaError_EsFailedDecryptPersonalisedTicket";
|
||||||
|
case Result_EsBadDecryptedPersonalisedTicketSize: return "SphairaError_EsBadDecryptedPersonalisedTicketSize";
|
||||||
|
case Result_OwoBadArgs: return "SphairaError_OwoBadArgs";
|
||||||
|
case Result_UsbCancelled: return "SphairaError_UsbCancelled";
|
||||||
|
case Result_UsbBadMagic: return "SphairaError_UsbBadMagic";
|
||||||
|
case Result_UsbBadVersion: return "SphairaError_UsbBadVersion";
|
||||||
|
case Result_UsbBadCount: return "SphairaError_UsbBadCount";
|
||||||
|
case Result_UsbBadTransferSize: return "SphairaError_UsbBadTransferSize";
|
||||||
|
case Result_UsbBadTotalSize: return "SphairaError_UsbBadTotalSize";
|
||||||
|
case Result_UsbUploadBadMagic: return "SphairaError_UsbUploadBadMagic";
|
||||||
|
case Result_UsbUploadExit: return "SphairaError_UsbUploadExit";
|
||||||
|
case Result_UsbUploadBadCount: return "SphairaError_UsbUploadBadCount";
|
||||||
|
case Result_UsbUploadBadTransferSize: return "SphairaError_UsbUploadBadTransferSize";
|
||||||
|
case Result_UsbUploadBadTotalSize: return "SphairaError_UsbUploadBadTotalSize";
|
||||||
|
case Result_UsbUploadBadCommand: return "SphairaError_UsbUploadBadCommand";
|
||||||
|
case Result_YatiContainerNotFound: return "SphairaError_YatiContainerNotFound";
|
||||||
|
case Result_YatiNcaNotFound: return "SphairaError_YatiNcaNotFound";
|
||||||
|
case Result_YatiInvalidNcaReadSize: return "SphairaError_YatiInvalidNcaReadSize";
|
||||||
|
case Result_YatiInvalidNcaSigKeyGen: return "SphairaError_YatiInvalidNcaSigKeyGen";
|
||||||
|
case Result_YatiInvalidNcaMagic: return "SphairaError_YatiInvalidNcaMagic";
|
||||||
|
case Result_YatiInvalidNcaSignature0: return "SphairaError_YatiInvalidNcaSignature0";
|
||||||
|
case Result_YatiInvalidNcaSignature1: return "SphairaError_YatiInvalidNcaSignature1";
|
||||||
|
case Result_YatiInvalidNcaSha256: return "SphairaError_YatiInvalidNcaSha256";
|
||||||
|
case Result_YatiNczSectionNotFound: return "SphairaError_YatiNczSectionNotFound";
|
||||||
|
case Result_YatiInvalidNczSectionCount: return "SphairaError_YatiInvalidNczSectionCount";
|
||||||
|
case Result_YatiNczBlockNotFound: return "SphairaError_YatiNczBlockNotFound";
|
||||||
|
case Result_YatiInvalidNczBlockVersion: return "SphairaError_YatiInvalidNczBlockVersion";
|
||||||
|
case Result_YatiInvalidNczBlockType: return "SphairaError_YatiInvalidNczBlockType";
|
||||||
|
case Result_YatiInvalidNczBlockTotal: return "SphairaError_YatiInvalidNczBlockTotal";
|
||||||
|
case Result_YatiInvalidNczBlockSizeExponent: return "SphairaError_YatiInvalidNczBlockSizeExponent";
|
||||||
|
case Result_YatiInvalidNczZstdError: return "SphairaError_YatiInvalidNczZstdError";
|
||||||
|
case Result_YatiTicketNotFound: return "SphairaError_YatiTicketNotFound";
|
||||||
|
case Result_YatiInvalidTicketBadRightsId: return "SphairaError_YatiInvalidTicketBadRightsId";
|
||||||
|
case Result_YatiInvalidTicketVersion: return "SphairaError_YatiInvalidTicketVersion";
|
||||||
|
case Result_YatiInvalidTicketKeyType: return "SphairaError_YatiInvalidTicketKeyType";
|
||||||
|
case Result_YatiInvalidTicketKeyRevision: return "SphairaError_YatiInvalidTicketKeyRevision";
|
||||||
|
case Result_YatiCertNotFound: return "SphairaError_YatiCertNotFound";
|
||||||
|
case Result_YatiNcmDbCorruptHeader: return "SphairaError_YatiNcmDbCorruptHeader";
|
||||||
|
case Result_YatiNcmDbCorruptInfos: return "SphairaError_YatiNcmDbCorruptInfos";
|
||||||
|
case Result_TicketInvalidTicketBadRightsId: return "SphairaError_TicketInvalidTicketBadRightsId";
|
||||||
|
case Result_TicketInvalidTicketVersion: return "SphairaError_TicketInvalidTicketVersion";
|
||||||
|
case Result_TicketInvalidTicketKeyType: return "SphairaError_TicketInvalidTicketKeyType";
|
||||||
|
case Result_TicketInvalidTicketKeyRevision: return "SphairaError_TicketInvalidTicketKeyRevision";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
ErrorBox::ErrorBox(const std::string& message) : m_message{message} {
|
ErrorBox::ErrorBox(const std::string& message) : m_message{message} {
|
||||||
log_write("[ERROR] %s\n", m_message.c_str());
|
log_write("[ERROR] %s\n", m_message.c_str());
|
||||||
@@ -22,6 +145,7 @@ ErrorBox::ErrorBox(const std::string& message) : m_message{message} {
|
|||||||
|
|
||||||
ErrorBox::ErrorBox(Result code, const std::string& message) : ErrorBox{message} {
|
ErrorBox::ErrorBox(Result code, const std::string& message) : ErrorBox{message} {
|
||||||
m_code = code;
|
m_code = code;
|
||||||
|
m_code_message = GetCodeMessage(code);
|
||||||
log_write("[ERROR] Code: 0x%X Module: %u Description: %u\n", R_VALUE(code), R_MODULE(code), R_DESCRIPTION(code));
|
log_write("[ERROR] Code: 0x%X Module: %u Description: %u\n", R_VALUE(code), R_MODULE(code), R_DESCRIPTION(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +163,11 @@ auto ErrorBox::Draw(NVGcontext* vg, Theme* theme) -> void {
|
|||||||
gfx::drawTextArgs(vg, center_x, 180, 63, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_ERROR), "\uE140");
|
gfx::drawTextArgs(vg, center_x, 180, 63, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_ERROR), "\uE140");
|
||||||
if (m_code.has_value()) {
|
if (m_code.has_value()) {
|
||||||
const auto code = m_code.value();
|
const auto code = m_code.value();
|
||||||
|
if (m_code_message.empty()) {
|
||||||
gfx::drawTextArgs(vg, center_x, 270, 25, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_TEXT), "Code: 0x%X Module: %u Description: 0x%X", R_VALUE(code), R_MODULE(code), R_DESCRIPTION(code));
|
gfx::drawTextArgs(vg, center_x, 270, 25, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_TEXT), "Code: 0x%X Module: %u Description: 0x%X", R_VALUE(code), R_MODULE(code), R_DESCRIPTION(code));
|
||||||
|
} else {
|
||||||
|
gfx::drawTextArgs(vg, center_x, 270, 25, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_TEXT), "%s", m_code_message.c_str());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
gfx::drawTextArgs(vg, center_x, 270, 25, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_TEXT), "An error occurred"_i18n.c_str());
|
gfx::drawTextArgs(vg, center_x, 270, 25, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_TEXT), "An error occurred"_i18n.c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -330,8 +330,9 @@ auto UninstallApp(ProgressBox* pbox, const Entry& entry) -> Result {
|
|||||||
fs::FsNativeSd fs;
|
fs::FsNativeSd fs;
|
||||||
|
|
||||||
if (manifest.empty()) {
|
if (manifest.empty()) {
|
||||||
R_UNLESS(!entry.binary.empty(), 0x1);
|
if (!entry.binary.empty()) {
|
||||||
fs.DeleteFile(entry.binary);
|
R_TRY(fs.DeleteFile(entry.binary));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (auto& e : manifest) {
|
for (auto& e : manifest) {
|
||||||
pbox->NewTransfer(e.path);
|
pbox->NewTransfer(e.path);
|
||||||
@@ -397,7 +398,7 @@ auto InstallApp(ProgressBox* pbox, const Entry& entry) -> Result {
|
|||||||
api_result = curl::ToMemory(api);
|
api_result = curl::ToMemory(api);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_UNLESS(api_result.success, 0x1);
|
R_UNLESS(api_result.success, Result_AppstoreFailedZipDownload);
|
||||||
}
|
}
|
||||||
|
|
||||||
ON_SCOPE_EXIT(fs.DeleteFile(zip_out));
|
ON_SCOPE_EXIT(fs.DeleteFile(zip_out));
|
||||||
@@ -416,7 +417,7 @@ auto InstallApp(ProgressBox* pbox, const Entry& entry) -> Result {
|
|||||||
|
|
||||||
if (strncasecmp(hash_out.data(), entry.md5.data(), entry.md5.length())) {
|
if (strncasecmp(hash_out.data(), entry.md5.data(), entry.md5.length())) {
|
||||||
log_write("bad md5: %.*s vs %.*s\n", 32, hash_out.data(), 32, entry.md5.c_str());
|
log_write("bad md5: %.*s vs %.*s\n", 32, hash_out.data(), 32, entry.md5.c_str());
|
||||||
R_THROW(0x1);
|
R_THROW(Result_AppstoreFailedMd5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,13 +432,13 @@ auto InstallApp(ProgressBox* pbox, const Entry& entry) -> Result {
|
|||||||
// 3. extract the zip
|
// 3. extract the zip
|
||||||
if (!pbox->ShouldExit()) {
|
if (!pbox->ShouldExit()) {
|
||||||
auto zfile = unzOpen2_64(zip_out, &file_func);
|
auto zfile = unzOpen2_64(zip_out, &file_func);
|
||||||
R_UNLESS(zfile, 0x1);
|
R_UNLESS(zfile, Result_UnzOpen2_64);
|
||||||
ON_SCOPE_EXIT(unzClose(zfile));
|
ON_SCOPE_EXIT(unzClose(zfile));
|
||||||
|
|
||||||
// get manifest
|
// get manifest
|
||||||
if (UNZ_END_OF_LIST_OF_FILE == unzLocateFile(zfile, "manifest.install", 0)) {
|
if (UNZ_END_OF_LIST_OF_FILE == unzLocateFile(zfile, "manifest.install", 0)) {
|
||||||
log_write("failed to find manifest.install\n");
|
log_write("failed to find manifest.install\n");
|
||||||
R_THROW(0x1);
|
R_THROW(Result_UnzLocateFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
ManifestEntries new_manifest;
|
ManifestEntries new_manifest;
|
||||||
@@ -445,26 +446,26 @@ auto InstallApp(ProgressBox* pbox, const Entry& entry) -> Result {
|
|||||||
{
|
{
|
||||||
if (UNZ_OK != unzOpenCurrentFile(zfile)) {
|
if (UNZ_OK != unzOpenCurrentFile(zfile)) {
|
||||||
log_write("failed to open current file\n");
|
log_write("failed to open current file\n");
|
||||||
R_THROW(0x1);
|
R_THROW(Result_UnzOpenCurrentFile);
|
||||||
}
|
}
|
||||||
ON_SCOPE_EXIT(unzCloseCurrentFile(zfile));
|
ON_SCOPE_EXIT(unzCloseCurrentFile(zfile));
|
||||||
|
|
||||||
unz_file_info64 info;
|
unz_file_info64 info;
|
||||||
if (UNZ_OK != unzGetCurrentFileInfo64(zfile, &info, 0, 0, 0, 0, 0, 0)) {
|
if (UNZ_OK != unzGetCurrentFileInfo64(zfile, &info, 0, 0, 0, 0, 0, 0)) {
|
||||||
log_write("failed to get current info\n");
|
log_write("failed to get current info\n");
|
||||||
R_THROW(0x1);
|
R_THROW(Result_UnzGetGlobalInfo64);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<char> manifest_data(info.uncompressed_size);
|
std::vector<char> manifest_data(info.uncompressed_size);
|
||||||
if ((int)info.uncompressed_size != unzReadCurrentFile(zfile, manifest_data.data(), manifest_data.size())) {
|
if ((int)info.uncompressed_size != unzReadCurrentFile(zfile, manifest_data.data(), manifest_data.size())) {
|
||||||
log_write("failed to read manifest file\n");
|
log_write("failed to read manifest file\n");
|
||||||
R_THROW(0x1);
|
R_THROW(Result_UnzReadCurrentFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
new_manifest = ParseManifest(manifest_data);
|
new_manifest = ParseManifest(manifest_data);
|
||||||
if (new_manifest.empty()) {
|
if (new_manifest.empty()) {
|
||||||
log_write("manifest is empty!\n");
|
log_write("manifest is empty!\n");
|
||||||
R_THROW(0x1);
|
R_THROW(Result_AppstoreFailedParseManifest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,19 +474,19 @@ auto InstallApp(ProgressBox* pbox, const Entry& entry) -> Result {
|
|||||||
|
|
||||||
if (UNZ_END_OF_LIST_OF_FILE == unzLocateFile(zfile, inzip, 0)) {
|
if (UNZ_END_OF_LIST_OF_FILE == unzLocateFile(zfile, inzip, 0)) {
|
||||||
log_write("failed to find %s\n", inzip.s);
|
log_write("failed to find %s\n", inzip.s);
|
||||||
R_THROW(0x1);
|
R_THROW(Result_UnzLocateFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNZ_OK != unzOpenCurrentFile(zfile)) {
|
if (UNZ_OK != unzOpenCurrentFile(zfile)) {
|
||||||
log_write("failed to open current file\n");
|
log_write("failed to open current file\n");
|
||||||
R_THROW(0x1);
|
R_THROW(Result_UnzOpenCurrentFile);
|
||||||
}
|
}
|
||||||
ON_SCOPE_EXIT(unzCloseCurrentFile(zfile));
|
ON_SCOPE_EXIT(unzCloseCurrentFile(zfile));
|
||||||
|
|
||||||
unz_file_info64 info;
|
unz_file_info64 info;
|
||||||
if (UNZ_OK != unzGetCurrentFileInfo64(zfile, &info, 0, 0, 0, 0, 0, 0)) {
|
if (UNZ_OK != unzGetCurrentFileInfo64(zfile, &info, 0, 0, 0, 0, 0, 0)) {
|
||||||
log_write("failed to get current info\n");
|
log_write("failed to get current info\n");
|
||||||
R_THROW(0x1);
|
R_THROW(Result_UnzGetCurrentFileInfo64);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto path = output;
|
auto path = output;
|
||||||
|
|||||||
@@ -800,7 +800,7 @@ void FsView::ZipFiles(fs::FsPath zip_out) {
|
|||||||
mz::FileFuncStdio(&file_func);
|
mz::FileFuncStdio(&file_func);
|
||||||
|
|
||||||
auto zfile = zipOpen2_64(zip_out, APPEND_STATUS_CREATE, nullptr, &file_func);
|
auto zfile = zipOpen2_64(zip_out, APPEND_STATUS_CREATE, nullptr, &file_func);
|
||||||
R_UNLESS(zfile, 0x1);
|
R_UNLESS(zfile, Result_ZipOpen2_64);
|
||||||
ON_SCOPE_EXIT(zipClose(zfile, "sphaira v" APP_VERSION_HASH));
|
ON_SCOPE_EXIT(zipClose(zfile, "sphaira v" APP_VERSION_HASH));
|
||||||
|
|
||||||
const auto zip_add = [&](const fs::FsPath& file_path) -> Result {
|
const auto zip_add = [&](const fs::FsPath& file_path) -> Result {
|
||||||
@@ -821,7 +821,7 @@ void FsView::ZipFiles(fs::FsPath zip_out) {
|
|||||||
|
|
||||||
if (ZIP_OK != zipOpenNewFileInZip(zfile, file_name_in_zip, &zip_info, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION)) {
|
if (ZIP_OK != zipOpenNewFileInZip(zfile, file_name_in_zip, &zip_info, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION)) {
|
||||||
log_write("failed to add zip for %s\n", file_path.s);
|
log_write("failed to add zip for %s\n", file_path.s);
|
||||||
R_THROW(0x1);
|
R_THROW(Result_ZipOpenNewFileInZip);
|
||||||
}
|
}
|
||||||
ON_SCOPE_EXIT(zipCloseFileInZip(zfile));
|
ON_SCOPE_EXIT(zipCloseFileInZip(zfile));
|
||||||
|
|
||||||
@@ -927,7 +927,7 @@ void FsView::UploadFiles() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
R_UNLESS(result.success, 0x1);
|
R_UNLESS(result.success, Result_FileBrowserFailedUpload);
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -1332,8 +1332,8 @@ void FsView::OnRenameCallback() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto FsView::CheckIfUpdateFolder() -> Result {
|
auto FsView::CheckIfUpdateFolder() -> Result {
|
||||||
R_UNLESS(IsSd(), FsError_InvalidMountName);
|
R_UNLESS(IsSd(), Result_FileBrowserDirNotDaybreak);
|
||||||
R_UNLESS(m_fs->IsNative(), 0x1);
|
R_UNLESS(m_fs->IsNative(), Result_FileBrowserDirNotDaybreak);
|
||||||
|
|
||||||
// check if we have already tried to find daybreak
|
// check if we have already tried to find daybreak
|
||||||
if (m_daybreak_path.has_value() && m_daybreak_path.value().empty()) {
|
if (m_daybreak_path.has_value() && m_daybreak_path.value().empty()) {
|
||||||
@@ -1357,16 +1357,16 @@ auto FsView::CheckIfUpdateFolder() -> Result {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check that we have enough ncas and not too many
|
// check that we have enough ncas and not too many
|
||||||
R_UNLESS(m_entries.size() > 150 && m_entries.size() < 300, 0x1);
|
R_UNLESS(m_entries.size() > 150 && m_entries.size() < 300, Result_FileBrowserDirNotDaybreak);
|
||||||
|
|
||||||
// check that all entries end in .nca
|
// check that all entries end in .nca
|
||||||
const auto nca_ext = std::string_view{".nca"};
|
const auto nca_ext = std::string_view{".nca"};
|
||||||
for (auto& e : m_entries) {
|
for (auto& e : m_entries) {
|
||||||
// check that we are at the bottom level
|
// check that we are at the bottom level
|
||||||
R_UNLESS(e.type == FsDirEntryType_File, 0x1);
|
R_UNLESS(e.type == FsDirEntryType_File, Result_FileBrowserDirNotDaybreak);
|
||||||
|
|
||||||
const auto ext = std::strrchr(e.name, '.');
|
const auto ext = std::strrchr(e.name, '.');
|
||||||
R_UNLESS(ext && ext == nca_ext, 0x1);
|
R_UNLESS(ext && ext == nca_ext, Result_FileBrowserDirNotDaybreak);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ struct NspEntry {
|
|||||||
const auto it = std::ranges::find_if(tickets, [&id](auto& e){
|
const auto it = std::ranges::find_if(tickets, [&id](auto& e){
|
||||||
return !std::memcmp(&id, &e.id, sizeof(id));
|
return !std::memcmp(&id, &e.id, sizeof(id));
|
||||||
});
|
});
|
||||||
R_UNLESS(it != tickets.end(), 0x1);
|
R_UNLESS(it != tickets.end(), Result_GameBadReadForDump);
|
||||||
|
|
||||||
const auto& data = collection.name.ends_with(".tik") ? it->tik_data : it->cert_data;
|
const auto& data = collection.name.ends_with(".tik") ? it->tik_data : it->cert_data;
|
||||||
std::memcpy(buf, data.data() + off, size);
|
std::memcpy(buf, data.data() + off, size);
|
||||||
@@ -225,7 +225,7 @@ struct NspSource final : dump::BaseSource {
|
|||||||
const auto it = std::ranges::find_if(m_entries, [&path](auto& e){
|
const auto it = std::ranges::find_if(m_entries, [&path](auto& e){
|
||||||
return path.find(e.path.s) != path.npos;
|
return path.find(e.path.s) != path.npos;
|
||||||
});
|
});
|
||||||
R_UNLESS(it != m_entries.end(), 0x1);
|
R_UNLESS(it != m_entries.end(), Result_GameBadReadForDump);
|
||||||
|
|
||||||
const auto rc = it->Read(buf, off, size, bytes_read);
|
const auto rc = it->Read(buf, off, size, bytes_read);
|
||||||
if (m_is_file_based_emummc) {
|
if (m_is_file_based_emummc) {
|
||||||
@@ -360,7 +360,7 @@ Result LoadControlManual(u64 id, ThreadResultData& data) {
|
|||||||
|
|
||||||
MetaEntries entries;
|
MetaEntries entries;
|
||||||
R_TRY(GetMetaEntries(id, entries));
|
R_TRY(GetMetaEntries(id, entries));
|
||||||
R_UNLESS(!entries.empty(), 0x1);
|
R_UNLESS(!entries.empty(), Result_GameEmptyMetaEntries);
|
||||||
|
|
||||||
u64 program_id;
|
u64 program_id;
|
||||||
fs::FsPath path;
|
fs::FsPath path;
|
||||||
@@ -541,8 +541,8 @@ Result BuildContentEntry(const NsApplicationContentMetaStatus& status, ContentIn
|
|||||||
NcmContentMetaKey key;
|
NcmContentMetaKey key;
|
||||||
R_TRY(ncmContentMetaDatabaseList(std::addressof(db), std::addressof(meta_total), std::addressof(meta_entries_written), std::addressof(key), 1, (NcmContentMetaType)status.meta_type, app_id, id_min, id_max, NcmContentInstallType_Full));
|
R_TRY(ncmContentMetaDatabaseList(std::addressof(db), std::addressof(meta_total), std::addressof(meta_entries_written), std::addressof(key), 1, (NcmContentMetaType)status.meta_type, app_id, id_min, id_max, NcmContentInstallType_Full));
|
||||||
log_write("ncmContentMetaDatabaseList(): AppId: %016lX Id: %016lX total: %d written: %d storageID: %u key.id %016lX\n", app_id, status.application_id, meta_total, meta_entries_written, status.storageID, key.id);
|
log_write("ncmContentMetaDatabaseList(): AppId: %016lX Id: %016lX total: %d written: %d storageID: %u key.id %016lX\n", app_id, status.application_id, meta_total, meta_entries_written, status.storageID, key.id);
|
||||||
R_UNLESS(meta_total == 1, 0x1);
|
R_UNLESS(meta_total == 1, Result_GameMultipleKeysFound);
|
||||||
R_UNLESS(meta_entries_written == 1, 0x1);
|
R_UNLESS(meta_entries_written == 1, Result_GameMultipleKeysFound);
|
||||||
|
|
||||||
std::vector<NcmContentInfo> cnmt_infos;
|
std::vector<NcmContentInfo> cnmt_infos;
|
||||||
for (s32 i = 0; ; i++) {
|
for (s32 i = 0; ; i++) {
|
||||||
@@ -648,7 +648,7 @@ Result BuildNspEntries(Entry& e, u32 flags, std::vector<NspEntry>& out) {
|
|||||||
out.emplace_back(nsp).icon = e.image;
|
out.emplace_back(nsp).icon = e.image;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_UNLESS(!out.empty(), 0x1);
|
R_UNLESS(!out.empty(), Result_GameNoNspEntriesBuilt);
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ struct XciSource final : dump::BaseSource {
|
|||||||
span = initial;
|
span = initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_UNLESS(!span.empty(), 0x1);
|
R_UNLESS(!span.empty(), Result_GcBadReadForDump);
|
||||||
|
|
||||||
size = ClipSize(off, size, span.size());
|
size = ClipSize(off, size, span.size());
|
||||||
*bytes_read = size;
|
*bytes_read = size;
|
||||||
@@ -376,7 +376,7 @@ Result GcSource::Read(void* buf, s64 off, s64 size, u64* bytes_read) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this will never fail, unless i break something in yati.
|
// this will never fail, unless i break something in yati.
|
||||||
R_UNLESS(found, 0x1);
|
R_UNLESS(found, Result_GcBadReadForDump);
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_file.Read(off - m_offset, buf, size, 0, bytes_read);
|
return m_file.Read(off - m_offset, buf, size, 0, bytes_read);
|
||||||
@@ -593,7 +593,7 @@ Result Menu::GcMount() {
|
|||||||
return !std::strncmp(str.str, e.name, std::strlen(str.str));
|
return !std::strncmp(str.str, e.name, std::strlen(str.str));
|
||||||
});
|
});
|
||||||
|
|
||||||
R_UNLESS(it != buf.cend(), yati::Result_NcaNotFound);
|
R_UNLESS(it != buf.cend(), Result_YatiNcaNotFound);
|
||||||
collections.emplace_back(it->name, it->file_size, info.content_type, info.id_offset);
|
collections.emplace_back(it->name, it->file_size, info.content_type, info.id_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,7 +624,7 @@ Result Menu::GcMount() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R_UNLESS(m_entries.size(), 0x1);
|
R_UNLESS(m_entries.size(), Result_GcEmptyGamecard);
|
||||||
|
|
||||||
// append tickets to every application, yati will ignore if undeeded.
|
// append tickets to every application, yati will ignore if undeeded.
|
||||||
for (auto& e : m_entries) {
|
for (auto& e : m_entries) {
|
||||||
@@ -742,12 +742,12 @@ Result Menu::GcMountStorage() {
|
|||||||
std::memcpy(&trim_size, header + 0x118, sizeof(trim_size));
|
std::memcpy(&trim_size, header + 0x118, sizeof(trim_size));
|
||||||
std::memcpy(&m_package_id, header + 0x110, sizeof(m_package_id));
|
std::memcpy(&m_package_id, header + 0x110, sizeof(m_package_id));
|
||||||
std::memcpy(m_initial_data_hash, header + 0x160, sizeof(m_initial_data_hash));
|
std::memcpy(m_initial_data_hash, header + 0x160, sizeof(m_initial_data_hash));
|
||||||
R_UNLESS(magic == XCI_MAGIC, 0x1);
|
R_UNLESS(magic == XCI_MAGIC, Result_GcBadXciMagic);
|
||||||
|
|
||||||
// calculate the reported size, error if not found.
|
// calculate the reported size, error if not found.
|
||||||
m_storage_full_size = GetXciSizeFromRomSize(rom_size);
|
m_storage_full_size = GetXciSizeFromRomSize(rom_size);
|
||||||
log_write("[GC] m_storage_full_size: %zd rom_size: 0x%X\n", m_storage_full_size, rom_size);
|
log_write("[GC] m_storage_full_size: %zd rom_size: 0x%X\n", m_storage_full_size, rom_size);
|
||||||
R_UNLESS(m_storage_full_size > 0, 0x1);
|
R_UNLESS(m_storage_full_size > 0, Result_GcBadXciRomSize);
|
||||||
|
|
||||||
R_TRY(fsStorageGetSize(&m_storage, &m_parition_normal_size));
|
R_TRY(fsStorageGetSize(&m_storage, &m_parition_normal_size));
|
||||||
R_TRY(GcMountPartition(FsGameCardPartitionRaw_Secure));
|
R_TRY(GcMountPartition(FsGameCardPartitionRaw_Secure));
|
||||||
@@ -1141,7 +1141,7 @@ Result Menu::GcGetSecurityInfo(GameCardSecurityInformation& out) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R_THROW(0x1);
|
R_THROW(Result_GcFailedToGetSecurityInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sphaira::ui::menu::gc
|
} // namespace sphaira::ui::menu::gc
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ auto DownloadApp(ProgressBox* pbox, const GhApiAsset& gh_asset, const AssetEntry
|
|||||||
R_TRY(fs.GetFsOpenResult());
|
R_TRY(fs.GetFsOpenResult());
|
||||||
ON_SCOPE_EXIT(fs.DeleteFile(temp_file));
|
ON_SCOPE_EXIT(fs.DeleteFile(temp_file));
|
||||||
|
|
||||||
R_UNLESS(!gh_asset.browser_download_url.empty(), 0x1);
|
R_UNLESS(!gh_asset.browser_download_url.empty(), Result_GhdlEmptyAsset);
|
||||||
|
|
||||||
// 2. download the asset
|
// 2. download the asset
|
||||||
if (!pbox->ShouldExit()) {
|
if (!pbox->ShouldExit()) {
|
||||||
@@ -101,7 +101,7 @@ auto DownloadApp(ProgressBox* pbox, const GhApiAsset& gh_asset, const AssetEntry
|
|||||||
curl::OnProgress{pbox->OnDownloadProgressCallback()}
|
curl::OnProgress{pbox->OnDownloadProgressCallback()}
|
||||||
);
|
);
|
||||||
|
|
||||||
R_UNLESS(result.success, 0x1);
|
R_UNLESS(result.success, Result_GhdlFailedToDownloadAsset);
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::FsPath root_path{"/"};
|
fs::FsPath root_path{"/"};
|
||||||
@@ -141,11 +141,11 @@ auto DownloadAssetJson(ProgressBox* pbox, const std::string& url, GhApiEntry& ou
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
R_UNLESS(result.success, 0x1);
|
R_UNLESS(result.success, Result_GhdlFailedToDownloadAssetJson);
|
||||||
from_json(result.path, out);
|
from_json(result.path, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_UNLESS(!out.assets.empty(), 0x1);
|
R_UNLESS(!out.assets.empty(), Result_GhdlEmptyAsset);
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ auto InstallUpdate(ProgressBox* pbox, const std::string url, const std::string v
|
|||||||
curl::OnProgress{pbox->OnDownloadProgressCallback()}
|
curl::OnProgress{pbox->OnDownloadProgressCallback()}
|
||||||
);
|
);
|
||||||
|
|
||||||
R_UNLESS(result.success, 0x1);
|
R_UNLESS(result.success, Result_MainFailedToDownloadUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
ON_SCOPE_EXIT(fs.DeleteFile(zip_out));
|
ON_SCOPE_EXIT(fs.DeleteFile(zip_out));
|
||||||
|
|||||||
@@ -394,7 +394,7 @@ Result LoadControlManual(u64 id, ThreadResultData& data) {
|
|||||||
|
|
||||||
MetaEntries entries;
|
MetaEntries entries;
|
||||||
R_TRY(GetMetaEntries(id, entries));
|
R_TRY(GetMetaEntries(id, entries));
|
||||||
R_UNLESS(!entries.empty(), 0x1);
|
R_UNLESS(!entries.empty(), Result_GameEmptyMetaEntries);
|
||||||
|
|
||||||
u64 program_id;
|
u64 program_id;
|
||||||
fs::FsPath path;
|
fs::FsPath path;
|
||||||
@@ -1193,7 +1193,7 @@ Result Menu::RestoreSaveInternal(ProgressBox* pbox, const Entry& e, const fs::Fs
|
|||||||
mz::FileFuncStdio(&file_func);
|
mz::FileFuncStdio(&file_func);
|
||||||
|
|
||||||
auto zfile = unzOpen2_64(path, &file_func);
|
auto zfile = unzOpen2_64(path, &file_func);
|
||||||
R_UNLESS(zfile, 0x1);
|
R_UNLESS(zfile, Result_UnzOpen2_64);
|
||||||
ON_SCOPE_EXIT(unzClose(zfile));
|
ON_SCOPE_EXIT(unzClose(zfile));
|
||||||
log_write("opened zip\n");
|
log_write("opened zip\n");
|
||||||
|
|
||||||
@@ -1225,22 +1225,22 @@ Result Menu::RestoreSaveInternal(ProgressBox* pbox, const Entry& e, const fs::Fs
|
|||||||
|
|
||||||
// todo:: manually calculate / guess the save size.
|
// todo:: manually calculate / guess the save size.
|
||||||
unz_global_info64 ginfo;
|
unz_global_info64 ginfo;
|
||||||
R_UNLESS(UNZ_OK == unzGetGlobalInfo64(zfile, &ginfo), 0x1);
|
R_UNLESS(UNZ_OK == unzGetGlobalInfo64(zfile, &ginfo), Result_UnzGetGlobalInfo64);
|
||||||
R_UNLESS(UNZ_OK == unzGoToFirstFile(zfile), 0x1);
|
R_UNLESS(UNZ_OK == unzGoToFirstFile(zfile), Result_UnzGoToFirstFile);
|
||||||
|
|
||||||
for (s64 i = 0; i < ginfo.number_entry; i++) {
|
for (s64 i = 0; i < ginfo.number_entry; i++) {
|
||||||
R_TRY(pbox->ShouldExitResult());
|
R_TRY(pbox->ShouldExitResult());
|
||||||
|
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
R_UNLESS(UNZ_OK == unzGoToNextFile(zfile), 0x1);
|
R_UNLESS(UNZ_OK == unzGoToNextFile(zfile), Result_UnzGoToNextFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_UNLESS(UNZ_OK == unzOpenCurrentFile(zfile), 0x1);
|
R_UNLESS(UNZ_OK == unzOpenCurrentFile(zfile), Result_UnzOpenCurrentFile);
|
||||||
ON_SCOPE_EXIT(unzCloseCurrentFile(zfile));
|
ON_SCOPE_EXIT(unzCloseCurrentFile(zfile));
|
||||||
|
|
||||||
unz_file_info64 info;
|
unz_file_info64 info;
|
||||||
fs::FsPath name;
|
fs::FsPath name;
|
||||||
R_UNLESS(UNZ_OK == unzGetCurrentFileInfo64(zfile, &info, name, sizeof(name), 0, 0, 0, 0), 0x1);
|
R_UNLESS(UNZ_OK == unzGetCurrentFileInfo64(zfile, &info, name, sizeof(name), 0, 0, 0, 0), Result_UnzGetCurrentFileInfo64);
|
||||||
|
|
||||||
if (name == NX_SAVE_META_NAME) {
|
if (name == NX_SAVE_META_NAME) {
|
||||||
continue;
|
continue;
|
||||||
@@ -1296,7 +1296,7 @@ Result Menu::BackupSaveInternal(ProgressBox* pbox, const dump::DumpLocation& loc
|
|||||||
} else if (location.entry.type == dump::DumpLocationType_SdCard) {
|
} else if (location.entry.type == dump::DumpLocationType_SdCard) {
|
||||||
fs = std::make_unique<fs::FsNativeSd>();
|
fs = std::make_unique<fs::FsNativeSd>();
|
||||||
} else {
|
} else {
|
||||||
R_THROW(0x1);
|
std::unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
pbox->SetTitle(e.GetName());
|
pbox->SetTitle(e.GetName());
|
||||||
@@ -1367,7 +1367,7 @@ Result Menu::BackupSaveInternal(ProgressBox* pbox, const dump::DumpLocation& loc
|
|||||||
|
|
||||||
{
|
{
|
||||||
auto zfile = zipOpen2_64(temp_path, APPEND_STATUS_CREATE, nullptr, &file_func);
|
auto zfile = zipOpen2_64(temp_path, APPEND_STATUS_CREATE, nullptr, &file_func);
|
||||||
R_UNLESS(zfile, 0x1);
|
R_UNLESS(zfile, Result_ZipOpen2_64);
|
||||||
ON_SCOPE_EXIT(zipClose(zfile, "sphaira v" APP_VERSION_HASH));
|
ON_SCOPE_EXIT(zipClose(zfile, "sphaira v" APP_VERSION_HASH));
|
||||||
|
|
||||||
// add save meta.
|
// add save meta.
|
||||||
@@ -1386,9 +1386,9 @@ Result Menu::BackupSaveInternal(ProgressBox* pbox, const dump::DumpLocation& loc
|
|||||||
.raw_size = e.size,
|
.raw_size = e.size,
|
||||||
};
|
};
|
||||||
|
|
||||||
R_UNLESS(ZIP_OK == zipOpenNewFileInZip(zfile, NX_SAVE_META_NAME, &zip_info_default, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_NO_COMPRESSION), 0x1);
|
R_UNLESS(ZIP_OK == zipOpenNewFileInZip(zfile, NX_SAVE_META_NAME, &zip_info_default, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_NO_COMPRESSION), Result_ZipOpenNewFileInZip);
|
||||||
ON_SCOPE_EXIT(zipCloseFileInZip(zfile));
|
ON_SCOPE_EXIT(zipCloseFileInZip(zfile));
|
||||||
R_UNLESS(ZIP_OK == zipWriteInFileInZip(zfile, &meta, sizeof(meta)), 0x1);
|
R_UNLESS(ZIP_OK == zipWriteInFileInZip(zfile, &meta, sizeof(meta)), Result_ZipWriteInFileInZip);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto zip_add = [&](const fs::FsPath& file_path) -> Result {
|
const auto zip_add = [&](const fs::FsPath& file_path) -> Result {
|
||||||
@@ -1409,7 +1409,7 @@ Result Menu::BackupSaveInternal(ProgressBox* pbox, const dump::DumpLocation& loc
|
|||||||
const auto level = compressed ? Z_DEFAULT_COMPRESSION : Z_NO_COMPRESSION;
|
const auto level = compressed ? Z_DEFAULT_COMPRESSION : Z_NO_COMPRESSION;
|
||||||
if (ZIP_OK != zipOpenNewFileInZip(zfile, file_name_in_zip, &zip_info_default, NULL, 0, NULL, 0, NULL, Z_DEFLATED, level)) {
|
if (ZIP_OK != zipOpenNewFileInZip(zfile, file_name_in_zip, &zip_info_default, NULL, 0, NULL, 0, NULL, Z_DEFLATED, level)) {
|
||||||
log_write("failed to add zip for %s\n", file_path.s);
|
log_write("failed to add zip for %s\n", file_path.s);
|
||||||
R_THROW(0x1);
|
R_THROW(Result_ZipOpenNewFileInZip);
|
||||||
}
|
}
|
||||||
ON_SCOPE_EXIT(zipCloseFileInZip(zfile));
|
ON_SCOPE_EXIT(zipCloseFileInZip(zfile));
|
||||||
|
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ auto InstallTheme(ProgressBox* pbox, const PackListEntry& entry) -> Result {
|
|||||||
|
|
||||||
if (!result.success || result.data.empty()) {
|
if (!result.success || result.data.empty()) {
|
||||||
log_write("error with download: %s\n", url.c_str());
|
log_write("error with download: %s\n", url.c_str());
|
||||||
R_THROW(0x1);
|
R_THROW(Result_ThemezerFailedToDownloadThemeMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
from_json(result.data, download_pack);
|
from_json(result.data, download_pack);
|
||||||
@@ -255,7 +255,7 @@ auto InstallTheme(ProgressBox* pbox, const PackListEntry& entry) -> Result {
|
|||||||
curl::OnProgress{pbox->OnDownloadProgressCallback()}
|
curl::OnProgress{pbox->OnDownloadProgressCallback()}
|
||||||
);
|
);
|
||||||
|
|
||||||
R_UNLESS(result.success, 0x1);
|
R_UNLESS(result.success, Result_ThemezerFailedToDownloadTheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
ON_SCOPE_EXIT(fs.DeleteFile(zip_out));
|
ON_SCOPE_EXIT(fs.DeleteFile(zip_out));
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ void thread_func(void* user) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto rc = app->m_usb_source->IsUsbConnected(CONNECTION_TIMEOUT);
|
const auto rc = app->m_usb_source->IsUsbConnected(CONNECTION_TIMEOUT);
|
||||||
if (rc == ::sphaira::usb::UsbDs::Result_Cancelled) {
|
if (rc == Result_UsbCancelled) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ auto ProgressBox::ShouldExit() -> bool {
|
|||||||
|
|
||||||
auto ProgressBox::ShouldExitResult() -> Result {
|
auto ProgressBox::ShouldExitResult() -> Result {
|
||||||
if (ShouldExit()) {
|
if (ShouldExit()) {
|
||||||
R_THROW(0xFFFF);
|
R_THROW(Result_TransferCancelled);
|
||||||
}
|
}
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,14 +67,14 @@ Result Usb::WaitForConnection(u64 timeout, u8 flags, std::span<const std::string
|
|||||||
Result Usb::PollCommands() {
|
Result Usb::PollCommands() {
|
||||||
tinfoil::USBCmdHeader header;
|
tinfoil::USBCmdHeader header;
|
||||||
R_TRY(m_usb->TransferAll(true, &header, sizeof(header)));
|
R_TRY(m_usb->TransferAll(true, &header, sizeof(header)));
|
||||||
R_UNLESS(header.magic == tinfoil::Magic_Command0, Result_BadMagic);
|
R_UNLESS(header.magic == tinfoil::Magic_Command0, Result_UsbUploadBadMagic);
|
||||||
|
|
||||||
if (header.cmdId == tinfoil::USBCmdId::EXIT) {
|
if (header.cmdId == tinfoil::USBCmdId::EXIT) {
|
||||||
return Result_Exit;
|
R_THROW(Result_UsbUploadExit);
|
||||||
} else if (header.cmdId == tinfoil::USBCmdId::FILE_RANGE) {
|
} else if (header.cmdId == tinfoil::USBCmdId::FILE_RANGE) {
|
||||||
return FileRangeCmd(header.dataSize);
|
return FileRangeCmd(header.dataSize);
|
||||||
} else {
|
} else {
|
||||||
return Result_BadCommand;
|
R_THROW(Result_UsbUploadBadCommand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ Result UsbDs::WaitUntilConfigured(u64 timeout) {
|
|||||||
|
|
||||||
// check if we got one of the cancel events.
|
// check if we got one of the cancel events.
|
||||||
if (R_SUCCEEDED(rc) && idx == waiters.size() - 1) {
|
if (R_SUCCEEDED(rc) && idx == waiters.size() - 1) {
|
||||||
rc = Result_Cancelled;
|
rc = Result_UsbCancelled;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ Result UsbDs::GetSpeed(UsbDeviceSpeed* out, u16* max_packet_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*max_packet_size = DEVICE_SPEED[*out];
|
*max_packet_size = DEVICE_SPEED[*out];
|
||||||
R_UNLESS(*max_packet_size > 0, 0x1);
|
R_UNLESS(*max_packet_size > 0, Result_UsbDsBadDeviceSpeed);
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,7 +275,7 @@ Result UsbDs::WaitTransferCompletion(UsbSessionEndpoint ep, u64 timeout) {
|
|||||||
// check if we got one of the cancel events.
|
// check if we got one of the cancel events.
|
||||||
if (R_SUCCEEDED(rc) && idx == waiters.size() - 1) {
|
if (R_SUCCEEDED(rc) && idx == waiters.size() - 1) {
|
||||||
log_write("got usb cancel event\n");
|
log_write("got usb cancel event\n");
|
||||||
rc = Result_Cancelled;
|
rc = Result_UsbCancelled;
|
||||||
} else if (R_SUCCEEDED(rc) && idx == waiters.size() - 2) {
|
} else if (R_SUCCEEDED(rc) && idx == waiters.size() - 2) {
|
||||||
log_write("got usbDsGetStateChangeEvent() event\n");
|
log_write("got usbDsGetStateChangeEvent() event\n");
|
||||||
m_max_packet_size = 0;
|
m_max_packet_size = 0;
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ Result UsbHs::IsUsbConnected(u64 timeout) {
|
|||||||
R_TRY(waitObjects(&idx, waiters.data(), waiters.size(), timeout));
|
R_TRY(waitObjects(&idx, waiters.data(), waiters.size(), timeout));
|
||||||
|
|
||||||
if (idx == waiters.size() - 1) {
|
if (idx == waiters.size() - 1) {
|
||||||
return Result_Cancelled;
|
return Result_UsbCancelled;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Connect();
|
return Connect();
|
||||||
@@ -168,7 +168,7 @@ Result UsbHs::WaitTransferCompletion(UsbSessionEndpoint ep, u64 timeout) {
|
|||||||
// check if we got one of the cancel events.
|
// check if we got one of the cancel events.
|
||||||
if (R_SUCCEEDED(rc) && idx == waiters.size() - 1) {
|
if (R_SUCCEEDED(rc) && idx == waiters.size() - 1) {
|
||||||
log_write("got usb cancel event\n");
|
log_write("got usb cancel event\n");
|
||||||
rc = Result_Cancelled;
|
rc = Result_UsbCancelled;
|
||||||
} else if (R_SUCCEEDED(rc) && idx == waiters.size() - 2) {
|
} else if (R_SUCCEEDED(rc) && idx == waiters.size() - 2) {
|
||||||
log_write("got usb timeout event\n");
|
log_write("got usb timeout event\n");
|
||||||
rc = KERNELRESULT(TimedOut);
|
rc = KERNELRESULT(TimedOut);
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ Result Nsp::GetCollections(Collections& out) {
|
|||||||
// get header
|
// get header
|
||||||
Pfs0Header header{};
|
Pfs0Header header{};
|
||||||
R_TRY(m_source->Read(std::addressof(header), off, sizeof(header), std::addressof(bytes_read)));
|
R_TRY(m_source->Read(std::addressof(header), off, sizeof(header), std::addressof(bytes_read)));
|
||||||
R_UNLESS(header.magic == PFS0_MAGIC, 0x1);
|
R_UNLESS(header.magic == PFS0_MAGIC, Result_NspBadMagic);
|
||||||
off += bytes_read;
|
off += bytes_read;
|
||||||
|
|
||||||
// get file table
|
// get file table
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ Result Hfs0GetPartition(source::Base* source, s64 off, Hfs0& out) {
|
|||||||
|
|
||||||
// get header
|
// get header
|
||||||
R_TRY(source->Read(std::addressof(out.header), off, sizeof(out.header), std::addressof(bytes_read)));
|
R_TRY(source->Read(std::addressof(out.header), off, sizeof(out.header), std::addressof(bytes_read)));
|
||||||
R_UNLESS(out.header.magic == HFS0_MAGIC, 0x1);
|
R_UNLESS(out.header.magic == HFS0_MAGIC, Result_XciBadMagic);
|
||||||
off += bytes_read;
|
off += bytes_read;
|
||||||
|
|
||||||
// get file table
|
// get file table
|
||||||
|
|||||||
@@ -194,16 +194,16 @@ Result GetTitleKey(keys::KeyEntry& out, const TicketData& data, const keys::Keys
|
|||||||
log_write("properties_bitfield: 0x%X\n", data.properties_bitfield);
|
log_write("properties_bitfield: 0x%X\n", data.properties_bitfield);
|
||||||
log_write("device_id: 0x%lX vs 0x%lX\n", data.device_id, std::byteswap(rsa_key->device_id));
|
log_write("device_id: 0x%lX vs 0x%lX\n", data.device_id, std::byteswap(rsa_key->device_id));
|
||||||
|
|
||||||
R_UNLESS(data.device_id == std::byteswap(rsa_key->device_id), 0x1);
|
R_UNLESS(data.device_id == std::byteswap(rsa_key->device_id), Result_EsPersonalisedTicketDeviceIdMissmatch);
|
||||||
log_write("device id is same\n");
|
log_write("device id is same\n");
|
||||||
|
|
||||||
u8 out_keydata[RSA2048_BYTES]{};
|
u8 out_keydata[RSA2048_BYTES]{};
|
||||||
size_t out_keydata_size;
|
size_t out_keydata_size;
|
||||||
R_UNLESS(rsa2048OaepDecrypt(out_keydata, sizeof(out_keydata), data.title_key_block, rsa_key->modulus, &rsa_key->public_exponent, sizeof(rsa_key->public_exponent), rsa_key->private_exponent, sizeof(rsa_key->private_exponent), NULL, 0, &out_keydata_size), 0x1);
|
R_UNLESS(rsa2048OaepDecrypt(out_keydata, sizeof(out_keydata), data.title_key_block, rsa_key->modulus, &rsa_key->public_exponent, sizeof(rsa_key->public_exponent), rsa_key->private_exponent, sizeof(rsa_key->private_exponent), NULL, 0, &out_keydata_size), Result_EsFailedDecryptPersonalisedTicket);
|
||||||
R_UNLESS(out_keydata_size >= sizeof(out), 0x1);
|
R_UNLESS(out_keydata_size >= sizeof(out), Result_EsBadDecryptedPersonalisedTicketSize);
|
||||||
std::memcpy(std::addressof(out), out_keydata, sizeof(out));
|
std::memcpy(std::addressof(out), out_keydata, sizeof(out));
|
||||||
} else {
|
} else {
|
||||||
R_THROW(0x1);
|
R_THROW(Result_EsBadTitleKeyType);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ Result parse_keys(Keys& out, bool read_from_file) {
|
|||||||
if (public_exponent == 0) {
|
if (public_exponent == 0) {
|
||||||
log_write("eticket device id is NULL\n");
|
log_write("eticket device id is NULL\n");
|
||||||
}
|
}
|
||||||
R_THROW(0x1);
|
R_THROW(Result_KeyFailedDecyptETicketDeviceKey);
|
||||||
} else {
|
} else {
|
||||||
log_write("eticket match\n");
|
log_write("eticket match\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ Result EncryptKeak(const keys::Keys& keys, Header& header, u8 key_generation) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result VerifyFixedKey(const Header& header) {
|
Result VerifyFixedKey(const Header& header) {
|
||||||
R_UNLESS(header.sig_key_gen < std::size(nca_hdr_fixed_key_moduli_retail), 0x1);
|
R_UNLESS(header.sig_key_gen < std::size(nca_hdr_fixed_key_moduli_retail), Result_NcaBadSigKeyGen);
|
||||||
auto mod = nca_hdr_fixed_key_moduli_retail[header.sig_key_gen];
|
auto mod = nca_hdr_fixed_key_moduli_retail[header.sig_key_gen];
|
||||||
|
|
||||||
const u8 E[3] = { 1, 0, 1 };
|
const u8 E[3] = { 1, 0, 1 };
|
||||||
@@ -141,7 +141,7 @@ Result VerifyFixedKey(const Header& header) {
|
|||||||
new_header.distribution_type ^= 1;
|
new_header.distribution_type ^= 1;
|
||||||
if (!rsa2048VerifySha256BasedPssSignature(&new_header.magic, 0x200, new_header.rsa_fixed_key, mod, E, sizeof(E))) {
|
if (!rsa2048VerifySha256BasedPssSignature(&new_header.magic, 0x200, new_header.rsa_fixed_key, mod, E, sizeof(E))) {
|
||||||
log_write("FAILED nca header hash\n");
|
log_write("FAILED nca header hash\n");
|
||||||
R_THROW(0x1);
|
R_THROW(Result_NcaFailedNcaHeaderHashVerify);
|
||||||
} else {
|
} else {
|
||||||
log_write("WARNING! nca is converted! distribution_type: %u\n", new_header.distribution_type);
|
log_write("WARNING! nca is converted! distribution_type: %u\n", new_header.distribution_type);
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace sphaira::yati::source {
|
|||||||
|
|
||||||
Result Stream::Read(void* _buf, s64 off, s64 size, u64* bytes_read_out) {
|
Result Stream::Read(void* _buf, s64 off, s64 size, u64* bytes_read_out) {
|
||||||
// streams don't allow for random access (seeking backwards).
|
// streams don't allow for random access (seeking backwards).
|
||||||
R_UNLESS(off >= m_offset, 0x1);
|
R_UNLESS(off >= m_offset, Result_StreamBadSeek);
|
||||||
|
|
||||||
auto buf = static_cast<u8*>(_buf);
|
auto buf = static_cast<u8*>(_buf);
|
||||||
*bytes_read_out = 0;
|
*bytes_read_out = 0;
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ Usb::~Usb() {
|
|||||||
Result Usb::WaitForConnection(u64 timeout, std::vector<std::string>& out_names) {
|
Result Usb::WaitForConnection(u64 timeout, std::vector<std::string>& out_names) {
|
||||||
tinfoil::TUSHeader header;
|
tinfoil::TUSHeader header;
|
||||||
R_TRY(m_usb->TransferAll(true, &header, sizeof(header), timeout));
|
R_TRY(m_usb->TransferAll(true, &header, sizeof(header), timeout));
|
||||||
R_UNLESS(header.magic == tinfoil::Magic_List0, Result_BadMagic);
|
R_UNLESS(header.magic == tinfoil::Magic_List0, Result_UsbBadMagic);
|
||||||
R_UNLESS(header.nspListSize > 0, Result_BadCount);
|
R_UNLESS(header.nspListSize > 0, Result_UsbBadCount);
|
||||||
m_flags = header.flags;
|
m_flags = header.flags;
|
||||||
log_write("[USB] got header, flags: 0x%X\n", m_flags);
|
log_write("[USB] got header, flags: 0x%X\n", m_flags);
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ Result Usb::WaitForConnection(u64 timeout, std::vector<std::string>& out_names)
|
|||||||
log_write("got name: %s\n", name.c_str());
|
log_write("got name: %s\n", name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
R_UNLESS(!out_names.empty(), Result_BadCount);
|
R_UNLESS(!out_names.empty(), Result_UsbBadCount);
|
||||||
log_write("USB SUCCESS\n");
|
log_write("USB SUCCESS\n");
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ struct Yati {
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto ThreadData::GetResults() -> Result {
|
auto ThreadData::GetResults() -> Result {
|
||||||
R_UNLESS(!yati->pbox->ShouldExit(), Result_Cancelled);
|
R_TRY(yati->pbox->ShouldExitResult());
|
||||||
R_TRY(read_result);
|
R_TRY(read_result);
|
||||||
R_TRY(decompress_result);
|
R_TRY(decompress_result);
|
||||||
R_TRY(write_result);
|
R_TRY(write_result);
|
||||||
@@ -308,7 +308,7 @@ Result ThreadData::Read(void* buf, s64 size, u64* bytes_read) {
|
|||||||
size = std::min<s64>(size, nca->size - read_offset);
|
size = std::min<s64>(size, nca->size - read_offset);
|
||||||
const auto rc = yati->source->Read(buf, nca->offset + read_offset, size, bytes_read);
|
const auto rc = yati->source->Read(buf, nca->offset + read_offset, size, bytes_read);
|
||||||
read_offset += *bytes_read;
|
read_offset += *bytes_read;
|
||||||
R_UNLESS(size == *bytes_read, Result_InvalidNcaReadSize);
|
R_UNLESS(size == *bytes_read, Result_YatiInvalidNcaReadSize);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,7 +374,7 @@ Result Yati::readFuncInternal(ThreadData* t) {
|
|||||||
std::memcpy(std::addressof(header), buf.data() + 0x4000, sizeof(header));
|
std::memcpy(std::addressof(header), buf.data() + 0x4000, sizeof(header));
|
||||||
if (header.magic == NCZ_SECTION_MAGIC) {
|
if (header.magic == NCZ_SECTION_MAGIC) {
|
||||||
// validate section header.
|
// validate section header.
|
||||||
R_UNLESS(header.total_sections, Result_InvalidNczSectionCount);
|
R_UNLESS(header.total_sections, Result_YatiInvalidNczSectionCount);
|
||||||
|
|
||||||
buf_size = 0x4000;
|
buf_size = 0x4000;
|
||||||
log_write("found ncz, total number of sections: %zu\n", header.total_sections);
|
log_write("found ncz, total number of sections: %zu\n", header.total_sections);
|
||||||
@@ -390,10 +390,10 @@ Result Yati::readFuncInternal(ThreadData* t) {
|
|||||||
log_write("storing temp data of size: %zu\n", temp_buf.size());
|
log_write("storing temp data of size: %zu\n", temp_buf.size());
|
||||||
} else {
|
} else {
|
||||||
// validate block header.
|
// validate block header.
|
||||||
R_UNLESS(t->ncz_block_header.version == 0x2, Result_InvalidNczBlockVersion);
|
R_UNLESS(t->ncz_block_header.version == 0x2, Result_YatiInvalidNczBlockVersion);
|
||||||
R_UNLESS(t->ncz_block_header.type == 0x1, Result_InvalidNczBlockType);
|
R_UNLESS(t->ncz_block_header.type == 0x1, Result_YatiInvalidNczBlockType);
|
||||||
R_UNLESS(t->ncz_block_header.total_blocks, Result_InvalidNczBlockTotal);
|
R_UNLESS(t->ncz_block_header.total_blocks, Result_YatiInvalidNczBlockTotal);
|
||||||
R_UNLESS(t->ncz_block_header.block_size_exponent >= 14 && t->ncz_block_header.block_size_exponent <= 32, Result_InvalidNczBlockSizeExponent);
|
R_UNLESS(t->ncz_block_header.block_size_exponent >= 14 && t->ncz_block_header.block_size_exponent <= 32, Result_YatiInvalidNczBlockSizeExponent);
|
||||||
|
|
||||||
// read blocks (array of block sizes).
|
// read blocks (array of block sizes).
|
||||||
std::vector<ncz::Block> blocks(t->ncz_block_header.total_blocks);
|
std::vector<ncz::Block> blocks(t->ncz_block_header.total_blocks);
|
||||||
@@ -460,7 +460,7 @@ Result Yati::decompressFuncInternal(ThreadData* t) {
|
|||||||
return e.InRange(written);
|
return e.InRange(written);
|
||||||
});
|
});
|
||||||
|
|
||||||
R_UNLESS(it != t->ncz_sections.cend(), Result_NczSectionNotFound);
|
R_UNLESS(it != t->ncz_sections.cend(), Result_YatiNczSectionNotFound);
|
||||||
ncz_section = &(*it);
|
ncz_section = &(*it);
|
||||||
log_write("[NCZ] found new section: %zu\n", written);
|
log_write("[NCZ] found new section: %zu\n", written);
|
||||||
|
|
||||||
@@ -515,7 +515,7 @@ Result Yati::decompressFuncInternal(ThreadData* t) {
|
|||||||
nca::Header header{};
|
nca::Header header{};
|
||||||
crypto::cryptoAes128Xts(buf.data(), std::addressof(header), keys.header_key, 0, 0x200, sizeof(header), false);
|
crypto::cryptoAes128Xts(buf.data(), std::addressof(header), keys.header_key, 0, 0x200, sizeof(header), false);
|
||||||
log_write("verifying nca header magic\n");
|
log_write("verifying nca header magic\n");
|
||||||
R_UNLESS(header.magic == 0x3341434E, Result_InvalidNcaMagic);
|
R_UNLESS(header.magic == 0x3341434E, Result_YatiInvalidNcaMagic);
|
||||||
log_write("nca magic is ok! type: %u\n", header.content_type);
|
log_write("nca magic is ok! type: %u\n", header.content_type);
|
||||||
|
|
||||||
// store the unmodified header.
|
// store the unmodified header.
|
||||||
@@ -545,7 +545,7 @@ Result Yati::decompressFuncInternal(ThreadData* t) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
log_write("looking for ticket %s\n", hexIdToStr(header.rights_id).str);
|
log_write("looking for ticket %s\n", hexIdToStr(header.rights_id).str);
|
||||||
R_UNLESS(it != t->tik.end(), Result_TicketNotFound);
|
R_UNLESS(it != t->tik.end(), Result_YatiTicketNotFound);
|
||||||
log_write("ticket found\n");
|
log_write("ticket found\n");
|
||||||
it->required = true;
|
it->required = true;
|
||||||
ticket = &(*it);
|
ticket = &(*it);
|
||||||
@@ -564,7 +564,7 @@ Result Yati::decompressFuncInternal(ThreadData* t) {
|
|||||||
R_TRY(es::GetTicketData(ticket->ticket, std::addressof(ticket_data)));
|
R_TRY(es::GetTicketData(ticket->ticket, std::addressof(ticket_data)));
|
||||||
|
|
||||||
// validate that this indeed the correct ticket.
|
// validate that this indeed the correct ticket.
|
||||||
R_UNLESS(!std::memcmp(std::addressof(header.rights_id), std::addressof(ticket_data.rights_id), sizeof(header.rights_id)), Result_InvalidTicketBadRightsId);
|
R_UNLESS(!std::memcmp(std::addressof(header.rights_id), std::addressof(ticket_data.rights_id), sizeof(header.rights_id)), Result_YatiInvalidTicketBadRightsId);
|
||||||
|
|
||||||
// some scene releases use buggy software which set the master key
|
// some scene releases use buggy software which set the master key
|
||||||
// revision in the properties bitfield...lol, still happens in 2025.
|
// revision in the properties bitfield...lol, still happens in 2025.
|
||||||
@@ -624,7 +624,7 @@ Result Yati::decompressFuncInternal(ThreadData* t) {
|
|||||||
return e.InRange(decompress_buf_off);
|
return e.InRange(decompress_buf_off);
|
||||||
});
|
});
|
||||||
|
|
||||||
R_UNLESS(it != t->ncz_blocks.cend(), Result_NczBlockNotFound);
|
R_UNLESS(it != t->ncz_blocks.cend(), Result_YatiNczBlockNotFound);
|
||||||
log_write("[NCZ] found new block: %zu off: %zd size: %zd\n", decompress_buf_off, it->offset, it->size);
|
log_write("[NCZ] found new block: %zu off: %zd size: %zd\n", decompress_buf_off, it->offset, it->size);
|
||||||
ncz_block = &(*it);
|
ncz_block = &(*it);
|
||||||
}
|
}
|
||||||
@@ -657,7 +657,7 @@ Result Yati::decompressFuncInternal(ThreadData* t) {
|
|||||||
if (ZSTD_isError(res)) {
|
if (ZSTD_isError(res)) {
|
||||||
log_write("[NCZ] ZSTD_decompressStream() pos: %zu size: %zu res: %zd msg: %s\n", input.pos, input.size, res, ZSTD_getErrorName(res));
|
log_write("[NCZ] ZSTD_decompressStream() pos: %zu size: %zu res: %zd msg: %s\n", input.pos, input.size, res, ZSTD_getErrorName(res));
|
||||||
}
|
}
|
||||||
R_UNLESS(!ZSTD_isError(res), Result_InvalidNczZstdError);
|
R_UNLESS(!ZSTD_isError(res), Result_YatiInvalidNczZstdError);
|
||||||
|
|
||||||
t->decompress_offset += output.pos;
|
t->decompress_offset += output.pos;
|
||||||
inflate_offset += output.pos;
|
inflate_offset += output.pos;
|
||||||
@@ -921,7 +921,7 @@ Result Yati::InstallNcaInternal(std::span<TikCollection> tickets, NcaCollection&
|
|||||||
if (!config.skip_nca_hash_verify && !nca.modified) {
|
if (!config.skip_nca_hash_verify && !nca.modified) {
|
||||||
if (std::memcmp(&nca.content_id, nca.hash, sizeof(nca.content_id))) {
|
if (std::memcmp(&nca.content_id, nca.hash, sizeof(nca.content_id))) {
|
||||||
log_write("nca hash is invalid!!!!\n");
|
log_write("nca hash is invalid!!!!\n");
|
||||||
R_UNLESS(!std::memcmp(&nca.content_id, nca.hash, sizeof(nca.content_id)), Result_InvalidNcaSha256);
|
R_UNLESS(!std::memcmp(&nca.content_id, nca.hash, sizeof(nca.content_id)), Result_YatiInvalidNcaSha256);
|
||||||
} else {
|
} else {
|
||||||
log_write("nca hash is valid!\n");
|
log_write("nca hash is valid!\n");
|
||||||
}
|
}
|
||||||
@@ -987,7 +987,7 @@ Result Yati::InstallCnmtNca(std::span<TikCollection> tickets, CnmtCollection& cn
|
|||||||
return e.name.find(str.str) != e.name.npos;
|
return e.name.find(str.str) != e.name.npos;
|
||||||
});
|
});
|
||||||
|
|
||||||
R_UNLESS(it != collections.cend(), Result_NcaNotFound);
|
R_UNLESS(it != collections.cend(), Result_YatiNcaNotFound);
|
||||||
|
|
||||||
log_write("found: %s\n", str.str);
|
log_write("found: %s\n", str.str);
|
||||||
cnmt.infos.emplace_back(packed_info);
|
cnmt.infos.emplace_back(packed_info);
|
||||||
@@ -1044,7 +1044,7 @@ Result Yati::ParseTicketsIntoCollection(std::vector<TikCollection>& tickets, con
|
|||||||
return e.name.find(str) != e.name.npos;
|
return e.name.find(str) != e.name.npos;
|
||||||
});
|
});
|
||||||
|
|
||||||
R_UNLESS(cert != collections.cend(), Result_CertNotFound);
|
R_UNLESS(cert != collections.cend(), Result_YatiCertNotFound);
|
||||||
entry.ticket.resize(collection.size);
|
entry.ticket.resize(collection.size);
|
||||||
entry.cert.resize(cert->size);
|
entry.cert.resize(cert->size);
|
||||||
|
|
||||||
@@ -1185,13 +1185,13 @@ Result Yati::RemoveInstalledNcas(const CnmtCollection& cnmt) {
|
|||||||
u64 out_size;
|
u64 out_size;
|
||||||
log_write("trying to get from db\n");
|
log_write("trying to get from db\n");
|
||||||
R_TRY(ncmContentMetaDatabaseGet(std::addressof(db), std::addressof(key), std::addressof(out_size), std::addressof(header), sizeof(header)));
|
R_TRY(ncmContentMetaDatabaseGet(std::addressof(db), std::addressof(key), std::addressof(out_size), std::addressof(header), sizeof(header)));
|
||||||
R_UNLESS(out_size == sizeof(header), Result_NcmDbCorruptHeader);
|
R_UNLESS(out_size == sizeof(header), Result_YatiNcmDbCorruptHeader);
|
||||||
log_write("trying to list infos\n");
|
log_write("trying to list infos\n");
|
||||||
|
|
||||||
std::vector<NcmContentInfo> infos(header.content_count);
|
std::vector<NcmContentInfo> infos(header.content_count);
|
||||||
s32 content_info_out;
|
s32 content_info_out;
|
||||||
R_TRY(ncmContentMetaDatabaseListContentInfo(std::addressof(db), std::addressof(content_info_out), infos.data(), infos.size(), std::addressof(key), 0));
|
R_TRY(ncmContentMetaDatabaseListContentInfo(std::addressof(db), std::addressof(content_info_out), infos.data(), infos.size(), std::addressof(key), 0));
|
||||||
R_UNLESS(content_info_out == infos.size(), Result_NcmDbCorruptInfos);
|
R_UNLESS(content_info_out == infos.size(), Result_YatiNcmDbCorruptInfos);
|
||||||
log_write("size matches\n");
|
log_write("size matches\n");
|
||||||
|
|
||||||
for (auto& info : infos) {
|
for (auto& info : infos) {
|
||||||
@@ -1362,7 +1362,7 @@ Result InstallInternalStream(ui::ProgressBox* pbox, std::shared_ptr<source::Base
|
|||||||
});
|
});
|
||||||
|
|
||||||
// this will never fail...but just in case.
|
// this will never fail...but just in case.
|
||||||
R_UNLESS(entry != tickets.end(), Result_CertNotFound);
|
R_UNLESS(entry != tickets.end(), Result_YatiCertNotFound);
|
||||||
|
|
||||||
u64 bytes_read;
|
u64 bytes_read;
|
||||||
if (collection.name.ends_with(".tik")) {
|
if (collection.name.ends_with(".tik")) {
|
||||||
@@ -1380,7 +1380,7 @@ Result InstallInternalStream(ui::ProgressBox* pbox, std::shared_ptr<source::Base
|
|||||||
return e.name == cnmt_nca.name;
|
return e.name == cnmt_nca.name;
|
||||||
});
|
});
|
||||||
|
|
||||||
R_UNLESS(it != ncas.cend(), Result_NczSectionNotFound);
|
R_UNLESS(it != ncas.cend(), Result_YatiNczSectionNotFound);
|
||||||
const auto type = cnmt_nca.type;
|
const auto type = cnmt_nca.type;
|
||||||
cnmt_nca = *it;
|
cnmt_nca = *it;
|
||||||
cnmt_nca.type = type;
|
cnmt_nca.type = type;
|
||||||
@@ -1414,7 +1414,7 @@ Result InstallFromFile(ui::ProgressBox* pbox, fs::Fs* fs, const fs::FsPath& path
|
|||||||
|
|
||||||
Result InstallFromSource(ui::ProgressBox* pbox, std::shared_ptr<source::Base> source, const fs::FsPath& path, const ConfigOverride& override) {
|
Result InstallFromSource(ui::ProgressBox* pbox, std::shared_ptr<source::Base> source, const fs::FsPath& path, const ConfigOverride& override) {
|
||||||
const auto ext = std::strrchr(path.s, '.');
|
const auto ext = std::strrchr(path.s, '.');
|
||||||
R_UNLESS(ext, Result_ContainerNotFound);
|
R_UNLESS(ext, Result_YatiContainerNotFound);
|
||||||
|
|
||||||
if (!strcasecmp(ext, ".nsp") || !strcasecmp(ext, ".nsz")) {
|
if (!strcasecmp(ext, ".nsp") || !strcasecmp(ext, ".nsz")) {
|
||||||
return InstallFromContainer(pbox, std::make_unique<container::Nsp>(source), override);
|
return InstallFromContainer(pbox, std::make_unique<container::Nsp>(source), override);
|
||||||
@@ -1422,7 +1422,7 @@ Result InstallFromSource(ui::ProgressBox* pbox, std::shared_ptr<source::Base> so
|
|||||||
return InstallFromContainer(pbox, std::make_unique<container::Xci>(source), override);
|
return InstallFromContainer(pbox, std::make_unique<container::Xci>(source), override);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_THROW(Result_ContainerNotFound);
|
R_THROW(Result_YatiContainerNotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result InstallFromContainer(ui::ProgressBox* pbox, std::shared_ptr<container::Base> container, const ConfigOverride& override) {
|
Result InstallFromContainer(ui::ProgressBox* pbox, std::shared_ptr<container::Base> container, const ConfigOverride& override) {
|
||||||
|
|||||||
Reference in New Issue
Block a user