Re[8]: иконки интерактивных служб под Windows 7
От: Maclaud  
Дата: 29.06.11 17:07
Оценка:
Сделал для тестов обработку пользовательского когда 128.
В HandlerEx собственно вызываю эту функцию RunProcessInSession.
В ней делаю пот шагам:
1. OpenProcessToken(GetCurrentProcess,MAXIMUM_ALLOWED,hProcessToken);
2. DuplicateTokenEx(hProcessToken,TOKEN_ALL_ACCESS or TOKEN_READ or TOKEN_WRITE or TOKEN_EXECUTE,nil,SecurityDelegation,TokenPrimary,hNewToken);
3. SetTokenInformation(hNewToken,TokenSessionId,@SessionID,sizeof(SessionID));
и на этом шаге, даже не дав обработать GetLastError в консоли вываливается:
D:\>sc control test_service 128
[SC] ControlService FAILED 1064:

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

M>Сделал для тестов обработку пользовательского когда 128.

M>В HandlerEx собственно вызываю эту функцию RunProcessInSession.
M>В ней делаю пот шагам:
M>1. OpenProcessToken(GetCurrentProcess,MAXIMUM_ALLOWED,hProcessToken);
M>2. DuplicateTokenEx(hProcessToken,TOKEN_ALL_ACCESS or TOKEN_READ or TOKEN_WRITE or TOKEN_EXECUTE,nil,SecurityDelegation,TokenPrimary,hNewToken);
M>3. SetTokenInformation(hNewToken,TokenSessionId,@SessionID,sizeof(SessionID));
M>и на этом шаге, даже не дав обработать GetLastError в консоли вываливается:
M>D:\>sc control test_service 128
M>[SC] ControlService FAILED 1064:

M>В чем может быть проблема? Где копать?


Покажите сам код. Скорее всего, неверный параметр (нужно сверяться с сигнатурами
функций очень внимательно).
Re[10]: иконки интерактивных служб под Windows 7
От: Maclaud  
Дата: 29.06.11 17:40
Оценка:
Ложная тревога, просто адрес SetTokenInformation получал не правильно.
Но почему то пока запускается невидимым.
Re[11]: иконки интерактивных служб под Windows 7
От: okman Беларусь https://searchinform.ru/
Дата: 29.06.11 17:45
Оценка:
Здравствуйте, Maclaud, Вы писали:

M>Ложная тревога, просто адрес SetTokenInformation получал не правильно.

M>Но почему то пока запускается невидимым.

Id сессии как определяется ?
Re[12]: иконки интерактивных служб под Windows 7
От: Maclaud  
Дата: 29.06.11 17:58
Оценка:
Так идет запуск:

SERVICE_CONTROL_SESSIONCHANGE: // Windows 2000: This value is not supported.
begin
{$IFDEF dm}_log('SERVICE_CONTROL_SESSIONCHANGE');{$ENDIF}
case dwEventType of
WTS_SESSION_LOGON:
begin
{$IFDEF dm}_log('WTS_SESSION_LOGON: start guard '+sa_inttostr(PWTSSESSION_NOTIFICATION(lpEventData)^.dwSessionID));{$ENDIF}
RunProcessInSession(PWTSSESSION_NOTIFICATION(lpEventData)^.dwSessionID,'c:\windows\system32\cmd.exe','');
exit;
end;
end;
end;

Потестил, захожу черех FUS за другого пользователя, там cmd.exe висит как и положено в его 4(на тот момент) сессии. Как и все другие приложения того пользователя. Но окна не видно.
Re[13]: иконки интерактивных служб под Windows 7
От: okman Беларусь https://searchinform.ru/
Дата: 29.06.11 18:05
Оценка:
Здравствуйте, Maclaud.

Покажите код функции RunProcessInSession — там ведь вся логика запуска нового процесса.
Re[14]: иконки интерактивных служб под Windows 7
От: Maclaud  
Дата: 29.06.11 18:14
Оценка:
function RunProcessInSession(SessionID:dword; AExeName,AParamStr:string):boolean;
var
  StartUpInfo: TStartUpInfo;
  ProcessInfo: TProcessInformation;
  hProcessToken,hNewToken:THandle;
  cmd:WideString;
