Для студентов згиа специальности 080403 ”Программное обеспечение




НазваниеДля студентов згиа специальности 080403 ”Программное обеспечение
страница11/34
Дата публикации25.02.2013
Размер3.71 Mb.
ТипМетодическое пособие
uchebilka.ru > Информатика > Методическое пособие
1   ...   7   8   9   10   11   12   13   14   ...   34
Раздел HKEY_LOCAL_MACHINE

Содержит глобальную информацию о конфигурации компьютера. Информация содержащаяся здесь действует применительно ко всем пользователям в системе. На верхнем уровне иерархии для подразделов этого раздела имеются ссылки которые называются HKEY_CLASSES_ROOT, HKEY_CURRENT_CONFIG и HKEY_DYN_DATA.

^ Подраздел HARDWARE

Описание аппаратного обеспечения системы и все сопоставления драйверов с устройствами. Диспетчер устройств Windows смотрит всего лишь этот раздел реестра. Если смотреть через редактор реестра, то мы мало чего увидим, потому что много параметров скрыто. Но мы можем использовать API функции для получения этих значений.

^ Подраздел SAM

Здесь находиться информация о локальных учётных записях и группах, например пароли, определения групп и сопоставления с доменами. Windows 2000 Server, работающий как контроллер, хранит учетные данные домена и групп в Active Directory – базе данных, которая содержит общедоменные параметры и сведения. По умолчанию дескриптор защиты раздела SAM сконфигурирован так, что к нему не имеет доступ даже администратор.

^ Подраздел Security

Здесь хранятся данные которые относятся к общесистемным политикам безопасности, а также сведения о правах назначенных пользователям и хранящихся паролей не относящихся к учетным записям системы. По умолчанию содержимое этого подраздела недоступно для просмотра, поскольку параметры защиты разрешают доступ только по учетной записи System.

^ Подраздел Software

Здесь хранится общесистемная конфигурационная информация не требуемая при загрузке системы. Здесь сохраняют свои настройки приложения сторонних разработчиков.

^ Подраздел System

Здесь хранится общесистемная конфигурационная информация требуемая при загрузке системы. Эта информация критична для загрузки системы поэтому Windows делает её копию, называемую последней удачной конфигурацией (last known good control set).

^ Раздел HKEY_CLASSES_ROOT

Cодержит двух основных типов – сопоставления расширений файлов и регистрационные данные COM-классов. Информация о классах хранится в разделе HKCU\Software\Classes. Регистрационные данные классов специфичные для текущего пользователя хранятся в файле “\Documents and Settings\%USERNAME%\Local Settings\Application Data\Microsoft\Windows\Usrclass.dat”. До ОС Windows 2000 не было регистрационных данных классов для каждого пользователя, были только общесистемные данные. В связи с этим непривилегированные пользователи не могут изменять общесистемные данные классов.

^ Раздел HKEY_CURRENT_USER

В этом разделе хранится информация специфичная для текущего пользователя. Т.е. для каждого пользователя имеется своя копия этого раздела. Этот раздел не содержит системной информации. Здесь хранятся, к примеру переменные окружения для текущего пользователя, настройки рабочего стола и т.д. Важно заметить, что на самом деле этот раздел разделом не является, а является ссылкой на соответствующий подраздел в HKEY_USERS.

^ Раздел HKEY_USERS

Здесь содержаться копии разделов HKEY_CURRENT_USER для всех профилей пользователей в системе. Имя подраздела соответствует SID’у пользователя. Здесь также присутствует подраздел .DEFAULT связанный с профилем рабочей станции по умолчанию. Этот профиль предназначен для процессов выполняемых под системной учетной записью.

^ Раздел HKEY_CURRENT_CONFIG

Это ссылка на текущий профиль оборудования, хранящийся в HKLM\System\CurrentControlSet\Hardware Profiles\Current.

Резервирование реестра

Реестр является базой данных, критичной для функционирования системы. Если файлы реестра повредятся, это чревато потерей работоспособности ОС. Для того, чтобы поврежденный реестр можно было восстановить производят его резервирование. Скопировать файлы обычным способом не получиться, потому что они открыты другими приложениями. Есть несколько различных способов для резервного копирования. Ниже приводиться их описание.

1) Резервирование с помощью программы архивации Windows. Запустить эту программу можно из меню Пуск:

