Repository navigation
Report an actionable error when the PrjFlt driver service is disabled - #2122
Tyrie Vella (tyrielv) wants to merge 1 commit into
Conversation
Nathan Baird (ShiningMassXAcc)
left a comment
There was a problem hiding this comment.
Review pass over this PR. 5 comment(s).
d0efb6b to
3187f0f
Compare
Nathan Baird (ShiningMassXAcc)
left a comment
There was a problem hiding this comment.
Re-review of the amended commit. All five of my earlier threads are genuinely addressed — thank you. Two new findings below; the first one I think inverts the PR's premise, so flagging it before this lands.
CI is green across every leg.
Nathan Baird (ShiningMassXAcc)
left a comment
There was a problem hiding this comment.
The current head is unchanged since the prior review. Requesting changes for the existing High finding: wrapped native service-start failures still enter the InvalidOperationException handler and are reported as "service was not found," bypassing the intended Win32 error mapping. Please address the existing thread and cover the wrapped-exception shape before merge:
#2122 (comment)
The existing Medium request for stable telemetry reason codes also remains:
#2122 (comment)
These are references to the original findings, not new duplicate inline threads.
VFS for Git requires the PrjFlt ProjFS minifilter driver on every volume. Its load behavior is governed by its service Start type. When a security baseline, an anti-virus product, Group Policy, or manual troubleshooting disables the service, the driver cannot start. Today ProjFSFilter.TryStartService calls ServiceController.Start() on the disabled service. That fails with ERROR_SERVICE_DISABLED (1058), which is caught by a generic Win32Exception handler and surfaces to the user as the dead-end message "Failed to start prjflt service" with no indication that the driver is disabled and no way to fix it. Nothing else in the product detects this state (the existing AutoLogger Start handling is an unrelated ETW logging key). Detect the disabled state and report it, rather than silently re-enabling a driver that an administrator or security tool may have disabled on purpose. Changes: - TryStartService checks the service start type only when the service is not already running, so an already-running service succeeds regardless of its start type. When the service is not running and its start type is Disabled, it returns a specific error naming the driver and the exact elevated command to re-enable it. - ServiceController reports a failed native service call as an InvalidOperationException that wraps the Win32Exception. TryStartService unwraps it and maps the native error code to a ServiceStartFailureReason: ERROR_SERVICE_DISABLED is ServiceDisabled, ERROR_SERVICE_DOES_NOT_EXIST is ServiceNotFound, and any other code is StartFailed. Only a missing service is reported as "not found". - TryStartService reports its result through out parameters, so the caller surfaces the specific message instead of the generic "Failed to start prjflt service". - EnableAndAttachProjFSHandler.TryEnablePrjFlt records the ServiceStartFailureReason in the TryEnablePrjFlt_Summary health telemetry. The reason is a stable code, so rewording the user-facing message does not change the metric. - Added unit tests that cover the disabled and enabled start types, and the error-code mapping through the wrapped InvalidOperationException shape. Assisted-by: Claude Opus 4.8 Signed-off-by: Tyrie Vella <tyrielv@gmail.com>
3187f0f to
c248802
Compare
|
[KeithBot]: 🟡 Medium · Design — Installer drops this message: exit code 4 still shows a dead-end fatal error Location: After install or upgrade, Setup.iss runs Evidence: Fix: Include the captured output in the FilterError branch, e.g. 🤖 KeithBot · 1/3 models · verified locally |
|
[KeithBot]: Validated: ✅ Build GVFS.UnitTests at source + base · ✅ ProjFSFilterTests 17/17 at source · 🤖 KeithBot · claude-opus-5.5, gpt-6.1-sol, gemini-4-argon · reply on a thread to dispute |
Problem and Context
VFS for Git requires the
PrjFltProjFS minifilter driver on every volume. The driver's load behavior is governed by its service Start type. A security-hardening baseline, an anti-virus/EDR product, Group Policy, or manual troubleshooting can set the service to Disabled. When that happens, VFS for Git cannot start the driver.Today
ProjFSFilter.TryStartServicecallsServiceController.Start()on the disabled service. The call fails withERROR_SERVICE_DISABLED(1058), which is caught by a genericWin32Exceptionhandler.EnableAndAttachProjFSHandler.TryEnablePrjFltthen reports the dead-end message "Failed to start prjflt service" — with no indication that the driver is disabled and no hint at the fix. No other code path detects or reports this state. (The existing AutoLoggerStarthandling is an unrelated ETW logging key, not the driver service.)This change detects the disabled state and reports it with an actionable message. It does not re-enable the driver: a disabled driver is often disabled deliberately by an administrator or a security tool, so silently re-enabling it would change the machine's security posture without consent.
Changes
ProjFSFilter.TryStartServicenow checksServiceController.StartType. When the service isDisabled, it returns a specific error that names the driver and gives the exact elevated command to re-enable it (sc.exe config prjflt start= auto). It also mapsERROR_SERVICE_DISABLEDfrom a failedStart()as a fallback for the disable-after-check race.TryStartServicenow reports its failure through anout string errorparameter instead of returning only a bool, so the caller can surface the specific message.EnableAndAttachProjFSHandler.TryEnablePrjFltpropagates that message instead of the generic "Failed to start prjflt service", and records the start-failure reason in theTryEnablePrjFlt_Summaryhealth telemetry so a disabled driver is detectable in aggregate.internal GetStartServiceFailureError(int nativeErrorCode)seam and unit tests inProjFSFilterTestscovering the disabled error code and other start-failure codes.