2020-04-16 01:06:41 +01:00
/*
2021-03-26 04:35:14 +00:00
* nxdt_utils . h
2020-04-16 01:06:41 +01:00
*
2023-04-08 12:42:22 +01:00
* Copyright ( c ) 2020 - 2023 , DarkMatterCore < pabloacurielz @ gmail . com > .
2020-07-03 10:31:22 +01:00
*
* This file is part of nxdumptool ( https : //github.com/DarkMatterCore/nxdumptool).
*
2021-03-25 19:26:58 +00:00
* nxdumptool is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
2020-04-16 01:06:41 +01:00
*
2021-03-25 19:26:58 +00:00
* nxdumptool is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2020-04-16 01:06:41 +01:00
*
* You should have received a copy of the GNU General Public License
2021-03-25 19:26:58 +00:00
* along with this program . If not , see < https : //www.gnu.org/licenses/>.
2020-04-16 01:06:41 +01:00
*/
2020-04-15 21:50:07 +01:00
# pragma once
2021-03-26 04:35:14 +00:00
# ifndef __NXDT_UTILS_H__
# define __NXDT_UTILS_H__
2020-04-15 21:50:07 +01:00
2021-06-08 04:13:45 +01:00
/* Included here for convenience. */
# include "nxdt_includes.h"
2020-10-08 19:31:09 +01:00
2021-03-23 14:06:52 +00:00
# ifdef __cplusplus
extern " C " {
# endif
2021-06-08 04:13:45 +01:00
/* Scoped lock macro. */
2021-06-09 05:48:17 +01:00
# define SCOPED_LOCK(mtx) for(UtilsScopedLock ANONYMOUS_VARIABLE(scoped_lock) CLEANUP(utilsUnlockScope) = utilsLockScope(mtx); ANONYMOUS_VARIABLE(scoped_lock).cond; ANONYMOUS_VARIABLE(scoped_lock).cond = 0)
/* Scoped try lock macro. */
# define SCOPED_TRY_LOCK(mtx) for(UtilsScopedLock ANONYMOUS_VARIABLE(scoped_lock) CLEANUP(utilsUnlockScope) = utilsTryLockScope(mtx); ANONYMOUS_VARIABLE(scoped_lock).cond; ANONYMOUS_VARIABLE(scoped_lock).cond = 0)
2021-05-18 13:32:43 +01:00
/// Used by scoped locks.
typedef struct {
Mutex * mtx ;
bool lock ;
int cond ;
} UtilsScopedLock ;
2020-04-15 21:50:07 +01:00
2020-12-02 06:28:35 +00:00
/// Used to determine which CFW is the application running under.
2020-04-15 21:50:07 +01:00
typedef enum {
2020-04-16 11:13:11 +01:00
UtilsCustomFirmwareType_Unknown = 0 ,
UtilsCustomFirmwareType_Atmosphere = 1 ,
UtilsCustomFirmwareType_SXOS = 2 ,
2023-07-17 00:03:05 +01:00
UtilsCustomFirmwareType_ReiNX = 3 ,
UtilsCustomFirmwareType_Count = 4 ///< Total values supported by this enum.
2020-04-15 21:50:07 +01:00
} UtilsCustomFirmwareType ;
2021-08-07 09:42:03 +01:00
/// Used to handle parsed data from a GitHub release JSON.
/// All strings are dynamically allocated.
typedef struct {
struct json_object * obj ; ///< JSON object. Must be freed using json_object_put().
const char * version ; ///< Pointer to the version string, referenced by obj.
const char * commit_hash ; ///< Pointer to the commit hash string, referenced by obj.
struct tm date ; ///< Release date.
const char * changelog ; ///< Pointer to the changelog string, referenced by obj.
const char * download_url ; ///< Pointer to the download URL string, referenced by obj.
} UtilsGitHubReleaseJsonData ;
2021-05-18 13:32:43 +01:00
/// Resource initialization.
/// Called at program startup.
2023-12-20 19:32:48 +00:00
bool utilsInitializeResources ( void ) ;
2021-05-18 13:32:43 +01:00
/// Resource deinitialization.
/// Called at program exit.
2020-05-03 00:40:50 +01:00
void utilsCloseResources ( void ) ;
2020-04-15 21:50:07 +01:00
2021-05-18 13:32:43 +01:00
/// Returns a pointer to the application launch path.
const char * utilsGetLaunchPath ( void ) ;
2022-07-12 01:27:03 +01:00
/// Returns the nxlink socket descriptor, or -1 if an nxlink connection couldn't be established.
int utilsGetNxLinkFileDescriptor ( void ) ;
2021-05-18 13:32:43 +01:00
/// Returns a pointer to the FsFileSystem object for the SD card.
FsFileSystem * utilsGetSdCardFileSystemObject ( void ) ;
/// Commits SD card filesystem changes.
/// Must be used after closing a file handle from the SD card.
bool utilsCommitSdCardFileSystemChanges ( void ) ;
/// Returns a UtilsCustomFirmwareType value.
u8 utilsGetCustomFirmwareType ( void ) ;
2020-08-18 06:04:13 +01:00
2023-04-08 12:34:53 +01:00
/// Returns true if the application is running under a Mariko unit.
bool utilsIsMarikoUnit ( void ) ;
2020-12-02 06:28:35 +00:00
/// Returns true if the application is running under a development unit.
2020-08-15 22:22:49 +01:00
bool utilsIsDevelopmentUnit ( void ) ;
2021-05-18 13:32:43 +01:00
/// Returns true if the application is running under applet mode.
2023-04-08 12:34:53 +01:00
bool utilsIsAppletMode ( void ) ;
2021-05-18 13:32:43 +01:00
/// Returns a pointer to the FsStorage object for the eMMC BIS System partition.
FsStorage * utilsGetEmmcBisSystemPartitionStorage ( void ) ;
2022-07-12 01:27:03 +01:00
/// Blocks HOME button presses, disables screen dimming and auto sleep and overclocks system CPU/MEM.
2021-07-29 17:48:32 +01:00
/// Must be called before starting long-running processes.
2022-07-12 01:27:03 +01:00
/// If state is set to false, regular system behavior is restored.
2021-07-29 17:48:32 +01:00
void utilsSetLongRunningProcessState ( bool state ) ;
2021-05-18 13:32:43 +01:00
/// Thread management functions.
bool utilsCreateThread ( Thread * out_thread , ThreadFunc func , void * arg , int cpu_id ) ;
void utilsJoinThread ( Thread * thread ) ;
2020-12-02 06:28:35 +00:00
/// Formats a string and appends it to the provided buffer.
/// If the buffer isn't big enough to hold both its current contents and the new formatted string, it will be resized.
2021-03-29 19:27:35 +01:00
__attribute__ ( ( format ( printf , 3 , 4 ) ) ) bool utilsAppendFormattedStringToBuffer ( char * * dst , size_t * dst_size , const char * fmt , . . . ) ;
2020-10-02 10:53:58 +01:00
2021-06-01 02:12:15 +01:00
/// Replaces illegal FAT characters in the provided UTF-8 string with underscores.
2022-07-06 10:57:31 +01:00
/// If 'ascii_only' is set to true, all codepoints outside the [0x20,0x7F) range will also be replaced with underscores.
2021-06-01 02:12:15 +01:00
/// Replacements are performed on a per-codepoint basis, which means the string length can be reduced by this function.
2020-05-05 19:04:23 +01:00
void utilsReplaceIllegalCharacters ( char * str , bool ascii_only ) ;
2020-04-15 21:50:07 +01:00
2020-12-02 06:28:35 +00:00
/// Trims whitespace characters from the provided string.
2020-05-03 00:40:50 +01:00
void utilsTrimString ( char * str ) ;
2020-04-16 11:13:11 +01:00
2023-10-22 23:44:40 +01:00
/// Generates a NULL-terminated hex string representation of the binary data in 'src' and stores it in 'dst'.
2021-05-11 23:36:15 +01:00
/// If 'uppercase' is true, uppercase characters will be used to generate the hex string. Otherwise, lowercase characters will be used.
2023-10-22 23:44:40 +01:00
void utilsGenerateHexString ( char * dst , size_t dst_size , const void * src , size_t src_size , bool uppercase ) ;
/// Parses the hex string in 'src' and stores its binary representation in 'dst'.
/// 'src' must match the regex /^(?:[A-Fa-f0-9]{2})+$/.
/// 'src_size' may be zero, in which case strlen() will be used to determine the length of 'src'. Furthermore, 'src_size' must always be a multiple of 2.
/// 'dst_size' must be at least 'src_size / 2'.
/// Returns false if there's an error validating input arguments.
bool utilsParseHexString ( void * dst , size_t dst_size , const char * src , size_t src_size ) ;
2020-04-15 21:50:07 +01:00
2021-03-07 23:22:49 +00:00
/// Formats the provided 'size' value to a human-readable size string and stores it in 'dst'.
2021-07-29 08:50:17 +01:00
void utilsGenerateFormattedSizeString ( double size , char * dst , size_t dst_size ) ;
2020-07-26 05:57:12 +01:00
2020-12-24 08:49:38 +00:00
/// Saves the total size and free space available from the filesystem pointed to by the input path (e.g. "sdmc:/") to 'out_total' and 'out_free', respectively.
2021-03-07 23:22:49 +00:00
/// Either 'out_total' or 'out_free' can be NULL, but at least one of them must be a valid pointer.
2020-12-02 06:28:35 +00:00
/// Returns false if there's an error.
2020-12-24 08:49:38 +00:00
bool utilsGetFileSystemStatsByPath ( const char * path , u64 * out_total , u64 * out_free ) ;
2020-12-02 06:28:35 +00:00
2021-07-21 16:04:18 +01:00
/// Creates output directories in the specified device.
/// If 'device' is NULL, output directories will be created on the SD card.
void utilsCreateOutputDirectories ( const char * device ) ;
2020-12-02 06:28:35 +00:00
/// Returns true if a file exists.
2020-05-03 00:40:50 +01:00
bool utilsCheckIfFileExists ( const char * path ) ;
2020-12-02 06:28:35 +00:00
/// Deletes a ConcatenationFile located at the input path.
2020-10-22 05:38:14 +01:00
void utilsRemoveConcatenationFile ( const char * path ) ;
2020-12-02 06:28:35 +00:00
/// Creates a ConcatenationFile at the input path.
2020-05-03 00:40:50 +01:00
bool utilsCreateConcatenationFile ( const char * path ) ;
2020-12-02 06:28:35 +00:00
/// Creates a full directory tree using the provided path.
/// If 'create_last_element' is true, the last element from the provided path will be created as well.
2020-07-29 22:02:21 +01:00
void utilsCreateDirectoryTree ( const char * path , bool create_last_element ) ;
2023-12-26 00:25:29 +00:00
/// Calculates the size of a directory by recursively traversing all of its child entries.
/// The provided path must be absolute and it must include the virtual device name it belongs to (e.g. "sdmc:/path/to/dir").
bool utilsGetDirectorySize ( const char * path , u64 * out_size ) ;
2023-05-24 20:05:34 +01:00
/// Recursively deletes the directory located at the provided path and all of its contents.
/// The provided path must be absolute and it must include the virtual device name it belongs to (e.g. "sdmc:/path/to/dir").
bool utilsDeleteDirectoryRecursively ( const char * path ) ;
2021-06-01 02:12:15 +01:00
/// Returns a pointer to a dynamically allocated string that holds the full path formed by the provided arguments. Both path prefix and file extension are optional.
/// If any elements from the generated path exceed safe filesystem limits, each exceeding element will be truncated. Truncations, if needed, are performed on a per-codepoint basis (UTF-8).
/// If an extension is provided, it will always be preserved, regardless of any possible truncations being carried out.
2022-03-17 12:37:24 +00:00
/// A path separator is automatically placed between the provided prefix and the filename if the prefix doesn't end with one.
/// A dot *isn't* automatically placed between the filename and the provided extension -- if required, it must be provided as part of the extension string.
2021-06-01 02:12:15 +01:00
/// Furthermore, if the full length for the generated path is >= FS_MAX_PATH, NULL will be returned.
2023-07-17 22:44:45 +01:00
/// The allocated buffer must be freed by the calling function using free().
2020-10-21 05:27:48 +01:00
char * utilsGeneratePath ( const char * prefix , const char * filename , const char * extension ) ;
2021-08-25 21:48:01 +01:00
/// Prints an error message using the standard console output and waits for the user to press a button.
void utilsPrintConsoleError ( const char * msg ) ;
2021-08-07 10:44:36 +01:00
/// Returns the current application updated state.
bool utilsGetApplicationUpdatedState ( void ) ;
/// Sets the application updated state to true, which makes utilsCloseResources() replace the application NRO.
void utilsSetApplicationUpdatedState ( void ) ;
2021-08-07 09:42:03 +01:00
/// Parses the provided GitHub release JSON data buffer.
/// The data from the output buffer must be freed using utilsFreeGitHubReleaseJsonData().
bool utilsParseGitHubReleaseJsonData ( const char * json_buf , size_t json_buf_size , UtilsGitHubReleaseJsonData * out ) ;
2021-08-07 10:44:36 +01:00
/// Parses the provided version string and compares it to the application version. Returns true if the application can be updated.
/// If both versions are equal, the provided commit hash is compared to our commit hash - if they're different, true will be returned.
bool utilsIsApplicationUpdatable ( const char * version , const char * commit_hash ) ;
2021-08-07 09:42:03 +01:00
/// Frees previously allocated data from a UtilsGitHubReleaseJsonData element.
NX_INLINE void utilsFreeGitHubReleaseJsonData ( UtilsGitHubReleaseJsonData * data )
{
if ( ! data ) return ;
if ( data - > obj ) json_object_put ( data - > obj ) ;
memset ( data , 0 , sizeof ( UtilsGitHubReleaseJsonData ) ) ;
}
2020-12-02 06:28:35 +00:00
/// Simple wrapper to sleep the current thread for a specific number of full seconds.
2020-05-03 00:40:50 +01:00
NX_INLINE void utilsSleep ( u64 seconds )
2020-04-15 21:50:07 +01:00
{
2020-04-17 22:59:05 +01:00
if ( seconds ) svcSleepThread ( seconds * ( u64 ) 1000000000 ) ;
2020-04-15 21:50:07 +01:00
}
2023-10-22 23:44:40 +01:00
/// Introduces a 33.33 milliseconds delay. Suitable to avoid hitting 100% CPU core usage in appletMainLoop() loops.
NX_INLINE void utilsAppletLoopDelay ( void )
{
svcSleepThread ( THIRTY_FPS_DELAY ) ;
}
2021-05-18 13:32:43 +01:00
/// Wrappers used in scoped locks.
NX_INLINE UtilsScopedLock utilsLockScope ( Mutex * mtx )
{
UtilsScopedLock scoped_lock = { mtx , ! mutexIsLockedByCurrentThread ( mtx ) , 1 } ;
if ( scoped_lock . lock ) mutexLock ( scoped_lock . mtx ) ;
return scoped_lock ;
}
2021-06-09 05:48:17 +01:00
NX_INLINE UtilsScopedLock utilsTryLockScope ( Mutex * mtx )
{
UtilsScopedLock scoped_lock = { mtx , ! mutexIsLockedByCurrentThread ( mtx ) , 1 } ;
if ( scoped_lock . lock ) scoped_lock . cond = ( int ) mutexTryLock ( scoped_lock . mtx ) ;
return scoped_lock ;
}
2021-05-18 13:32:43 +01:00
NX_INLINE void utilsUnlockScope ( UtilsScopedLock * scoped_lock )
{
if ( scoped_lock - > lock ) mutexUnlock ( scoped_lock - > mtx ) ;
}
2021-03-23 14:06:52 +00:00
# ifdef __cplusplus
}
# endif
2021-03-26 04:35:14 +00:00
# endif /* __NXDT_UTILS_H__ */