"Пуск\Программы\Стандартные\Служебные\Архивация данных" или в командной строке набрать ntbackup. При выполнении резервного копирования система сохраняет копии файлов реестра в папке %SystemRoot%\repair. Для восстановления необходимо создать дискету аварийного восстановления. При создании этой дискеты делается резервная копия системы. Файлы реестра копируются в папку указанную выше. Понадобится всего одна дискета. При загрузке с этой дискеты программа будет использовать файлы из папки repair.

2) Можно экспортировать весь реестр или его часть в reg-файл, иcпользуя редактор реестра Windows. Используя такой способ естественно реестр резервируется не полностью. Например раздел SAM не резервируется вообще.

Наиболее предпочтительным является первый способ, т.к. он поддерживается системой.

^ Безопасность реестра

В ОС Windows 2000/XP можно поставить специальные разрешения на доступ к любому разделу для определенного пользователя. Такая схема называется управление избирательным доступом. Вот список всех разрешений, которые могут быть применены для разделов реестра:

• Полный доступ

• Запрос значения

• Задание значения

• Создание подраздела

• Перечисление подразделов

• Уведомление

• Создание связи

• Запись DAC

• Смена владельца

• Чтение разрешений

Безопасность реестра поддерживается стандартными механизмами защиты объектов Windows.
^ API функции для работы с реестром

При программировании приложений программы используют реестр для хранения своих конфигурационных данных, а также для получения различной информации. Интерфейс WinAPI предоставляет набор функций для работы с реестром. Вот их список:

RegCloseKey - закрыть ключ;

RegConnectRegistry - подключиться к удаленному реестру;

RegCreateKey - создать раздел (для Windows 95);

RegCreateKeyEx - создать раздел (для всех версий Windows выше Windows 95);

RegDeleteKey - удаление раздела;

RegDeleteValue - удалить параметр;

RegEnumKey- перечисление всех ключей в данном открытом ключе (для Windows 95);

RegEnumKeyEx - перечисление всех ключей в данном открытом ключе (для всех версий Windows выше Windows 95);

RegEnumValue - перечисление всех параметров в данном открытом ключе;

RegFlushKey - записывает все изменения данного открытого ключа на диск в файл реестра;

RegGetKeySecurity - восстанавливает копию описателя защиты для данного открытого ключа;

RegLoadKey - загружает подключ в разделы HKEY_USER или HKEY_LOCAL_MACHINE из HIV файла;

RegNotifyChangeKeyValue - уведомляет вызывающую программу об изменении атрибутов или состава ключа;

RegOpenKey - открыть ключ (для Windows 95);

RegOpenKeyEx - открыть ключ (для всех версий Windows выше Windows 95);

RegQueryInfoKey - возвращает информацию о ключе;

RegQueryMultipleValues - возвращает тип и данные для списка параметров;

RegQueryValue - считать значение параметра (для Windows 95);

RegQueryValueEx - считать значение параметра (для всех версий Windows выше Windows 95);

RegReplaceKey - заменяет файл ассоциированный с ключом и все его подключи новым файлом

RegRestoreKey - читает информацию из файла реестра и записывает в реестр;

RegSaveKey - сохраняет ключ и все его подключи в новый файл;

RegSetKeySecurity - задает параметры безопасности для текущего открытого ключа;

RegSetValue - изменить параметр (для Windows 95);

RegSetValueEx - изменить параметр (для всех версий Windows выше Windows 95);

RegUnLoadKey - выгружает ключ и подключ из реестра.


    1. ^ Сервисы в Windows

      1. Концепция сервиса

Сервис это процесс, который выполняет служебные функции. Сервисы являются аналогами резидентных программ, которые использовались в операционных системах, предшествующих операционной системе Windows NT [5,36]. То есть сервис это такая программа, которая запускается при загрузке операционной системы или в процессе ее работы по специальной команде и заканчивает свою работу при завершении работы операционной системы или по специальной команде. Обычно сервисы выполняют определенные служебные функции, необходимые для работы приложений или какого-то конкретного приложения. Примером сервиса может служить фоновый процесс, который обеспечивает доступ к базе данных — такие сервисы также называются серверами. Другой тип сервисов — это программы, обеспечивающие доступ к внешним устройствам, такие сервисы называются драйверами. Как сервис также может быть реализован процесс, отслеживающий работу некоторого приложения, такие сервисы также называются мониторами.

