2010-06-29 5 views
0

Существует ли окно api для определения того, работает ли моя dll в системной службе или обычном пользовательском процессе?Обнаруживать, если dll загружается в службу

Раньше я смотрел на текущее имя пользователя и игнорировал «SYSTEM», «LOCAL SERVICE» и «NETWORK SERVICE». Но теперь я вижу GetUsername return machine_name $ в случаях, когда svchost запускается в определенных ситуациях, прежде чем кто-либо войдет в систему. Кроме того, я не могу найти документацию для machine_name $ result из GetUsername в Vista, кто-нибудь видел это поведение?

+1

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

ответ

2

Это какая бы то ни было учетная запись пользователя для настройки службы. Может быть что угодно, администратору системы выбрать эти учетные записи. Что, конечно, означает, что вы можете не надежно использовать его, чтобы определить, работает ли ваш код в службе.

Вы должны позволить службе, которая использует вашу DLL, сказать вам, что это сервис, он всегда знает. Автоматическое обнаружение сложно, GetProcessWindowStation() должен быть лидером. Вызовите GetUserObjectИнформацию о возвращаемом дескрипторе с флагом UOI_FLAGS и проверьте, есть ли у вас USEROBJECTFLAGS.dwFlags = WSF_VISIBLE. Могут быть некоторые дегенеративные случаи с RDP, я полагаю, но вы можете получить , если у пользователя есть вероятность увидеть выход процесса.

+0

Проблема заключается в переключении «Разрешить работу с рабочим столом» (при работе в качестве локальной системы). Если этот переключатель установлен, служба будет запущена под Session0/WinSta0, если этот флаг WSF_VISIBLE установлен в '1'. –

3

Вы можете посмотреть в токене процесса, чтобы узнать, активен ли известный токен SID NT \ Служба в токене. Если это так, значит, вы работаете в службе. Вы можете использовать CheckTokenMembership, чтобы узнать, работает ли ваш процесс с определенным активным идентификатором SID в токене.

0

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

В прошлом я исследовал вопрос, подобный этому: может ли исполняемый файл определить, выполняется ли он как служба или как обычная программа? Вывод там, казалось, заключался в том, что нет официального способа рассказать. Единственный разумно надежный способ, который я нашел, включал в себя изучение успеха или неудачи одной из функций, которые должна вызвать служебная программа при ее запуске. Очевидно, что этот метод не используется для использования dll службой.

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

2

Для Windows Vista и выше можно проверить текущий сеанс как службы, загруженные в session0, и пользовательские процессы, загруженные в session1 и выше. Я не тестировал, но что-то вроде этого должно работать:

if (Win32MajorVersion < 6) return PROCESSTYPE_CANNOTDETECT; 

DWORD SessionId; 
if (ProcessIdToSessionId(GetCurrentProcessId(), &SessionId) 
    && (0 == SessionId)) 
{ 
    return PROCESSTYPE_SERVICE_OR_DRIVER; 
} 
else 
{ 
    return PROCESSTYPE_USERAPP; 
} 
Смежные вопросы