Skip to content

Commit 49101da

Browse files
fix: harden Ext2Mgr mount assigns and Ext2Srv pipe accept
Prevent Ext2Mgr Session Manager assigns from crashing on non-EXT volumes (MountPoints.cpp). Speed Ext2Srv named-pipe accept with dual idle listeners, softer create retries, and no WRITE_THROUGH. Document those changes in Ext2Mgr/IMPROVEMENTS.md and the root README. Drop the January .gitignore entries for docs/ and Ext4Fsd.sln.
1 parent 1846b3a commit 49101da

5 files changed

Lines changed: 152 additions & 15 deletions

File tree

.gitignore

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,3 @@ Release/
44
*.vcxproj.user
55
Ext2Fsd-setup.exe
66
*/cab/
7-
8-
# Local docs (moved from root); keep out of version control
9-
docs/
10-
11-
# Solution file can be machine-specific; remove from .gitignore to track it
12-
Ext4Fsd.sln

Ext2Mgr/IMPROVEMENTS.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Ext2Mgr / Ext2Srv — classic stack improvements
2+
3+
Fixes and service changes that apply to the **regular** MFC **Ext2 Volume Manager** (`Ext2Mgr/`) and/or **Ext2Srv**, independent of the Iced port.
4+
5+
Rebuild Ext2Mgr / reinstall Ext2Srv (`Scripts\build.ps1`, `Scripts\install_driver.ps1`) to pick these up. Optional Iced GUI comparisons live on the `ext2mgr-iced` branch under `ext2mgr_iced/PORT_IMPROVEMENTS.md`.
6+
7+
---
8+
9+
## Ext2Mgr (`Ext2Mgr/`)
10+
11+
### Change Drive Letters — crash on non-EXT / Session Manager
12+
13+
**Symptom:** Choosing **Session Manager DOS Devices** (or temporary DOS devices) for an NTFS/FAT partition could crash Ext2Mgr.
14+
15+
**Cause:** `CMountPoints::AddMountPoint` in `MountPoints.cpp`:
16+
17+
1. On successful Session Manager registry write it called `EndDialog(0)` **without returning**, so execution continued.
18+
2. It always ran `Ext2QueryExt2Property(Handle, EVP)` to store Ext2Fsd automount properties.
19+
3. For a **partition-selected** native volume, `EVP` stayed **NULL** (only set from `m_Volume` or an EXT `m_Part->Volume` branch) → null dereference.
20+
21+
**Fix:**
22+
23+
- `return TRUE` immediately after a successful Session Manager assign + `EndDialog`.
24+
- If `EVP` is NULL, **skip** the Ext2 property IOCTL path and only assign the DOS letter (`Ext2AssignDrvLetter`), then update letter masks / notify.
25+
26+
**Note:** Classic assign remains `DefineDosDevice` to `\Device\HarddiskVolumeN` (same path Session Manager uses). This fix is **crash safety** only.
27+
28+
---
29+
30+
## Ext2Srv (`Ext2Srv/`)
31+
32+
These pipe-server changes help **both** Ext2Mgr and `ext2mgr_iced` (temporary EXT letter ops via `\\.\pipe\EXT2MGR_PSRV`).
33+
34+
| Change | File | What |
35+
|--------|------|------|
36+
| Dual idle pipe listeners | `Ext2Pipe.cpp` (`Ext2StartPipeSrv`) | Second `Ext2PipeEngine` thread so reconnect / overlap rarely hits `ERROR_PIPE_BUSY` |
37+
| Soft create retries | `Ext2Pipe.cpp` (`Ext2PipeEngine`) | Cap create failures at 3×50ms (+ short sleep) instead of long backoff storms |
38+
| No `FILE_FLAG_WRITE_THROUGH` | `Ext2Pipe.cpp` (`Ext2CreatePipe`) | Dropped on tiny IPC messages; measured after reinstall (2026-07-28): cold connect median ~0.7 ms, burst reconnect ~0.2 ms, `QUERY_DRV` ~0.1 ms (query-only probe) |
39+
40+
---
41+
42+
## Intentionally not changed here
43+
44+
| Topic | Status |
45+
|-------|--------|
46+
| Mount Manager for NTFS in classic Ext2Mgr | Not needed for Explorer when Session Manager / DosDevice targets `\Device\HarddiskVolumeN`. Classic UI still forces DosDev (`#if TRUE` in `MountPoints.cpp`). |
47+
| EXT-only “Assign Drive Letter” gating | Iced-only (classic still offers assign more broadly and can wait on Ext2Srv). |
48+
| Dead-letter detection breadth | Iced lists more orphans; classic logic unchanged. |
49+
50+
---
51+
52+
## Related docs
53+
54+
- [`../README.md`](../README.md) — fork build/install scripts and driver changelog
55+
- `ext2mgr_iced/` on branch `ext2mgr-iced` — optional Iced GUI port

