Re[5]: иконки интерактивных служб под Windows 7
От: okman Беларусь https://searchinform.ru/
Дата: 29.06.11 06:56
Оценка:
Здравствуйте, Maclaud, Вы писали:

M>Опиши пожалуйста второй способ.

M>У меня как раз задача, есть сервис и нужно чтобы он запускал себя же (в смысле свой exe) с теми же правами но в консольной сессии.
M>За ранее благодарю.

Несколько основных положений:

1. Сервис должен выполняться от имени LocalSystem, иначе некоторые функции будут недоступны.

2. При старте нужно подписаться на событие SERVICE_ACCEPT_SESSIONCHANGE.
Любые события, связанные со входом и выходом пользователя из системы, включая
терминальный доступ, будут проходить через обработчик (HandlerEx), а по параметрам
легко определить тип события (например, WTS_SESSION_LOGON, см. WTSSESSION_NOTIFICATION).
Я настоятельно рекомендую сделать демо-сервис с записью событий в журнал, а затем
поэкспериментировать с тем, какие события и когда вызываются, особенно в контексте
быстрого переключения пользователей и терминальных сеансов. Потому что кроме событий
logon/logoff есть еще connect/disconnect, которые вносят некоторую путаницу.

3. Id сессии, в которой произошло событие, нужно получать именно из обработчика, а
не путем всяких WTSGetActiveConsoleSessionId, потому что так можно будет вести учет того,
какие сеансы у нас запускаются, а какие отключаются.

4. Есть один подводный камень, связанный с запуском службы и перехватом первого логина.
Дело в том, что если используется простой вход в систему (минуя окно ввода имя
пользователя и пароля), служба в некоторых случаях может не успеть запуститься.
То есть, событие первого входа в систему не будет перехвачено.
Я не знаю, каков рекомендованный MSDN способ обхода этого ограничения и поступаю так —
всегда указываю принадлежность своей службы группе "Boot Bus Extender".
Радикально, но работает.

5. Id сессии, в которой произошел вход в систему, нужно запомнить.
Потому что это — "наше все". По нему можно определить имя пользователя, тип сеанса
(консольный или терминальный) и многие другие данные, см. WTSQuerySessionInformation.
Еще один ключевой показатель — маркер безопасности пользователя.
Получается с помощью WTSQueryUserToken.

Допустим, некто вошел в систему и мы знаем Id его сессии, а также получили маркер безопасности.
И нужно создать в его сессии интерактивный процесс, выполняющийся в контексте безопасности
нашей службы (LocalSystem).

Последовательность действий примерно такова:

1. Заполняем структуру STARTUPINFO, в lpDesktop пишем "WinSta0\Default".

2. Создаем новый маркер безопасности:

DuplicateTokenEx(hProcessToken, // получается с помощью OpenProcessToken.
    MAXIMUM_ALLOWED,
    NULL,
    SecurityDelegation,
    TokenPrimary,
    &hNewToken);


В созданном маркере устанавливаем Id сессии:

SetTokenInformation(hNewToken,
    TokenSessionId,
    &IdSession,
    sizeof (IdSession));


3. Создаем процесс с помощью CreateProcessAsUser, первым
аргументом передается новый маркер безопасности.
Созданный процесс будет отображаться в диспетчере задач как SYSTEM и его
нельзя будет "прибить" из-под неадминистраторской учетки, но при этом он
приаттачен к пользовательской сессии и полностью интерактивен.
Со всеми, так сказать, вытекающими.

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

Есть и другие особенности, но они специфичны и к теме отношения не имеют.

Собственно, все.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.