Функция HandlerEx
октября 12 2009 by admin in СлужбыКаждая служба, содержащаяся в исполняемом модуле, должна иметь связанную с ней функцию HandlerEx-.
DWORD WINAPI HandlerEx( DWORD dwControl, DWORD dwEventType, PVOID pvEventData, PVOID pvContext);
Я называю эту функцию HandlerEx, по ее имя — дело вашего вкуса: ведь вы передаете ее адрес как параметр функции RegisterServiceCtrlHandlerEx. Однако вы не можете иметь две одноименных функции HandlerEx в одном исполняемом файле, иначе компилятор или компоновщик выдадут ошибку при попытке сборки вашего проекта.
Большую часть времени основной поток процесса находится в состоянии ожидания в результате обращения к функции StartServiceCtrlDispatcher. Когда SCP требуется управление службой, SCM связывается с основным потоком процесса, в результате чего этот поток разблокируется и вызывает функцию HandlerEx соответствующей службы. Например, когда администратор с помощью модульного компонента Services останавливает службу, этот компонент взаимодействует с выбранным администратором локальным или удаленным SCM. В итоге SCM выводит из ожидания основной поток исполняемого модуля службы, который вызывает функцию HandlerEx требуемой службы, передавая ей управляющий код SERVICE_CONTROL_STOP.
Кроме того, SCM сообщает функции HandlerEx службы об устройстве, профиле оборудования и событиях, связанных с питанием компьютера. Эти уведомления позволяют службе перенастроить саму себя так, чтобы адекватно реагировать на изменения в системе.
Поскольку HandlerEx исполняется основным потоком, а служба — другим, может возникнуть необходимость взаимодействия HandlerEx с потоком службы. Стандартного способа такого взаимодействия нет-, выбранный метод будет зависеть от способа реализации службы. Вы можете организовать очередь вызовов асинхронных процедур (АРС), отправлять состояние завершения ввода-вывода, сообщение в окно или действовать иначе. Я рекомендую выбрать тот или иной механизм очередей, как, например, те, которые я только что упоминал (применяемые во избежание синхронизации потоков HandlerEx и Service-Main). Лично я всегда управляю этим взаимодействием, посылая состояние завершения ввода-вывода.
В функцию HandlerEx передаются четыре параметра. Первый, dwControl, указывает запрашиваемую операцию или уведомление. Он указывает уведомление об устройстве, профиле оборудования или событии, связанном с питанием, а параметры dwEventType и pvEventData содержат более конкретную информацию об операции или уведомлении. Параметр pvContext — это определенное пользователем значение, которое изначально передавалось функции Regis-terServiceCtrllkmdlerEx. Используя это значение, вы можете создать единственную HandlerEx, используемую всеми службами в одном исполняемом модуле. Значение pvContext может определять конкретную службу, с которой должна взаимодействовать HandlerEx. В следующем разделе я расскажу, как обрабатывать эти управляющие коды и уведомления.
Значение, возвращаемое HandlerEx, позволяет службе вернуть данные SCM. Если HandlerEx не обрабатывает некоторый управляющий код, возвращайте начение ERROR_CALL_NOT_IMPLEMENTED. Чтобы отклонить запрос, верните любой другой код ошибки Win32. Для всех других управляющих кодов HandlerEx должна возвращать NO_ERROR.