Changing a Service Configuration

In the following example, a service configuration program uses the ChangeServiceConfig function to change the configuration parameters of an installed service. The program first tries to lock the database, to prevent the SCM from starting a service while it is being reconfigured. If it successfully locks the database, the program opens a handle to the service object, modifies its configuration, unlocks the database, and then closes the service object handle. If the program does not successfully in lock the database, it uses the QueryServiceLockStatus function to retrieve information about the lock.

VOID ReconfigureSampleService(BOOL fDisable) 
{ 
    SC_LOCK sclLock; 
    LPQUERY_SERVICE_LOCK_STATUS lpqslsBuf; 
    DWORD dwBytesNeeded, dwStartType; 
 
    // Need to acquire database lock before reconfiguring. 
 
    sclLock = LockServiceDatabase(schSCManager); 
 
    // If the database cannot be locked, report the details. 
 
    if (sclLock == NULL) 
    { 
        // Exit if the database is not locked by another process. 
 
        if (GetLastError() != ERROR_SERVICE_DATABASE_LOCKED) 
            MyErrorExit("LockServiceDatabase"); 
 
        // Allocate a buffer to get details about the lock. 
 
        lpqslsBuf = (LPQUERY_SERVICE_LOCK_STATUS) LocalAlloc( 
            LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS)+256); 
        if (lpqslsBuf == NULL) 
            MyErrorExit("LocalAlloc"); 
 
        // Get and print the lock status information. 
 
        if (!QueryServiceLockStatus( 
            schSCManager, 
            lpqslsBuf, 
            sizeof(QUERY_SERVICE_LOCK_STATUS)+256, 
            &dwBytesNeeded) ) 
            MyErrorExit("QueryServiceLockStatus"); 
 
        if (lpqslsBuf->fIsLocked) 
            printf("Locked by: %s, duration: %d seconds\n", 
                lpqslsBuf->lpLockOwner, 
                lpqslsBuf->dwLockDuration); 
        else 
            printf("No longer locked\n"); 
 
        LocalFree(lpqslsBuf); 
        MyErrorExit("Could not lock database"); 
    } 
 
    // The database is locked, so it is safe to make changes. 
 
    // Open a handle to the service. 
 
    schService = OpenService( 
        schSCManager,           // SCManager database 
        TEXT("Sample_Srv"),     // name of service 
        SERVICE_CHANGE_CONFIG); // need CHANGE access 
    if (schService == NULL) 
        MyErrorExit("OpenService"); 
 
    dwStartType = (fDisable) ? SERVICE_DISABLED : 
                            SERVICE_DEMAND_START; 
 
    if (! ChangeServiceConfig( 
        schService,        // handle of service 
        SERVICE_NO_CHANGE, // service type: no change 
        dwStartType,       // change service start type 
        SERVICE_NO_CHANGE, // error control: no change 
        NULL,              // binary path: no change 
        NULL,              // load order group: no change 
        NULL,              // tag ID: no change 
        NULL,              // dependencies: no change 
        NULL,              // account name: no change 
        NULL) )            // password: no change 
    {
        MyErrorExit("ChangeServiceConfig"); 
    }
    else 
        printf("ChangeServiceConfig SUCCESS\n"); 
 
    // Release the database lock. 
 
    UnlockServiceDatabase(sclLock); 
 
    // Close the handle to the service. 
 
    CloseServiceHandle(schService); 
}