begin
  {$IFDEF dm}_log('RunProcessInSession start '+AExeName+' '+AParamStr,false,1);{$ENDIF}

  result:=false;

  {$IFDEF dm}_log('call OpenProcessToken',false,0,5);{$ENDIF}
  if WindowsError(func_OpenProcessToken(func_GetCurrentProcess,MAXIMUM_ALLOWED,hProcessToken)) then
  begin
    {$IFDEF dm}_log('Oops... fail to OpenProcessToken',false,-1);{$ENDIF}
    exit;
  end;

  {$IFDEF dm}_log('call DuplicateTokenEx',false,0,5);{$ENDIF}
  if WindowsError(func_DuplicateTokenEx(hProcessToken,TOKEN_ALL_ACCESS or TOKEN_READ or TOKEN_WRITE or TOKEN_EXECUTE,nil,SecurityDelegation,TokenPrimary,hNewToken)) then
  begin
    {$IFDEF dm}_log('Oops... fail to DuplicateTokenEx',false,-1);{$ENDIF}
    func_CloseHandle(hProcessToken);
    exit;
  end;

  {$IFDEF dm}_log('call SetTokenInformation',false,0,5);{$ENDIF}
  if WindowsError(func_SetTokenInformation(hNewToken,TokenSessionId,@SessionID,sizeof(SessionID))) then
  begin
    {$IFDEF dm}_log('Oops... fail to SetTokenInformation',false,-1);{$ENDIF}
    func_CloseHandle(hProcessToken);
    func_CloseHandle(hNewToken);
    exit;
  end;

  FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);

  FillChar(StartUpInfo, SizeOf(TStartUpInfo), 0);
  with StartUpInfo do
  begin
    cb := SizeOf(TStartUpInfo);
    dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
    wShowWindow := SW_SHOWNORMAL;
    lpDesktop := PChar('winsta0\default');
  end;

  cmd:=AExeName+' '+AParamStr;
  {$IFDEF dm}_log('call CreateProcessAsUser',false,0,5);{$ENDIF}
  result:=func_CreateProcessAsUserW(hNewToken,
    nil,
    PWideChar(cmd),
    nil,
    nil,
    FALSE,
    NORMAL_PRIORITY_CLASS or CREATE_UNICODE_ENVIRONMENT,
    nil,
    nil,
    StartUpInfo,
    ProcessInfo);

  if not WindowsError(result) then
  begin
    result:=true;
    func_CloseHandle(ProcessInfo.hThread);
    func_CloseHandle(ProcessInfo.hProcess);
  end
  else
  begin
    {$IFDEF dm}_log('Oops... fail to CreateProcessAsUser',false,0,3);{$ENDIF}
  end;

  func_CloseHandle(hProcessToken);
  func_CloseHandle(hNewToken);

  {$IFDEF dm}_log('RunProcessInSession end',false,-1);{$ENDIF}
end;
Re[15]: иконки интерактивных служб под Windows 7
От: okman Беларусь https://searchinform.ru/
Дата: 29.06.11 18:38
Оценка:
Здравствуйте, Maclaud, Вы писали:

M>
M>function RunProcessInSession(SessionID:dword; AExeName,AParamStr:string):boolean;
M>...
M>

Это ведь код на Delphi, так ?
Вот тут не может быть ошибки:
lpDesktop := PChar('winsta0\default');


В том смысле, что не может ли обратный слэш восприниматься как escape-последовательность ?
P.S. Я в Delphi не смыслю ничего...
Re[16]: иконки интерактивных служб под Windows 7
От: Maclaud  
Дата: 29.06.11 19:06
Оценка:
Здравствуйте, okman, Вы писали:

O>Здравствуйте, Maclaud, Вы писали:


M>>
M>>function RunProcessInSession(SessionID:dword; AExeName,AParamStr:string):boolean;
M>>...
M>>

O>Это ведь код на Delphi, так ?
O>Вот тут не может быть ошибки:
O>
O>lpDesktop := PChar('winsta0\default');
O>


O>В том смысле, что не может ли обратный слэш восприниматься как escape-последовательность ?

O>P.S. Я в Delphi не смыслю ничего...

Нет, в делфи нет экранирования.
Вот такое создание из из сервиса, нормально создает видимый процесс, но только на консоли.
function RunProcess(AExeName,AParamStr:string):boolean;
var
  StartUpInfo: TStartUpInfo;
  ProcessInfo: TProcessInformation;
