Releases: Dev00113/ioFTPD
v7.10.1
ioFTPD v7.10.1
Release date: 2026‑04‑20
This release delivers stability fixes targeting crash scenarios found in production, expands the process virtual address space to 4 GB, and adds git‑stamped version strings to every build.
Crash Fixes
NULL dereference in UserFile/GroupFile Write callbacks
TCL bots that call userfile open / userfile unlock (or equivalent group file operations) before a user has ever logged in could crash the daemon with an access violation.
lpInternal is intentionally NULL in the shared user/group file copy until the first FTP login opens a real file handle via User_StandardOpen. All Write callbacks (User_StandardWrite, User_Default_Write, Group_StandardWrite, Group_Default_Write, Group_Register) previously dereferenced lpInternal unconditionally.
All callbacks now open the file on demand when lpInternal is NULL and proceed with the write, matching the recovery pattern already present in User_Default_Write. This eliminates crashes on sites where a bot performs file operations before any user has authenticated.
Access violation in ExecuteAsync for non‑FTP events
ioFTPD crashed with 0xC0000005 EXCEPTION_ACCESS_VIOLATION when the scheduler or a TCL‑triggered event fired outside of an active FTP session.
The cleanup path in ExecuteAsync called LockClient(dwCID) unconditionally. When there is no FTP client, dwCID is (DWORD)-1 (0xFFFFFFFF). Indexing lpClientArray[-1] returned a garbage pointer that passed the NULL check and was then dereferenced, crashing the daemon.
LockClient / UnlockClient are now skipped when dwCID == (DWORD)-1.
TCL panic falling through to INT3 breakpoint
A heap allocation failure inside TCL (e.g. TclAllocElemsEx returning NULL) calls Tcl_Panic, which invokes the registered panic handler. The previous handler returned normally; the compiler‑inserted INT3 padding bytes after the call site then caused an 0x80000003 EXCEPTION_BREAKPOINT crash with no diagnostic information.
The panic handler (IoFTPD_TclPanicProc) now:
- Writes a timestamped entry to
ioFTPD_panic.login thesystem\directory - Outputs the message to the debugger via
OutputDebugStringA - Calls
ExitProcess(1)— it never returns
Improvements
4 GB virtual address space
ioFTPD is now built with LARGEADDRESSAWARE, allowing the 32‑bit process to address up to ~3.8 GB of virtual memory on 64‑bit Windows. Previously the limit was 2 GB.
Git‑stamped version string
Every build now embeds the git commit count and short hash in the version string: 7.10.1.72-0ad5fdd
The format is Major.Minor.Patch.Build-hash, where Build is the monotonically increasing git rev-list --count HEAD. A -dirty suffix is appended when the working tree has uncommitted changes.
The version string appears in:
- Startup log
SITE IOVERSION- Crash log header (
crash_YYYYMMDD_HHMMSS.dmp) io versionTCL command
Builds from a source zip (no git history) fall back to 7.10.1.0-unknown.
Upgrading from v7.10.0
No configuration changes are required.
User and group file formats are unchanged.
All changes are either fixes or opt‑in improvements.
Replace ioFTPD.exe (and ioFTPD.map if you use crash analysis) in your system\ directory. No other files need to change.
v7.10.0
ioFTPD v7.10.0
Release date: 2026‑03‑03
This release introduces full long‑path support across all FTP operations, modern certificate‑generation options (RSA/ECDSA), and several important fixes to improve reliability on deep directory structures, UNC paths, and Windows long‑path environments.
Long‑Path Support
ioFTPD now supports files and directories whose absolute path exceeds the legacy 260‑character MAX_PATH limit, on:
- Windows 10 build 14393 (v1607) or later
- Windows Server 2016 or later
All FTP operations now work correctly on long paths:
- Upload (STOR / APPE)
- Download (RETR)
- Delete (DELE / RMD)
- Rename / Move (RNFR / RNTO)
- Make directory (MKD)
- Directory listing (LIST / MLSD / STAT)
- Metadata operations (SIZE / MDTM / MLST)
User and group file formats are unchanged; no migration is required.
Requirements
All three conditions must be met:
- OS: Windows 10 build 14393+ or Windows Server 2016+
- Registry:
HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled = 1
- This build of ioFTPD, which includes an embedded
longPathAwaremanifest
Configuration
A new INI key controls long‑path behavior:
[FTP]
Long_Path_Support = Auto ; Auto (default), On, or Off
- Auto — Detects OS support at startup and logs the result
- On — Forces long‑path mode (requires registry key)
- Off — Disables long‑path support and reverts to MAX_PATH behavior
Backend Support Matrix
| Backend | Status | Notes |
|---|---|---|
| Local NTFS | Full support | Deepest and most reliable long‑path behavior |
| Mapped drive | Full support | Windows resolves UNC before ioFTPD sees it |
| UNC / SMB | Partial | SMB servers impose their own limits (typically 1–4 KB) and often reject before NTFS would |
When a path is too long, ioFTPD now returns a consistent error:
550 <path>: Path too long for NTFS.
This replaces older, inconsistent messages such as Invalid filename.
Configurable Certificate Type for MAKECERT
A new per‑service INI key controls which key algorithm is used when ioFTPD auto‑generates a TLS certificate (either at startup or via SITE MAKECERT):
[FTP_Service]
Certificate_Type = RSA ; RSA (default) or ECDSA
Supported Algorithms
| Value | Key Size | Notes |
|---|---|---|
| RSA | 2048‑bit | Default. Maximum compatibility with all FTP clients. |
| ECDSA | P‑256 | Smaller keys, faster handshakes. Recommended for new deployments. |
Unrecognized values fall back to RSA and log a warning.
The selected algorithm is logged and displayed in the FTP response when using SITE MAKECERT.
Fixes
RMD incorrectly returned “550 Directory not empty”
Directories containing only the internal .ioFTPD permissions file could not be removed on long paths because deletion of .ioFTPD silently failed.
This is now fixed.
Consistent “550 Path too long for NTFS.” reply
Previously, long‑path failures could return:
Invalid filename- OS‑dependent error messages
- Any of four Windows error codes:
ERROR_FILENAME_EXCED_RANGE,ERROR_INVALID_NAME,ERROR_PATH_NOT_FOUND,ERROR_FILE_NOT_FOUND
All six long‑path wrappers now normalize these into a single consistent FTP reply across:
STOR, APPE, RETR, DELE, RMD, MKD, RNFR, RNTO, MDTM, SIZE, MLST.
IoRemoveReparsePoint error handling
A failed FSCTL call followed by CloseHandle clobbered GetLastError(), causing silent failures.
Error propagation is now correct and logged.
Upgrading from v7.9.0
No configuration changes are required.
All new features are opt‑in via INI keys.
Binary compatibility with existing user and group files is maintained.
To enable long‑path support, set the Windows registry key and restart:
reg add "HKLM\SYSTEM\CurrentControlSet\Control\FileSystem" /v LongPathsEnabled /t REG_DWORD /d 1 /f
v7.9.0
Release Highlights
Required:
- Visual C++ 2015–2022 Redistributable (x86) — https://aka.ms/vc14/vc_redist.x86.exe
- Windows Vista or higher
New Features
- Added MLST/MLSD commands (RFC 3659) — structured directory listings with standardized fact sets for modern FTP clients.
Security & Libraries
- OpenSSL upgraded: 1.0.x → 3.6.1 with full TLS 1.3 and ECDHE support
- Tcl upgraded: 8.5.9 → 9.0.2 (no source patches required)
- New INI options:
OpenSSL_SecurityLevel,OpenSSL_Ciphers13,OpenSSL_Groups - Updated MAKECERT: now generates a 2048‑bit RSA key, uses SHA‑256, includes modern X.509 extensions, and uses OpenSSL 3.x EVP APIs
Stability / Race Conditions
- Fixed use-after-free race between
ioCloseSocketand in-flight TLS IOCP callbacks - Fixed use-after-free race between
ioCloseSocketand in-flightReceiveLineIOCP callbacks - Fixed use-after-free race between
ioCloseSocketandSendQuickComplete+hEventclose - Fixed
UnregisterWaitEx(NULL)returningINVALID_HANDLE_VALUE— now blocks until dispatched callbacks finish - Fixed timer/
TransmitFilerace:InterlockedExchange+CloseSocketgate prevents double-complete
Memory Safety
- Fixed 21
ULONG→ULONG_PTRpointer truncation sites in the custom bucket allocator - Fixed
tolower()/toupper()undefined behaviour on signed char values ≥ 0x80 in all path comparators - Fixed pointer truncation in transfer‑rate structure initialization (
SocketAPI.c)
Bug Fixes
- Fixed OpenSSL legacy provider failing silently on deployment — path now resolved relative to exe at runtime
- Fixed garbled log output when printing narrow (
char*) filenames in Unicode build - Fixed XCRC direction inversion
- Fixed 49‑day idle‑time wrap
- Fixed FXP passive‑mode compatibility
- Fixed MAKECERT buffer overrun