Учитывая то, что сервис является EXE файлом, запуск его возможен как SCM, так и пользователем. Нужно определить, что сервис запущен именно SCM. Пока думаю использовать QueryServiceStatusEx. Сравнивать PID процесса с SERVICE_STATUS_PROCESS.dwProcessId и SERVICE_START_PENDING.dwCurrentState должен быть равен SERVICE_START_PENDING. Может есть способ проще?
есть может и не проще но правильнее OpenProcessToken GetTokenInformation(TokenSource) memcmp(SourceName, "*SYSTEM*", 8) а с чего ты решил что dwCurrentState будет SERVICE_START_PENDING ?
По идее, если сервис запущен SCM, то PID его родителя будет соответсвовать PID'у SCM (services.exe). Но если services.exe может быть завершён(?), то подобный способ никуда не годится.
z0mailbox Если я правильно понял - ловится учётка SYSTEM? Если да, то это ни есть гуд... Сервис однако под разными учётками можно запускать. Это не я решил, а на rsdn вычитал. Вот здесь: http://www.rsdn.ru/article/baseserv/svcadmin-2.xml К сожалению PID службы во время запуска недоступен, а вот dwCurrentState равен SERVICE_START_PENDING.
нет неправильно понял это так подписывается токен процесса фишка эта недокументированная и непонятная насколько я знаю - *SYSTEM* это системные процессы system/csrss/lsass/services/winlogon а также все сервисы под любыми учетными записями стартовавшие через StartService а вот если сервис вызвал CreateProcess то учетная запись нового процесса будет например родительская, например LOCAL_SYSTEM, а токен подпишется пустой строкой я не очень понимаю в какой момент ты исследуешь сервис ты перехватил StartService? или заинжектился в services.exe и похучил RPC таблицу? само собой что иногда стейт будет равен START_PENDING, вопрос - можно ли это уверенно отловить?
Вообще обычно это делается чтением флага WSF_VISIBLE для window station-а процесса. Если visible - то процесс запущен пользователем, если нет, то SCM: Код (Text): USEROBJECTFLAGS flags; DWORD sizeNeeded; BOOL isStartedAsService = GetUserObjectInformation(GetProcessWindowStation(), UOI_FLAGS, &flags, sizeof(flags), &sizeNeeded) && !(flags.dwFlags & WSF_VISIBLE);
нет необязательно SCM возможно совсем другим процессом например - заходим телнетом на комп и запускаем процесс -> WSF_VISIBLE =0 или - запуск через at без /INTERACTIVE итд итп