Алекс Jenter - Программирование на Visual C++. Архив рассылки

Тут можно читать онлайн Алекс Jenter - Программирование на Visual C++. Архив рассылки - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Программирование на Visual C++. Архив рассылки
  • Автор:
  • Жанр:
  • Издательство:
    неизвестно
  • Год:
    неизвестен
  • ISBN:
    нет данных
  • Рейтинг:
    4.33/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Алекс Jenter - Программирование на Visual C++. Архив рассылки краткое содержание

Программирование на Visual C++. Архив рассылки - описание и краткое содержание, автор Алекс Jenter, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.

Программирование на Visual C++. Архив рассылки - читать онлайн бесплатно полную версию (весь текст целиком)

Программирование на Visual C++. Архив рассылки - читать книгу онлайн бесплатно, автор Алекс Jenter
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать
Система безопасности служб

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

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

• Все пользователи имеют права SERVICE_QUERY_CONFIG, SERVICE_QUERY_STATUS, SERVICE_ENUMERATE_DEPENDENTS, SERVICE_INTERROGATE и SERVICE_USER_DEFINED_CONTROL;

• Пользователи, входящие в группу Power Users и учетная запись LocalSystem дополнительно имеют права SERVICE_START, SERVICE_PAUSE_CONTINUE и SERVICE_STOP;

• Пользователи, входящие в группы Administrators и System Operators имеют право SERVICE_ALL_ACCESS.

Службы и интерактивность

По умолчанию интерактивные службы могут выполняться только в контексте безопасности LocalSystem. Это связано с особенностями вывода на экран монитора в Windows NT, где существует, например, такой объект как "Desktop", для работы с которым нужно иметь соответствующие права доступа, которых может не оказаться у произвольной учетной записи, отличной от LocalSystem. Несмотря на то, что в подавляющем большинстве случаев это ограничение несущественно однако иногда существует необходимость создать службу, которая выводила бы информацию на экран монитора и при этом выполнялась бы в контексте безопасности отличном от LocalSystem, например, серверная компонента приложения для запуска приложений на удаленном компьютере.

Следующий фрагмент кода иллюстрирует такую возможность.

// Функция, аналог MessageBox Win32 API

int ServerMessageBox(RPC_BINDING_HANDLE h, LPSTR lpszText, LPSTR lpszTitle, UINT fuStyle) {

DWORD dwThreadId;

HWINSTA hwinstaSave;

HDESK hdeskSave;

HWINSTA hwinstaUser;

HDESK hdeskUser;

int result;

// Запоминаем текущие объекты "Window station" и "Desktop".

GetDesktopWindow();

hwinstaSave = GetProcessWindowStation();

dwThreadId = GetCurrentThreadId();

hdeskSave = GetThreadDesktop(dwThreadId);

// Меняем контекст безопасности на тот,

// который есть у вызавшего клиента RPC

// и получаем доступ к пользовательским

// объектам "Window station" и "Desktop".

RpcImpersonateClient(h);

hwinstaUser = OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);

if (hwinstaUser == NULL) {

RpcRevertToSelf();

return 0;

}

SetProcessWindowStation(hwinstaUser);

hdeskUser = OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);

RpcRevertToSelf();

if (hdeskUser == NULL) {

SetProcessWindowStation(hwinstaSave);

CloseWindowStation(hwinstaUser);

return 0;

}

SetThreadDesktop(hdeskUser);

// Выводим обычное текстовое окно.

result = MessageBox(NULL, lpszText, lpszTitle, fuStyle);

// Восстанавливаем сохраненные объекты

// "Window station" и "Desktop".

SetThreadDesktop(hdeskSave);

SetProcessWindowStation(hwinstaSave);

CloseDesktop(hdeskUser);

CloseWindowStation(hwinstaUser);

return result;

}

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

Пример службы (ключевые фрагменты)

Рассмотрим на примере ключевые фрагменты приложения на языке C++, реализующего службу Windows NT. Для наглядности несущественные части кода опущены.