Сервисы реализованы только на платформах Windows NT/2000/XP. Управляет работой сервисов специальная программа операционной системы, которая называется менеджер сервисов (Service Control Manager, SCM). Ниже перечислены функции, которые выполняет менеджер сервисов:

  • поддержка базы данных установленных сервисов;

  • запуск сервисов при загрузке операционной системы;

  • поддержка информации о состоянии работающих сервисов;

  • передача управляющих запросов работающим сервисам;

  • блокировка и разблокирование базы данных сервисов.

Для того чтобы менеджер сервисов знал о существовании определенного сервиса – его нужно установить. Информация обо всех установленных сервисах хранится в реестре операционной системы Windows под ключом HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services. Сервис может запускаться как операционной системой при загрузке, так и программно – из приложения. Если сервис больше не нужен, то его нужно удалить из базы данных операционной системы. Для работы с сервисами в операционных системах Windows предназначены специальные функции из Win32 API. Управлять работой сервисов можно также и через панель управления, а именно Control Panel | Administrative Tools | Services (Панель управления | Администрирование | Службы). Мы будут рассматривать только программные средства для управления сервисами.

В заключение скажем об отладке сервисов. Так как сервисы запускаются операционной системой, то невозможно выполнить отладку сервиса как обычного консольного приложения. В этом случае можно использовать отладчик так, как это описано в справочной системе MSDN (в разделе Windows Development | Windows Base Services | DLL, Processes and Threads | SDK Documentation | DLL, Processes and Threads | Services | About Services | Debugging a Service). Но можно использовать для отладки сервиса старые методы отладки программ. А именно, создать так называемый лог-файл и записывать в него протокол работы сервиса и его состояние, включающее контекст памяти, в контрольных точках.

      1. ^ Структура сервиса

Так как сервисы работают под управлением менеджера сервисов, то они должны удовлетворять определенным соглашениям, которые определяют интерфейс сервиса. Сам сервис может быть как консольным приложением, так и приложением с графическим интерфейсом. Это не имеет значения, т. к. сервисы могут взаимодействовать с пользователем только через рабочий стол или через окно сообщений. Поэтому обычно сервисы оформляются как консольные приложения. Кроме того, каждый сервис должен содержать две функции обратного вызова, которые вызываются операционной системой. Одна из этих функций определяет точку входа сервиса, т. е., собственно, и является сервисом, а вторая — должна реагировать на управляющие сигналы от операционной системы. Отсюда следует, что если консольное приложение определяет один сервис, то оно должно иметь следующую структуру:

// главная функция консольного приложения

int main (int argc, char *argv) { ... }

// точка входа сервиса

VOID WINAPI ServiсeMain(DWORD dwArgc, LPTSTR *lpszArgv){ ... }

// обработчик запросов

VOID WINAPI ServiceCtrlHandler (DWORD dwControl) { ... }

Конечно, допускается присутствие и других функций, но эти три функции должны быть обязательно.

Главной задачей функции main является запуск диспетчера сервиса, который является потоком и управляет этим сервисом. Диспетчер сервиса получает управляющие сигналы от менеджера сервисов по именованному каналу и передает эти запросы функции ServiceCtrlHandler, которая обрабатывает эти управляющие запросы. Если в приложении несколько сервисов, то для каждого сервиса запускается свой диспетчер и для каждого диспетчера определяется своя функция обработки управляющих запросов, которая выполняется в контексте соответствующего диспетчера сервисов. Запуск диспетчеров сервисов выполняется при помощи вызова функции StartServiceCtrlDispatcher.

Для подключения обработчика запросов к сервису используется функция RegisterServiceCtrlHandler.

Функция, определяющая точку входа сервиса, должна иметь следующий прототип:

VOID WINAPI имя_точки_входа(DWORD dwArgc, LPTSTR *lpszArgv);

Если определяется только один сервис, то эта функция обычно называется ServiceMain, хотя возможны и другие, более подходящие по смыслу имена точек входа сервисов. Если же в приложении определяется несколько сервисов, то естественно каждый из них должен иметь свое имя. Эта функция содержит два параметра, которые аналогичны параметрам функции main консольного приложения. Параметр dwArgc содержит количество аргументов в массиве lpszArgv, а сам этот массив содержит адреса строк. Причем первый из этих адресов указывает на строку, содержащую имя сервиса, а последующие аргументы передаются из функции StartService.

Функция, определяющая обработчик управляющих запросов, должна иметь следующий прототип:

