Other changes include:
* title: update titleGetContentInfosByGameCardContentMetaContext() to make it write the forged NcmContentInfo entry for the Meta NCA at the start of the returned buffer (matches ncm output).
Changes include:
* nxdt_utils: add utilsEscapeCharacters().
* title: add titleGenerateTitleRecordsCsv().
* title: move core logic from titleGetUserApplicationData() into _titleGetUserApplicationData(). titleGetUserApplicationData() now only takes care of duplicating the retrieved data.
* title: update titleGetContentInfosByGameCardContentMetaContext() to make it write the forged NcmContentInfo entry for the Meta NCA at the end of the returned buffer.
* title: fix a bug in titleRefreshGameCardTitleInfo() that prevented a title info's metadata pointer to be updated after retrieving application metadata via ns.
* title: update titleGenerateGameCardApplicationMetadataArray() to add a logfile warning if an application entry doesn't have a valid application metadata pointer.
* title: make _titleGenerateGameCardFileName() a bit easier to read.
Makes it possible to generate TitleInfo and TitleApplicationMetadata elements for gamecards that can't be used with ncm (e.g. Kiosk / Quest gamecards under retail, non-Quest units). This is achieved by:
1. Retrieving a Hash FS context for the gamecard's secure partition.
2. Initializing NCA and CNMT contexts for all of the Meta NCAs within the secure partition.
3. Manually generating NcmContentMetaKey and NcmContentInfo elements per each CNMT context.
4. Creating TitleInfo elements using the generated NcmContentMetaKey and NcmContentInfo elements.
5. Initializing NCA and NACP contexts for the base (or update) Control NCAs within the secure partition.
6. Manually generating a NsApplicationControlData element per each NACP context.
7. Creating TitleApplicationMetadata elements using the generated NsApplicationControlData elements.
Afterwards, gamecard title/content enumeration and all other features that rely on it (e.g. NSP, NCA, NCA FS) work as expected. Please note that this process is only carried out if regular title storage initialization fails.
Other changes include:
* title: reorder code.
* title: add TitleGameCardContentMetaContext struct.
* title: rename titleGetInfoFromStorageByTitleId() -> titleGetTitleInfoEntryFromStorageByTitleId().
* title: add titleInitializeGameCardTitleStorageByHashFileSystem().
* title: rename titleGenerateDummySystemMetadataEntry() -> titleGetSystemMetadataEntry().
* title: rename titleRetrieveUserApplicationMetadataByTitleId() -> titleGenerateUserMetadataEntryFromNs().
* title: move ns logic from titleRetrieveUserApplicationMetadataByTitleId() into a new function: titleGetApplicationControlDataFromNs().
* title: add titleGenerateUserMetadataEntryFromControlNca().
* title: add titleGetApplicationControlDataFromControlNca().
* title: add titleInitializeUserMetadataEntryFromControlData().
* title: add titleGenerateTitleInfoEntriesByHashFileSystemForGameCardTitleStorage().
* title: move TitleInfo generation logic from titleGenerateTitleInfoEntriesForTitleStorage() into a new function: titleGenerateTitleInfoEntry().
* title: add titleInitializeTitleInfoApplicationMetadataFromControlNca().
* title: add titleGetGameCardContentMetaContexts().
* title: add titleFreeGameCardContentMetaContexts().
* title: add titleGetContentInfosByGameCardContentMetaContext().
* title: rename _titleGetInfoFromStorageByTitleId() -> _titleGetTitleInfoEntryFromStorageByTitleId().
* title: rename titleSystemTitleMetadataEntrySortFunction() -> titleSystemMetadataSortFunction().
* title: rename titleUserApplicationMetadataEntrySortFunction() -> titleUserMetadataSortFunction().
* title: rename titleInfoEntrySortFunction() -> titleInfoSortFunction().
* title: add titleGameCardContentMetaContextSortFunction().
* codebase: update to reflect the rest of the changes.
Changes include:
* title: define a global string array for the pre-generated gamecard filenames.
* title: move gamecard filename generation logic into a new function, _titleGenerateGameCardFileName().
* title: update background gamecard thread logic to make it generate gamecard filenames on any status changes.
* title: update titleGenerateFileName() to make it return a duplicate of the gamecard filename requested by the caller.
titleGetApplicationMetadataEntries() and titleGetGameCardApplicationMetadataEntries() will now return dynamically allocated copies of internal pre-filtered / pre-processed arrays, which are generated using the background gamecard thread. This results in less overhead for any potential calls to these functions.
Other changes include:
* title: rename TitleGameCardApplicationMetadataEntry -> TitleGameCardApplicationMetadata.
* title: add `has_patch` field to TitleGameCardApplicationMetadata struct.
* title: declare internal TitleApplicationMetadata arrays to hold pre-filtered application metadata.
* title: declare internal TitleGameCardApplicationMetadata array to hold pre-processed gamecard application metadata.
* title: move filtering logic from titleGetApplicationMetadataEntries() to a new function: titleGenerateFilteredApplicationMetadataPointerArray().
* title: move processing logic from titleGetGameCardApplicationMetadataEntries() to a new function: titleGenerateGameCardApplicationMetadataArray().
* title: rename titleGetPatchVersionString() -> titleGetDisplayVersionString().
* title: add extra debug log messages to some functions.
* title: update titleFreeApplicationMetadata() to also free the new internal metadata arrays.
* title: update background thread logic in titleGameCardInfoThreadFunc() to also regenerate the pre-filtered application metadata and gamecard application metadata arrays right after a successful call to titleRefreshGameCardTitleInfo().
* title: update titleGetDisplayVersionString() to also support base application titles.
* title: simplify string generation logic in titleGenerateGameCardFileName() by using the cached gamecard application metadata array.
* GameCardStatusTask: add GetGameCardStatus() method.
* GameCardTab: fix callback argument type in class constructor.
* GameCardTab: update ProcessGameCardStatus() to block user inputs while processing the new gamecard status.
* RootView: add GetGameCardStatus() method.
* StatusInfoTask: turn IsInternetConnectionAvailable() into an inline method.
* TitleMetadataTask: turn GetApplicationMetadata() into an inline method.
* TitleMetadataTask: move debug log messages around.
* TitlesTab: update PopulateList() to block user inputs while updating the titles list.
* UmsTask: turn GetUmsDevices() into an inline method.
* UsbHostTask: turn GetUsbHostSpeed() into an inline method.
The directory layout is partially based on the C++ namespaces we're currently using.
Other changes include:
* devoptab: move directory into "core".
* fatfs: move directory into "core".
* GameCardTab: move portions of logic from PopulateList() into their own methods.
* GameCardTab: use a macro to generate the properties table.
* GameCardTab: use a macro to add ListItem elements.
* GameCardTab: update AddApplicationMetadataItems() method to also display the number of DLCs available in the inserted gamecard for each application whenever possible.
* Makefile: remove all extra entries from the INCLUDES variable.
* nxdt_includes: move HOS version structs into their own header file.
* tasks: move code for each individual task into its own file(s).
* title: update titleGetGameCardApplicationMetadataEntries() to also count the number of DLCs available in the inserted gamecard for any given base application.
* title: reorder gamecard application metadata entries by name before returning the buffer in titleGetGameCardApplicationMetadataEntries().
DataTransferTaskFrame is a template class that's derived from brls::AppletFrame, which automatically starts a background task using an internal object belonging to a class derived from DataTransferTask. A DataTransferProgressDisplay view is used to show progress updates. If the background task hits an error, the class takes care of switching to an ErrorFrame view with the corresponding error message.
GameCardImageDumpTaskFrame is a derived class of DataTransferTaskFrame that uses a GameCardImageDumpTask object as its background task. In layman's terms, this provides a way to fully dump gamecard images using the new UI.
DataTransferTaskFrame depends on the newly added is_base_template helper from goneskiing to check if the class for the provided task is derived from DataTransferTask.
Other changes include:
* DataTransferProgressDisplay: rename setProgress() method to SetProgress().
* DataTransferTask: move post-task-execution code into its own new private method, PostExecutionCallback(), and update both OnCancelled() and OnPostExecute() callbacks to invoke it.
* DataTransferTask: update OnProgressUpdate() to allow sending a last progress update to all event subscribers even if the background task was cancelled.
* DataTransferTask: update OnProgressUpdate() to allow sending a first progress update if no data has been transferred but the total transfer size is already known.
* DataTransferTask: update OnProgressUpdate() to avoid calculating the ETA if the speed isn't greater than 0.
* DumpOptionsFrame: remove UpdateOutputStorages() method.
* DumpOptionsFrame: update class to use the cached output storage value from our RootView.
* DumpOptionsFrame: add GenerateOutputStoragesVector() method, which is used to avoid setting dummy options while initializing the output storages SelectListItem.
* DumpOptionsFrame: update UMS task callback to add the rest of the leftover logic from UpdateOutputStorages().
* DumpOptionsFrame: update RegisterButtonListener() to use a wrapper callback around the user-provided callback to check if the USB host was selected as the output storage but no USB host connection is available.
* ErrorFrame: use const references for all input string arguments.
* FileWriter: fix a localization stirng name typo.
* FileWriter: fix an exception that was previously being thrown by a fmt::format() call because of a wrong format specifier.
* FocusableItem: add a static assert to check if the provided ViewType is derived from brls::View.
* gamecard: redefine global gamecard status variable as an atomic unsigned 8-bit integer, which fixes a "status-hopping" issue previously experienced by repeating tasks running under other threads that periodically call gamecardGetStatus().
* GameCardImageDumpOptionsFrame: define GAMECARD_TOGGLE_ITEM macro, which is used to initialize all ToggleListItem elements from the view.
* GameCardImageDumpOptionsFrame: update button callback to push a GameCardImageDumpTaskFrame view onto the borealis stack.
* GameCardImageDumpTask: move class into its own header and module files.
* GameCardImageDumpTask: update class to also take in the checksum lookup method (not yet implemented).
* GameCardImageDumpTask: update class to send its first progress update as soon as the gamecard image size is known.
* GameCardImageDumpTask: update class to avoid returning a string if the task was cancelled -- DataTransferTaskFrame offers logic to display the appropiate cancel message on its own.
* GameCardTab: update PopulateList() method to display the new version information available in TitleGameCardApplicationMetadataEntry elements as part of the generated TitlesTabItem objects.
* i18n: add new localization strings.
* OptionsTab: update background task callback logic to handle task cancellation, reflecting the changes made to DataTransferTask.
* OptionsTab: reflect changes made to DataTransferProgressDisplay.
* RootView: cache the currently selected output storage value at all times, which is propagated throughout different parts of the UI. Getter and setter helpers have been added to operate with this value.
* RootView: add GetUsbHostSpeed() helper, which can be used by child views to retrieve the USB host speed on demand.
* RootView: update UMS task callback to automatically reset the cached output storage value back to the SD card if a UMS device was previously selected.
* title: define TitleGameCardApplicationMetadataEntry struct, which also holds version-specific information retrieved from the gamecard titles.
* title: refactor titleGetGameCardApplicationMetadataEntries() to return a dynamically allocated array of TitleGameCardApplicationMetadataEntry elements.
* usb: redefine global endpoint max packet size variable as an atomic unsigned 16-bit integer, which fixes a "status-hopping" issue previously experienced by repeating tasks running under other threads that periodically call usbIsReady().
* UsbHostTask: add GetUsbHostSpeed() method.
This commit implements a devoptab wrapper for Partition FS sections within NCAs, using code from pfs.c/h.
Other changes include:
* codebase: use NX_IGNORE_ARG macro where needed.
* hfs: slight tweaks to some of the static functions.
* pfs: slight tweaks to some of the static functions.
* pfs: use pfsIsValidContext() where needed.
* utils: update utilsInitializeResources() to use __system_argc and __system_argv variables from libnx.
* todo: update text file.
libnx now implements fsDeviceOperatorGetGameCardIdSet(), so I got rid of my own implementation.
Other changes include:
* cnmt: add cnmtVerifyContentHash().
* defines: add SHA256_HASH_STR_SIZE.
* fs_ext: add FsCardId1MakerCode, FsCardId1MemoryType and FsCardId2CardType enums.
* fs_ext: update FsCardId* structs.
* gamecard: change all package_id definitions from u64 -> u8[0x8].
* gamecard: fix misleading struct member names in GameCardHeader.
* gamecard: rename gamecardGetIdSet() -> gamecardGetCardIdSet().
* gamecard_tab: fix Package ID printing.
* gamecard_tab: add Card ID Set printing.
* host: add executable flag to Python scripts.
* keys: detect if we're dealing with a wiped eTicket RSA device key (e.g. via set:cal blanking). If so, the application will still launch, but all operations related to personalized titlekey crypto are disabled.
* pfs: rename PartitionFileSystemFileContext -> PartitionFileSystemImageContext and propagate the change throughout the codebase.
* pfs: rename PFS_FULL_HEADER_ALIGNMENT -> PFS_HEADER_PADDING_ALIGNMENT and update pfsWriteImageContextHeaderToMemoryBuffer() accordingly.
* poc: print certain button prompts with reversed colors, in the hopes of getting the user's attention.
* poc: NSP, Ticket and NCA submenus for updates and DLC updates now display the highest available title by default.
* poc: simplified output path generation for extracted NCA FS section dumps.
* poc: handle edge cases where a specific NCA from an update has no matching equivalent by type/ID offset in its base title (e.g. Fall Guys' HtmlDocument NCA).
* poc: implement NCA checksum validation while generating NSP dumps.
* romfs: update romfsInitializeContext() to allow its base_nca_fs_ctx argument to be NULL.
* usb: use USB_BOS_SIZE only once.
* workflow: update commit hash referenced by "rewrite-prerelease" tag on update.
Implement utilsParseHexString() and utilsAppletLoopDelay().
Other changes include:
* defines: add THIRTY_FPS_DELAY define.
* defines: remove unused CERT_PATH define.
* gamecard: restore original reserved_2 field in GameCardInfo struct. The last 16 bytes weren't being properly due to an issue within libnx's AES-CBC implementation.
* gamecard: rename GAMECARD_ACCESS_WAIT_TIME -> GAMECARD_ACCESS_DELAY.
* host: improve ABI documentation (thanks @v1993).
* keys: remove keysConvertHexDigitToBinary().
* keys: change keysParseHexKey() function signature + update it to use utilsParseHexString() instead.
* nso: change "NRO" to "NSO" in some misleading log error messages (thanks @liamadvance).
* nxdt_rw_poc: replace svcSleepThread() calls with utilsAppletLoopDelay().
* nxdt_utils: rename utilsGenerateHexStringFromData() -> utilsGenerateHexString().
* nxdt_utils: add static utilsConvertHexDigitToBinary() function, used by utilsParseHexString().
* nxdt_utils: update utilsAppendFormattedStringToBuffer() to avoid logging an error string if resources haven't been initialized.
* nxdt_utils: use a single call to sprintf() with a variable precision argument in utilsGenerateFormattedSizeString().
* nxdt_utils: call utilsAppletLoopDelay() in the while loop from utilsPrintConsoleError().
* nxdt_utils: remove unused utilsCloseFileDescriptor() function.
* tik: log input rights ID at the start of tikRetrieveTicketByRightsId().
system_title_dumper PoC build is no more.
Other changes include:
* smc: add missing assert for SmcGenerateAesKekOption struct.
* title: update titleGenerateFileName() to add support for system titles.
Other changes include:
* nca: add title_id and title_type fields to NcaContext; redefine title_version field in NcaContext; redefine ncaInitializeContext() function signature (now requiring NcmContentMetaKey and NcmContentInfo objects); modify ncaInitializeFsSectionContext() to make it skip extra boundary checks on FS sections with a bogus sparse storage.
* config: rename "nsp/write_section_image" flag to "nsp/write_raw_section".
* nxdt_utils: modify utilsGeneratePath() to make it also check if the first character from the filename is a slash.
* pfs: modify pfsGetEntryIndexByName() to only log an error if the entry name being looked up isn't "main.npdm".
And I don't need anyone to tell me so, thank you very much.
* PoC: remove gc_dumper and nsp_dumper PoC; create nxdt_rw_poc with all gc_dumper and nsp_dumper capabilities + standalone ticket dumping + raw NCA dumping; use ftruncate() to set output file sizes whenever possible. PoC code is a mess, as always. Expect the features from the rest of the PoCs to be implemented into nxdt_rw_poc soon.
* workflow: temporarily disable borealis build generation; comment out manual installation of up-to-date packages from Leseratte's mirrors because the latest devkitA64 Docker image has them all.
* borealis: update to fix building issues with latest devkitA64.
* bfttf: error out on invalid NCA signatures.
* config: save configuration to the current working directory; parse and validate new "gamecard/write_raw_hfs_partition" flag.
* defines: remove CONFIG_PATH macro; rename CONFIG_FILE_NAME.
* gamecard: rename fs_ctx -> hfs_ctx everywhere; use HFS function calls to retrieve partition names.
* hfs: move GameCardHashFileSystemPartitionType enum from gamecard.h and rename it to HashFileSystemPartitionType; add hfsIsValidContext(); add hfsGetPartitionNameString().
* nca/npdm: update comments to reflect latest HOS version.
* nxdt_bfsar: always generate absolute SD card paths with the device name; error out on an invalid NCA signature.
* nxdt_includes: include dirent.h; refactor Version struct to make it a union of all known *Version structs.
* nxdt_log: don't write session separator if the logfile is empty.
* nxdt_utils: log appletIsGamePlayRecordingSupported() errors; add utilsDeleteDirectoryRecursively().
* rsa: provide clearer function descriptions in header file.
* services: handle usb:ds initialization.
* tik: update tikConvertPersonalizedTicketToCommonTicket() to allow NULL input pointers as raw certificate chain arguments (much needed for standalone ticket dumping).
* title: add titleGetApplicationIdByMetaKey().
* usb: refactor interface (de)initialization code; slightly improve ABI usage (console-side only); redefine ABI version field in StartSession command blocks; upgrade ABI to v1.1.
* FatFs: rename DIR -> FDIR to avoid conflicts with definitions from stdlib's dirent.h.
* gamecard_tab: display package ID from the inserted gamecard; fix displayed version numbers from bundled system updates below 3.0.0.
* todo: add notes about creating devoptab devices for HFS/PFS/RomFS file tree dumping.
* gc_dumper: add UMS device support.
* nsp_dumper: add DLC Update support.
* cnmt: add a reminder about the extended data size in NcmContentMetaType_DataPatch CNMTs.
* nca: update NcaKeyGeneration enum comment.
* title: update system titles array, severely overhaul the way linked lists work in Title* structs to properly support DLC updates.
This commit uses my yet unmerged libnx PR to update ncm_types.h.
PoC code hasn't been updated yet, so proper support for DLC updates will arrive at a later time.
Note to self: implement a way to provide access to loaded DataPatch TitleInfo entries (linked list hell).
* bktr: renamed bktrBucketInitializeSubStorageReadParams to bktrInitializeSubStorageReadParams to avoid redundancy, added debug code to dump BucketInfo and BucketTree tables if BucketTree storage initialization fails.
* cnmt: updated ContentMetaAddOnContentMetaExtendedHeader struct to its 15.x equivalent, added ContentMetaLegacyAddOnContentMetaExtendedHeader struct, added ContentMetaDataPatchMetaExtendedHeader struct, updated the cnmtGetRequiredTitleId and cnmtGetRequiredTitleVersion functions to support DataPatch titles, updated cnmtInitializeContext to support both the new AddOnContent extended header and DataPatch titles, added debug code to dump the whole CNMT if context initialization fails, updated cnmtGenerateAuthoringToolXml to support DataPatch titles.
* keys: updated block hashes to match 15.x keyset, use case-insensitive comparison while looking for entry names in keysReadKeysFromFile, make sure the eticket_rsa_kek is non-zero before proceeding in keysGetDecryptedEticketRsaDeviceKey.
* nca: updated NcaKeyGeneration enum, added reminder about updating NcaSignatureKeyGeneration if necessary, replaced ncaFsSectionCheckHashRegionAccess with ncaFsSectionCheckPlaintextHashRegionAccess, removed all extents checks on Patch RomFS and sparse sections, updated ncaGetFsSectionTypeName to reflect if a FS section holds a sparse layer or not.
* nca_storage: updated ncaStorageInitializeContext to avoid initializing a compressed storage if a sparse layer is also used (fixes issues with Them's Fightin' Herds), updated ncaStorageSetPatchOriginalSubStorage to enforce the presence of a compressed storage in a patch if the base FS holds a compressed storage.
* npdm: added reminder about updating NpdmSignatureKeyGeneration if necessary, updated NpdmFsAccessControlFlags enum, updated NpdmAccessibility enum, updated NpdmSystemCallId enum, fixed typos.
* title: updated all relevant functions that deal with NcmContentMetaType values to also handle DataPatch titles, added functions to handle DataPatchId values, removed titleConvertNcmContentSizeToU64 and titleConvertU64ToNcmContentSize functions in favor of ncmContentInfoSizeToU64 and ncmU64ToContentInfoSize from my unmerged libnx PR, updated internal arrays to match 15.x changes, renamed titleOrphanTitleInfoSortFunction to titleInfoEntrySortFunction and updated it to also sort entries by version and storage ID, updated titleGenerateTitleInfoEntriesForTitleStorage to sort TitleInfo entries, simplified titleDuplicateTitleInfo a bit by using macros.
* Update libusbhsfs.
* Update borealis.
* nsp_dumper: force free size retrieval after dumping an NSP.
* title: add titleGetGameCardApplicationMetadataEntries().
* Makefile: remove -gdwarf-4 flag.
* nxdt_utils: treat NT_MAX_FILENAME_LENGTH as bytes instead of codepoints, add "TiB" to the array of supported size suffixes.
* GameCardTab: add ProcessGameCardStatus() and PopulateList(), manage list updates in the same fashion as TitlesTab, display message about how to mitigate launch errors after exiting the application, display available applications in the inserted gamecard, display message about how to perform individual operations on the gamecard titles.
* main: add a try/catch block to intercept any possible exceptions thrown while the application is running + use brls::Application::crash() to gracefully exit afterwards. Temporarily disable Applet Mode support.
* exception_handler: use LOG_LEVEL_ERROR.
* LayeredErrorFrame: add GetListFirstFocusableChild().
* title: implemented titleGetNcmStorageIdName().
* nxdt_log: implemented log verbosity levels (debug, info, warning, error, none) and helper macros for each level. The rest of the codebase still needs to be updated to take advantange of this change.
* nxdt_log: implemented auxiliary logging via nxlink, if available.
* nxdt_utils: system CPU/MEM overclocking is now only applied through utilsSetLongRunningProcessState(), as it should have been from the beginning.
* nxdt_utils: nxlink initialization is now carried out without redirecting stdout and/or stderr, entirely removing the need for utilsRestoreConsoleOutput(). utilsGetNxLinkFileDescriptor() is used to send data to the nxlink host via dprintf() in log functions.
The exception handler is capable of logging CPU registers and a stack trace using the current log implementation.
Furthermore, if borealis has been initialized, it'll also display the PC register value using a CrashFrame. Otherwise, console output is used to display the same message.
Other changes include:
* utils: made utilsPrintConsoleError non-static.
* utils: implemented a workaround to restore console output after initializing nxlink.
Other changes include:
* utils: utilsGenerateFormattedSizeString() now takes an input double instead of size_t.
* DownloadTask: calculated speed is now expressed in bytes per second, so now it's up to the caller to convert it to other units.
* DownloadTask: set download size and percentage if the download size isn't known and we're dealing with the final chunk.
* http: slightly improved CURL error info formatting.
* OptionsTab: fully implemented NSWDB XML update option.
* Thread-safe.
* Provides getter/setter functions for the data types used by nxdumptool's configuration.
* Each setter function writes the modified JSON configuration back to the SD card.
* Configuration is validated on interface initialization. If validation fails, a default JSON template is loaded from the application's RomFS and written back to the SD card.
Other changes:
* Implement directory creation.
* Moved more preprocessor definitions to defines.h.
* Replaced strtok() calls throughout the code with strtok_r() to guarantee thread-safety.
* Updated borealis fork (refer to https://github.com/DarkMatterCore/borealis/commits/nxdumptool-legacy).
* Updated NcaKeyGeneration enum.
* Commented out title task notification.
* Remove unnecessary instant view invalidations.
* NS application records are now retrieved using a loop.
* Fixed text alignment issues in RootView.
* Slightly improved gamecard notifications.
* core: implemented SCOPED_TRY_LOCK macro. Specific functions are now using it instead of SCOPED_LOCK to avoid potentially locking the Borealis UI.
* UI: implemented background tasks for Borealis, which call functions that now use SCOPED_TRY_LOCK.
* Both gamecard header and decrypted CardInfo area are now retrieved upon gamecard insertion. LAFW version is checked against the CardInfo LAFW version right afterwards.
* Expanded GameCardStatus enum to add NoGameCardPatchEnabled and LotusAsicFirmwareUpdateRequired values.
* Updated utilsReplaceIllegalCharacters() to perform replacements on a per-codepoint basis, which means that invalid multibyte UTF-8 codepoints can now be replaced with a single ASCII underscore.
* Updated utilsGeneratePath() to truncate path elements that exceed 255 UTF-8 codepoints (safe limit for FAT and NTFS filesystems).
* Heavily simplified core logic in title functions by using newly defined TitleStorage elements (which hold the NCM database/storage handles, a TitleInfo array and a title counter) instead of the old, global index-based methods.
* Simplified background gamecard title thread logic by always returning duplicated TitleInfo data to the user.
* Update title API to account for the previously mentioned changes, including functions to free duplicated title data.
* Fallback gamecard filename string now also holds the gamecard package ID whenever possible.
* Implemented HDCP patching for Control NCAs.
* Implemented RSA-2048-PSS + SHA256 signature verification.
* Refactored RSA-2048-OAEP decryption steps to use mbedtls function calls.
* Implemented NCA header main signature verification.
* Replaced Björn Samuelsson's CRC32 algorithm with the hardware accelerated CRC32 checksum calculation from libnx (latest commit with support for calculation in blocks).
* Rewrote mutex handling throughout the code to use a small, macro-based scoped lock implementation.
* Removed extern variables from common.h - launch path management is now completely handled in utils.c.
* Updated NpdmSystemCallId_Count to reflect changes introduced in 12.0.0.
* Added NcaMainSignatureKeyGeneration enum.
* NCA main signature moduli are now retrieved from FS .rodata at runtime.
* Simplified lock management in usb.c by using a single global mutex with scoped locks instead of three different r/w locks.
* Updated FatFs to R0.14b.
* Enabled 64-bit LBA support in FatFs to potentially support custom eMMC replacements / resized USER partitions in the future.
* Updated LZ4 to v1.9.3.
* Fixed typos.
* USB gamecard dumper PoC now only dumps the Initial Data area.
* Updated to-do list.