begin
  {$IFDEF dm}_log('RunProcess start '+AExeName+' '+AParamStr,false,1);{$ENDIF}

  FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);

  FillChar(StartUpInfo, SizeOf(TStartUpInfo), 0);
  with StartUpInfo do
  begin
    cb := SizeOf(TStartUpInfo);
    dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
    wShowWindow := SW_SHOWNORMAL;
    lpDesktop := PChar('winsta0\default');
  end;

  result := func_CreateProcessA(PChar(AExeName), PChar(AExeName+' '+AParamStr), nil, nil, false, NORMAL_PRIORITY_CLASS, nil, nil, StartUpInfo, ProcessInfo);

  if not WindowsError(result) then
  begin
    //func_WaitForInputIdle(ProcessInfo.hProcess, 60000);
    func_CloseHandle(ProcessInfo.hThread);
    func_CloseHandle(ProcessInfo.hProcess);
  end;

  {$IFDEF dm}_log('RunProcess end',false,-1);{$ENDIF}
end;
Re[13]: иконки интерактивных служб под Windows 7
От: okman Беларусь https://searchinform.ru/
Дата: 29.06.11 19:48
Оценка:
Здравствуйте, Maclaud, Вы писали:

M>Так идет запуск:


M>SERVICE_CONTROL_SESSIONCHANGE: // Windows 2000: This value is not supported.

M> begin
M> {$IFDEF dm}_log('SERVICE_CONTROL_SESSIONCHANGE');{$ENDIF}
M> case dwEventType of
M> WTS_SESSION_LOGON:
M> begin
M> {$IFDEF dm}_log('WTS_SESSION_LOGON: start guard '+sa_inttostr(PWTSSESSION_NOTIFICATION(lpEventData)^.dwSessionID));{$ENDIF}
M> RunProcessInSession(PWTSSESSION_NOTIFICATION(lpEventData)^.dwSessionID,'c:\windows\system32\cmd.exe','');
M> exit;
M> end;
M> end;
M> end;

M>Потестил, захожу черех FUS за другого пользователя, там cmd.exe висит как и положено в его 4(на тот момент) сессии. Как и все другие приложения того пользователя. Но окна не видно.


Дабы развеять сомнения провел следующий эксперимент.
Накатал сервис, который при старте запускает командное окно (cmd.exe) и
калькулятор (calc.exe), обе программы в сессиях 1 и 2.
Запустил Windows Vista, залогинился админом (сессия 1), затем гостем (сессия 2),
затем снова переключился на админа и запустил сервис командой net start.
Номера сессий подсмотрел в диспетчере задач.

При запуске появилось окно калькулятора и командной оболочки.
Переключился на гостя — там то же самое, свои экземпляры cmd.exe и calc.exe.

Так что проверьте все внимательно еще раз.
Re[14]: иконки интерактивных служб под Windows 7
От: Maclaud  
Дата: 30.06.11 04:57
Оценка:
Выложи плиз исходники, я си нормально знаю, постараюсь сравнить найти косяк.
Re[2]: иконки интерактивных служб под Windows 7
От: ononim  
Дата: 30.06.11 06:43
Оценка:
O>Кстати, Shell_NotifyIcon иногда возвращает ошибку, если пользователь уже вошел в систему, а
O>его интерактивное окружение (рабочий стол) еще не до конца загрузилось.
O>Надо просто организовать цикл и в нем вызывать Shell_NotifyIcon до тех пор, пока она
O>не вернет код успеха. Скажем, раз в секунду. Проверено.
Не надо цикла, надо реагировать на сообщение с кодом, полученным от RegisterWindowMessage("TaskbarCreated").
Но это все равно не поможет топикстартеру.
Как много веселых ребят, и все делают велосипед...
Re[15]: иконки интерактивных служб под Windows 7
От: Maclaud  
Дата: 30.06.11 07:10
Оценка:
Здравствуйте, Maclaud, Вы писали:

M>Выложи плиз исходники, я си нормально знаю, постараюсь сравнить найти косяк.


Не знаю как но поборол, по моему заменой CreateProcessAsUserW на CreateProcessAsUserA.
Благодарю за помощь.
Re[15]: иконки интерактивных служб под Windows 7
От: okman Беларусь https://searchinform.ru/
Дата: 30.06.11 08:16
Оценка:
Здравствуйте, Maclaud, Вы писали:

M>Выложи плиз исходники, я си нормально знаю, постараюсь сравнить найти косяк.


  здесь