VOID WINAPI имя_обработчика_запросов(DWORD dwControl);

Если определяется только один сервис, то эта функция обычно называется ServiceCtrlHandler. Если же в приложении определяется несколько сервисов, то естественно, что обработчик запросов для каждого сервиса должен иметь свое имя. Эта функция содержит только один параметр, который содержит код управляющего сигнала.

      1. ^ Организация функции main

Как уже было сказано, главной задачей функции main является запуск диспетчера сервиса для каждого из сервисов. Для запуска диспетчера используется функция StartServiceCtrlDispatcher, которая должна быть вызвана в течение 30 секунд с момента запуска программы main. Поэтому всю необходимую инициализацию сервиса нужно делать в самом сервисе, т. е. в теле функции ServiceMain. Если же необходимо выполнить инициализацию глобальных переменных, то для этой цели лучше запустить из функции main отдельный поток.

Функция StartServiceCtrlDispatcher имеет следующий прототип:

BOOL StartServiceCtrlDispatcher(

CONST LPSERVICE_TABLE_ENTRY IpServiceTable // таблица сервисов

);

Функция имеет единственный параметр, который указывает на таблицу сервисов, которая представляет собой массив. Каждый элемент этого массива имеет следующий тип:

typedef struct _SERVICE_TABLE_ENTRY{

LPSTR lpServiceName; // имя сервиса

LPSERVICE_MAIN_FUNCTION lpServiceProc; // функция сервиса

} SERVICE_TABLE_ENTRY, * LPSERVTCE_TABLE_ENTRY;

Поле lpServiceName содержит указатель на строку, содержащую имя сервиса, а поле IpServiceProc указывает на функцию самого сервиса. При этом отметим, что последний элемент таблицы сервисов должен содержать пустую структуру, т. е. структуру с пустыми указателями.

Ниже приведен пример программы main, которая запускает диспетчер для одного сервиса. Перед телом функции объявлены все глобальные имена, которые в дальнейшем используются в сервисе.

Листинг 2.6. Пример функции main сервиса [5].

#include

#include

char service_name[ ]="DemoService" ;//имя сервиса
SERVICE_STATUS service_status;

SERVICE_STATUS_HANDLE hServiceStatus;
VOID WINAPI ServiceMain (DWORD dwArgc, LPTSTR *lpszArgv);

VOID WINAPI ServiceCtrlHandler(DWORD dwControl);

ofstream out; //выходной файл для протокола работы сервиса

int nCount; // счетчик
// главная функция приложения

int main()

{

// инициализируем структуру сервисов

SERVICE_TABLE_ENTRY service_table[] = {

{service_name, ServiceMain}, // имя сервиса и функция сервиса

{ NULL, NULL } // больше сервисов нет

};
// запускаем диспетчер сервиса

if (!StartServiceCtrlDispatcher(service_table)) {

out.open("С:\\ServiceFile.log") ;

out<<"Start service control dispatcher failed."; out.close();

return 0;

}

return 0;

}

      1. ^ Организация функции ServiceMain

Как уже говорилось, функция, определяющая точку входа сервиса, должна иметь следующий прототип:

VOID WINAPI имя_точки_входа(DWORD dwArgc, LPTSTR *lpszArgv);

Если в приложении определен только один сервис, то эта функция обычно называется ServiceMain.

Функция ServiceMain должна выполнить следующую последовательность действий:

  • Немедленно запустить обработчик управляющих команд от менеджера сервисов, вызвав функцию RegisterServiceCtrlHandler.

  • Установить стартующее состояние сервиса SERVICE_START_PENDING посредством вызова функции SetServiceStatus.

  • Провести локальную инициализацию сервиса.

  • Установить рабочее состояние сервиса SERVICE_RUNNING посредством вызова функции SetServiceStatus.

  • Выполнять работу сервиса, учитывая состояния сервиса, которые могут изменяться обработчиком управляющих команд от менеджера сервисов.

  • После перехода в состояние останова SERVICE_STOPPED выполнить освобождение захваченных ресурсов и закончить работу.

Опишем подробно функции, которые должны использоваться в сервисе.

Для запуска обработчика управляющих команд от менеджера сервисов сер-вис должеен использовать функцию RegisterServiceCtrlHandler, которая имеет следующий прототип:

