Skip to content

[Correctness] ServiceManager.UninstallServiceAsync — ChangeServiceConfig called on a handle opened without SERVICE_CHANGE_CONFIG (silent ERROR_ACCESS_DENIED) #985

@Christophe-Rogiers

Description

@Christophe-Rogiers

Severity: Warning

File: src/Servy.Core/Services/ServiceManager.cs:543-635

Code:

```csharp
// Line 560 — handle opened with stop/query/delete only
uint uninstallRights = SERVICE_STOP | SERVICE_QUERY_STATUS | SERVICE_DELETE;
using (var serviceHandle = _windowsServiceApi.OpenService(scmHandle, serviceName, uninstallRights))
{
...

// Line 569-580 — but this requires SERVICE_CHANGE_CONFIG
// Standardize start type before stopping
_windowsServiceApi.ChangeServiceConfig(
    serviceHandle,
    SERVICE_NO_CHANGE,
    SERVICE_DEMAND_START,
    SERVICE_NO_CHANGE,
    null, null, IntPtr.Zero,
    null, null, null, null);

```

Explanation:

The Win32 `ChangeServiceConfig` API requires the `SERVICE_CHANGE_CONFIG` (0x0002) access right on the service handle. `UninstallServiceAsync` opens the handle with `SERVICE_STOP | SERVICE_QUERY_STATUS | SERVICE_DELETE` only — `SERVICE_CHANGE_CONFIG` is missing. The call therefore fails with ERROR_ACCESS_DENIED at runtime, but the return value is also ignored, so the failure is silent. The intent of "standardize start type to demand-start before stopping" never actually takes effect; if the service was Automatic, it stays Automatic until it is finally deleted.

Suggested fix:

Add `SERVICE_CHANGE_CONFIG` to the requested access mask, and check the result:

```csharp
uint uninstallRights = SERVICE_STOP | SERVICE_QUERY_STATUS | SERVICE_DELETE | SERVICE_CHANGE_CONFIG;
...
bool ok = _windowsServiceApi.ChangeServiceConfig(...);
if (!ok)
{
Logger.Warn($"Failed to standardize start type before uninstall for '{serviceName}': Win32 error {_win32ErrorProvider.GetLastWin32Error()}");
}
```

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions