Код (Text): do { scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); sc_s = CreateService(scm, ServiceName, ServiceName, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szDriverFile, NULL, NULL, NULL, NULL, NULL); while (sc_s == NULL && GetLastError() == ERROR_SERVICE_EXISTS) { CloseServiceHandle(sc_s); CloseServiceHandle(scm); sc_s = scm = NULL; scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); sc_s = OpenService(scm, ServiceName, DELETE); BOOL k = DeleteService(sc_s); CloseServiceHandle(sc_s); CloseServiceHandle(scm); sc_s = scm = NULL; } m = StartService(sc_s, NULL, NULL); } while (!m); В данном коде после удаления сервиса не могу создать новый. Функция GetLastError() возвращает следующее: "Сервис уже отмечен для удаления". Кто-нибудь сталкивался с такой проблемой?
Сервис ещё не удален и присутствует в бд scm. На самом деле, функция DeleteService ничего ниоткуда не удаляет. Она только сообщает системе, что это можно сделать, когда наступит благоприятный момент. А он наступит тогда, когда все описатели службы будут закрыты. Т.к. мы все еще держим описатель hService открытым, то удаления не происходит. Если попытаться вызвать DeleteService повторно, то он завершится неудачей, а последующий вызов функции GetLastError вернет ERROR_SERVICE_MARKED_FOR_DELETE. (выдержка из статьи Four-F) Скорее всего присутствует описатель не закрытый, возможно от scm (то есть служба ещё запущена). Нужно закрыть все описатели.
Кто-нибудь знает, существует ли возможность ожидания окончания выполнения потока сервиса-драйвера в ring 3?
Попробуй получить хэндл службы и заюзать WaitForSingleObject. Не уверен что будет работать. Если не получится можно тоже самое сделать для процесса службы
Нед. Есть юзермодные службы (их обычно и называют службами), а есть кернелмодные (драйверы). Для юзермодных точно можно получить хендл процесса, для других не знаю. А что через хендл службы не получается?
Есть ещё сервисы в виде dll, которые живут внутри процессов svchost.exe, причём в одном процессе может быть несколько служб, так что с хэндлом процесса в этом случае решение не прокатит.
Теперь возникла проблема с остановкой сервиса. Функция StartService не завершается, пока сам сервис не прекратит свою работу. Поэтому останавливать сервис приходится из другого потока. Но вызов функций ControlService(sc_s, SERVICE_CONTROL_STOP, NULL); ControlService(sc_s, SERVICE_CONTROL_SHUTDOWN, NULL); приводит к ошибке "Отказано в доступе". Кто знает, как можно остановить сервис из другого потока?
Неправильный сервис значит: When a driver service is started, the StartService function does not return until the device driver has finished initializing. (возврат из функции после завершения инициализации). В любом случае, раз отказано в доступе => значит прав недостаточно => твой хэдл не имеет соответствующих прав доступа или, вероятно, ты что-то делаешь неправильно внутри службы. Тебе нужен SERVICE_STOP (смотри msdn)
Неправильно это, заставлять вызывающую программу ждать. Она ведь думает что идет инициализация.. Хотя и не так важно это все