diff --git a/Makefile b/Makefile
index b2fd0d9..8111506 100644
--- a/Makefile
+++ b/Makefile
@@ -69,7 +69,7 @@ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
-LIBS := -lcurl -lmbedtls -lmbedx509 -lmbedcrypto -lxml2 -lz -lusbhsfs -lnx -ljson-c -lm `freetype-config --libs` -lturbojpeg
+LIBS := -lcurl -lmbedtls -lmbedx509 -lmbedcrypto -lxml2 -lz -lusbhsfs -lntfs-3g -lnx -ljson-c -lm `freetype-config --libs` -lturbojpeg
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
@@ -160,7 +160,7 @@ endif
all: $(BUILD)
usbhsfs:
- @$(MAKE) --no-print-directory -C libusbhsfs release
+ @$(MAKE) --no-print-directory -C libusbhsfs BUILD_TYPE=GPL release
$(BUILD): usbhsfs
@[ -d $@ ] || mkdir -p $@
diff --git a/build.sh b/build.sh
index da14b42..d45bf9e 100644
--- a/build.sh
+++ b/build.sh
@@ -23,7 +23,7 @@ for f in ./code_templates/*.c; do
rm -f ./source/main.c
cp $f ./source/main.c
- make BUILD_TYPE="$filename"
+ make BUILD_TYPE="$filename" -j12
rm -f ./build/main.o ./build/main.d
mkdir ./code_templates/tmp/$filename
diff --git a/source/utils.c b/source/utils.c
index 32257fa..4e40d23 100644
--- a/source/utils.c
+++ b/source/utils.c
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*/
+#include
#include
#include "utils.h"
@@ -581,12 +582,29 @@ void utilsGenerateFormattedSizeString(u64 size, char *dst, size_t dst_size)
}
}
-bool utilsGetFreeSdCardFileSystemSpace(u64 *out)
+bool utilsGetFreeSpaceFromFileSystemByPath(const char *path, u64 *out)
{
- if (!g_sdCardFileSystem) return false;
- Result rc = fsFsGetFreeSpace(g_sdCardFileSystem, "/", (s64*)out);
- if (R_FAILED(rc)) LOGFILE("fsFsGetFreeSpace failed! (0x%08X).", rc);
- return R_SUCCEEDED(rc);
+ char *name_end = NULL, stat_path[32] = {0};
+ struct statvfs info = {0};
+ int ret = -1;
+
+ if (!path || !*path || !(name_end = strchr(path, ':')) || *(name_end + 1) != '/' || !out)
+ {
+ LOGFILE("Invalid parameters!");
+ return false;
+ }
+
+ name_end += 2;
+ sprintf(stat_path, "%.*s", (int)(name_end - path), path);
+
+ if ((ret = statvfs(stat_path, &info)) != 0)
+ {
+ LOGFILE("statvfs failed! (%d) (errno: %d).", ret, errno);
+ return false;
+ }
+
+ *out = ((u64)info.f_bfree * (u64)info.f_frsize);
+ return true;
}
bool utilsCommitSdCardFileSystemChanges(void)
diff --git a/source/utils.h b/source/utils.h
index 2aa8c19..cca43d2 100644
--- a/source/utils.h
+++ b/source/utils.h
@@ -65,7 +65,7 @@
-
+/// Used to determine which CFW is the application running under.
typedef enum {
UtilsCustomFirmwareType_Unknown = 0,
UtilsCustomFirmwareType_Atmosphere = 1,
@@ -73,57 +73,90 @@ typedef enum {
UtilsCustomFirmwareType_ReiNX = 3
} UtilsCustomFirmwareType;
+/// Resource (de)initialization.
+/// Called at program startup.
bool utilsInitializeResources(void);
void utilsCloseResources(void);
+/// Thread management functions.
bool utilsCreateThread(Thread *out_thread, ThreadFunc func, void *arg, int cpu_id);
void utilsJoinThread(Thread *thread);
+/// Returns true if the application is running under a development unit.
bool utilsIsDevelopmentUnit(void);
-/// hidScanInput() must be called before any of these functions.
+/// Functions to retrieve down/held keys from all input controllers.
+/// hidScanInput() must be called before any of these.
u64 utilsHidKeysAllDown(void);
u64 utilsHidKeysAllHeld(void);
+/// Waits until any key matching the provided input flag is pressed.
+/// If 'flag' is set to zero (KEY_ANY), any key press will count.
void utilsWaitForButtonPress(u64 flag);
+/// 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.
bool utilsAppendFormattedStringToBuffer(char **dst, size_t *dst_size, const char *fmt, ...);
+/// Logfile management functions.
void utilsWriteMessageToLogFile(const char *func_name, const char *fmt, ...);
void utilsWriteMessageToLogBuffer(char **dst, size_t *dst_size, const char *func_name, const char *fmt, ...);
void utilsWriteLogBufferToLogFile(const char *src);
void utilsLogFileMutexControl(bool lock);
+/// Replaces illegal FAT characters in the provided string with underscores.
+/// If 'ascii_only' is set to true, all characters outside the (0x20,0x7E] range will also be replaced with underscores.
void utilsReplaceIllegalCharacters(char *str, bool ascii_only);
+/// Trims whitespace characters from the provided string.
void utilsTrimString(char *str);
+/// Generates a lowercase hex string representation of the binary data stored in 'src' and stores it in 'dst'.
void utilsGenerateHexStringFromData(char *dst, size_t dst_size, const void *src, size_t src_size);
+/// Formats the provided 'size' value to a human readable size string and stores it in 'dst'.
void utilsGenerateFormattedSizeString(u64 size, char *dst, size_t dst_size);
-bool utilsGetFreeSdCardFileSystemSpace(u64 *out);
+/// Saves the free file space from the filesystem pointed to by the input path (e.g. "sdmc:/") to 'out'.
+/// Returns false if there's an error.
+bool utilsGetFreeSpaceFromFileSystemByPath(const char *path, u64 *out);
+
+/// Commits SD card filesystem changes.
+/// Must be used after closing a file handle from the SD card.
bool utilsCommitSdCardFileSystemChanges(void);
+/// Returns true if a file exists.
bool utilsCheckIfFileExists(const char *path);
+/// Deletes a ConcatenationFile located at the input path.
void utilsRemoveConcatenationFile(const char *path);
+
+/// Creates a ConcatenationFile at the input path.
bool utilsCreateConcatenationFile(const char *path);
+/// 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.
void utilsCreateDirectoryTree(const char *path, bool create_last_element);
+/// Returns a pointer to a dynamically allocated string that holds the full path formed by the provided arguments.
char *utilsGeneratePath(const char *prefix, const char *filename, const char *extension);
+/// Returns true if the application is running under Applet Mode.
bool utilsAppletModeCheck(void);
+/// (Un)blocks HOME button presses.
void utilsChangeHomeButtonBlockStatus(bool block);
-u8 utilsGetCustomFirmwareType(void); ///< UtilsCustomFirmwareType.
+/// Returns a UtilsCustomFirmwareType value.
+u8 utilsGetCustomFirmwareType(void);
+/// Returns a pointer to the FsStorage object for the eMMC BIS System partition.
FsStorage *utilsGetEmmcBisSystemPartitionStorage(void);
+/// Enables/disables CPU/MEM overclocking.
void utilsOverclockSystem(bool overclock);
+/// Simple wrapper to sleep the current thread for a specific number of full seconds.
NX_INLINE void utilsSleep(u64 seconds)
{
if (seconds) svcSleepThread(seconds * (u64)1000000000);