Ext2Mgr/MountPoints.cpp

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ CMountPoints::AddMountPoint(
123123
if (Ext2SetRegistryMountPoint(&drvChar, devPath, bRegistry)) {
124124
Ext2AssignDrvLetter(drvLetter, devPath, FALSE);
125125
EndDialog(0);
126+
return TRUE;
126127
} else {
127128
str.Format("Failed to modify registry: SYSTEM\\CurrentControlSet\\Control\\Session Manager\\DOS Devices\n");
128129
AfxMessageBox(str, MB_OK|MB_ICONWARNING);
@@ -152,7 +153,42 @@ CMountPoints::AddMountPoint(
152153
}
153154
}
154155

155-
/* create an entry in regisgtry */
156+
/* Ext2 property IOCTL — only for EXT volumes (EVP non-NULL).
157+
NTFS/FAT hit this path via Change Drive Letters and used to crash
158+
on Ext2QueryExt2Property(NULL). Assign the DOS letter only. */
159+
if (!EVP) {
160+
rc = Ext2AssignDrvLetter(drvLetter, devPath, bMountMgr);
161+
if (!rc && !bMountMgr) {
162+
CString str;
163+
str.Format("Failed to assign new drive letter %c:\n", drvChar);
164+
AfxMessageBox(str, MB_OK|MB_ICONWARNING);
165+
return FALSE;
166+
}
167+
if (rc) {
168+
m_bUpdated = TRUE;
169+
if (m_Part) {
170+
m_Part->DrvLetters |= letterMask;
171+
if (m_Part->Volume) {
172+
m_Part->Volume->DrvLetters |= letterMask;
173+
}
174+
InitializeList(m_Part->DrvLetters);
175+
}
176+
if (m_Volume) {
177+
m_Volume->DrvLetters |= letterMask;
178+
InitializeList(m_Volume->DrvLetters);
179+
}
180+
if (m_Cdrom) {
181+
m_Cdrom->DrvLetters |= letterMask;
182+
InitializeList(m_Cdrom->DrvLetters);
183+
}
184+
m_MainDlg->SendMessage(
185+
WM_MOUNTPOINT_NOTIFY,
186+
'DA', (LPARAM)drvLetter->Letter);
187+
}
188+
return rc;
189+
}
190+
191+
/* create an entry in registry (EXT only) */
156192
{
157193

158194
NT::NTSTATUS status;

Ext2Srv/Ext2Pipe.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ Ext2CreatePipe()
151151

152152
sa = Ext2CreateSA();
153153

154-
ap->p = CreateNamedPipe( _T(EXT2_MGR_SRV), PIPE_ACCESS_DUPLEX |
155-
FILE_FLAG_WRITE_THROUGH /* | ACCESS_SYSTEM_SECURITY */,
154+
ap->p = CreateNamedPipe( _T(EXT2_MGR_SRV), PIPE_ACCESS_DUPLEX,
155+
/* no WRITE_THROUGH: tiny IPC messages; measure if needed */
156156
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
157157
PIPE_WAIT /* PIPE_REJECT_REMOTE_CLIENTS */ ,
158158
PIPE_UNLIMITED_INSTANCES,
@@ -429,21 +429,23 @@ Ext2PipeEngine(VOID *arg)
429429
/* create named pipe */
430430
ap = Ext2CreatePipe();
431431
if (NULL == ap) {
432-
if (times++ < 10) {
433-
Sleep(250 * times);
432+
if (times++ < 3) {
433+
Sleep(50);
434434
goto retry;
435435
}
436+
Sleep(100);
436437
continue;
437438
}
438439

439440
/* ASSD_PIPE is valid or not */
440441
if (!ap->p || ap->p == INVALID_HANDLE_VALUE ||
441442
!ap->e || ap->e == INVALID_HANDLE_VALUE) {
442443
Ext2DestroyPipe(ap);
443-
if (times++ < 10) {
444-
Sleep(500);
444+
if (times++ < 3) {
445+
Sleep(50);
445446
goto retry;
446447
}
448+
Sleep(100);
447449
continue;
448450
}
449451

@@ -498,6 +500,9 @@ DWORD Ext2StartPipeSrv()
498500
rc = WaitForSingleObject(g_wait, 1000*1);
499501
} while (rc == WAIT_TIMEOUT);
500502

503+
/* Second idle listener so a reconnect/overlap rarely hits PIPE_BUSY. */
504+
_beginthread(Ext2PipeEngine, 0, NULL);
505+
501506
return 0;
502507
}
503508

README.md

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
Scripts and building from source (this fork)
2+
--------------------------------------------
3+
4+
This fork adds PowerShell scripts for building, installing, signing, and diagnosing the driver. All scripts live in **Scripts/**. Run them from the repo root, e.g. `.\Scripts\build.ps1`.
5+
6+
**Build and install**
7+
- **Scripts\build.ps1** — Build driver, Ext2Srv, Ext2Mgr (requires Visual Studio 2019/2022 and WDK for the driver). Optionally signs the driver if `EXT4FSD_CERT_PATH` is set. Ext2Mgr vendors a small `Ext2Mgr/mountmgr.h`, so the manager app can be built without installing the full WDK.
8+
- **Scripts\install_driver.ps1** — Copy driver to System32, register kernel driver, install Ext2Srv. Run as Administrator.
9+
- **Scripts\uninstall_driver.ps1** — Remove driver and services.
10+
- **Scripts\register_driver.ps1** — Register the kernel driver service (driver must already be in System32).
11+
- **Scripts\disable_driver.ps1** — Disable the Ext2Fsd service (e.g. to stop boot retries after signature failures).
12+
13+
**Signing**
14+
- **Scripts\sign_driver.ps1** — Sign the driver with a code-signing certificate. Set `EXT4FSD_CERT_PATH` and optionally `MSIX_CERT_PASSWORD`, or pass `-CertificatePath` / `-CertificatePassword`.
15+
- **Scripts\install_certificate.ps1** — Install the signing certificate into Trusted Publishers (required for loading self-signed drivers). Run as Administrator.
16+
17+
**Diagnostics**
18+
- **Scripts\diagnose_ext2fsd.ps1** — Unified diagnostic (signature, cert stores, event log, driver status). Use for load failures or error 577. Use `-UseSigntool:$false` to skip signtool (e.g. when SDK is not installed).
19+
- **Scripts\check_driver_load_error.ps1**, **Scripts\diagnose_error_577.ps1**, **Scripts\verify_driver_signature.ps1** — Wrappers that call `diagnose_ext2fsd.ps1`.
20+
21+
**Other**
22+
- **Scripts\fix_sdk_version.ps1** — Update project files' `WindowsTargetPlatformVersion` to match the installed SDK.
23+
124

225
Latest release
326
--------------
@@ -50,6 +73,16 @@ Changes to the source code in git after latest release
5073
- The fields s_wtime and s_wtime_hi in the superblock will be
5174
updated with the current time at shutdown.
5275

76+
- Timeouts on block/PnP/fsctl waits so surprise-removal of USB
77+
or other removable ext4 volumes no longer hangs the system
78+
waiting forever for I/O that will never complete.
79+
80+
- Corrected the wait argument to CcCopyRead / CcCopyWrite and
81+
simplified the related read/write paths.
82+
83+
- Filesystems with EXT4_FEATURE_INCOMPAT_CASEFOLD can be mounted
84+
(the feature bit is treated as supported).
85+
5386
Application:
5487

5588
- If an on disk filesystem contains new ext4 features that is
@@ -66,6 +99,16 @@ Changes to the source code in git after latest release
6699
- The donate dialog box is disabled because the information in
67100
it is outdated.
68101

102+
- High-DPI awareness is disabled in the Ext2Mgr project so the
103+
classic Win32 UI scales more predictably on high-resolution
104+
monitors.
105+
106+
- Ext2Mgr includes a subset of mountmgr.h so the application can
107+
be compiled without installing the Windows Driver Kit.
108+
109+
- Fork manager notes (this tree): Ext2Mgr/IMPROVEMENTS.md covers
110+
classic Ext2Mgr crash fixes and Ext2Srv pipe speedups.
111+
69112

70113
About
71114
-----
@@ -172,5 +215,9 @@ Unsupported Ext4 Features
172215
2, EXT4_FEATURE_INCOMPAT_MMP (multiple mount protection)
173216
3, EXT4_FEATURE_INCOMPAT_INLINE_DATA (storing small files in inode)
174217
4, EXT4_FEATURE_INCOMPAT_ENCRYPT
175-
5, EXT4_FEATURE_INCOMPAT_CASEFOLD (case insensitive file names (claimed to be used by SteamOS as default))
176-
6, EXT4_FEATURE_INCOMPAT_LARGEDIR (3-level htree)
218+
5, EXT4_FEATURE_INCOMPAT_LARGEDIR (3-level htree)
219+
220+
Note: EXT4_FEATURE_INCOMPAT_CASEFOLD is no longer in this list;
221+
the driver accepts that incompat bit so casefolded volumes can
222+
be mounted. Full case-insensitive name matching semantics may
223+
still be incomplete compared to Linux.

0 commit comments

Comments
 (0)