Код проверен на XP SP2, Server 2003 R2, Vista SP2 (x86), Windows 7 (amd64) и Server 2008 R2.

#include "Common.h" // "targetver.h", <Windows.h>, и др.
#include <boost/smart_ptr.hpp>
#include "Procedures.h"



namespace {

BOOL
_stdcall
RunInteractiveProcess(
    __in    wchar_t const     * pCmdLine,
    __in    DWORD               IdSession
    )
{
    // Получаем маркер безопасности текущего процесса.

    HANDLE hProcessToken;

    if (FALSE == OpenProcessToken(GetCurrentProcess(),
        TOKEN_ALL_ACCESS,
        &hProcessToken))
    {
        return FALSE;
    }   

    // Создаем производный маркер.

    HANDLE hNewToken;

    if (FALSE == DuplicateTokenEx(hProcessToken,
        MAXIMUM_ALLOWED,
        NULL,
        SecurityDelegation,
        TokenPrimary,
        &hNewToken))
    {
        CloseHandle(hProcessToken);
        return FALSE;
    }

    CloseHandle(hProcessToken);

    // Устанавливаем в маркере id сессии пользователя, в
    // которой будет создан новый процесс.

    if (FALSE == SetTokenInformation(hNewToken,
        TokenSessionId,
        &IdSession,
        sizeof (IdSession)))
    {
        CloseHandle(hNewToken);
        return FALSE;
    }

    // Выделяем временный буфер для командной строки.
    // Зачем это надо - смотрите в описании третьего параметра
    // функции CreateProcessAsUser (MSDN).

    int LengthOfCmdLine = lstrlenW(pCmdLine);
    boost::scoped_array<wchar_t> CmdLineBuffer(new wchar_t[LengthOfCmdLine + 1]);
    lstrcpyW(CmdLineBuffer.get(), pCmdLine);

    // Заполняем структуру STARTUPINFO.

    STARTUPINFOW si;
    
    GetStartupInfoW(&si);

    si.dwFlags      = STARTF_USESHOWWINDOW;
    si.wShowWindow  = SW_SHOWNORMAL;
    si.lpDesktop    = L"WinSta0\\Default";

    // Запускаем процесс с новым маркером безопасности.

    PROCESS_INFORMATION pi;

    if (FALSE == CreateProcessAsUserW(hNewToken,
        NULL,
        CmdLineBuffer.get(),
        NULL,
        NULL,
        FALSE,
        NORMAL_PRIORITY_CLASS,
        NULL,
        NULL,
        &si,
        &pi))
    {
        CloseHandle(hNewToken);
        return FALSE;
    }

    // Очистка ресурсов и выход.

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    CloseHandle(hNewToken);
    return TRUE;
}

} // namespace (anonymous)



VOID
_stdcall
ServiceMain(
    __in    DWORD           /* nArgs */,
    __in    wchar_t      ** /* pArgs */
    )
{
    // Id сессий можно посмотреть в диспетчере задач.

    // Если залогиниться двумя пользователями, то они
    // будут иметь номера сессий 0 и 1 в Windows XP, и
    // 1 и 2 на Vista и более поздних системах (ввиду
    // "Session 0 isolation").

    DWORD AdminSessionId = 0; // 1 for Vista and later.
    DWORD GuestSessionId = 1; // 2 for Vista and later.

    RunInteractiveProcess(L"cmd.exe", AdminSessionId);
    RunInteractiveProcess(L"calc.exe", AdminSessionId);

    RunInteractiveProcess(L"cmd.exe", GuestSessionId);
    RunInteractiveProcess(L"calc.exe", GuestSessionId);

    // Необходимо сообщить менеджеру служб об остановке,
    // иначе служба "повиснет".

    SERVICE_STATUS_HANDLE hStatus = RegisterServiceCtrlHandlerExW(L"my_service",
        HandlerEx,
        NULL);

    SERVICE_STATUS ss;
    ZeroMemory(&ss, sizeof (ss));

    ss.dwServiceType        = SERVICE_WIN32_OWN_PROCESS;
    ss.dwControlsAccepted   = SERVICE_ACCEPT_SHUTDOWN |
        SERVICE_ACCEPT_SESSIONCHANGE | SERVICE_ACCEPT_STOP;
    ss.dwCurrentState       = SERVICE_STOPPED;
    SetServiceStatus(hStatus, &ss);
}


