diff --git a/Ext2Mgr/Ext2Mgr.vcxproj b/Ext2Mgr/Ext2Mgr.vcxproj index 6f57299..896c7e8 100644 --- a/Ext2Mgr/Ext2Mgr.vcxproj +++ b/Ext2Mgr/Ext2Mgr.vcxproj @@ -1,431 +1,432 @@ - - - - - Debug - ARM - - - Debug - ARM64 - - - Debug - Win32 - - - Release - ARM - - - Release - ARM64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {E1AF85D7-0179-4CF0-B0D1-21AE72B6DC2E} - Ext2Mgr - 10.0 - - - - Application - true - v143 - MultiByte - Dynamic - - - Application - true - v143 - MultiByte - Dynamic - - - Application - false - v143 - true - MultiByte - Dynamic - - - Application - false - v143 - true - MultiByte - Dynamic - - - Application - true - v143 - MultiByte - Dynamic - - - Application - true - v143 - MultiByte - Dynamic - - - Application - false - v143 - true - MultiByte - Dynamic - - - Application - false - v143 - true - MultiByte - Dynamic - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Ext2Mgr - $(SolutionDir)Ext2Mgr\$(Configuration)\x86\ - $(Configuration)\x86\ - - - Ext2Mgr - $(SolutionDir)Ext2Mgr\$(Configuration)\arm\ - $(Configuration)\arm\ - - - Ext2Mgr - $(SolutionDir)Ext2Mgr\$(Configuration)\x86\ - $(Configuration)\x86\ - - - Ext2Mgr - $(SolutionDir)Ext2Mgr\$(Configuration)\arm\ - $(Configuration)\arm\ - - - Ext2Mgr - $(SolutionDir)Ext2Mgr\$(Configuration)\x64\ - $(Configuration)\x64\ - - - Ext2Mgr - $(SolutionDir)Ext2Mgr\$(Configuration)\arm64\ - $(Configuration)\arm64\ - - - Ext2Mgr - $(SolutionDir)Ext2Mgr\$(Configuration)\x64\ - $(Configuration)\x64\ - - - Ext2Mgr - $(SolutionDir)Ext2Mgr\$(Configuration)\arm64\ - $(Configuration)\arm64\ - - - - Level3 - Disabled - true - true - /Zc:strictStrings- %(AdditionalOptions) - _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) - 4996;4703;%(DisableSpecificWarnings) - $(UM_IncludePath)\..\km;%(AdditionalIncludeDirectories) - - - Windows - ntdll.lib;setupapi.lib;%(AdditionalDependencies) - RequireAdministrator - - - $(SolutionDir)Ext2Srv\$(Configuration)\x86;%(AdditionalIncludeDirectories) - - - false - - - - - Level3 - Disabled - true - true - /Zc:strictStrings- %(AdditionalOptions) - _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) - 4996;4703;%(DisableSpecificWarnings) - $(UM_IncludePath)\..\km;%(AdditionalIncludeDirectories) - - - Windows - ntdll.lib;setupapi.lib;%(AdditionalDependencies) - RequireAdministrator - - - $(SolutionDir)Ext2Srv\$(Configuration)\arm;%(AdditionalIncludeDirectories) - - - false - - - - - Level3 - Disabled - true - true - /Zc:strictStrings- %(AdditionalOptions) - _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) - 4996;4703;%(DisableSpecificWarnings) - $(UM_IncludePath)\..\km;%(AdditionalIncludeDirectories) - - - Windows - ntdll.lib;setupapi.lib;%(AdditionalDependencies) - RequireAdministrator - - - $(SolutionDir)Ext2Srv\$(Configuration)\x64;%(AdditionalIncludeDirectories) - - - false - - - - - Level3 - Disabled - true - true - /Zc:strictStrings- %(AdditionalOptions) - _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) - 4996;4703;%(DisableSpecificWarnings) - $(UM_IncludePath)\..\km;%(AdditionalIncludeDirectories) - - - Windows - ntdll.lib;setupapi.lib;%(AdditionalDependencies) - RequireAdministrator - - - $(SolutionDir)Ext2Srv\$(Configuration)\arm64;%(AdditionalIncludeDirectories) - - - false - - - - - Level3 - MaxSpeed - true - true - true - true - /Zc:strictStrings- %(AdditionalOptions) - _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) - 4996;4703;%(DisableSpecificWarnings) - $(UM_IncludePath)\..\km;%(AdditionalIncludeDirectories) - - - true - true - Windows - ntdll.lib;setupapi.lib;%(AdditionalDependencies) - RequireAdministrator - - - $(SolutionDir)Ext2Srv\$(Configuration)\x86;%(AdditionalIncludeDirectories) - - - false - - - - - Level3 - MaxSpeed - true - true - true - true - /Zc:strictStrings- %(AdditionalOptions) - _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) - 4996;4703;%(DisableSpecificWarnings) - $(UM_IncludePath)\..\km;%(AdditionalIncludeDirectories) - - - true - true - Windows - ntdll.lib;setupapi.lib;%(AdditionalDependencies) - RequireAdministrator - - - $(SolutionDir)Ext2Srv\$(Configuration)\arm;%(AdditionalIncludeDirectories) - - - false - - - - - Level3 - MaxSpeed - true - true - true - true - /Zc:strictStrings- %(AdditionalOptions) - _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) - 4996;4703;%(DisableSpecificWarnings) - $(UM_IncludePath)\..\km;%(AdditionalIncludeDirectories) - - - true - true - Windows - ntdll.lib;setupapi.lib;%(AdditionalDependencies) - RequireAdministrator - - - $(SolutionDir)Ext2Srv\$(Configuration)\x64;%(AdditionalIncludeDirectories) - - - false - - - - - Level3 - MaxSpeed - true - true - true - true - /Zc:strictStrings- %(AdditionalOptions) - _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) - 4996;4703;%(DisableSpecificWarnings) - $(UM_IncludePath)\..\km;%(AdditionalIncludeDirectories) - - - true - true - Windows - ntdll.lib;setupapi.lib;%(AdditionalDependencies) - RequireAdministrator - - - $(SolutionDir)Ext2Srv\$(Configuration)\arm64;%(AdditionalIncludeDirectories) - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {E1AF85D7-0179-4CF0-B0D1-21AE72B6DC2E} + Ext2Mgr + 10.0 + Spectre + + + + Application + true + v143 + MultiByte + Dynamic + + + Application + true + v143 + MultiByte + Dynamic + + + Application + false + v143 + true + MultiByte + Dynamic + + + Application + false + v143 + true + MultiByte + Dynamic + + + Application + true + v143 + MultiByte + Dynamic + + + Application + true + v143 + MultiByte + Dynamic + + + Application + false + v143 + true + MultiByte + Dynamic + + + Application + false + v143 + true + MultiByte + Dynamic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Ext2Mgr + $(SolutionDir)Ext2Mgr\$(Configuration)\x86\ + $(Configuration)\x86\ + + + Ext2Mgr + $(SolutionDir)Ext2Mgr\$(Configuration)\arm\ + $(Configuration)\arm\ + + + Ext2Mgr + $(SolutionDir)Ext2Mgr\$(Configuration)\x86\ + $(Configuration)\x86\ + + + Ext2Mgr + $(SolutionDir)Ext2Mgr\$(Configuration)\arm\ + $(Configuration)\arm\ + + + Ext2Mgr + $(SolutionDir)Ext2Mgr\$(Configuration)\x64\ + $(Configuration)\x64\ + + + Ext2Mgr + $(SolutionDir)Ext2Mgr\$(Configuration)\arm64\ + $(Configuration)\arm64\ + + + Ext2Mgr + $(SolutionDir)Ext2Mgr\$(Configuration)\x64\ + $(Configuration)\x64\ + + + Ext2Mgr + $(SolutionDir)Ext2Mgr\$(Configuration)\arm64\ + $(Configuration)\arm64\ + + + + Level3 + Disabled + true + true + /Zc:strictStrings- %(AdditionalOptions) + _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) + 4996;4703;%(DisableSpecificWarnings) + $(UM_IncludePath)\..\km;%(AdditionalIncludeDirectories) + + + Windows + ntdll.lib;setupapi.lib;%(AdditionalDependencies) + RequireAdministrator + + + $(SolutionDir)Ext2Srv\$(Configuration)\x86;%(AdditionalIncludeDirectories) + + + false + + + + + Level3 + Disabled + true + true + /Zc:strictStrings- %(AdditionalOptions) + _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) + 4996;4703;%(DisableSpecificWarnings) + $(UM_IncludePath)\..\km;%(AdditionalIncludeDirectories) + + + Windows + ntdll.lib;setupapi.lib;%(AdditionalDependencies) + RequireAdministrator + + + $(SolutionDir)Ext2Srv\$(Configuration)\arm;%(AdditionalIncludeDirectories) + + + false + + + + + Level3 + Disabled + true + true + /Zc:strictStrings- %(AdditionalOptions) + _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) + 4996;4703;%(DisableSpecificWarnings) + $(UM_IncludePath)\..\km;%(AdditionalIncludeDirectories) + + + Windows + ntdll.lib;setupapi.lib;%(AdditionalDependencies) + RequireAdministrator + + + $(SolutionDir)Ext2Srv\$(Configuration)\x64;%(AdditionalIncludeDirectories) + + + false + + + + + Level3 + Disabled + true + true + /Zc:strictStrings- %(AdditionalOptions) + _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) + 4996;4703;%(DisableSpecificWarnings) + $(UM_IncludePath)\..\km;%(AdditionalIncludeDirectories) + + + Windows + ntdll.lib;setupapi.lib;%(AdditionalDependencies) + RequireAdministrator + + + $(SolutionDir)Ext2Srv\$(Configuration)\arm64;%(AdditionalIncludeDirectories) + + + false + + + + + Level3 + MaxSpeed + true + true + true + true + /Zc:strictStrings- %(AdditionalOptions) + _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) + 4996;4703;%(DisableSpecificWarnings) + $(UM_IncludePath)\..\km;%(AdditionalIncludeDirectories) + + + true + true + Windows + ntdll.lib;setupapi.lib;%(AdditionalDependencies) + RequireAdministrator + + + $(SolutionDir)Ext2Srv\$(Configuration)\x86;%(AdditionalIncludeDirectories) + + + false + + + + + Level3 + MaxSpeed + true + true + true + true + /Zc:strictStrings- %(AdditionalOptions) + _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) + 4996;4703;%(DisableSpecificWarnings) + $(UM_IncludePath)\..\km;%(AdditionalIncludeDirectories) + + + true + true + Windows + ntdll.lib;setupapi.lib;%(AdditionalDependencies) + RequireAdministrator + + + $(SolutionDir)Ext2Srv\$(Configuration)\arm;%(AdditionalIncludeDirectories) + + + false + + + + + Level3 + MaxSpeed + true + true + true + true + /Zc:strictStrings- %(AdditionalOptions) + _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) + 4996;4703;%(DisableSpecificWarnings) + $(UM_IncludePath)\..\km;%(AdditionalIncludeDirectories) + + + true + true + Windows + ntdll.lib;setupapi.lib;%(AdditionalDependencies) + RequireAdministrator + + + $(SolutionDir)Ext2Srv\$(Configuration)\x64;%(AdditionalIncludeDirectories) + + + false + + + + + Level3 + MaxSpeed + true + true + true + true + /Zc:strictStrings- %(AdditionalOptions) + _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) + 4996;4703;%(DisableSpecificWarnings) + $(UM_IncludePath)\..\km;%(AdditionalIncludeDirectories) + + + true + true + Windows + ntdll.lib;setupapi.lib;%(AdditionalDependencies) + RequireAdministrator + + + $(SolutionDir)Ext2Srv\$(Configuration)\arm64;%(AdditionalIncludeDirectories) + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Ext2Mgr/IMPROVEMENTS.md b/Ext2Mgr/IMPROVEMENTS.md new file mode 100644 index 0000000..bfc4a3b --- /dev/null +++ b/Ext2Mgr/IMPROVEMENTS.md @@ -0,0 +1,55 @@ +# Ext2Mgr / Ext2Srv — classic stack improvements + +Fixes and service changes that apply to the **regular** MFC **Ext2 Volume Manager** (`Ext2Mgr/`) and/or **Ext2Srv**, independent of the Iced port. + +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`. + +--- + +## Ext2Mgr (`Ext2Mgr/`) + +### Change Drive Letters — crash on non-EXT / Session Manager + +**Symptom:** Choosing **Session Manager DOS Devices** (or temporary DOS devices) for an NTFS/FAT partition could crash Ext2Mgr. + +**Cause:** `CMountPoints::AddMountPoint` in `MountPoints.cpp`: + +1. On successful Session Manager registry write it called `EndDialog(0)` **without returning**, so execution continued. +2. It always ran `Ext2QueryExt2Property(Handle, EVP)` to store Ext2Fsd automount properties. +3. For a **partition-selected** native volume, `EVP` stayed **NULL** (only set from `m_Volume` or an EXT `m_Part->Volume` branch) → null dereference. + +**Fix:** + +- `return TRUE` immediately after a successful Session Manager assign + `EndDialog`. +- If `EVP` is NULL, **skip** the Ext2 property IOCTL path and only assign the DOS letter (`Ext2AssignDrvLetter`), then update letter masks / notify. + +**Note:** Classic assign remains `DefineDosDevice` to `\Device\HarddiskVolumeN` (same path Session Manager uses). This fix is **crash safety** only. + +--- + +## Ext2Srv (`Ext2Srv/`) + +These pipe-server changes help **both** Ext2Mgr and `ext2mgr_iced` (temporary EXT letter ops via `\\.\pipe\EXT2MGR_PSRV`). + +| Change | File | What | +|--------|------|------| +| Dual idle pipe listeners | `Ext2Pipe.cpp` (`Ext2StartPipeSrv`) | Second `Ext2PipeEngine` thread so reconnect / overlap rarely hits `ERROR_PIPE_BUSY` | +| Soft create retries | `Ext2Pipe.cpp` (`Ext2PipeEngine`) | Cap create failures at 3×50ms (+ short sleep) instead of long backoff storms | +| 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) | + +--- + +## Intentionally not changed here + +| Topic | Status | +|-------|--------| +| 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`). | +| EXT-only “Assign Drive Letter” gating | Iced-only (classic still offers assign more broadly and can wait on Ext2Srv). | +| Dead-letter detection breadth | Iced lists more orphans; classic logic unchanged. | + +--- + +## Related docs + +- [`../README.md`](../README.md) — fork build/install scripts and driver changelog +- `ext2mgr_iced/` on branch `ext2mgr-iced` — optional Iced GUI port diff --git a/Ext2Mgr/MountPoints.cpp b/Ext2Mgr/MountPoints.cpp index 7bd393b..f92b5d5 100644 --- a/Ext2Mgr/MountPoints.cpp +++ b/Ext2Mgr/MountPoints.cpp @@ -123,6 +123,7 @@ CMountPoints::AddMountPoint( if (Ext2SetRegistryMountPoint(&drvChar, devPath, bRegistry)) { Ext2AssignDrvLetter(drvLetter, devPath, FALSE); EndDialog(0); + return TRUE; } else { str.Format("Failed to modify registry: SYSTEM\\CurrentControlSet\\Control\\Session Manager\\DOS Devices\n"); AfxMessageBox(str, MB_OK|MB_ICONWARNING); @@ -152,7 +153,42 @@ CMountPoints::AddMountPoint( } } - /* create an entry in regisgtry */ + /* Ext2 property IOCTL — only for EXT volumes (EVP non-NULL). + NTFS/FAT hit this path via Change Drive Letters and used to crash + on Ext2QueryExt2Property(NULL). Assign the DOS letter only. */ + if (!EVP) { + rc = Ext2AssignDrvLetter(drvLetter, devPath, bMountMgr); + if (!rc && !bMountMgr) { + CString str; + str.Format("Failed to assign new drive letter %c:\n", drvChar); + AfxMessageBox(str, MB_OK|MB_ICONWARNING); + return FALSE; + } + if (rc) { + m_bUpdated = TRUE; + if (m_Part) { + m_Part->DrvLetters |= letterMask; + if (m_Part->Volume) { + m_Part->Volume->DrvLetters |= letterMask; + } + InitializeList(m_Part->DrvLetters); + } + if (m_Volume) { + m_Volume->DrvLetters |= letterMask; + InitializeList(m_Volume->DrvLetters); + } + if (m_Cdrom) { + m_Cdrom->DrvLetters |= letterMask; + InitializeList(m_Cdrom->DrvLetters); + } + m_MainDlg->SendMessage( + WM_MOUNTPOINT_NOTIFY, + 'DA', (LPARAM)drvLetter->Letter); + } + return rc; + } + + /* create an entry in registry (EXT only) */ { NT::NTSTATUS status; diff --git a/Ext2Srv/Ext2Pipe.cpp b/Ext2Srv/Ext2Pipe.cpp index 3d3e971..ae99d7c 100644 --- a/Ext2Srv/Ext2Pipe.cpp +++ b/Ext2Srv/Ext2Pipe.cpp @@ -151,8 +151,8 @@ Ext2CreatePipe() sa = Ext2CreateSA(); - ap->p = CreateNamedPipe( _T(EXT2_MGR_SRV), PIPE_ACCESS_DUPLEX | - FILE_FLAG_WRITE_THROUGH /* | ACCESS_SYSTEM_SECURITY */, + ap->p = CreateNamedPipe( _T(EXT2_MGR_SRV), PIPE_ACCESS_DUPLEX, + /* no WRITE_THROUGH: tiny IPC messages; measure if needed */ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT /* PIPE_REJECT_REMOTE_CLIENTS */ , PIPE_UNLIMITED_INSTANCES, @@ -429,10 +429,11 @@ Ext2PipeEngine(VOID *arg) /* create named pipe */ ap = Ext2CreatePipe(); if (NULL == ap) { - if (times++ < 10) { - Sleep(250 * times); + if (times++ < 3) { + Sleep(50); goto retry; } + Sleep(100); continue; } @@ -440,10 +441,11 @@ Ext2PipeEngine(VOID *arg) if (!ap->p || ap->p == INVALID_HANDLE_VALUE || !ap->e || ap->e == INVALID_HANDLE_VALUE) { Ext2DestroyPipe(ap); - if (times++ < 10) { - Sleep(500); + if (times++ < 3) { + Sleep(50); goto retry; } + Sleep(100); continue; } @@ -498,6 +500,9 @@ DWORD Ext2StartPipeSrv() rc = WaitForSingleObject(g_wait, 1000*1); } while (rc == WAIT_TIMEOUT); + /* Second idle listener so a reconnect/overlap rarely hits PIPE_BUSY. */ + _beginthread(Ext2PipeEngine, 0, NULL); + return 0; } diff --git a/Ext2Srv/Ext2Srv.cpp b/Ext2Srv/Ext2Srv.cpp index 2658d02..ffc18ad 100644 --- a/Ext2Srv/Ext2Srv.cpp +++ b/Ext2Srv/Ext2Srv.cpp @@ -318,13 +318,14 @@ Ext2SetupService(BOOL bInstall) if (bInstall) { // now create service entry for Ext2Mgr + // Note: SERVICE_INTERACTIVE_PROCESS removed - interactive services are deprecated + // and don't work on modern Windows (can't create named pipes accessible to user sessions) hService = CreateService( hManager, // SCManager database _T("Ext2Srv"), // name of service _T("Ext2Fsd Service Manager"), // name to display SERVICE_ALL_ACCESS, // desired access - SERVICE_WIN32_OWN_PROCESS | // service type - SERVICE_INTERACTIVE_PROCESS, + SERVICE_WIN32_OWN_PROCESS, // service type (removed SERVICE_INTERACTIVE_PROCESS) SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type Target, // service's binary diff --git a/Ext2Srv/Ext2Srv.rc b/Ext2Srv/Ext2Srv.rc index 6ccd216..d640438 100644 --- a/Ext2Srv/Ext2Srv.rc +++ b/Ext2Srv/Ext2Srv.rc @@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,4,71,1 - PRODUCTVERSION 1,4,71,1 + FILEVERSION 1,4,71,2 + PRODUCTVERSION 1,4,71,2 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -85,12 +85,12 @@ BEGIN VALUE "Comments", "Bo Branten " VALUE "CompanyName", "Ext2Fsd Group (www.ext2fsd.com)" VALUE "FileDescription", "Ext2Fsd Service" - VALUE "FileVersion", "1.4.71.1" + VALUE "FileVersion", "1.4.71.2" VALUE "InternalName", "Ext2Srv" VALUE "LegalCopyright", "Copyright (C) 2002-2017 Matt Wu " VALUE "OriginalFilename", "Ext2Srv.exe" VALUE "ProductName", "Ext2Fsd Service" - VALUE "ProductVersion", "1.4.71.1" + VALUE "ProductVersion", "1.4.71.2" END END BLOCK "VarFileInfo" diff --git a/Ext4Fsd/Ext4Fsd.vcxproj b/Ext4Fsd/Ext4Fsd.vcxproj index cef69c3..932bedb 100644 --- a/Ext4Fsd/Ext4Fsd.vcxproj +++ b/Ext4Fsd/Ext4Fsd.vcxproj @@ -1,395 +1,399 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - Debug - ARM - - - Release - ARM - - - Debug - ARM64 - - - Release - ARM64 - - - - {E98007B5-02C6-4C8F-BB89-E0D530991559} - {dd38f7fc-d7bd-488b-9242-7d8754cde80d} - v4.5 - 12.0 - Debug - Win32 - Ext4Fsd - 10.0.22621.0 - - - - Windows10 - true - WindowsKernelModeDriver10.0 - WDM - 1 - Driver - Windows Driver - - - Windows10 - false - WindowsKernelModeDriver10.0 - WDM - 1 - Driver - Windows Driver - - - Windows10 - true - WindowsKernelModeDriver10.0 - Driver - WDM - 1 - Windows Driver - <_NT_TARGET_VERSION>0xA00000B - - - Windows10 - false - WindowsKernelModeDriver10.0 - Driver - WDM - 1 - Windows Driver - <_NT_TARGET_VERSION>0xA00000B - - - Windows10 - true - WindowsKernelModeDriver10.0 - Driver - WDM - 1 - Windows Driver - - - Windows10 - false - WindowsKernelModeDriver10.0 - Driver - WDM - 1 - Windows Driver - - - Windows10 - true - WindowsKernelModeDriver10.0 - Driver - WDM - 1 - Windows Driver - - - Windows10 - false - WindowsKernelModeDriver10.0 - Driver - WDM - 1 - Windows Driver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DbgengKernelDebugger - $(SolutionDir)Ext4Fsd\$(ConfigurationName)\x86\ - $(ConfigurationName)\x86\ - Ext2Fsd - true - - - DbgengKernelDebugger - $(SolutionDir)Ext4Fsd\$(ConfigurationName)\x86\ - $(ConfigurationName)\x86\ - Ext2Fsd - true - - - DbgengKernelDebugger - $(SolutionDir)Ext4Fsd\$(ConfigurationName)\x64\ - $(ConfigurationName)\x64\ - Ext2Fsd - true - - - DbgengKernelDebugger - $(SolutionDir)Ext4Fsd\$(ConfigurationName)\x64\ - $(ConfigurationName)\x64\ - Ext2Fsd - true - - - DbgengKernelDebugger - $(SolutionDir)Ext4Fsd\$(ConfigurationName)\arm\ - $(ConfigurationName)\arm\ - Ext2Fsd - true - - - DbgengKernelDebugger - $(SolutionDir)Ext4Fsd\$(ConfigurationName)\arm\ - $(ConfigurationName)\arm\ - Ext2Fsd - true - - - DbgengKernelDebugger - $(SolutionDir)Ext4Fsd\$(ConfigurationName)\arm64\ - $(ConfigurationName)\arm64\ - Ext2Fsd - true - - - DbgengKernelDebugger - $(SolutionDir)Ext4Fsd\$(ConfigurationName)\arm64\ - $(ConfigurationName)\arm64\ - Ext2Fsd - true - - - - .\include;.\include\linux;.\include\asm;%(AdditionalIncludeDirectories) - Level3 - __KERNEL__;%(PreprocessorDefinitions) - 4995;%(DisableSpecificWarnings) - - - %(AdditionalDependencies) - - - sha1 - - - - - .\include;.\include\linux;.\include\asm;%(AdditionalIncludeDirectories) - Level3 - __KERNEL__;%(PreprocessorDefinitions) - 4995;%(DisableSpecificWarnings) - - - %(AdditionalDependencies) - - - sha1 - - - - - .\include;.\include\linux;.\include\asm;%(AdditionalIncludeDirectories) - Level3 - __KERNEL__;%(PreprocessorDefinitions) - 4995;%(DisableSpecificWarnings) - - - sha1 - - - - - .\include;.\include\linux;.\include\asm;%(AdditionalIncludeDirectories) - Level3 - __KERNEL__;%(PreprocessorDefinitions) - 4995;%(DisableSpecificWarnings) - - - sha1 - - - - - .\include;.\include\linux;.\include\asm;%(AdditionalIncludeDirectories) - Level3 - __KERNEL__;%(PreprocessorDefinitions) - 4995;%(DisableSpecificWarnings) - - - %(AdditionalDependencies) - - - - - .\include;.\include\linux;.\include\asm;%(AdditionalIncludeDirectories) - Level3 - __KERNEL__;%(PreprocessorDefinitions) - 4995;%(DisableSpecificWarnings) - - - %(AdditionalDependencies) - - - - - .\include;.\include\linux;.\include\asm;%(AdditionalIncludeDirectories) - Level3 - __KERNEL__;%(PreprocessorDefinitions) - 4995;%(DisableSpecificWarnings) - - - - - .\include;.\include\linux;.\include\asm;%(AdditionalIncludeDirectories) - Level3 - __KERNEL__;%(PreprocessorDefinitions) - 4995;%(DisableSpecificWarnings) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM + + + Release + ARM + + + Debug + ARM64 + + + Release + ARM64 + + + + {E98007B5-02C6-4C8F-BB89-E0D530991559} + {dd38f7fc-d7bd-488b-9242-7d8754cde80d} + v4.5 + 12.0 + Debug + Win32 + Ext4Fsd + 10.0.26100.0 + + + + Windows10 + true + WindowsKernelModeDriver10.0 + WDM + 1 + Driver + Windows Driver + + + Windows10 + false + WindowsKernelModeDriver10.0 + WDM + 1 + Driver + Windows Driver + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + 1 + Windows Driver + <_NT_TARGET_VERSION>0xA00000B + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + 1 + Windows Driver + <_NT_TARGET_VERSION>0xA00000B + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + 1 + Windows Driver + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + 1 + Windows Driver + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + 1 + Windows Driver + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + 1 + Windows Driver + + + + <_WdkKmInclude Condition="'$(MSBuildProgramFiles32)' != '' and '$(WindowsTargetPlatformVersion)' != ''">$(MSBuildProgramFiles32)\Windows Kits\10\Include\$(WindowsTargetPlatformVersion)\km + <_WdkKmInclude Condition="'$(_WdkKmInclude)' == ''">C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\km + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DbgengKernelDebugger + $(SolutionDir)Ext4Fsd\$(ConfigurationName)\x86\ + $(ConfigurationName)\x86\ + Ext2Fsd + true + + + DbgengKernelDebugger + $(SolutionDir)Ext4Fsd\$(ConfigurationName)\x86\ + $(ConfigurationName)\x86\ + Ext2Fsd + true + + + DbgengKernelDebugger + $(SolutionDir)Ext4Fsd\$(ConfigurationName)\x64\ + $(ConfigurationName)\x64\ + Ext2Fsd + true + + + DbgengKernelDebugger + $(SolutionDir)Ext4Fsd\$(ConfigurationName)\x64\ + $(ConfigurationName)\x64\ + Ext2Fsd + true + + + DbgengKernelDebugger + $(SolutionDir)Ext4Fsd\$(ConfigurationName)\arm\ + $(ConfigurationName)\arm\ + Ext2Fsd + true + + + DbgengKernelDebugger + $(SolutionDir)Ext4Fsd\$(ConfigurationName)\arm\ + $(ConfigurationName)\arm\ + Ext2Fsd + true + + + DbgengKernelDebugger + $(SolutionDir)Ext4Fsd\$(ConfigurationName)\arm64\ + $(ConfigurationName)\arm64\ + Ext2Fsd + true + + + DbgengKernelDebugger + $(SolutionDir)Ext4Fsd\$(ConfigurationName)\arm64\ + $(ConfigurationName)\arm64\ + Ext2Fsd + true + + + + $(_WdkKmInclude);.\include;.\include\linux;.\include\asm;%(AdditionalIncludeDirectories) + Level3 + __KERNEL__;%(PreprocessorDefinitions) + 4995;%(DisableSpecificWarnings) + + + %(AdditionalDependencies) + + + sha1 + + + + + $(_WdkKmInclude);.\include;.\include\linux;.\include\asm;%(AdditionalIncludeDirectories) + Level3 + __KERNEL__;%(PreprocessorDefinitions) + 4995;%(DisableSpecificWarnings) + + + %(AdditionalDependencies) + + + sha1 + + + + + $(_WdkKmInclude);.\include;.\include\linux;.\include\asm;%(AdditionalIncludeDirectories) + Level3 + __KERNEL__;%(PreprocessorDefinitions) + 4995;%(DisableSpecificWarnings) + + + sha1 + + + + + $(_WdkKmInclude);.\include;.\include\linux;.\include\asm;%(AdditionalIncludeDirectories) + Level3 + __KERNEL__;%(PreprocessorDefinitions) + 4995;%(DisableSpecificWarnings) + + + sha1 + + + + + $(_WdkKmInclude);.\include;.\include\linux;.\include\asm;%(AdditionalIncludeDirectories) + Level3 + __KERNEL__;%(PreprocessorDefinitions) + 4995;%(DisableSpecificWarnings) + + + %(AdditionalDependencies) + + + + + $(_WdkKmInclude);.\include;.\include\linux;.\include\asm;%(AdditionalIncludeDirectories) + Level3 + __KERNEL__;%(PreprocessorDefinitions) + 4995;%(DisableSpecificWarnings) + + + %(AdditionalDependencies) + + + + + $(_WdkKmInclude);.\include;.\include\linux;.\include\asm;%(AdditionalIncludeDirectories) + Level3 + __KERNEL__;%(PreprocessorDefinitions) + 4995;%(DisableSpecificWarnings) + + + + + $(_WdkKmInclude);.\include;.\include\linux;.\include\asm;%(AdditionalIncludeDirectories) + Level3 + __KERNEL__;%(PreprocessorDefinitions) + 4995;%(DisableSpecificWarnings) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Ext4Fsd/create.c b/Ext4Fsd/create.c index 902bdc6..8275977 100644 --- a/Ext4Fsd/create.c +++ b/Ext4Fsd/create.c @@ -585,7 +585,7 @@ Ext2ScanDir ( /* grab parent's reference first */ Ext2ReferMcb(Parent); - /* bad request ! Can a man be pregnant ? Maybe:) */ + /* bad request ! */ if (!IsMcbDirectory(Parent)) { Status = STATUS_NOT_A_DIRECTORY; __leave; diff --git a/Ext4Fsd/fsctl.c b/Ext4Fsd/fsctl.c index ca2b18d..ba14477 100644 --- a/Ext4Fsd/fsctl.c +++ b/Ext4Fsd/fsctl.c @@ -2867,7 +2867,7 @@ Ext2FileSystemControl (IN PEXT2_IRP_CONTEXT IrpContext) default: - DEBUG(DL_ERR, ( "Ext2FilsSystemControl: Invalid Device Request.\n")); + DEBUG(DL_DBG, ( "Ext2FilsSystemControl: Invalid Device Request.\n")); Status = STATUS_INVALID_DEVICE_REQUEST; Ext2CompleteIrpContext(IrpContext, Status); } diff --git a/Ext4Fsd/init.c b/Ext4Fsd/init.c index fd25f4b..f66dd91 100644 --- a/Ext4Fsd/init.c +++ b/Ext4Fsd/init.c @@ -286,7 +286,6 @@ Ext2QueryGlobalParameters(IN PUNICODE_STRING RegistryPath) return NT_SUCCESS(Status); } - BOOLEAN Ext2QueryRegistrySettings(IN PUNICODE_STRING RegistryPath) { @@ -405,14 +404,6 @@ Ext2QueryRegistrySettings(IN PUNICODE_STRING RegistryPath) return TRUE; } -#define NLS_OEM_LEAD_BYTE_INFO (*NlsOemLeadByteInfo) - -#define FsRtlIsLeadDbcsCharacter(DBCS_CHAR) ( \ - (BOOLEAN)((UCHAR)(DBCS_CHAR) < 0x80 ? FALSE : \ - (NLS_MB_CODE_PAGE_TAG && \ - (NLS_OEM_LEAD_BYTE_INFO[(UCHAR)(DBCS_CHAR)] != 0))) \ -) - VOID Ext2EresourceAlignmentChecking() { diff --git a/README.md b/README.md index 7465595..f731cbd 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,26 @@ +Scripts and building from source (this fork) +-------------------------------------------- + +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`. + +**Build and install** +- **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. +- **Scripts\install_driver.ps1** — Copy driver to System32, register kernel driver, install Ext2Srv. Run as Administrator. +- **Scripts\uninstall_driver.ps1** — Remove driver and services. +- **Scripts\register_driver.ps1** — Register the kernel driver service (driver must already be in System32). +- **Scripts\disable_driver.ps1** — Disable the Ext2Fsd service (e.g. to stop boot retries after signature failures). + +**Signing** +- **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`. +- **Scripts\install_certificate.ps1** — Install the signing certificate into Trusted Publishers (required for loading self-signed drivers). Run as Administrator. + +**Diagnostics** +- **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). +- **Scripts\check_driver_load_error.ps1**, **Scripts\diagnose_error_577.ps1**, **Scripts\verify_driver_signature.ps1** — Wrappers that call `diagnose_ext2fsd.ps1`. + +**Other** +- **Scripts\fix_sdk_version.ps1** — Update project files' `WindowsTargetPlatformVersion` to match the installed SDK. + Latest release -------------- @@ -50,6 +73,16 @@ Changes to the source code in git after latest release - The fields s_wtime and s_wtime_hi in the superblock will be updated with the current time at shutdown. + - Timeouts on block/PnP/fsctl waits so surprise-removal of USB + or other removable ext4 volumes no longer hangs the system + waiting forever for I/O that will never complete. + + - Corrected the wait argument to CcCopyRead / CcCopyWrite and + simplified the related read/write paths. + + - Filesystems with EXT4_FEATURE_INCOMPAT_CASEFOLD can be mounted + (the feature bit is treated as supported). + Application: - 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 - The donate dialog box is disabled because the information in it is outdated. + - High-DPI awareness is disabled in the Ext2Mgr project so the + classic Win32 UI scales more predictably on high-resolution + monitors. + + - Ext2Mgr includes a subset of mountmgr.h so the application can + be compiled without installing the Windows Driver Kit. + + - Fork manager notes (this tree): Ext2Mgr/IMPROVEMENTS.md covers + classic Ext2Mgr crash fixes and Ext2Srv pipe speedups. + About ----- @@ -172,5 +215,9 @@ Unsupported Ext4 Features 2, EXT4_FEATURE_INCOMPAT_MMP (multiple mount protection) 3, EXT4_FEATURE_INCOMPAT_INLINE_DATA (storing small files in inode) 4, EXT4_FEATURE_INCOMPAT_ENCRYPT - 5, EXT4_FEATURE_INCOMPAT_CASEFOLD (case insensitive file names (claimed to be used by SteamOS as default)) - 6, EXT4_FEATURE_INCOMPAT_LARGEDIR (3-level htree) + 5, EXT4_FEATURE_INCOMPAT_LARGEDIR (3-level htree) + + Note: EXT4_FEATURE_INCOMPAT_CASEFOLD is no longer in this list; + the driver accepts that incompat bit so casefolded volumes can + be mounted. Full case-insensitive name matching semantics may + still be incomplete compared to Linux. diff --git a/Scripts/build.ps1 b/Scripts/build.ps1 new file mode 100644 index 0000000..3eb3c29 --- /dev/null +++ b/Scripts/build.ps1 @@ -0,0 +1,222 @@ +<# +.SYNOPSIS + Build script for Ext4Fsd driver from source + +.DESCRIPTION + This script builds the Ext4Fsd driver, Ext2Srv service, and Ext2Mgr application + from source. It requires Visual Studio 2019/2022 and Windows Driver Kit (WDK). + +.PARAMETER Configuration + Build configuration: Debug or Release (default: Release) + +.PARAMETER Platform + Target platform: x64, x86, ARM, or ARM64 (default: x64) + +.PARAMETER Clean + Clean the solution before building + +.EXAMPLE + .\Scripts\build.ps1 + Builds Release x64 configuration (run from repo root) + +.EXAMPLE + .\Scripts\build.ps1 -Configuration Debug -Platform x64 + Builds Debug x64 configuration +#> + +[CmdletBinding()] +param( + [ValidateSet("Debug", "Release")] + [string]$Configuration = "Release", + + [ValidateSet("x64", "x86", "ARM", "ARM64")] + [string]$Platform = "x64", + + [switch]$Clean +) + +$ErrorActionPreference = "Stop" +$script:BuildRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path + +$header = " Ext4Fsd Build Script" +Write-Host ("=" * ($header.Length + 1)) -ForegroundColor Cyan +Write-Host $header -ForegroundColor Cyan +Write-Host ("=" * ($header.Length + 1)) -ForegroundColor Cyan +Write-Host "" + +# Find Visual Studio installation (including Build Tools) +Write-Host "Searching for Visual Studio or Build Tools..." -ForegroundColor Yellow +$vsInstallPath = $null +$vsVersions = @( + "${env:ProgramFiles}\Microsoft Visual Studio\2022\Community", + "${env:ProgramFiles}\Microsoft Visual Studio\2022\Professional", + "${env:ProgramFiles}\Microsoft Visual Studio\2022\Enterprise", + "${env:ProgramFiles}\Microsoft Visual Studio\2022\BuildTools", + "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2022\Community", + "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2022\Professional", + "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2022\Enterprise", + "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2022\BuildTools", + "${env:ProgramFiles}\Microsoft Visual Studio\2019\Community", + "${env:ProgramFiles}\Microsoft Visual Studio\2019\Professional", + "${env:ProgramFiles}\Microsoft Visual Studio\2019\Enterprise", + "${env:ProgramFiles}\Microsoft Visual Studio\2019\BuildTools", + "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\Community", + "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\Professional", + "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\Enterprise", + "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\BuildTools" +) + +foreach ($path in $vsVersions) { + if (Test-Path $path) { + $vsInstallPath = $path + Write-Host "Found Visual Studio at: $vsInstallPath" -ForegroundColor Green + break + } +} + +if (-not $vsInstallPath) { + Write-Host "ERROR: Visual Studio 2019/2022 or Build Tools not found!" -ForegroundColor Red + Write-Host "Please install Visual Studio 2019/2022 or Build Tools with C++ desktop development workload." -ForegroundColor Yellow + exit 1 +} + +# Find MSBuild +$msbuildPath = Join-Path $vsInstallPath "MSBuild\Current\Bin\MSBuild.exe" +if (-not (Test-Path $msbuildPath)) { + # Try older path + $msbuildPath = Join-Path $vsInstallPath "MSBuild\15.0\Bin\MSBuild.exe" + if (-not (Test-Path $msbuildPath)) { + Write-Host "ERROR: MSBuild not found!" -ForegroundColor Red + exit 1 + } +} + +Write-Host "Using MSBuild: $msbuildPath" -ForegroundColor Green + +# Check for WDK +Write-Host "" +Write-Host "Checking for Windows Driver Kit (WDK)..." -ForegroundColor Yellow +$wdkPaths = @( + "${env:ProgramFiles(x86)}\Windows Kits\10\Include", + "${env:ProgramFiles}\Windows Kits\10\Include" +) + +$wdkFound = $false +foreach ($path in $wdkPaths) { + if (Test-Path $path) { + $wdkFound = $true + Write-Host "Found WDK at: $path" -ForegroundColor Green + break + } +} + +if (-not $wdkFound) { + Write-Host "WARNING: Windows Driver Kit (WDK) not found!" -ForegroundColor Yellow + Write-Host "The driver project requires WDK to build." -ForegroundColor Yellow + Write-Host "Download from: https://learn.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk" -ForegroundColor Yellow + Write-Host "" + $continue = Read-Host "Continue anyway? (y/N)" + if ($continue -ne "y" -and $continue -ne "Y") { + exit 1 + } +} + +# Solution file +$solutionPath = Join-Path $script:BuildRoot "Ext4Fsd.sln" +if (-not (Test-Path $solutionPath)) { + Write-Host "ERROR: Solution file not found: $solutionPath" -ForegroundColor Red + exit 1 +} + +Write-Host "" +Write-Host "Build Configuration:" -ForegroundColor Cyan +Write-Host " Configuration: $Configuration" -ForegroundColor White +Write-Host " Platform: $Platform" -ForegroundColor White +Write-Host " Solution: $solutionPath" -ForegroundColor White +Write-Host "" + +# Clean if requested +if ($Clean) { + Write-Host "Cleaning solution..." -ForegroundColor Yellow + & $msbuildPath $solutionPath /t:Clean /p:Configuration=$Configuration /p:Platform=$Platform /v:minimal + if ($LASTEXITCODE -ne 0) { + Write-Host "WARNING: Clean failed, but continuing..." -ForegroundColor Yellow + } + Write-Host "" +} + +# Build the solution +Write-Host "Building solution..." -ForegroundColor Yellow +Write-Host "" + +$buildArgs = @( + $solutionPath + "/p:Configuration=$Configuration" + "/p:Platform=$Platform" + "/t:Build" + "/v:normal" + "/m" # Parallel build + "/nologo" +) + +& $msbuildPath @buildArgs + +if ($LASTEXITCODE -eq 0) { + Write-Host "" + $msg = " Build completed successfully!" + Write-Host ("=" * ($msg.Length + 1)) -ForegroundColor Green + Write-Host $msg -ForegroundColor Green + Write-Host ("=" * ($msg.Length + 1)) -ForegroundColor Green + Write-Host "" + + # Show output locations + $outputDirs = @( + "Ext4Fsd\$Configuration\$Platform", + "Ext2Srv\$Configuration\$Platform", + "Ext2Mgr\$Configuration\$Platform" + ) + + Write-Host "Output files:" -ForegroundColor Cyan + foreach ($dir in $outputDirs) { + $fullPath = Join-Path $script:BuildRoot $dir + if (Test-Path $fullPath) { + Write-Host " $fullPath" -ForegroundColor White + Get-ChildItem $fullPath -File | ForEach-Object { + Write-Host " - $($_.Name)" -ForegroundColor Gray + } + } + } + + # Post-build: Sign driver if certificate is configured + $driverPath = Join-Path $script:BuildRoot "Ext4Fsd\$Configuration\$Platform\Ext2Fsd.sys" + if (Test-Path $driverPath) { + Write-Host "" + $signScript = Join-Path $script:BuildRoot "Scripts\sign_driver.ps1" + if (Test-Path $signScript) { + Write-Host "Running post-build driver signing..." -ForegroundColor Cyan + & $signScript -DriverPath $driverPath -SkipIfMissing + # Note: sign_driver.ps1 exits with 0 if skipped (SkipIfMissing), so this is fine + } + } + + Write-Host "" + Write-Host "Next Steps:" -ForegroundColor Cyan + Write-Host " To sign the driver (optional):" -ForegroundColor Yellow + Write-Host " `$env:EXT4FSD_CERT_PATH = 'C:\path\to\certificate.pfx'" -ForegroundColor White + Write-Host " `$env:MSIX_CERT_PASSWORD = 'your_password'" -ForegroundColor White + Write-Host " .\Scripts\sign_driver.ps1" -ForegroundColor White + Write-Host "" + Write-Host " To install the driver:" -ForegroundColor Yellow + Write-Host " .\Scripts\install_driver.ps1" -ForegroundColor White + Write-Host " (Requires administrator privileges)" -ForegroundColor Gray + Write-Host "" + Write-Host " See INSTALLATION.md for detailed instructions" -ForegroundColor Cyan + +} else { + Write-Host "" + $msg = " Build failed!" + Write-Host ("=" * ($msg.Length + 1)) -ForegroundColor Red + Write-Host $msg -ForegroundColor Red + Write-Host ("=" * ($msg.Length + 1)) -ForegroundColor Red + exit 1 +} diff --git a/Scripts/check_driver_load_error.ps1 b/Scripts/check_driver_load_error.ps1 new file mode 100644 index 0000000..29bd6ff --- /dev/null +++ b/Scripts/check_driver_load_error.ps1 @@ -0,0 +1,7 @@ +<# +.SYNOPSIS + Check Windows Event Log and driver load status for load errors. +.NOTES + Runs the unified diagnostic script. See diagnose_ext2fsd.ps1 sections 3, 8, 9, 10. +#> +& "${PSScriptRoot}\diagnose_ext2fsd.ps1" diff --git a/Scripts/diagnose_error_577.ps1 b/Scripts/diagnose_error_577.ps1 new file mode 100644 index 0000000..5db5460 --- /dev/null +++ b/Scripts/diagnose_error_577.ps1 @@ -0,0 +1,17 @@ +<# +.SYNOPSIS + Comprehensive diagnostic for error 577 (driver signature verification failure). +.PARAMETER DriverPath + Path to the driver file. +.PARAMETER CertificatePath + Optional path to certificate (reserved for future use). +.NOTES + This runs the unified diagnostic (diagnose_ext2fsd.ps1), which includes signature, + cert stores, EKU, chain, Secure Boot, service status, and recommendations. +#> +[CmdletBinding()] +param( + [string]$DriverPath = "C:\Windows\System32\drivers\Ext2Fsd.sys", + [string]$CertificatePath +) +& "${PSScriptRoot}\diagnose_ext2fsd.ps1" -DriverPath $DriverPath -CertificatePath $CertificatePath diff --git a/Scripts/diagnose_ext2fsd.ps1 b/Scripts/diagnose_ext2fsd.ps1 new file mode 100644 index 0000000..511886f --- /dev/null +++ b/Scripts/diagnose_ext2fsd.ps1 @@ -0,0 +1,254 @@ +<# +.SYNOPSIS + Unified diagnostic script for the Ext2Fsd/Ext4Fsd driver. + +.DESCRIPTION + Combines checks from check_code_integrity, check_driver_load_error, + diagnose_error_577, and verify_driver_signature. Use this script for + full driver diagnostics (load failures, error 577, signature, event log). + +.PARAMETER DriverPath + Path to the driver file. Defaults to system driver location. + +.PARAMETER CertificatePath + Optional path to certificate (.pfx) for additional checks. + +.PARAMETER UseSigntool + When driver exists, also run signtool verify if Windows SDK is present. + Default: $true. Set -UseSigntool:$false to skip (e.g. no SDK). +#> + +[CmdletBinding()] +param( + [string]$DriverPath = "C:\Windows\System32\drivers\Ext2Fsd.sys", + [string]$CertificatePath, + [bool]$UseSigntool = $true +) + +$ErrorActionPreference = "Continue" + +function Write-Section { param([string]$Title) Write-Host ""; Write-Host $Title -ForegroundColor Cyan; Write-Host ("-" * [Math]::Min(60, $Title.Length)) -ForegroundColor Gray } +function Write-Check { param([string]$Label, [string]$Value, [string]$Color = "White") Write-Host " $Label" -NoNewline; Write-Host " $Value" -ForegroundColor $Color } + +Write-Host "" +Write-Host "Ext2Fsd/Ext4Fsd Driver Diagnostic" -ForegroundColor Cyan +Write-Host "=================================" -ForegroundColor Cyan +Write-Host " Driver: $DriverPath" -ForegroundColor White +Write-Host "" + +# ---- 1. Code Integrity & Test Signing ---- +Write-Section "1. Code Integrity & Test Signing" + +try { + $ciPolicy = Get-CIPolicy -ErrorAction SilentlyContinue + if ($ciPolicy) { + Write-Check "Code Integrity Policy:" "ACTIVE (may block driver)" "Yellow" + $ciPolicy | Format-List | Out-String | Write-Host + } else { + Write-Check "Code Integrity Policy:" "NOT ACTIVE" "Green" + } +} catch { + Write-Check "Code Integrity:" "Could not check: $_" "Gray" +} + +$bcdOutput = bcdedit /enum {current} 2>&1 | Select-String "testsigning" +Write-Check "BCD Test Signing:" $(if ($bcdOutput -match "Yes") { "ENABLED" } else { "DISABLED" }) $(if ($bcdOutput -match "Yes") { "Green" } else { "Yellow" }) + +# ---- 2. Windows Version ---- +Write-Section "2. Windows Version" + +$os = Get-CimInstance Win32_OperatingSystem +Write-Check "Version:" $os.Version "White" +Write-Check "Build:" $os.BuildNumber "White" +if ([int]$os.BuildNumber -ge 22000) { Write-Check "Note:" "Windows 11 - stricter Code Integrity" "Yellow" } + +# ---- 3. Driver File ---- +Write-Section "3. Driver File" + +$driverExists = Test-Path $DriverPath +if ($driverExists) { + $fileInfo = Get-Item $DriverPath + Write-Check "Exists:" "YES" "Green" + Write-Check "Size:" "$($fileInfo.Length) bytes" "White" + Write-Check "Last modified:" $fileInfo.LastWriteTime "White" + try { + $null = [System.IO.File]::Open($DriverPath, 'Open', 'Read', 'None').Close() + Write-Check "Accessible:" "YES" "Green" + } catch { + Write-Check "Accessible:" "LOCKED or inaccessible" "Red" + } +} else { + Write-Check "Exists:" "NO" "Red" + Write-Check "Note:" "Likely cause of error 31 / load failure" "Yellow" +} + +# ---- 4. Signature (Authenticode + optional signtool) ---- +if ($driverExists) { + Write-Section "4. Driver Signature" + + $signature = Get-AuthenticodeSignature -FilePath $DriverPath + Write-Check "Authenticode Status:" $signature.Status $(if ($signature.Status -eq 'Valid') { 'Green' } else { 'Red' }) + if ($signature.SignerCertificate) { + Write-Check "Signer:" $signature.SignerCertificate.Subject "White" + $isTestSigned = $signature.SignerCertificate.Subject -match "Test|TEST" -or $signature.SignerCertificate.Subject -eq $signature.SignerCertificate.Issuer + Write-Check "Test-signed:" $isTestSigned "Yellow" + } + + if ($UseSigntool) { + $sdkBase = "${env:ProgramFiles(x86)}\Windows Kits\10\bin" + $signtool = $null + if (Test-Path $sdkBase) { + $dirs = Get-ChildItem $sdkBase -Directory -ErrorAction SilentlyContinue | Sort-Object Name -Descending + foreach ($d in $dirs) { + $path = Join-Path $d.FullName "x64\signtool.exe" + if (Test-Path $path) { $signtool = $path; break } + } + } + if ($signtool) { + Write-Host " signtool verify:" -ForegroundColor Yellow + $stOut = & $signtool verify /pa /v $DriverPath 2>&1 + $stExit = $LASTEXITCODE + Write-Host ($stOut | Out-String) + Write-Check "signtool result:" $(if ($stExit -eq 0) { "PASSED" } else { "FAILED" }) $(if ($stExit -eq 0) { "Green" } else { "Red" }) + } + } +} + +# ---- 5. Certificate Stores, EKU, Chain (when driver exists and has signer) ---- +$hasCodeSigning = $false +$publisherCertCount = 0 +if ($driverExists -and $signature -and $signature.SignerCertificate) { + Write-Section "5. Certificate Stores & EKU" + + $cert = $signature.SignerCertificate + $thumbprint = $cert.Thumbprint + + $rootStore = New-Object System.Security.Cryptography.X509Certificates.X509Store([System.Security.Cryptography.X509Certificates.StoreName]::Root, [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine) + $rootStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly) + $rootCert = $rootStore.Certificates.Find([System.Security.Cryptography.X509Certificates.X509FindType]::FindByThumbprint, $thumbprint, $false) + $rootStore.Close() + Write-Check "Trusted Root:" $(if ($rootCert.Count -gt 0) { "FOUND" } else { "NOT FOUND" }) $(if ($rootCert.Count -gt 0) { "Green" } else { "Red" }) + + $pubStore = New-Object System.Security.Cryptography.X509Certificates.X509Store([System.Security.Cryptography.X509Certificates.StoreName]::TrustedPublisher, [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine) + $pubStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly) + $publisherCert = $pubStore.Certificates.Find([System.Security.Cryptography.X509Certificates.X509FindType]::FindByThumbprint, $thumbprint, $false) + $pubStore.Close() + $publisherCertCount = $publisherCert.Count + Write-Check "Trusted Publishers:" $(if ($publisherCert.Count -gt 0) { "FOUND" } else { "NOT FOUND (often causes 577)" }) $(if ($publisherCert.Count -gt 0) { "Green" } else { "Red" }) + + $ekuExt = $cert.Extensions | Where-Object { $_.Oid.Value -eq '2.5.29.37' } + if ($ekuExt) { + $ekuStr = $ekuExt[0].Format($false) + $hasCodeSigning = $ekuStr -match "Code Signing|1\.3\.6\.1\.5\.5\.7\.3\.3" + Write-Check "Code Signing EKU:" $(if ($hasCodeSigning) { "PRESENT" } else { "MISSING" }) $(if ($hasCodeSigning) { "Green" } else { "Red" }) + } else { + Write-Check "EKU:" "No EKU extensions" "Yellow" + } + + Write-Section "6. Certificate Chain" + try { + $chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain + $chain.ChainPolicy.RevocationMode = [System.Security.Cryptography.X509Certificates.X509RevocationMode]::NoCheck + $chain.ChainPolicy.VerificationFlags = [System.Security.Cryptography.X509Certificates.X509VerificationFlags]::AllowUnknownCertificateAuthority + $built = $chain.Build($cert) + Write-Check "Chain validation:" $(if ($built) { "SUCCESS (length $($chain.ChainElements.Count))" } else { "FAILED" }) $(if ($built) { "Green" } else { "Red" }) + if (-not $built) { + foreach ($s in $chain.ChainStatus) { Write-Host " $($s.Status): $($s.StatusInformation)" -ForegroundColor Red } + } + } catch { + Write-Check "Chain:" "Error: $_" "Red" + } +} else { + Write-Section "5. Certificate Stores & EKU" + Write-Host " Skipped (driver missing or no signer)" -ForegroundColor Gray + Write-Section "6. Certificate Chain" + Write-Host " Skipped (driver missing or no signer)" -ForegroundColor Gray +} + +# ---- 7. Secure Boot ---- +Write-Section "7. Secure Boot" +try { + $sb = Confirm-SecureBootUEFI -ErrorAction SilentlyContinue + Write-Check "Secure Boot:" $(if ($sb) { "ENABLED" } else { "DISABLED" }) $(if ($sb) { "Yellow" } else { "Green" }) +} catch { + Write-Check "Secure Boot:" "Could not determine (e.g. non-UEFI)" "Gray" +} + +# ---- 8. Driver Service Status ---- +Write-Section "8. Driver Service Status" + +$scOut = & sc.exe query Ext2Fsd 2>&1 +$scExit = $LASTEXITCODE +if ($scExit -eq 0) { + $win32Line = $scOut | Select-String "WIN32_EXIT_CODE" + Write-Host " Service: Registered" -ForegroundColor White + if ($win32Line) { Write-Host " $($win32Line.Line)" -ForegroundColor $(if ($win32Line -match "577") { "Red" } else { "White" }) } +} else { + Write-Check "Service:" "Not registered" "Yellow" +} + +# ---- 9. Driver Load Status (WMI) ---- +Write-Section "9. Driver Load Status" + +$loaded = Get-WmiObject Win32_SystemDriver -ErrorAction SilentlyContinue | Where-Object { $_.Name -eq "Ext2Fsd" } +if ($loaded) { + Write-Check "Loaded:" "YES" "Green" + Write-Check "State:" $loaded.State "White" + Write-Check "Status:" $loaded.Status "White" +} else { + Write-Check "Loaded:" "NO" "Yellow" + Write-Host " (Expected if driver failed to start)" -ForegroundColor Gray +} + +# ---- 10. Event Log ---- +Write-Section "10. Event Log (Driver Load Errors)" + +try { + $events219 = Get-WinEvent -FilterHashtable @{LogName='System'; ID=219} -MaxEvents 10 -ErrorAction SilentlyContinue + $relevant = $events219 | Where-Object { $_.Message -match "Ext2Fsd|ext2fsd" } + if ($relevant) { + foreach ($e in $relevant | Select-Object -First 5) { + Write-Host " [$($e.TimeCreated)]" -ForegroundColor White + Write-Host " $($e.Message)" -ForegroundColor Red + Write-Host "" + } + } else { + Write-Check "Event ID 219 (Ext2Fsd):" "No recent matches" "Green" + } +} catch { + Write-Check "Event log:" "Could not read: $_" "Gray" +} + +try { + $anyExt = Get-WinEvent -FilterHashtable @{LogName='System'} -MaxEvents 100 -ErrorAction SilentlyContinue | Where-Object { $_.Message -match "Ext2Fsd|ext2fsd" } + if ($anyExt -and -not $relevant) { + foreach ($e in ($anyExt | Select-Object -First 3)) { + Write-Host " [$($e.TimeCreated)] ID:$($e.Id) $($e.Message)" -ForegroundColor Gray + } + } +} catch { } + +# ---- 11. Recommendations ---- +Write-Section "Recommendations" + +if (-not $driverExists) { + Write-Host " Install or copy the driver to: $DriverPath" -ForegroundColor Yellow + Write-Host " Then run .\Scripts\register_driver.ps1 and .\Scripts\install_driver.ps1 as needed." -ForegroundColor White +} elseif ($signature.Status -ne 'Valid') { + Write-Host " Signature is not valid. Re-sign and ensure cert is in Trusted Root:" -ForegroundColor Yellow + Write-Host " .\Scripts\sign_driver.ps1 -DriverPath '$DriverPath'" -ForegroundColor White +} else { + if ($publisherCertCount -eq 0) { + Write-Host " 1. Install certificate in Trusted Publishers: .\Scripts\install_certificate.ps1 -CertificatePath 'CERT_PATH'" -ForegroundColor Yellow + } + if (-not $hasCodeSigning -and $signature.SignerCertificate) { + Write-Host " 2. Certificate may lack Code Signing EKU; recreate or use a code-signing cert." -ForegroundColor Yellow + } + Write-Host " 3. Steps to try:" -ForegroundColor Yellow + Write-Host " a. Certificate in Trusted Publishers" -ForegroundColor White + Write-Host " b. Re-sign: .\Scripts\sign_driver.ps1 -DriverPath '$DriverPath'" -ForegroundColor White + Write-Host " c. Restart computer" -ForegroundColor White + Write-Host " d. Start driver: sc.exe start Ext2Fsd" -ForegroundColor White +} + +Write-Host "" diff --git a/Scripts/disable_driver.ps1 b/Scripts/disable_driver.ps1 new file mode 100644 index 0000000..5c6213b --- /dev/null +++ b/Scripts/disable_driver.ps1 @@ -0,0 +1,72 @@ +<# +.SYNOPSIS + Disable the Ext2Fsd kernel driver service to restore Windows stability + +.DESCRIPTION + When the Ext2Fsd driver fails to load (e.g. signature verification errors), + Windows may keep retrying and cause boot delays or instability. + This script disables the Ext2Fsd service so Windows stops trying to start it. +#> + +[CmdletBinding()] +param( + [switch]$AlsoDisableExt2Srv, + [switch]$RemoveService +) + +$ErrorActionPreference = "Stop" +$scExe = "sc.exe" + +$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) +if (-not $isAdmin) { + Write-Host "ERROR: Run as Administrator." -ForegroundColor Red + exit 1 +} + +Write-Host "" +Write-Host "Disabling Ext2Fsd Driver Service" -ForegroundColor Cyan +Write-Host "" + +# Stop Ext2Fsd if running +$null = & $scExe query Ext2Fsd 2>&1 +if ($LASTEXITCODE -eq 0) { + Write-Host "Stopping Ext2Fsd..." -ForegroundColor Yellow + $null = & $scExe stop Ext2Fsd 2>&1 + Start-Sleep -Seconds 2 +} + +# Disable Ext2Fsd +Write-Host "Disabling Ext2Fsd service (start= disabled)..." -ForegroundColor Yellow +$null = & $scExe config Ext2Fsd start= disabled 2>&1 +if ($LASTEXITCODE -eq 0) { + Write-Host " Ext2Fsd: DISABLED" -ForegroundColor Green +} else { + Write-Host " Ext2Fsd: Failed to disable" -ForegroundColor Red +} + +if ($AlsoDisableExt2Srv) { + Write-Host "Disabling Ext2Srv service..." -ForegroundColor Yellow + $null = & $scExe stop Ext2Srv 2>&1 + $null = & $scExe config Ext2Srv start= disabled 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Host " Ext2Srv: DISABLED" -ForegroundColor Green + } +} + +if ($RemoveService) { + Write-Host "Removing Ext2Fsd service..." -ForegroundColor Yellow + $null = & $scExe delete Ext2Fsd 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Host " Ext2Fsd service removed" -ForegroundColor Green + } + $driverPath = "C:\Windows\System32\drivers\Ext2Fsd.sys" + if (Test-Path $driverPath) { + Remove-Item $driverPath -Force -ErrorAction SilentlyContinue + Write-Host " Driver file removed" -ForegroundColor Green + } +} + +Write-Host "" +Write-Host "Done. Windows should no longer attempt to start Ext2Fsd at boot." -ForegroundColor Green +Write-Host "To re-enable later: sc config Ext2Fsd start= system" -ForegroundColor Gray +Write-Host "" diff --git a/Scripts/fix_sdk_version.ps1 b/Scripts/fix_sdk_version.ps1 new file mode 100644 index 0000000..e61b0d2 --- /dev/null +++ b/Scripts/fix_sdk_version.ps1 @@ -0,0 +1,64 @@ +<# +.SYNOPSIS + Updates the Windows SDK version in Ext4Fsd project files to match installed SDK + +.DESCRIPTION + This script updates the WindowsTargetPlatformVersion in the project files + to use the installed Windows SDK version (10.0.26100.0) instead of the + hardcoded version (10.0.22621.0). +#> + +$ErrorActionPreference = "Stop" +$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path + +Write-Host "Updating Windows SDK version in project files..." -ForegroundColor Cyan +Write-Host "" + +# Find installed SDK version +$sdkPath = "${env:ProgramFiles(x86)}\Windows Kits\10\Include" +if (Test-Path $sdkPath) { + $installedSdk = Get-ChildItem $sdkPath -Directory | Sort-Object Name -Descending | Select-Object -First 1 + $sdkVersion = $installedSdk.Name + Write-Host "Found installed SDK version: $sdkVersion" -ForegroundColor Green +} else { + Write-Host "ERROR: Windows SDK not found!" -ForegroundColor Red + exit 1 +} + +# Project files to update +$projectFiles = @( + "Ext4Fsd\Ext4Fsd.vcxproj", + "Ext2Mgr\Ext2Mgr.vcxproj", + "Ext2Srv\Ext2Srv.vcxproj" +) + +$updated = 0 +foreach ($file in $projectFiles) { + $fullPath = Join-Path $repoRoot $file + if (Test-Path $fullPath) { + Write-Host "Updating: $file" -ForegroundColor Yellow + $content = Get-Content $fullPath -Raw + + # Replace WindowsTargetPlatformVersion + if ($content -match 'WindowsTargetPlatformVersion>10\.0\.\d+\.\d+<') { + $newContent = $content -replace 'WindowsTargetPlatformVersion>10\.0\.\d+\.\d+<', "WindowsTargetPlatformVersion>$sdkVersion<" + Set-Content $fullPath -Value $newContent -NoNewline + Write-Host " Updated to $sdkVersion" -ForegroundColor Green + $updated++ + } else { + Write-Host " No WindowsTargetPlatformVersion found" -ForegroundColor Yellow + } + } else { + Write-Host " ✗ File not found: $fullPath" -ForegroundColor Red + } +} + +Write-Host "" +if ($updated -gt 0) { + Write-Host "Updated $updated project file(s) to use SDK version $sdkVersion" -ForegroundColor Green + Write-Host "" + Write-Host "You can now try building again:" -ForegroundColor Cyan + Write-Host " .\Scripts\build.ps1" -ForegroundColor White +} else { + Write-Host "No files were updated." -ForegroundColor Yellow +} diff --git a/Scripts/install_certificate.ps1 b/Scripts/install_certificate.ps1 new file mode 100644 index 0000000..37e0367 --- /dev/null +++ b/Scripts/install_certificate.ps1 @@ -0,0 +1,134 @@ +<# +.SYNOPSIS + Install code signing certificate to Trusted Publishers store + +.DESCRIPTION + This script installs a code signing certificate to the Trusted Publishers store, + which is required for Windows to load kernel-mode drivers signed with self-signed certificates. + +.PARAMETER CertificatePath + Path to the certificate (.pfx) file. + +.PARAMETER CertificatePassword + Certificate password. If not specified, prompts for it. +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory=$true)] + [string]$CertificatePath, + [SecureString]$CertificatePassword +) + +$ErrorActionPreference = "Stop" + +# Check for administrator privileges +$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) + +if (-not $isAdmin) { + Write-Host "ERROR: This script requires administrator privileges!" -ForegroundColor Red + Write-Host " Please run PowerShell as Administrator" -ForegroundColor Yellow + exit 1 +} + +if (-not (Test-Path $CertificatePath)) { + Write-Host "ERROR: Certificate file not found: $CertificatePath" -ForegroundColor Red + exit 1 +} + +Write-Host "" +Write-Host "Installing Certificate to Trusted Publishers Store" -ForegroundColor Cyan +Write-Host " Certificate: $CertificatePath" -ForegroundColor White +Write-Host "" + +# Get certificate password +if (-not $CertificatePassword) { + $certPasswordString = $env:MSIX_CERT_PASSWORD + if ($certPasswordString) { + $CertificatePassword = ConvertTo-SecureString -String $certPasswordString -AsPlainText -Force + } +} + +if (-not $CertificatePassword) { + Write-Host "Enter certificate password:" -ForegroundColor Yellow + $CertificatePassword = Read-Host -AsSecureString +} + +try { + # Read the certificate + Write-Host "Reading certificate..." -ForegroundColor Yellow + $certData = Get-PfxData -FilePath $CertificatePath -Password $CertificatePassword + + if ($certData.EndEntityCertificates.Count -eq 0) { + Write-Host "ERROR: No certificate found in PFX file" -ForegroundColor Red + exit 1 + } + + $cert = $certData.EndEntityCertificates[0] + Write-Host " Certificate Subject: $($cert.Subject)" -ForegroundColor White + Write-Host " Certificate Thumbprint: $($cert.Thumbprint)" -ForegroundColor White + + # Check for Code Signing EKU + $ekuExtensions = $cert.Extensions | Where-Object { $_.Oid.Value -eq '2.5.29.37' } + if ($ekuExtensions) { + $eku = $ekuExtensions[0] + $ekuOids = $eku.Format($false) -split "`r`n" + $hasCodeSigning = $false + foreach ($oid in $ekuOids) { + if ($oid -match "Code Signing|1\.3\.6\.1\.5\.5\.7\.3\.3") { + $hasCodeSigning = $true + break + } + } + if ($hasCodeSigning) { + Write-Host " Code Signing EKU: PRESENT" -ForegroundColor Green + } else { + Write-Host " Code Signing EKU: MISSING" -ForegroundColor Yellow + Write-Host " WARNING: Certificate may not work for kernel driver signing!" -ForegroundColor Yellow + } + } else { + Write-Host " Code Signing EKU: NOT CHECKED" -ForegroundColor Gray + } + Write-Host "" + + # Check if already installed + $publishersStore = New-Object System.Security.Cryptography.X509Certificates.X509Store([System.Security.Cryptography.X509Certificates.StoreName]::TrustedPublisher, [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine) + $publishersStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly) + $existingCert = $publishersStore.Certificates.Find([System.Security.Cryptography.X509Certificates.X509FindType]::FindByThumbprint, $cert.Thumbprint, $false) + $publishersStore.Close() + + if ($existingCert.Count -gt 0) { + Write-Host "Certificate is already installed in Trusted Publishers store" -ForegroundColor Green + Write-Host "" + Write-Host "If the driver still fails with error 577, try:" -ForegroundColor Yellow + Write-Host " 1. Restart the computer" -ForegroundColor White + Write-Host " 2. Verify Secure Boot status: Confirm-SecureBootUEFI" -ForegroundColor White + exit 0 + } + + # Install to Trusted Publishers store + Write-Host "Installing certificate to Trusted Publishers store..." -ForegroundColor Yellow + $publishersStore = New-Object System.Security.Cryptography.X509Certificates.X509Store([System.Security.Cryptography.X509Certificates.StoreName]::TrustedPublisher, [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine) + $publishersStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite) + $publishersStore.Add($cert) + $publishersStore.Close() + + Write-Host "Certificate installed successfully!" -ForegroundColor Green + Write-Host "" + Write-Host "Next steps:" -ForegroundColor Cyan + Write-Host " 1. Restart your computer (required for kernel driver changes)" -ForegroundColor White + Write-Host " 2. After restart, try starting the driver: sc.exe start Ext2Fsd" -ForegroundColor White + Write-Host " 3. If it still fails, verify Secure Boot status: Confirm-SecureBootUEFI" -ForegroundColor White + Write-Host "" + +} catch { + Write-Host "" + Write-Host "ERROR: Failed to install certificate: $_" -ForegroundColor Red + Write-Host "" + Write-Host "Alternative method using certmgr.msc:" -ForegroundColor Yellow + Write-Host " 1. Open certmgr.msc" -ForegroundColor White + Write-Host " 2. Navigate to: Trusted Publishers > Certificates" -ForegroundColor White + Write-Host " 3. Right-click Certificates > All Tasks > Import" -ForegroundColor White + Write-Host " 4. Import your certificate: $CertificatePath" -ForegroundColor White + exit 1 +} diff --git a/Scripts/install_driver.ps1 b/Scripts/install_driver.ps1 new file mode 100644 index 0000000..47bd80c --- /dev/null +++ b/Scripts/install_driver.ps1 @@ -0,0 +1,379 @@ +<# +.SYNOPSIS + Install script for Ext4Fsd driver and Ext2Srv service + +.DESCRIPTION + This script installs the compiled Ext4Fsd driver and Ext2Srv service. + It copies the driver to the system drivers folder and registers/installs the service. + +.PARAMETER DriverPath + Path to the driver file (.sys). If not specified, uses default build output location. + +.PARAMETER ServicePath + Path to the Ext2Srv service executable. If not specified, uses default build output location. + +.PARAMETER Configuration + Build configuration (Release or Debug). Used to find default paths. Default: Release + +.PARAMETER Platform + Target platform (x64, x86, ARM, ARM64). Used to find default paths. Default: x64 + +.PARAMETER SkipServiceInstall + Skip service installation/registration. Only copy the driver. + +.PARAMETER SkipServiceStart + Skip starting the service after installation. + +.EXAMPLE + .\Scripts\install_driver.ps1 + +.EXAMPLE + .\Scripts\install_driver.ps1 -Configuration Release -Platform x64 + +.EXAMPLE + .\Scripts\install_driver.ps1 -DriverPath "Ext4Fsd\Release\x64\Ext2Fsd.sys" -ServicePath "Ext2Srv\Release\x64\Ext2Srv.exe" +#> + +[CmdletBinding()] +param( + [string]$DriverPath, + [string]$ServicePath, + [ValidateSet("Debug", "Release")] + [string]$Configuration = "Release", + [ValidateSet("x64", "x86", "ARM", "ARM64")] + [string]$Platform = "x64", + [switch]$SkipServiceInstall, + [switch]$SkipServiceStart +) + +$ErrorActionPreference = "Stop" +$script:BuildRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path + +# Use sc.exe explicitly to avoid PowerShell alias (sc -> Set-Content) +$scExe = "sc.exe" + +# Check for administrator privileges +$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) + +if (-not $isAdmin) { + Write-Host "ERROR: This script requires administrator privileges!" -ForegroundColor Red + Write-Host " Please run PowerShell as Administrator" -ForegroundColor Yellow + Write-Host "" + Write-Host " Right-click PowerShell and select 'Run as Administrator'" -ForegroundColor Yellow + Write-Host " Or use: Start-Process powershell -Verb RunAs" -ForegroundColor Yellow + exit 1 +} + +Write-Host "" +Write-Host "Installing Ext4Fsd Driver" -ForegroundColor Cyan +Write-Host "" + +# Default paths if not specified +if (-not $DriverPath) { + $DriverPath = Join-Path $script:BuildRoot "Ext4Fsd\$Configuration\$Platform\Ext2Fsd.sys" +} + +if (-not $ServicePath) { + $ServicePath = Join-Path $script:BuildRoot "Ext2Srv\$Configuration\$Platform\Ext2Srv.exe" +} + +# Verify files exist +if (-not (Test-Path $DriverPath)) { + Write-Host "ERROR: Driver file not found: $DriverPath" -ForegroundColor Red + Write-Host " Build the driver first using: .\Scripts\build.ps1" -ForegroundColor Yellow + exit 1 +} + +if (-not $SkipServiceInstall -and -not (Test-Path $ServicePath)) { + Write-Host "ERROR: Service executable not found: $ServicePath" -ForegroundColor Red + Write-Host " Build the service first using: .\Scripts\build.ps1" -ForegroundColor Yellow + exit 1 +} + +Write-Host "Files:" -ForegroundColor Cyan +Write-Host " Driver: $DriverPath" -ForegroundColor White +if (-not $SkipServiceInstall) { + Write-Host " Service: $ServicePath" -ForegroundColor White +} +Write-Host "" + +# Step 1: Stop the service if running +Write-Host "Step 1: Checking service status..." -ForegroundColor Yellow +$serviceStatus = & $scExe query Ext2Srv 2>$null +if ($LASTEXITCODE -eq 0) { + $serviceRunning = $null -ne ($serviceStatus | Select-String "RUNNING") + if ($serviceRunning) { + Write-Host " Service is running, stopping..." -ForegroundColor Yellow + & $scExe stop Ext2Srv | Out-Null + Start-Sleep -Seconds 2 + + # Wait for service to stop + $timeout = 10 + $elapsed = 0 + while ($elapsed -lt $timeout) { + $status = & $scExe query Ext2Srv 2>$null + if ($null -ne ($status | Select-String "STOPPED")) { + Write-Host " Service stopped successfully" -ForegroundColor Green + break + } + Start-Sleep -Seconds 1 + $elapsed++ + } + + if ($elapsed -ge $timeout) { + Write-Host " WARNING: Service did not stop within timeout" -ForegroundColor Yellow + } + } else { + Write-Host " Service is not running" -ForegroundColor Gray + } +} else { + Write-Host " Service not installed yet" -ForegroundColor Gray +} + +# Step 2: Copy driver to system folder +Write-Host "" +Write-Host "Step 2: Copying driver to system folder..." -ForegroundColor Yellow +$systemDriverPath = "C:\Windows\System32\drivers\Ext2Fsd.sys" + +try { + Copy-Item $DriverPath $systemDriverPath -Force + Write-Host " Driver copied successfully" -ForegroundColor Green + Write-Host " Destination: $systemDriverPath" -ForegroundColor Gray +} catch { + Write-Host "ERROR: Failed to copy driver: $_" -ForegroundColor Red + exit 1 +} + +# Step 2a: Register kernel driver service (if not already registered) +Write-Host "" +Write-Host "Step 2a: Registering kernel driver service..." -ForegroundColor Yellow + +$null = & $scExe query Ext2Fsd 2>&1 +$queryExitCode = $LASTEXITCODE +if ($queryExitCode -ne 0) { + Write-Host " Kernel driver service not found, registering..." -ForegroundColor Yellow + + # Register the kernel driver service + # Type: filesys = FILE_SYSTEM_DRIVER (kernel filesystem driver) + # Start: system = SERVICE_SYSTEM_START (starts early in boot process) + # ErrorControl: normal = SERVICE_ERROR_NORMAL + $createOutput = & $scExe create Ext2Fsd type= filesys start= system binPath= "$systemDriverPath" error= normal 2>&1 + $createExitCode = $LASTEXITCODE + + if ($createExitCode -eq 0) { + Write-Host " Kernel driver service registered successfully" -ForegroundColor Green + + # Create registry keys that Ext2Mgr expects + Write-Host " Creating registry keys..." -ForegroundColor Yellow + try { + $regPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Ext2Fsd" + $paramsPath = "$regPath\Parameters" + + if (-not (Test-Path $regPath)) { + New-Item -Path $regPath -Force | Out-Null + } + if (-not (Test-Path $paramsPath)) { + New-Item -Path $paramsPath -Force | Out-Null + } + + # Set default values from Ext2Fsd.inf + Set-ItemProperty -Path $paramsPath -Name "AutoMount" -Value 1 -Type DWord -ErrorAction SilentlyContinue + Set-ItemProperty -Path $paramsPath -Name "CheckingBitmap" -Value 0 -Type DWord -ErrorAction SilentlyContinue + Set-ItemProperty -Path $paramsPath -Name "Ext3ForceWriting" -Value 1 -Type DWord -ErrorAction SilentlyContinue + Set-ItemProperty -Path $paramsPath -Name "WritingSupport" -Value 1 -Type DWord -ErrorAction SilentlyContinue + Set-ItemProperty -Path $paramsPath -Name "CodePage" -Value "utf8" -Type String -ErrorAction SilentlyContinue + + Write-Host " Registry keys created successfully" -ForegroundColor Green + } catch { + Write-Host " WARNING: Failed to create registry keys: $_" -ForegroundColor Yellow + Write-Host " Ext2Mgr may not be able to save settings until keys are created" -ForegroundColor Yellow + } + } else { + Write-Host " ERROR: Failed to register kernel driver service" -ForegroundColor Red + Write-Host " Error output: $createOutput" -ForegroundColor Yellow + Write-Host " You may need to run: .\register_driver.ps1" -ForegroundColor Yellow + } +} else { + Write-Host " Kernel driver service already registered" -ForegroundColor Gray + + # Ensure registry keys exist even if service was already registered + try { + $paramsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Ext2Fsd\Parameters" + if (-not (Test-Path $paramsPath)) { + Write-Host " Creating missing registry keys..." -ForegroundColor Yellow + New-Item -Path $paramsPath -Force | Out-Null + + # Set default values + Set-ItemProperty -Path $paramsPath -Name "AutoMount" -Value 1 -Type DWord -ErrorAction SilentlyContinue + Set-ItemProperty -Path $paramsPath -Name "Ext3ForceWriting" -Value 1 -Type DWord -ErrorAction SilentlyContinue + Set-ItemProperty -Path $paramsPath -Name "WritingSupport" -Value 1 -Type DWord -ErrorAction SilentlyContinue + Set-ItemProperty -Path $paramsPath -Name "CodePage" -Value "utf8" -Type String -ErrorAction SilentlyContinue + + Write-Host " Registry keys created" -ForegroundColor Green + } + } catch { + Write-Host " WARNING: Could not verify/create registry keys: $_" -ForegroundColor Yellow + } +} + +# Start the kernel driver if not running +$kernelStatus = & $scExe query Ext2Fsd 2>&1 +$kernelQueryExitCode = $LASTEXITCODE +if ($kernelQueryExitCode -eq 0) { + $kernelRunning = $null -ne ($kernelStatus | Select-String "RUNNING") + if (-not $kernelRunning) { + Write-Host " Starting kernel driver..." -ForegroundColor Yellow + $null = & $scExe start Ext2Fsd 2>&1 + Start-Sleep -Seconds 2 + } +} + +# Step 3: Install/register the service +if (-not $SkipServiceInstall) { + Write-Host "" + Write-Host "Step 3: Installing service..." -ForegroundColor Yellow + + # Check if service already exists + $serviceCheck = & $scExe query Ext2Srv 2>&1 + $serviceQueryExitCode = $LASTEXITCODE + if ($serviceQueryExitCode -eq 0) { + Write-Host " Service already registered" -ForegroundColor Gray + + # Check if service binary path matches what we're installing + $binaryPathMatch = $serviceCheck | Select-String "BINARY_PATH_NAME" + $currentBinaryPath = $null + + if ($binaryPathMatch) { + $binaryPathLine = $binaryPathMatch.Line + if ($binaryPathLine -match "BINARY_PATH_NAME\s+:\s+(.+)") { + $currentBinaryPath = $matches[1].Trim() + } + } + + # Also check service type to detect if it's still the old interactive version + $serviceTypeMatch = $serviceCheck | Select-String "TYPE" + $isInteractiveService = $false + if ($serviceTypeMatch) { + $typeLine = $serviceTypeMatch.Line + if ($typeLine -match "TYPE\s+:\s+\d+\s+.*\(interactive\)") { + $isInteractiveService = $true + } + } + + $newBinaryPath = (Resolve-Path $ServicePath).Path + + # Reinstall if: binary path differs OR service is still interactive (old version) + if (($currentBinaryPath -and $currentBinaryPath -ne $newBinaryPath) -or $isInteractiveService) { + if ($isInteractiveService) { + Write-Host " Service is configured as interactive (old version), reinstalling..." -ForegroundColor Yellow + } else { + Write-Host " Service binary path differs, reinstalling..." -ForegroundColor Yellow + Write-Host " Current: $currentBinaryPath" -ForegroundColor Gray + Write-Host " New: $newBinaryPath" -ForegroundColor Gray + } + + # Remove old service + Write-Host " Removing old service..." -ForegroundColor Yellow + & $ServicePath /removeservice 2>$null | Out-Null + + # Wait a moment for service removal + Start-Sleep -Seconds 2 + + # Reinstall with new binary + Write-Host " Registering Ext2Srv service with new binary..." -ForegroundColor Yellow + & $ServicePath /installasservice + + if ($LASTEXITCODE -eq 0) { + Write-Host " Service reinstalled successfully" -ForegroundColor Green + } else { + Write-Host " WARNING: Service reinstallation may have failed (check output above)" -ForegroundColor Yellow + } + } else { + if ($currentBinaryPath) { + Write-Host " Service binary path matches and type is correct, skipping reinstallation" -ForegroundColor Gray + } else { + Write-Host " Could not determine current binary path, skipping reinstallation" -ForegroundColor Gray + Write-Host " If service type shows 'interactive', manually reinstall with:" -ForegroundColor Yellow + $removeCmd = "& `"$ServicePath`" /removeservice" + $installCmd = "& `"$ServicePath`" /installasservice" + Write-Host " $removeCmd" -ForegroundColor White + Write-Host " $installCmd" -ForegroundColor White + } + } + } else { + Write-Host " Registering Ext2Srv service..." -ForegroundColor Yellow + & $ServicePath /installasservice + + if ($LASTEXITCODE -eq 0) { + Write-Host " Service registered successfully" -ForegroundColor Green + } else { + Write-Host " WARNING: Service registration may have failed (check output above)" -ForegroundColor Yellow + } + } +} + +# Step 4: Start the service +if (-not $SkipServiceStart) { + Write-Host "" + Write-Host "Step 4: Starting service..." -ForegroundColor Yellow + + $null = & $scExe start Ext2Srv 2>&1 + Start-Sleep -Seconds 2 + + # Check if service started + $serviceStatus = & $scExe query Ext2Srv 2>&1 + $serviceStartExitCode = $LASTEXITCODE + if ($serviceStartExitCode -eq 0) { + $serviceRunning = $null -ne ($serviceStatus | Select-String "RUNNING") + if ($serviceRunning) { + Write-Host " Service started successfully" -ForegroundColor Green + } else { + Write-Host " WARNING: Service did not start" -ForegroundColor Yellow + Write-Host " Check service status: sc query Ext2Srv" -ForegroundColor Yellow + Write-Host " Check event logs for errors" -ForegroundColor Yellow + } + } else { + Write-Host " ERROR: Failed to query service status" -ForegroundColor Red + } +} + +# Summary +Write-Host "" +Write-Host "Installation Summary" -ForegroundColor Cyan +Write-Host " Driver installed: $systemDriverPath" -ForegroundColor White + +# Check kernel driver status +$kernelStatus = & $scExe query Ext2Fsd 2>&1 +$kernelSummaryExitCode = $LASTEXITCODE +if ($kernelSummaryExitCode -eq 0) { + $kernelRunning = $null -ne ($kernelStatus | Select-String "RUNNING") + if ($kernelRunning) { + Write-Host " Kernel driver (Ext2Fsd): RUNNING" -ForegroundColor Green + } else { + Write-Host " Kernel driver (Ext2Fsd): STOPPED" -ForegroundColor Yellow + } +} else { + Write-Host " Kernel driver (Ext2Fsd): NOT REGISTERED" -ForegroundColor Red +} + +if (-not $SkipServiceInstall) { + $serviceStatus = & $scExe query Ext2Srv 2>&1 + $serviceSummaryExitCode = $LASTEXITCODE + if ($serviceSummaryExitCode -eq 0) { + $serviceRunning = $null -ne ($serviceStatus | Select-String "RUNNING") + if ($serviceRunning) { + Write-Host " Service (Ext2Srv): RUNNING" -ForegroundColor Green + } else { + Write-Host " Service (Ext2Srv): STOPPED" -ForegroundColor Yellow + } + } else { + Write-Host " Service (Ext2Srv): NOT INSTALLED" -ForegroundColor Red + } +} + +Write-Host "" +Write-Host "Next steps:" -ForegroundColor Cyan +Write-Host " 1. Verify driver is working: sc query Ext2Srv" -ForegroundColor White +Write-Host " 2. Mount ext4 partitions using Ext2Mgr or command line" -ForegroundColor White +Write-Host " 3. See INSTALLATION.md for mounting instructions" -ForegroundColor White +Write-Host "" diff --git a/Scripts/register_driver.ps1 b/Scripts/register_driver.ps1 new file mode 100644 index 0000000..5c53e16 --- /dev/null +++ b/Scripts/register_driver.ps1 @@ -0,0 +1,89 @@ +<# +.SYNOPSIS + Register the Ext2Fsd kernel driver as a Windows service + +.DESCRIPTION + This script registers the Ext2Fsd.sys kernel driver as a Windows kernel driver service. + The driver must already be copied to C:\Windows\System32\drivers\Ext2Fsd.sys +#> + +[CmdletBinding()] +param() + +$ErrorActionPreference = "Stop" + +# Use sc.exe explicitly to avoid PowerShell alias (sc -> Set-Content) +$scExe = "sc.exe" + +# Check for administrator privileges +$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) + +if (-not $isAdmin) { + Write-Host "ERROR: This script requires administrator privileges!" -ForegroundColor Red + Write-Host " Please run PowerShell as Administrator" -ForegroundColor Yellow + exit 1 +} + +$driverPath = "C:\Windows\System32\drivers\Ext2Fsd.sys" + +if (-not (Test-Path $driverPath)) { + Write-Host "ERROR: Driver file not found: $driverPath" -ForegroundColor Red + Write-Host " Copy the driver first using: .\Scripts\install_driver.ps1" -ForegroundColor Yellow + exit 1 +} + +Write-Host "" +Write-Host "Registering Ext2Fsd Kernel Driver" -ForegroundColor Cyan +Write-Host "" + +# Check if service already exists +$null = & $scExe query Ext2Fsd 2>&1 +$queryExitCode = $LASTEXITCODE +if ($queryExitCode -eq 0) { + Write-Host " Kernel driver service already exists" -ForegroundColor Gray + Write-Host " Removing existing service..." -ForegroundColor Yellow + $null = & $scExe delete Ext2Fsd 2>&1 + Start-Sleep -Seconds 1 +} + +Write-Host " Creating kernel driver service..." -ForegroundColor Yellow + +# Register the kernel driver service +# Type: filesys = FILE_SYSTEM_DRIVER (kernel filesystem driver) +# Start: system = SERVICE_SYSTEM_START (starts early in boot process) +# ErrorControl: normal = SERVICE_ERROR_NORMAL +# BinaryPathName: path to driver +$createOutput = & $scExe create Ext2Fsd type= filesys start= system binPath= "$driverPath" error= normal 2>&1 +$createExitCode = $LASTEXITCODE + +if ($createExitCode -eq 0) { + Write-Host " Kernel driver service registered successfully" -ForegroundColor Green + + Write-Host "" + Write-Host " Starting driver..." -ForegroundColor Yellow + $null = & $scExe start Ext2Fsd 2>&1 + + Start-Sleep -Seconds 2 + + $status = & $scExe query Ext2Fsd 2>&1 + $statusExitCode = $LASTEXITCODE + if ($statusExitCode -eq 0) { + $running = $null -ne ($status | Select-String "RUNNING") + if ($running) { + Write-Host " Driver started successfully" -ForegroundColor Green + } else { + Write-Host " WARNING: Driver did not start" -ForegroundColor Yellow + Write-Host " Check event logs for errors" -ForegroundColor Yellow + } + } +} else { + Write-Host " ERROR: Failed to register kernel driver service" -ForegroundColor Red + exit 1 +} + +Write-Host "" +Write-Host "Next steps:" -ForegroundColor Cyan +Write-Host " 1. Verify driver is loaded: sc query Ext2Fsd" -ForegroundColor White +Write-Host " 2. Check if device exists: Test-Path '\\.\Ext2Fsd'" -ForegroundColor White +Write-Host " 3. Try Ext2Mgr again" -ForegroundColor White +Write-Host "" diff --git a/Scripts/sign_driver.ps1 b/Scripts/sign_driver.ps1 new file mode 100644 index 0000000..a2bf912 --- /dev/null +++ b/Scripts/sign_driver.ps1 @@ -0,0 +1,179 @@ +<# +.SYNOPSIS + Post-build script to sign the Ext4Fsd driver with a code signing certificate + +.DESCRIPTION + This script signs the compiled Ext4Fsd driver (.sys file) with a code signing certificate. + It can be run manually or integrated into the build process. + +.PARAMETER DriverPath + Path to the driver file to sign. If not specified, uses default build output location. + +.PARAMETER CertificatePath + Path to the certificate (.pfx) file. If not specified, checks environment variable EXT4FSD_CERT_PATH. + +.PARAMETER CertificatePassword + Certificate password. If not specified, checks environment variable MSIX_CERT_PASSWORD or prompts. + +.PARAMETER SkipIfMissing + If certificate is not found, skip signing instead of failing (useful for automated builds). + +.EXAMPLE + .\Scripts\sign_driver.ps1 + +.EXAMPLE + .\Scripts\sign_driver.ps1 -CertificatePath "C:\path\to\cert.pfx" -SkipIfMissing +#> + +[CmdletBinding()] +param( + [string]$DriverPath, + [string]$CertificatePath, + [string]$CertificatePassword, + [switch]$SkipIfMissing +) + +$ErrorActionPreference = "Stop" +$script:BuildRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path + +# Default driver path if not specified +if (-not $DriverPath) { + $DriverPath = Join-Path $script:BuildRoot "Ext4Fsd\Release\x64\Ext2Fsd.sys" +} + +# Check if driver exists +if (-not (Test-Path $DriverPath)) { + Write-Host "ERROR: Driver file not found: $DriverPath" -ForegroundColor Red + exit 1 +} + +Write-Host "" +Write-Host "Signing Driver" -ForegroundColor Cyan +Write-Host " Driver: $DriverPath" -ForegroundColor White + +# Get certificate path +if (-not $CertificatePath) { + $CertificatePath = $env:EXT4FSD_CERT_PATH +} + +if (-not $CertificatePath) { + if ($SkipIfMissing) { + Write-Host " Certificate path not specified (EXT4FSD_CERT_PATH not set)" -ForegroundColor Yellow + Write-Host " Skipping driver signing..." -ForegroundColor Yellow + exit 0 + } else { + Write-Host "ERROR: Certificate path not specified!" -ForegroundColor Red + Write-Host " Set EXT4FSD_CERT_PATH environment variable or use -CertificatePath parameter" -ForegroundColor Yellow + Write-Host " Example: `$env:EXT4FSD_CERT_PATH = 'C:\path\to\certificate.pfx'" -ForegroundColor Yellow + exit 1 + } +} + +if (-not (Test-Path $CertificatePath)) { + if ($SkipIfMissing) { + Write-Host " Certificate file not found: $CertificatePath" -ForegroundColor Yellow + Write-Host " Skipping driver signing..." -ForegroundColor Yellow + exit 0 + } else { + Write-Host "ERROR: Certificate file not found: $CertificatePath" -ForegroundColor Red + exit 1 + } +} + +Write-Host " Certificate: $CertificatePath" -ForegroundColor White + +# Get certificate password +if (-not $CertificatePassword) { + $CertificatePassword = $env:MSIX_CERT_PASSWORD +} + +if (-not $CertificatePassword) { + Write-Host " Certificate password not found in MSIX_CERT_PASSWORD environment variable" -ForegroundColor Yellow + $securePassword = Read-Host "Enter certificate password" -AsSecureString + $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePassword) + $CertificatePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) + [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR) +} + +# Find signtool.exe +Write-Host " Searching for signtool.exe..." -ForegroundColor Yellow + +# Try to find Windows SDK version from driver path or use default +$sdkVersion = "10.0.26100.0" # Default, adjust if needed + +# Check common SDK locations +$signtoolPaths = @( + "${env:ProgramFiles(x86)}\Windows Kits\10\bin\$sdkVersion\x64\signtool.exe", + "${env:ProgramFiles}\Windows Kits\10\bin\$sdkVersion\x64\signtool.exe" +) + +# Also try to find latest SDK version +$sdkBasePath = "${env:ProgramFiles(x86)}\Windows Kits\10\bin" +if (Test-Path $sdkBasePath) { + $sdkVersions = Get-ChildItem $sdkBasePath -Directory | Sort-Object Name -Descending + foreach ($version in $sdkVersions) { + $signtoolPath = Join-Path $version.FullName "x64\signtool.exe" + if (Test-Path $signtoolPath) { + $signtoolPaths = @($signtoolPath) + $signtoolPaths + break + } + } +} + +$signtool = $null +foreach ($path in $signtoolPaths) { + if (Test-Path $path) { + $signtool = $path + break + } +} + +if (-not $signtool) { + Write-Host "ERROR: signtool.exe not found!" -ForegroundColor Red + Write-Host " Please install Windows SDK or specify the path manually" -ForegroundColor Yellow + exit 1 +} + +Write-Host " Found signtool: $signtool" -ForegroundColor Green + +# Sign the driver +Write-Host "" +Write-Host "Signing driver..." -ForegroundColor Yellow + +$signArgs = @( + "sign" + "/f", $CertificatePath + "/p", $CertificatePassword + "/fd", "SHA256" + "/t", "http://timestamp.digicert.com" + $DriverPath +) + +try { + & $signtool @signArgs + + if ($LASTEXITCODE -eq 0) { + Write-Host "" + Write-Host " Driver signed successfully!" -ForegroundColor Green + + # Verify signature + Write-Host " Verifying signature..." -ForegroundColor Yellow + & $signtool verify /pa /v $DriverPath | Out-Null + + if ($LASTEXITCODE -eq 0) { + Write-Host " Signature verified successfully!" -ForegroundColor Green + } else { + Write-Host " WARNING: Signature verification failed" -ForegroundColor Yellow + } + } else { + Write-Host "" + Write-Host "ERROR: Driver signing failed!" -ForegroundColor Red + exit 1 + } +} catch { + Write-Host "" + Write-Host "ERROR: Failed to sign driver: $_" -ForegroundColor Red + exit 1 +} + +Write-Host "" diff --git a/Scripts/uninstall_driver.ps1 b/Scripts/uninstall_driver.ps1 new file mode 100644 index 0000000..df343de --- /dev/null +++ b/Scripts/uninstall_driver.ps1 @@ -0,0 +1,112 @@ +<# +.SYNOPSIS + Fully uninstall the locally built Ext4Fsd driver and Ext2Srv service + +.DESCRIPTION + Removes the Ext2Fsd kernel driver service, Ext2Srv user-mode service, + and the driver file from System32\drivers. Use this before testing + the official signed release (e.g. v0.71 from GitHub) to verify whether + service communication issues (e.g. interactive flag) still apply. + +.PARAMETER Ext2SrvPath + Path to Ext2Srv.exe used when the service was installed. If provided, + the script uses "Ext2Srv.exe /removeservice" for clean removal. + If not provided, uses "sc delete Ext2Srv" (service is still fully removed). + +.PARAMETER KeepDriverFile + Do not delete Ext2Fsd.sys from System32\drivers. Used only for testing. + +.EXAMPLE + .\Scripts\uninstall_driver.ps1 + +.EXAMPLE + .\Scripts\uninstall_driver.ps1 -Ext2SrvPath ".\Ext2Srv\Release\x64\Ext2Srv.exe" +#> + +[CmdletBinding()] +param( + [string]$Ext2SrvPath, + [switch]$KeepDriverFile +) + +$ErrorActionPreference = "Stop" +$scExe = "sc.exe" +$systemDriverPath = "C:\Windows\System32\drivers\Ext2Fsd.sys" + +$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) +if (-not $isAdmin) { + Write-Host "ERROR: Run as Administrator." -ForegroundColor Red + exit 1 +} + +Write-Host "" +Write-Host "Uninstalling Ext4Fsd (full removal)" -ForegroundColor Cyan +Write-Host "" + +# 1. Stop Ext2Srv +Write-Host "Step 1: Stopping Ext2Srv..." -ForegroundColor Yellow +$null = & $scExe query Ext2Srv 2>&1 +if ($LASTEXITCODE -eq 0) { + $null = & $scExe stop Ext2Srv 2>&1 + Start-Sleep -Seconds 2 + Write-Host " Ext2Srv stopped" -ForegroundColor Green +} else { + Write-Host " Ext2Srv not installed" -ForegroundColor Gray +} + +# 2. Remove Ext2Srv service +Write-Host "" +Write-Host "Step 2: Removing Ext2Srv service..." -ForegroundColor Yellow +if ($Ext2SrvPath -and (Test-Path $Ext2SrvPath)) { + & $Ext2SrvPath /removeservice 2>&1 + Start-Sleep -Seconds 2 + Write-Host " Ran $Ext2SrvPath /removeservice" -ForegroundColor Green +} +$null = & $scExe query Ext2Srv 2>&1 +if ($LASTEXITCODE -eq 0) { + $null = & $scExe delete Ext2Srv 2>&1 + Start-Sleep -Seconds 1 +} +$null = & $scExe query Ext2Srv 2>&1 +if ($LASTEXITCODE -ne 0) { + Write-Host " Ext2Srv service removed" -ForegroundColor Green +} else { + Write-Host " Ext2Srv service removed (or was not installed)" -ForegroundColor Green +} + +# 3. Stop and remove Ext2Fsd kernel driver service +Write-Host "" +Write-Host "Step 3: Stopping and removing Ext2Fsd kernel driver service..." -ForegroundColor Yellow +$null = & $scExe query Ext2Fsd 2>&1 +if ($LASTEXITCODE -eq 0) { + $null = & $scExe stop Ext2Fsd 2>&1 + Start-Sleep -Seconds 2 + $null = & $scExe delete Ext2Fsd 2>&1 + Start-Sleep -Seconds 1 + Write-Host " Ext2Fsd service removed" -ForegroundColor Green +} else { + Write-Host " Ext2Fsd service not installed" -ForegroundColor Gray +} + +# 4. Remove driver file +Write-Host "" +Write-Host "Step 4: Removing driver file..." -ForegroundColor Yellow +if ($KeepDriverFile) { + Write-Host " Skipped (KeepDriverFile)" -ForegroundColor Gray +} elseif (Test-Path $systemDriverPath) { + Remove-Item $systemDriverPath -Force -ErrorAction Stop + Write-Host " Removed $systemDriverPath" -ForegroundColor Green +} else { + Write-Host " File not present" -ForegroundColor Gray +} + +Write-Host "" +Write-Host "Uninstall complete." -ForegroundColor Green +Write-Host "" +Write-Host "You can now install the official signed release:" -ForegroundColor Cyan +Write-Host " https://github.com/bobranten/Ext4Fsd/releases/tag/v0.71" -ForegroundColor White +Write-Host " (Ext4Fsd-0.71-setup.exe or equivalent)" -ForegroundColor White +Write-Host "" +Write-Host "After installing the official build, check whether Ext2Srv still shows" -ForegroundColor Cyan +Write-Host " TYPE 110 (interactive) with: sc qc Ext2Srv" -ForegroundColor White +Write-Host "" diff --git a/Scripts/verify_driver_signature.ps1 b/Scripts/verify_driver_signature.ps1 new file mode 100644 index 0000000..9000e19 --- /dev/null +++ b/Scripts/verify_driver_signature.ps1 @@ -0,0 +1,11 @@ +<# +.SYNOPSIS + Verify the digital signature of the Ext4Fsd driver. +.PARAMETER DriverPath + Path to the driver file. +.NOTES + Runs the unified diagnostic script; signature and cert checks are in sections 4–6. +#> +[CmdletBinding()] +param([string]$DriverPath = "C:\Windows\System32\drivers\Ext2Fsd.sys") +& "${PSScriptRoot}\diagnose_ext2fsd.ps1" -DriverPath $DriverPath