Huge refactor/code cleanup.
- lib:
- Add
usbHsFsGetDeviceByPath(), which fills its outputUsbHsFsDeviceelement with information about the mounted volume pointed to by the input path (e.g.ums0:/switch/). - Ditch
FS_MAX_PATHmacro in favor ofLIBUSBHSFS_MAX_PATH(set to 4096 bytes), providing better support for longer filesystem paths. - Add support for retrieving and setting FAT/NTFS specific file attribute bitmasks via
stat(),chmod(),readdir(),fstat()(NTFS only) andfchmod()(NTFS only). Please keep in mind that in order to preserve regular POSIX file attributes, thest_spare4[0]field from thestatstruct is used to store this information. - Add
UsbHsFsDosNtFileAttributesenum to easily handle FAT/NTFS attribute bitmasks. - Allow listing of dotfiles in directories whenever possible across all supported filesystems.
- Reduce the size of the dedicated transfer buffer for each UMS device from 8 MiB to 1 MiB.
- Add
_GNU_SOURCEdefinition toCFLAGSin Makefile.
- Add
- devoptab:
- Add a new header file with generic versions of the macros previously used in all devoptab interfaces.
- examples:
- Use dynamically allocated buffers for the tested filesystem paths (using the LIBUSBHSFS_MAX_PATH macro).
- Reduce file copy block size to 1 MiB to match the rest of the changes.
- Print FAT/NTFS specific file attribute bitmasks during the file tests, depending on the mounted filesystem type.
- Unconditionally print full POSIX attributes bitmask during the file tests.
- Print last access and creation timestamps during the file tests.
- fat:
- Update FatFs to R0.16 p2 (September 13th, 2025).
- Cherrypick specific FatFs improvements from the fork maintained by Extrems, while still retaining support for our runtime read-only flag. These include:
- Remove internal volume management system in favor of explicitly passing FATFS objects.
- Modify
ff_stat()to allow its use on the origin directory. - Modify
FILINFOstruct to expose the cluster number and the last access timestamp. - Prevent automatic hiding of dotfiles in directory listings.
- Integrate contiguous clusters patch from Wonderful Toolchain.
- Fix file growth error on exFAT.
- Add a small optimization to
FAT_TIMESTAMPmacro. - Update
get_fattime()to use plain oldtime()instead. - Fix timestamp generation in
get_fattime()by adding previously missing time offsets totimeinfo.tm_year(+1900) andtimeinfo.tm_mon(+1). Thanks to ITotalJustice. - Refactor
ffdev_fixpath()intoffdev_get_fixed_path(). - Update
ffdev_fill_stat()to store the last access and creation timestamps into the output stat struct, as well as the FAT-specific file attributes bitmask. - Delegate timestamp conversion to the new
ffdev_time_posix2fat()andffdev_time_fat2posix()helpers. - Implement
ffdev_chmod().
- ext:
- Add
mountedflag toext_vd, in order to prevent unmounting an EXT volume that hasn't really been successfully mounted. - Remove
extdev_fixpath()in favor ofextdev_get_fixed_path(). - Only use full second precision in
extdev_utimes().
- Add
- ntfs:
- Add
NTFS_MAX_NAME_LEN_BYTESmacro. - Make
ntfs_pathstruct public, remove its internal buffer and turn all strings into dynamically allocated pointers. - Update
ntfs_inode_create(),ntfs_inode_link()andntfs_inode_unlink()to take inntfs_pathobjects instead of character strings. - Add
ntfs_path_destroy(). - Remove
ntfs_split_path(). - Refactor
ntfsdev_fixpath()intontfsdev_get_fixed_path(). - Move path split logic from
ntfs_split_path()intontfsdev_get_fixed_path(). - Update
ntfsdev_dirnext()andntfsdev_dirnext_filldir()to allow listing of dotfiles in directories. - Update
ntfsdev_statvfs()to useNTFS_MAX_NAME_LEN_BYTESas the value forf_namemax. - Implement
ntfsdev_chmod()andntfsdev_fchmod(). - Update
ntfsdev_fill_stat()to store the NTFS-specific file attributes bitmask.
- Add
- usbfs:
- Add
UsbFsMountStatusenum. - Update
UsbFsServiceCmdenum to follow the same codestyle as the rest of the codebase.
- Add
- Other internal changes:
- Use C23 strongly typed enums.
- Use forward declarations for structs whenever needed.
- usbhsfs_drive:
- Move struct definitions into their own header file.
- Update
UsbHsFsDriveLogicalUnitFileSystemContextto use a singlevoid*pointer to represent the underlying filesystem object. - Update
UsbHsFsDriveContextto use a recursive mutex instead of a regular one. - Update
usbHsFsDriveInitializeContext()to return a pointer to a dynamically allocatedUsbHsFsDriveContextobject. - Update
usbHsFsDriveDestroyContext()to lock the drive recursive mutex + let it take care of freeingusbHsFsDriveDestroyContextpointers as well. - Heavily simplify
usbHsFsDriveIsValidLogicalUnitFileSystemContext(). - Move LUN initialization logic into
usbHsFsDriveInitializeLogicalUnitContext(). - Update
usbHsFsDriveClearStallStatus()to add small 10 ms delays after each call tousbHsFsRequestClearEndpointHaltFeature(). - Fix required conditions for an interface change in
usbHsFsDriveChangeInterfaceDescriptor(). - Add
usbHsFsDriveDestroyLogicalUnitContext().
- usbhsfs_log:
- Define stubbed macros for public
usbHsFsLog*()calls when the library is not built in debug mode.
- Define stubbed macros for public
- usbhsfs_manager:
- Remove
usbHsFsManagerGetLogicalUnitContextForFatFsDriveNumber(). - Move Atmosphère-specific (de)initialization logic into
usbHsFsManagerInitializeAtmosphereDriverResources()andusbHsFsManagerCloseAtmosphereDriverResources(). - Move SX OS-specific (de)initialization logic into
usbHsFsManagerInitializeSXOSDriverResources()andusbHsFsManagerCloseSXOSDriverResources(). - Move NTFS/EXT debug logging configuration logic into
usbHsFsManagerSetupFileSystemDriverLogging(). - Rename
usbHsFsCreateDriveManagerThread()tousbHsFsManagerCreateBackgroundThread(). - Rename
usbHsFsCloseDriveManagerThread()tousbHsFsManagerDestroyBackgroundThread(). - Rename
usbHsFsDriveManagerThreadFuncAtmosphere()tousbHsFsManagerAtmosphereThreadFunc(). - Rename
usbHsFsDriveManagerThreadFuncSXOS()tousbHsFsManagerSXOSThreadFunc(). - Rename
usbHsFsResetDrives()tousbHsFsManagerResetMassStorageDevices(). - Refactor
usbHsFsUpdateDriveContexts()intousbHsFsManagerAddConnectedDriveContexts(). - Rename
usbHsFsAddDriveContextToList()tousbHsFsManagerInitializeAndAddDriveContextToList(). - Move drive initialization logic from
usbHsFsUpdateDriveContexts()intousbHsFsManagerInitializeAndAddDriveContextToList(). - Add
usbHsFsManagerRemoveDisconnectedDriveContexts(). - Rename
usbHsFsRemoveDriveContextFromListByIndex()tousbHsFsManagerRemoveDriveContextFromListByIndex(). - Rename
usbHsFsPopulateDeviceList()tousbHsFsManagerPopulateDeviceList(). - Rename
usbHsFsExecutePopulateCallback()tousbHsFsManagerExecutePopulateCallback(). - Rename
usbHsFsFillDeviceElement()tousbHsFsManagerFillDeviceElement().
- Remove
- usbhsfs_mount:
- Define new macros for all the constants used throughout the compilation unit.
- Remove padding from the
GuidPartitionTableHeaderstruct to bring the size down to0x5C, which actually matches the contents of itsheader_sizefield. - Move MBR partition entry parsing logic into
usbHsFsMountParseMasterBootRecordPartitionEntry(). - Move GPT header parsing logic into
usbHsFsMountGetGuidPartitionTableHeader(). - Move GPT entry parsing logic into
usbHsFsMountParseGuidPartitionTableEntry(). - Refactor
usbHsFsMountRegisterVolume()intousbHsFsMountInitializeLogicalUnitFileSystemContext(). - Move LUN FS deinitialization logic into
usbHsFsMountDestroyLogicalUnitFileSystemContext(). - Update
usbHsFsMountRegisterDevoptabDevice()to take in a pointer to a devoptab interface. - Move devoptab device unregistration logic into
usbHsFsMountUnregisterDevoptabDevice().
- usbhsfs_request:
- Use
usbHsFsUtilsAlignedAlloc()instead ofmemalign().
- Use
- usbhsfs_scsi:
- Update to reflect the changes in the rest of the codebase.
- usbhsfs_utils:
- Add
ALIGN_UP,IS_ALIGNED,IS_POWER_OF_TWO,MAX_ELEMENTS,SCOPED_LOCK_BASE,SCOPED_RLOCKandUTF8_MAX_CODEPOINT_SIZEmacros. - Update
SCOPED_LOCKmacro to rely on the newSCOPED_LOCK_BASEmacro. - Add
UsbHsFsUtilsScopedRecursiveLockstruct. - Add
usbHsFsUtilsAlignedAlloc(). - Rename
usbHsFsUtilsLockScope()tousbHsFsUtilsAcquireScopedLock(). - Rename
usbHsFsUtilsUnlockScope()tousbHsFsUtilsReleaseScopedLock(). - Add
usbHsFsUtilsAcquireScopedRecursiveLock(). - Add
usbHsFsUtilsReleaseScopedRecursiveLock().
- Add
Resources from this release:
libusbhsfs_0.2.10-main-3b897ed-src.tar.bz2: full libusbhsfs source code.libusbhsfs_0.2.10-main-3b897ed_ISC.tar.bz2: ISC licensed build of libusbhsfs. Only offers support for FAT filesystems (FAT12, FAT16, FAT32, exFAT).libusbhsfs_0.2.10-main-3b897ed_GPLv2+.tar.bz2: GPLv2+ licensed build of libusbhsfs. Offers support for FAT filesystems (FAT12, FAT16, FAT32, exFAT), NTFS and EXT filesystems (EXT2, EXT3, EXT4). Applications using this build must also be linked against NTFS-3G and lwext4 - please check the README for further information.
Both ISC and GPLv2+ archives also hold the example test application NRO linked against that version of the library with debugging enabled.
EDIT 2025-12-06 00:23 UTC+1: resources were updated to fix some minor issues in NTFS path normalization, please redownload.