Функция main

Вот как выглядит код функции main:

void main() {

SERVICE_TABLE_ENTRY steTable[] = {

{SERVICENAME, ServiceMain}, {NULL, NULL}

};

// Устанавливаем соединение с SCM. Внутри этой функции

// происходит прием и диспетчеризация запросов.

StartServiceCtrlDispatcher(steTable);

}

Функция ServiceMain

Особенностью кода, содержащегося в ServiceMain, является то, что часто невозможно заранее предсказать время выполнения той или иной операции, особенно, если учесть, что ее выполнение происходит в операционной системе с вытесняющей многозадачностью. Если операция продлится дольше указанного в параметре вызова SetServiceStatus интервала времени, служба не сможет во-время отправить следующее уведомление, в результате чего SCM остановит ее работу. Примерами потенциально операций могут служить вызовы функций работы с сетью при больших таймаутах или единовременное чтение большого количества информации с медленного носителя. Кроме того, такой подход совершенно не применим при отладке службы, поскольку выполнение программы в отладчике сопровождается большими паузами, необходимыми разработчику.

Для преодоления этой проблемы все операции по взаимодействию с SCM следует выполнять в отдельном потоке, не зависящем от действий, происходящих на этапе инициализации.

Алгоритм корректного запуска службы, использующий вспомогательный поток:

void WINAPI ServiceMain(DWORD dwArgc, LPSTR *psArgv) {

// Сразу регистрируем обработчик запросов.

hSS = RegisterServiceCtrlHandler(SERVICENAME, ServiceHandler);

sStatus.dwCheckPoint = 0;

sStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;

sStatus.dwServiceSpecificExitCode = 0;

sStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;

sStatus.dwWaitHint = 0;

sStatus.dwWin32ExitCode = NOERROR;

// Для инициализации службы вызывается функция InitService();

// Для того, чтобы в процессе инициализации система не

// выгрузила службу, запускается поток, который раз в

// секунду сообщает, что служба в процессе инициализации.

// Для синхронизации потока создаётся событие.

// После этого запускается рабочий поток, для

// синхронизации которого также

// создаётся событие.

hSendStartPending = CreateEvent(NULL, TRUE, FALSE, NULL);

HANDLE hSendStartThread;

DWORD dwThreadId;

hSendStartThread = CreateThread(NULL, 0, SendStartPending, NULL, 0, &dwThreadId);

//Здесь производится вся инициализация службы.

InitService();

SetEvent(hSendStartPending);

if (WaitForSingleObject(hSendStartThread, 2000) != WAIT_OBJECT_0) {

TerminateThread(hSendStartThread, 0);

}

CloseHandle(hSendStartPending);

CloseHandle(hSendStartThread);

hWork = CreateEvent(NULL, TRUE, FALSE, NULL);

hServiceThread = CreateThread(NULL, 0, ServiceFunc, 0, 0, &dwThreadId);

sStatus.dwCurrentState = SERVICE_RUNNING;

SetServiceStatus(hSS, &sStatus);

}

// Функция потока, каждую секунду посылающая уведомления SCM

// о том, что процесс инициализации идёт. Работа функции

// завершается, когда устанавливается

// событие hSendStartPending.

DWORD WINAPI SendStartPending(LPVOID) {

sStatus.dwCheckPoint = 0;

sStatus.dwCurrentState = SERVICE_START_PENDING;

sStatus.dwWaitHint = 2000;

// "Засыпаем" на 1 секунду. Если через 1 секунду

// событие hSendStartPending не перешло

// в сигнальное состояние (инициализация службы не

// закончилась), посылаем очередное уведомление,

// установив максимальный интервал времени

// в 2 секунды, для того, чтобы был запас времени до

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Алекс Jenter читать все книги автора по порядку

Алекс Jenter - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Программирование на Visual C++. Архив рассылки отзывы


Отзывы читателей о книге Программирование на Visual C++. Архив рассылки, автор: Алекс Jenter. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x