Конференция "WinAPI" » Как достоверно определить что программа запущена как сервис?
 
  • KSergey © (15.04.09 12:18) [20]
    > SPeller ©   (15.04.09 10:08) [9]
    > Никаких параметров не получает. Процесс регистрирует callback через RegisterServiceCtrlHandler.

    Ну так я о чем и толкую: запустили - оно регистрирует свой call-back да и все. И ничем кроме сервиса быть не может по определению.
    А если нужна отладка - то телается распознавание ключика /d - по нему вместо регистрации call-back передается управление в основную функцию обработки с выставлением флажка "запустили как консольку", в этом случае в консольку можно смело лог, например, писать. Вот и все.
    Зачем родительсткие процессы шукать - мне не ясно.
  • Anatoly Podgoretsky © (15.04.09 13:11) [21]
    > SPeller  (15.04.2009 11:34:18)  [18]

    Можно попытаться передавать в строке запуска ключ.
    Это если не изучать работу с сервисами и менеджером служб
  • sniknik © (15.04.09 13:12) [22]
    > Вобщем, получился такой код. Интересует критика
    тебе за построчно платят? тогда все замечательно, отлично просто. но вообще там Rouse_ предлагал более компактный, наглядный вариант, который ничего не стоит переделать...
    вот в это например

    function ParentProcName: string;
    const
     ProcessBasicInformation = 0;
    var
     Info: PROCESS_BASIC_INFORMATION;
     dwProcessHandle: dword;
     ProcessName: string;
     Hndl: THandle;
    begin
     Result:= 'noname';
     dwProcessHandle:= GetCurrentProcess;
     if NtQueryInformationProcess(dwProcessHandle, ProcessBasicInformation, @Info, SizeOf(Info), nil) = NO_ERROR
       then begin
         Hndl:= OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, Info.uInheritedFromUniqueProcessId);
         if Hndl <> 0 then
           try
             SetLength(ProcessName, MAX_PATH);
             if GetModuleBaseNameA(Hndl, 0, PChar(ProcessName), MAX_PATH) > 0
               then Result:= PChar(ProcessName);
           finally
             CloseHandle(Hndl);
           end;
       end;
    end;



    это заменяет две трети твоего кода.

    > Зачем родительсткие процессы шукать - мне не ясно.
    если не только для отладки, если прога написана так как приведенный мной ранее пример борландовской программы.
  • SPeller © (16.04.09 03:35) [23]

    > запустили - оно регистрирует свой call-back да и все. И
    > ничем кроме сервиса быть не может по определению

    Может :) Сервис - это тот же самый процесс, и ничем не отличается от обычного процесса кроме того, что запускается и управляется системным менеджером.


    > тебе за построчно платят? тогда все замечательно, отлично
    > просто. но вообще там Rouse_ предлагал более компактный,
    >  наглядный вариант, который ничего не стоит переделать..

    См пост 14 и 15. Если msdn красным не рекомендует использовать - значит нафик. Сегодня работает, завтра не известно будет или нет. Админы поставят 2008-й сервак, а там кто даст гарантию что будет работать? Если бы это было поделкой для своих личных нужд - без проблем. А когда этот софт делается для работы - то лучше избавить себя от потенциальных ошибок в будущем. Имхо.
  • SPeller © (16.04.09 03:59) [24]

    > это заменяет две трети твоего кода

    Так то оно так, но помимо красных предупреждений по поводу NtQueryInformationProcess, есть еще один момент, который я тоже упоминал:

    The handle must have the PROCESS_QUERY_INFORMATION and PROCESS_VM_READ access rights

    Это и к GetModuleFileNameEx  относится, и к GetModuleBaseName. Взгляни в msdn, если не веришь. А сервис, напомню, не обязан иметь указанные права, поскольку может быть запущен от имени любого пользователя.
  • sniknik © (16.04.09 10:25) [25]
    > Если msdn красным не рекомендует использовать - значит нафик.
    не вижу красного
    http://msdn.microsoft.com/en-us/library/ms684280(VS.85).aspx

    > The handle must have the PROCESS_QUERY_INFORMATION and PROCESS_VM_READ access rights
    именно поэтому они здесь и запрашиваются
    Hndl:= OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, Info.uInheritedFromUniqueProcessId)
    потому, что handle должен их иметь...

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

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

    > поскольку может быть запущен от имени любого пользователя.
    вообще то по логике не может... сервис сам по себе для своего обслуживания должен иметь кое какие права... и они, имхо, больше чем требуется чтобы прочитать имя модуля.
  • SPeller © (17.04.09 02:31) [26]

    > не вижу красного
    Там оно не красным, а черным. В локальной версии - красным выделена строка may be altered or unavailable in future versions of Windows. Разве этого не достаточно чтобы опасаться воплощения в жизнь обещания "may be altered or unavailable"? Да и поля uInheritedFromUniqueProcessId в структуре PROCESS_BASIC_INFORMATION даже в самой свежей, онлайн версии msdn, нет. Изменит там что-то мелкософт, а пинать-то за ошибки в программе будут меня )


    > именно поэтому они здесь и запрашиваются
    И именно из-за ограниченности прав юзверя OpenProcess возвращает Access denied при попытке открыть родительский процесс.


    > там запрашивается инфа о собственном процессе
    Зачем мне собственный? Мне родительский нужен. PID я получу родительского, а вот имя файла родительского процесса - только через ToolHelp, который работает из-под ограниченной учетки.
  • SPeller © (17.04.09 02:36) [27]

    > проверь, запусти свой сервис под юзером с правами гостя
    Я это с самого начала и делал :) Правда, не под гостем, а под специальной учеткой, которая состоит в группе пользователей. Права на функции Nt/ZwХХХ не проверял, а вот на GetModuleFileNameEx и GetModuleBaseName споткнулся сразу. Через снапшот всё получилось без вопросов.
  • SPeller © (17.04.09 02:39) [28]
    Кстати, работаю тут еще с правами. Оказалось что у борланда несколько функций объявлены неправильно.BuildExplicitAccessWithName и GetSecurityInfo некорректно объявлены. А рядом с BuildExplicitAccessWithName еще видел функции, которые с постфиксом W имеют параметры PAnsiChar.
  • Игорь Шевченко © (17.04.09 02:51) [29]

    > Оказалось что у борланда несколько функций объявлены неправильно.
    > BuildExplicitAccessWithName и GetSecurityInfo некорректно
    > объявлены. А рядом с BuildExplicitAccessWithName еще видел
    > функции, которые с постфиксом W имеют параметры PAnsiChar.
    >


    И на солнце бывают пятна.

    Пользуйся лучше Jedi API Translation (http://www.delphi-jedi.org) - там вроде меньше ошибок
  • Anatoly Podgoretsky © (17.04.09 09:59) [30]
    > SPeller  (17.04.2009 2:39:28)  [28]

    Не несколько, а много и исправляются или медленно или никогда.
  • SPeller © (17.04.09 16:37) [31]
    Удалено модератором
 
Конференция "WinAPI" » Как достоверно определить что программа запущена как сервис?
Есть новые Нет новых   [134433   +21][b:0][p:0.001]