Изменение конфигурации службы


В следующем примере, программа конфигурации службы использует функции ChangeServiceConfig и ChangeServiceConfig2, чтобы изменить параметры конфигурации установленной службы. Программа сначала делает попытку блокировать базу данных, воспрепятствовать Диспетчеру управления службами (SCM) запустить службу, в то время когда она переконфигурируется. Если она успешно блокирует базу данных, программа открывает дескриптор объекта службы, модифицирует его конфигурацию, открывает базу данных, а затем закрывает дескриптор объекта службы. Если программе не удается заблокировать базу данных, она использует функцию QueryServiceLockStatus, чтобы извлечь информацию о блокировке.

#include <windows.h>
#include <stdio.h>

BOOL ReconfigureSampleService(BOOL fDisable, LPSTR lpDesc) 
{ 
    SC_LOCK sclLock; 
    LPQUERY_SERVICE_LOCK_STATUS lpqslsBuf; 
    SERVICE_DESCRIPTION sdBuf;
    DWORD dwBytesNeeded, dwStartType; 
    BOOL bSuccess=TRUE;
 
    // Нужно собрать данные о блокировке базы данных перед реконфигурированием. 
 
    sclLock = LockServiceDatabase(schSCManager); 
 
    // Если база данных не может быть блокирована, то подробный отчет. 
 
    if (sclLock == NULL) 
    { 
        // Выход, если база данных не блокируется другими процессами. 
 
        if (GetLastError() != ERROR_SERVICE_DATABASE_LOCKED) 
        {
            printf("LockServiceDatabase failed (%d)\n", GetLastError()); 
            return FALSE;
        }
 
        // Назначаем буфер для получения деталей о блокировке. 
 
        lpqslsBuf = (LPQUERY_SERVICE_LOCK_STATUS) LocalAlloc( 
            LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS)+256); 
        if (lpqslsBuf == NULL) 
        {
            printf("LocalAlloc failed (%d)\n", GetLastError()); 
            return FALSE;
        }
 
        // Получаем и печатаем информацию о состоянии блокировки. 
 
        if (!QueryServiceLockStatus( 
            schSCManager, 
            lpqslsBuf, 
            sizeof(QUERY_SERVICE_LOCK_STATUS)+256, 
            &dwBytesNeeded) ) 
        {
            printf("QueryServiceLockStatus failed (%d)", GetLastError()); 
            return FALSE;
        }
 
        if (lpqslsBuf->fIsLocked) 
            printf("Locked by: %s, duration: %d seconds\n", 
                lpqslsBuf->lpLockOwner, 
                lpqslsBuf->dwLockDuration); 
        else 
            printf("No longer locked\n"); 
 
        LocalFree(lpqslsBuf); 
    } 
 
    // База данных блокирована, таким образом,  что она сохранит сделанные изменения. 
 
    // Откроем дескриптор службы. 
 
    schService = OpenService( 
        schSCManager,           // база данных SCManager 
        "Sample_Srv",           // имя службы 
        SERVICE_CHANGE_CONFIG); // требуемый уровень доступа - CHANGE 
    if (schService == NULL) 
    {
        printf("OpenService failed (%d)\n", GetLastError()); 
        return FALSE;
    }

    dwStartType = (fDisable) ? SERVICE_DISABLED : 
                            SERVICE_DEMAND_START; 
 
    // Делаем изменения. 

    if (! ChangeServiceConfig( 
        schService,        // дескриптор службы 
        SERVICE_NO_CHANGE, // тип службы: не изменяется 
        dwStartType,       // тип запущенной службы, который изменяется 
        SERVICE_NO_CHANGE, // контроль за ошибками: не изменяется 
        NULL,              // путь к двоичному коду: не изменяется 
        NULL,              // загрузка очередности групп: не изменяется 
        NULL,              // ID признака: не изменяется 
        NULL,              // зависимость от других служб: не изменяется 
        NULL,              // имя учетной записи: не изменяется 
        NULL,              // пароль: не изменяется 
        NULL) )            // показываемое имя: не изменяется
    {
        printf("ChangeServiceConfig failed (%d)\n", GetLastError()); 
        bSuccess = FALSE;
    }
    else 
        printf("ChangeServiceConfig succeeded.\n"); 
 
    sdBuf.lpDescription = lpDesc;

    if( !ChangeServiceConfig2(
        schService,                 // дескриптор службы
        SERVICE_CONFIG_DESCRIPTION, // изменение: описание
        &sdBuf) )                   // значение: новое описание
    {
        printf("ChangeServiceConfig2 failed\n");
        bSuccess = FALSE;
    }
    else
        printf("ChangeServiceConfig2 succeeded\n");

    // Отменим блокировку базы данных. 
 
    UnlockServiceDatabase(sclLock); 
 
    // Закроем дескриптор службы. 
 
    CloseServiceHandle(schService); 
    return bSuccess;
}

 

Назад в оглавление
На главную страницу

Hosted by uCoz