SERVICE_STATUS_HANDLE RegisterServiceCtrlHandler(

LPCTSTR lpServiceName, // имя сервиса

LPHANDLER_FUNCTION lpHandlerProc // функция обработчика

) ;

В случае успешного завершения функция возвращает дескриптор состояния сервиса, а в случае неудачи – ноль. Параметр lpServiceName этой функции должен указывать на строку, которая содержит имя сервиса, а параметр lpHandlerProc — на процедуру обработки управляющих команд от менеджера сервисов.

Для запуска обработчика управляющих команд может также использоваться функция RegisterServiceCtrlHandlerEx, которая имеет более широкие возможности по сравнению с функцией RegisterServiceCtrlHandler.

Для изменения состояния сервиса используется функция SetServiceStatus, которая имеет следующий прототип:

BOOL SetServiceStatus(

SERVICE_STATUS_HANDLE hServiceStatus, //дескриптор состояния сервиса

LPSERVTCE_STATUS lpServiceStatus // структура состояния

) ;

В случае успешного завершения функция возвращает ненулевое значение, а в случае неудачи – FALSE.

Параметр hservicestatus должен содержать дескриптор состояния сервиса, который был получен функцией RegisterServiceCtrlHandler.

Параметр lpServiceStatus должен указывать на структуру типа SERVICE_STATUS, которая содержит информацию о состоянии сервиса. Эта структура имеет следующий формат:

typedef struct _SERVICE_STATUS {

DWORD dwServiceType; // тип сервиса

DWORD dwCurrentState; // текущее состояние сервиса

DWORD dwControlsAccepted; // допускаемое управление

DWORD dwWin32ExitCode; // код возврата для Win32

DWORD dwServiceSpecificExitCode; // специфический код возврата

// сервиса

DWORD dwCheckPoint; // контрольная точка

DWORD dwWaitHint; // период ожидания команды управления

} SERVICE_STATUS, *LPSERVTCE_STATUS;

Поле dwServiceType содержит тип сервиса и может принимать следующие значения:

  • SERVICE_WIN32_OWN_PROCESS – сервис является самостоятельным процессом;

  • SERVICE_WIN32_SHARE_PROCESS — сервис разделяет процесс с другими сервисами;

  • SERVICE_KERNEL_DRIVER – сервис является драйвером устройства;

  • SERVICE_FILE_SYSTEM_DRIVER – сервис является драйвером файловой системы.

Кроме того, первые два флага могут быть установлены совместно с флагом SERVICE_INTERACTIVE_PROCESS – сервис может взаимодействовать с рабо-чим столом. То есть сервисы, которые не являются драйверами, могут взаимодействовать с рабочим столом.

Поле dwCurrentState содержит текущее состояние сервиса. Это поле может принимать одно из следующих значений:

  • SERVICE_STOPPED – сервис остановлен;

  • SERVICE_START_PENDING – сервис стартует;

  • SERVICE_STOP_PENDING – сервис останавливается;

  • SERVICE_RUNNING – сервис работает;

  • SERVICE_CONTINUE_PENDING – сервис переходит в рабочее состояние;

  • SERVICE_PAUSE_PENDING — сервис переходит в состояние ожидания;

  • SERVICE_PAUSED – сервис находится в состоянии ожидания.

Поле dwControlsAccepted содержит коды управляющих команд, которые могут быть переданы обработчику этих команд, определенному в приложении. В этом поле может быть установлена любая комбинация следующих флагов:

  • SERVICE_ACCEPT_STOP – можно остановить сервис;

  • SERVICE_ACCEPT_PAUSE_CONTINUE – можно приостановить и возобновить сервис;

  • SERVICE_ACCEPT_SHUTDOWN – сервис информируется о выключении системы.

Кроме того, по умолчанию предполагается, что каждый обработчик может получить команду:

  • SERVICE_CONTROL_INTERROGATE – немедленно обновить статус сервиса.

Поле dwWin32ExitCode может содержать одно из следующих двух значений:

  • ERROR_SERVICE_SPECIFIC_ERROR – ошибка во время запуска или остановки сервиса;

  • NO_ERROR – ошибки нет.

Если в этом поле установлено значение ERROR_SERVICE_SPECIFIC_ERROR, то код самой ошибки находится в следующем поле dwServiceSpecificExitCode. Этот код может быть получен функцией GetLastError.

Поле dwServiceSpecificExitCode содержит код возврата из сервиса, этот код действителен только в том случае, если в поле dwWin32ExitCode установлено значение ERROR_SERVICE_SPECIFIC_ERROR.