Ваша ошибка, скорее всего, связана либо с путаницей между ANSI- и Unicode-версиями функций,
либо с неправильной инициализацией структуры STARTUPINFO (в моем коде вызывается GetStartupInfo).
Re[3]: иконки интерактивных служб под Windows 7
От: okman Беларусь https://searchinform.ru/
Дата: 30.06.11 08:22
Оценка:
Здравствуйте, ononim, Вы писали:

O>>Кстати, Shell_NotifyIcon иногда возвращает ошибку, если пользователь уже вошел в систему, а

O>>его интерактивное окружение (рабочий стол) еще не до конца загрузилось.
O>>Надо просто организовать цикл и в нем вызывать Shell_NotifyIcon до тех пор, пока она
O>>не вернет код успеха. Скажем, раз в секунду. Проверено.
O>Не надо цикла, надо реагировать на сообщение с кодом, полученным от RegisterWindowMessage("TaskbarCreated").
O>Но это все равно не поможет топикстартеру.

Знаю, но на Vista и выше у этого подхода проблемы с User Interface Privilege Isolation (UIPI),
поэтому приходится еще вызывать ChangeWindowMessageFilter.
Re[4]: иконки интерактивных служб под Windows 7
От: ononim  
Дата: 30.06.11 09:13
Оценка:
O>Знаю, но на Vista и выше у этого подхода проблемы с User Interface Privilege Isolation (UIPI),
O>поэтому приходится еще вызывать ChangeWindowMessageFilter.
ну да, а че тут такого? цикла то все равно не надо
Как много веселых ребят, и все делают велосипед...
Re[5]: иконки интерактивных служб под Windows 7
От: okman Беларусь https://searchinform.ru/
Дата: 30.06.11 10:23
Оценка:
Здравствуйте, ononim, Вы писали:

O>>Знаю, но на Vista и выше у этого подхода проблемы с User Interface Privilege Isolation (UIPI),

O>>поэтому приходится еще вызывать ChangeWindowMessageFilter.
O>ну да, а че тут такого? цикла то все равно не надо

Да, но дело в том, что ChangeWindowMessageFilter(Ex) поддерживается только на Vista и выше.
Это значит, что для XP и Server 2003 нужно будет писать #ifdef или шаблон,
параметризированный номером версии NT. Либо получать функцию через LoadLibrary.
Цикл все же проще.
Re[6]: иконки интерактивных служб под Windows 7
От: ononim  
Дата: 30.06.11 12:02
Оценка: 5 (1)
O>Да, но дело в том, что ChangeWindowMessageFilter(Ex) поддерживается только на Vista и выше.
O>Это значит, что для XP и Server 2003 нужно будет писать #ifdef или шаблон,
O>параметризированный номером версии NT. Либо получать функцию через LoadLibrary.
O>Цикл все же проще.
1) Цикл не поможет от пропажи иконки изза скоропостижно скончавшегося (и автоматически перезапущенного системой) эксплорера, а месага — поможет
2) Pooling зло.
Как много веселых ребят, и все делают велосипед...
Re[7]: иконки интерактивных служб под Windows 7
От: okman Беларусь https://searchinform.ru/
Дата: 30.06.11 12:11
Оценка:
Здравствуйте, ononim, Вы писали:

O>>Да, но дело в том, что ChangeWindowMessageFilter(Ex) поддерживается только на Vista и выше.

O>>Это значит, что для XP и Server 2003 нужно будет писать #ifdef или шаблон,
O>>параметризированный номером версии NT. Либо получать функцию через LoadLibrary.
O>>Цикл все же проще.
O>1) Цикл не поможет от пропажи иконки изза скоропостижно скончавшегося (и автоматически перезапущенного системой) эксплорера, а месага — поможет

Вот этого не знал, спасибо.

O>2) Pooling зло.


О чем конкретно речь ?
Re[8]: иконки интерактивных служб под Windows 7
От: ononim  
Дата: 30.06.11 13:02
Оценка:
O>>2) Pooling зло.
O>О чем конкретно речь ?
О том что pooling жрет CPU бес толку. Понятно, что если такая программа на компе одна и делает это не часто — это некритично. А когда таких прог куча и работают они на терминальном сервере с сотней-другой юзеров...
Как много веселых ребят, и все делают велосипед...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.