/** * @file error.h * @brief Wrapper for using the error LibraryApplet. * @author StuntHacks, yellows8 * @copyright libnx Authors */ #pragma once #include "../types.h" #include "../services/set.h" /// Error type for ErrorCommonHeader.type. typedef enum { ErrorType_Normal = 0, ///< Normal ErrorType_System = 1, ///< System ErrorType_Application = 2, ///< Application ErrorType_Eula = 3, ///< EULA ErrorType_Pctl = 4, ///< Parental Controls ErrorType_Record = 5, ///< Record ErrorType_SystemUpdateEula = 8, ///< SystemUpdateEula } ErrorType; /// Stores error-codes which are displayed as XXXX-XXXX, low for the former and desc for the latter. typedef struct { u32 low; ///< The module portion of the error, normally this should be set to module + 2000. u32 desc; ///< The error description. } ErrorCode; /// Error type for ErrorContext.type typedef enum { ErrorContextType_None = 0, ///< None ErrorContextType_Http = 1, ///< Http ErrorContextType_FileSystem = 2, ///< FileSystem ErrorContextType_WebMediaPlayer = 3, ///< WebMediaPlayer ErrorContextType_LocalContentShare = 4, ///< LocalContentShare } ErrorContextType; /// Error context. typedef struct { u8 type; ///< Type, see \ref ErrorContextType. u8 pad[7]; ///< Padding u8 data[0x1f4]; ///< Data Result res; ///< Result } ErrorContext; /// Common header for the start of the arg storage. typedef struct { u8 type; ///< Type, see \ref ErrorType. u8 jumpFlag; ///< When clear, this indicates WithoutJump. u8 unk_x2[3]; ///< Unknown u8 contextFlag; ///< When set with ::ErrorType_Normal, indicates that an additional storage is pushed for \ref ErrorResultBacktrace. [4.0.0+] Otherwise, when set indicates that an additional storage is pushed for \ref ErrorContext. u8 resultFlag; ///< ErrorCommonArg: When clear, errorCode is used, otherwise the applet generates the error-code from res. u8 contextFlag2; ///< Similar to contextFlag except for ErrorCommonArg, indicating \ref ErrorContext is used. } ErrorCommonHeader; /// Common error arg data. typedef struct { ErrorCommonHeader hdr; ///< Common header. ErrorCode errorCode; ///< \ref ErrorCode Result res; ///< Result } ErrorCommonArg; /// Error arg data for certain errors with module PCTL. typedef struct { ErrorCommonHeader hdr; ///< Common header. Result res; ///< Result } ErrorPctlArg; /// ResultBacktrace typedef struct { s32 count; ///< Total entries in the backtrace array. Result backtrace[0x20]; ///< Result backtrace. } ErrorResultBacktrace; /// Error arg data for EULA. typedef struct { ErrorCommonHeader hdr; ///< Common header. SetRegion regionCode; ///< \ref SetRegion } ErrorEulaArg; /// Additional input storage data for \ref errorSystemUpdateEulaShow. typedef struct { u8 data[0x20000]; ///< data } ErrorEulaData; /// Error arg data for Record. typedef struct { ErrorCommonHeader hdr; ///< Common header. ErrorCode errorCode; ///< \ref ErrorCode u64 timestamp; ///< POSIX timestamp. } ErrorRecordArg; /// SystemErrorArg typedef struct { ErrorCommonHeader hdr; ///< Common header. ErrorCode errorCode; ///< \ref ErrorCode u64 languageCode; ///< See set.h. char dialogMessage[0x800]; ///< UTF-8 Dialog message. char fullscreenMessage[0x800]; ///< UTF-8 Fullscreen message (displayed when the user clicks on "Details"). } ErrorSystemArg; /// Error system config. typedef struct { ErrorSystemArg arg; ///< Arg data. ErrorContext ctx; ///< Optional error context. } ErrorSystemConfig; /// ApplicationErrorArg typedef struct { ErrorCommonHeader hdr; ///< Common header. u32 errorNumber; ///< Raw decimal error number which is displayed in the dialog. u64 languageCode; ///< See set.h. char dialogMessage[0x800]; ///< UTF-8 Dialog message. char fullscreenMessage[0x800]; ///< UTF-8 Fullscreen message (displayed when the user clicks on "Details"). } NX_PACKED ErrorApplicationArg; /// Error application config. typedef struct { ErrorApplicationArg arg; ///< Arg data. } ErrorApplicationConfig; /** * @brief Creates an \ref ErrorCode. * @param low The module portion of the error, normally this should be set to module + 2000. * @param desc The error description. */ static inline ErrorCode errorCodeCreate(u32 low, u32 desc) { return (ErrorCode){low, desc}; } /** * @brief Creates an \ref ErrorCode with the input Result. Wrapper for \ref errorCodeCreate. * @param res Input Result. */ static inline ErrorCode errorCodeCreateResult(Result res) { return errorCodeCreate(2000 + R_MODULE(res), R_DESCRIPTION(res)); } /** * @brief Creates an invalid \ref ErrorCode. */ static inline ErrorCode errorCodeCreateInvalid(void) { return (ErrorCode){0}; } /** * @brief Checks whether the input ErrorCode is valid. * @param errorCode \ref ErrorCode */ static inline bool errorCodeIsValid(ErrorCode errorCode) { return errorCode.low!=0; } /** * @brief Launches the applet for displaying the specified Result. * @param res Result * @param jumpFlag Jump flag, normally this is true. * @param ctx Optional \ref ErrorContext, can be NULL. Unused when jumpFlag=false. Ignored on pre-4.0.0, since it's only available for [4.0.0+]. * @note Sets the following fields: jumpFlag and contextFlag2. Uses ::ErrorType_Normal normally. * @note For module=PCTL errors with desc 100-119 this sets uses ::ErrorType_Pctl, in which case the applet will display the following special dialog: "This software is restricted by Parental Controls". * @note If the input Result is 0xC8A2, the applet will display a special dialog regarding the current application requiring a software update, with buttons "Later" and "Restart". * @note [3.0.0+] If the input Result is 0xCAA2, the applet will display a special dialog related to DLC version. * @warning This applet creates an error report that is logged in the system, when not handling the above special dialogs. Proceed at your own risk! */ Result errorResultShow(Result res, bool jumpFlag, const ErrorContext* ctx); /** * @brief Launches the applet for displaying the specified ErrorCode. * @param errorCode \ref ErrorCode * @param jumpFlag Jump flag, normally this is true. * @param ctx Optional \ref ErrorContext, can be NULL. Unused when jumpFlag=false. Ignored on pre-4.0.0, since it's only available for [4.0.0+]. * @note Sets the following fields: jumpFlag and contextFlag2. resultFlag=1. Uses ::ErrorType_Normal. * @warning This applet creates an error report that is logged in the system. Proceed at your own risk! */ Result errorCodeShow(ErrorCode errorCode, bool jumpFlag, const ErrorContext* ctx); /** * @brief Creates an ErrorResultBacktrace struct. * @param backtrace \ref ErrorResultBacktrace struct. * @param count Total number of entries. * @param entries Input array of Result. */ Result errorResultBacktraceCreate(ErrorResultBacktrace* backtrace, s32 count, const Result* entries); /** * @brief Launches the applet for \ref ErrorResultBacktrace. * @param backtrace ErrorResultBacktrace struct. * @param res Result * @note Sets the following fields: jumpFlag=1, contextFlag=1, and uses ::ErrorType_Normal. * @warning This applet creates an error report that is logged in the system. Proceed at your own risk! */ Result errorResultBacktraceShow(Result res, const ErrorResultBacktrace* backtrace); /** * @brief Launches the applet for displaying the EULA. * @param RegionCode \ref SetRegion * @note Sets the following fields: jumpFlag=1, regionCode, and uses ::ErrorType_Eula. */ Result errorEulaShow(SetRegion RegionCode); /** * @brief Launches the applet for displaying the system-update EULA. * @param RegionCode \ref SetRegion * @param eula EULA data. Address must be 0x1000-byte aligned. * @note Sets the following fields: jumpFlag=1, regionCode, and uses ::ErrorType_SystemUpdateEula. */ Result errorSystemUpdateEulaShow(SetRegion RegionCode, const ErrorEulaData* eula); /** * @brief Launches the applet for displaying an error full-screen, using the specified ErrorCode and timestamp. * @param errorCode \ref ErrorCode * @param timestamp POSIX timestamp. * @note Sets the following fields: jumpFlag=1, errorCode, timestamp, and uses ::ErrorType_Record. * @note The applet does not log an error report for this. error*RecordShow is used by qlaunch for displaying previously logged error reports. */ Result errorCodeRecordShow(ErrorCode errorCode, u64 timestamp); /** * @brief Launches the applet for displaying an error full-screen, using the specified Result and timestamp. * @param res Result * @param timestamp POSIX timestamp. * @note Wrapper for \ref errorCodeRecordShow, see \ref errorCodeRecordShow notes. */ static inline Result errorResultRecordShow(Result res, u64 timestamp) { return errorCodeRecordShow(errorCodeCreateResult(res), timestamp); } /** * @brief Creates an ErrorSystemConfig struct. * @param c ErrorSystemConfig struct. * @param dialog_message UTF-8 dialog message. * @param fullscreen_message UTF-8 fullscreen message, displayed when the user clicks on "Details". Optional, can be NULL (which disables displaying Details). * @note Sets the following fields: {strings}, and uses ::ErrorType_System. The rest are cleared. * @note On pre-5.0.0 this will initialize languageCode by using: setInitialize(), setMakeLanguageCode(SetLanguage_ENUS, ...), and setExit(). This is needed since an empty languageCode wasn't supported until [5.0.0+] (which would also use SetLanguage_ENUS). * @warning This applet creates an error report that is logged in the system. Proceed at your own risk! */ Result errorSystemCreate(ErrorSystemConfig* c, const char* dialog_message, const char* fullscreen_message); /** * @brief Launches the applet with the specified config. * @param c ErrorSystemConfig struct. */ Result errorSystemShow(ErrorSystemConfig* c); /** * @brief Sets the error code. * @param c ErrorSystemConfig struct. * @param errorCode \ref ErrorCode */ static inline void errorSystemSetCode(ErrorSystemConfig* c, ErrorCode errorCode) { c->arg.errorCode = errorCode; } /** * @brief Sets the error code, using the input Result. Wrapper for \ref errorSystemSetCode. * @param c ErrorSystemConfig struct. * @param res The Result to set. */ static inline void errorSystemSetResult(ErrorSystemConfig* c, Result res) { errorSystemSetCode(c, errorCodeCreateResult(res)); } /** * @brief Sets the LanguageCode. * @param c ErrorSystemConfig struct. * @param LanguageCode LanguageCode, see set.h. */ static inline void errorSystemSetLanguageCode(ErrorSystemConfig* c, u64 LanguageCode) { c->arg.languageCode = LanguageCode; } /** * @brief Sets the ErrorContext. * @note Only available on [4.0.0+], on older versions this will return without setting the context. * @param c ErrorSystemConfig struct. * @param ctx ErrorContext, NULL to clear it. */ void errorSystemSetContext(ErrorSystemConfig* c, const ErrorContext* ctx); /** * @brief Creates an ErrorApplicationConfig struct. * @param c ErrorApplicationConfig struct. * @param dialog_message UTF-8 dialog message. * @param fullscreen_message UTF-8 fullscreen message, displayed when the user clicks on "Details". Optional, can be NULL (which disables displaying Details). * @note Sets the following fields: jumpFlag=1, {strings}, and uses ::ErrorType_Application. The rest are cleared. * @note On pre-5.0.0 this will initialize languageCode by using: setInitialize(), setMakeLanguageCode(SetLanguage_ENUS, ...), and setExit(). This is needed since an empty languageCode wasn't supported until [5.0.0+] (which would also use SetLanguage_ENUS). * @note With [10.0.0+] this must only be used when running under an Application, since otherwise the applet will trigger a fatalerr. * @warning This applet creates an error report that is logged in the system. Proceed at your own risk! */ Result errorApplicationCreate(ErrorApplicationConfig* c, const char* dialog_message, const char* fullscreen_message); /** * @brief Launches the applet with the specified config. * @param c ErrorApplicationConfig struct. */ Result errorApplicationShow(ErrorApplicationConfig* c); /** * @brief Sets the error code number. * @param c ErrorApplicationConfig struct. * @param errorNumber Error code number. Raw decimal error number which is displayed in the dialog. */ static inline void errorApplicationSetNumber(ErrorApplicationConfig* c, u32 errorNumber) { c->arg.errorNumber = errorNumber; } /** * @brief Sets the LanguageCode. * @param c ErrorApplicationConfig struct. * @param LanguageCode LanguageCode, see set.h. */ static inline void errorApplicationSetLanguageCode(ErrorApplicationConfig* c, u64 LanguageCode) { c->arg.languageCode = LanguageCode; }