Поле dwCheckPoint содержит значение, которое сервис должен периодически увеличивать на единицу, сообщая о продвижении своей работы во время инициализации и длительных переходов из состояния в состояние. Это значение может использоваться программой пользователя, которая отслеживает работу сервиса. Если это значение не используется пользовательской программой и переход из состояния в состояние занимает менее 30 секунд, то оно может быть установлено в 0.

Поле dwWaitHint содержит интервал времени в миллисекундах, в течение которого сервис переходит из состояния в состояние перед вызовом функции установки состояния SetServiceStatus. Если в течение этого интервала не произошло изменение состояния сервиса в поле dwServiceState или не изменилось значение поля dwCheckPoint, то менеджер сервисов считает, что в сервисе произошла ошибка.

В листинге приведен пример функции ServiceMain сервиса.

Листинг 2.7. Пример функции ServiceMain сервиса [5].
VOID WINAPI ServiceMain (DWORD dwArgc, LPTSTR *lpszArgv)

{

// регистрируем обработчик управляющих команд для сервиса

hServiceStatus = RegisterServiceCtrlHandler(

service_name, // имя сервиса

ServiceCtrlHandler // обработчик управляющих команд ) ;

if(!hServiceStatus){

out.open ("С:\\ServiceFile.log");

out<<"Register service control handler failed.";

out.close();
return;

}
// инициализируем структуру состояния сервиса

service_status .dwServiceType = SERVICE_WIN32_OWN_PROCESS;

service_status.dwCurrentState = SERVICE_START_PENDING;

service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP |

SERVICE_ACCEPT_SHUTDOWN ;

service_status.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;

service_status.dwServiceSpecificExitCode = 0;

service_status.dwCheckPoint = 0;

service_status.dwWaitHint = 5000;
// устанавливаем состояние сервиса

if (!SetServiceStatus(hServiceStatus, &service_status)) {

out.open ("C:\\ServiceFile.log");

out<<"Set service status SERVICE_START_PENDING failed.";

out.close();
return;

}
// определяем сервис как работающий

service_status.dwCurrentState = SERVICE_RUNNING;

// нет ошибок

service_status.dwWin32ExitCode = NO_ERROR;

// устанавливаем новое состояние сервиса

if(!SetServiceStatus(hServiceStatus, &service_status))

{

out.open ("С:\\ServiceFile.log”) ;

out<<"Set service status START_PENDING failed.";

out.close();

return;

}
// открываем файл протокола работы сервиса

out.open("С:\\ServiceFile.log");

out<<"The service is started."<
out<<"My name is: " << lpszArgv[0] << endl << flush;

for (int i = 1;i <(int)dwArgc; ++i)

out <<"My "<< i <<" parameter = " << lpszArgv[i] <
// рабочий цикл сервиса

while (service_status.dwCurrentState == SERVICE_RUNNING)

{

++nCount; Sleep(3000);

}

}

      1. ^ Организация обработчика управляющих команд

Функция-обработчик управляющих запросов, должна иметь следующий прототип:

VOID WINAPI имя_обработчика_запросов(DWORD dwControl);

Если приложение содержит только один сервис, то эта функция обычно на-зывается ServiceCtrlHandler. В противном случае обработчик запросов для каждого сервиса должен иметь свое имя. Эта функция содержит только один параметр, который содержит код управляющего сигнала. Возможны следующие управляющие коды:

  • SERVICE_CONTROL_STOP – остановить сервис;

  • SERVICE_CONTROL_PAUSE – приостановить сервис;

  • SERVICE_CONTROL_CONTINUE – возобновить сервис;

  • SERVICE_CONTROL_INTERROGATE – обновить состояние сервиса;

  • SERVICE_CONTROL_SHUTDOWN – закончить работу сервиса.

Дополнительно в операционной системе Windows 2000 допускаются еще и другие коды управляющих команд.

Но обработчик должен обрабатывать только те команды, которые допускаются в поле dwControlsAccepted структуры типа SERVICE_STATUS, рассмотренной ранее. Напомним, что по соглашению обработчик всегда получает сигнал с кодом SERVICE_CONTROL_INTERROGATE, по которому он должен немедленно обновить состояние сервиса. Для обновления состояния сервиса используется функция SetServiceStatus, которая была рассмотрена ранее. Кроме того, обработчик может получать коды, определенные пользователем. Для кодов пользователя зарезервирован диапазон от 128 до 255.

Вызывается обработчик управляющих запросов диспетчером сервиса и, следовательно, выполняется в его контексте. Обработчик должен изменить состояние сервиса в течение 30 секунд, в противном случае диспетчер серви-сов считает, что произошла ошибка. Если для изменения состояния сервиса требуется более продолжительный интервал времени, то для этой цели нуж-но запустить отдельный поток. Для обработки кода SERVICE_CONTROL_SHUTDOWN сервису отводится 20 секунд, в течение которых он должен освободить захваченные им ресурсы.

В листинге приведена функция обработки управляющих команд для сервиса из предыдущего раздела.

Листинг 2.8. Пример функции обработки управляющих команд

VOID WINAPI ServiceCtrlHandler(DWORD dwControl) {

switch(dwControl) {

case SERVICE_CONTROL_STOP: // остановить сервис

// записываем конечное значение счетчика

out << "Count = " << nCount << endl;

out << "The service is finished." << endl << flush;

// закрываем файл

out.close();
// устанавливаем состояние остановки

service_status.dwCurrentState = SERVICE_STOPPED;

// изменить состояние сервиса

SetServiceStatus(hServiceStatus, &service_status);

break;
case SERVICE_CONTROL_SHUTDOWN : // завершить сервис

service_status.dwCurrentState = SERVICE_STOPPED;

// изменить состояние сервиса

SetServiceStatus(hServiceStatus, &service_status);

break;
default:

// увеличиваем значение контрольной точки

++service_status.dwCheckPoint;

// оставляем состояние сервиса без изменения

SetServiceStatus(hServiceStatus, &service_status);

break;

}

return;

}

1   ...   7   8   9   10   11   12   13   14   ...   34

Похожие:

Для студентов згиа специальности 080403 ”Программное обеспечение iconМетодические указания к лабораторному практикуму для студентов згиа...
Методические указания к лабораторному практикуму для студентов згиа специальности 080403 «Программное обеспечение автоматизированных...

Для студентов згиа специальности 080403 ”Программное обеспечение iconМетодические указания для студентов специальности 080403
Згиа [8, 10] и других вузов [4]. Наиболее полно описаны курсовые, дипломные и квалификационные работы, однако большинство положений...

Для студентов згиа специальности 080403 ”Программное обеспечение iconМетодические указания к курсовой работе по дисциплине «Системное...
Методические указания к курсовой работе по дисциплине «Системное программирование и операционные системы» для студентов специальности...

Для студентов згиа специальности 080403 ”Программное обеспечение iconПравила использования программного обеспечения в рамках программы...
Используя программное обеспечение вы тем самым подтверждаете свое согласие придерживаться этих правил. Если вы не согласны, не используйте...

Для студентов згиа специальности 080403 ”Программное обеспечение iconМетодические указания по выполнению лабораторных работ по курсу “
Информационные управляющие системы и технологии, 080403 – Программное обеспечение автоматизированных систем

Для студентов згиа специальности 080403 ”Программное обеспечение iconКлассификация программного обеспечения
В отличие от аппаратного обеспечения, программы, которые выполняются на нем, неосязаемы и классифицируются как программное обеспечение....

Для студентов згиа специальности 080403 ”Программное обеспечение iconКурсовая работа выполняется на основании 'Задания на курсовую работу'...
Целью курсовой работы является закрепление практических навыков самостоятельной постановки и решения задачи обработки данных с помощью...

Для студентов згиа специальности 080403 ”Программное обеспечение icon1. Классификация программного обеспечения
Назначением ЭВМ является выполнение программ. Программа содержит команды, определяющие порядок действии компьютера. Совокупность...

Для студентов згиа специальности 080403 ”Программное обеспечение iconОпорный конспект лекций по дисциплине Компьютерная графика для специальности...
Тема. Основные понятия компьютерной графики. Аппаратное и программное обеспечение

Для студентов згиа специальности 080403 ”Программное обеспечение iconМетодические указания и задание к выполнению курсового проекта по...
Методические указания и задание к выполнению курсового проекта по дисциплине «Алгоритмическое и программное обеспечение электротехнических...

Вы можете разместить ссылку на наш сайт:
Школьные материалы


При копировании материала укажите ссылку © 2013
контакты
uchebilka.ru
Главная страница


<