Skip to content

Report an actionable error when the PrjFlt driver service is disabled - #2122

Draft
Tyrie Vella (tyrielv) wants to merge 1 commit into
microsoft:masterfrom
tyrielv:tyrielv/fix-prjflt-disabled-start
Draft

Tyrie Vella (tyrielv) wants to merge 1 commit into
microsoft:masterfrom
tyrielv:tyrielv/fix-prjflt-disabled-start

Conversation

@tyrielv

Copy link
Copy Markdown
Contributor

Problem and Context

VFS for Git requires the PrjFlt ProjFS 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.TryStartService calls ServiceController.Start() on the disabled service. The call fails with ERROR_SERVICE_DISABLED (1058), which is caught by a generic Win32Exception handler. EnableAndAttachProjFSHandler.TryEnablePrjFlt then 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 AutoLogger Start handling 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.TryStartService now checks ServiceController.StartType. When the service is Disabled, 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 maps ERROR_SERVICE_DISABLED from a failed Start() as a fallback for the disable-after-check race.
  • TryStartService now reports its failure through an out string error parameter instead of returning only a bool, so the caller can surface the specific message.
  • EnableAndAttachProjFSHandler.TryEnablePrjFlt propagates that message instead of the generic "Failed to start prjflt service", and records the start-failure reason in the TryEnablePrjFlt_Summary health telemetry so a disabled driver is detectable in aggregate.
  • Added a pure internal GetStartServiceFailureError(int nativeErrorCode) seam and unit tests in ProjFSFilterTests covering the disabled error code and other start-failure codes.

VFS for Git requires the PrjFlt ProjFS minifilter driver on every volume.
Its load behavior is governed by the 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 ServiceController.StartType and, when it is
  Disabled, returns a specific error naming the driver and the exact
  elevated command to re-enable it. It also maps ERROR_SERVICE_DISABLED
  from a failed start as a fallback, and now reports its error through an
  out parameter so the caller surfaces the specific message.
- EnableAndAttachProjFSHandler.TryEnablePrjFlt propagates that message
  instead of the generic "Failed to start prjflt service", and records the
  start-failure reason in the health-summary telemetry so a disabled driver
  is detectable in aggregate.
- Add a pure GetStartServiceFailureError seam and unit tests covering the
  disabled error code and other start-failure codes.

Assisted-by: Claude Opus 4.8
Signed-off-by: Tyrie Vella <tyrielv@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant