I have a slight problem with a service I have written in C++. The service itself functions correctly and is running under the SYSTEM account. During one point of execution, I have to start or stop another service. This, however, is not working. The call to OpenService() returns error code 5, which is "Access denied".

To give a little bit more detail: I have to start an own time provider service that tries to open port 123 on a network adapter, and this port is often already opened by the win32time Service from Windows. What I try to do is to give the user the option to automatically stop this service when my service is starting, and starting it again when it stops.

This service can only be accessed with elevated user privileges on systems that are UAC-capable, I know that, but I always thought that the SYSTEM account would be able to perform this action by default, but apparently I am wrong.

Is it possible somehow to elevate my service (maybe by adapting the privilege level in the manifest to 'requireAdministrator' or something similar)? I haven't tried this yet to be honest, since I fear that the UAC prompt will be stuck in session 0 or things the like. Or is there another way to grant my service running under SYSTEM the privileges to control another service's status?

Any suggestions are very much appreciates, thanks!

EDIT

Okay, here's the code, and I feel a little bit stupid now... I have totally forgotten to check the API thoroughly, because I thought that the parameters of OpenSCManager() and OpenService() can be zero to request all privileges by default, but I have to pass SC_MANAGER_ALL_ACCESS. Sorry for bothering everybody. I will try this tomorrow and close this question when I have the results.

// I am missing SC_MANAGER_ALL_ACCESS here probably...
SC_HANDLE scm = OpenSCManager(nullptr, nullptr, SC_MANAGER_CREATE_SERVICE) ;
if(nullptr == scm) {
/* Handle and return */
}

// ...and possibly here, too
SC_HANDLE svc = OpenService(scm, _T("w32time"), 0);
int lastError = GetLastError();

if(ERROR_SERVICE_DOES_NOT_EXIST == lastError) {
/* Handle and return */
}

if(start) {
    if(0 != StartService(svc, 0, nullptr)) {
        int lastError = GetLastError();
        if(ERROR_SERVICE_ALREADY_RUNNING != lastError) {
            /* Handle */
        }
    }
} else {
    SERVICE_STATUS status;
    QueryServiceStatus(svc, &status);
    if(SERVICE_STOPPED != status.dwCurrentState) {
        if(ControlService(svc, SERVICE_CONTROL_STOP, &status)) {
            do {
                QueryServiceStatus(svc, &status);
            } while(SERVICE_STOPPED != status.dwCurrentState);
        } else {
            /* Handle */
        }
    }
}

CloseServiceHandle(svc);
CloseServiceHandle(scm);
有帮助吗?

解决方案

Okay, the problem was just the missing SC_MANAGER_ALL_ACCESS access right mask. My service can now start/stop the requested other service.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top