![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
CreateProcessAsUserW и ошибка ERROR_PIPE_NOT_CONNECTED
Eraser © (2007-02-28 21:46:00)Имеется сервис, который работает с правами системы. Он отслеживает подключение терминальных сессий, при подключении новой терминальной сесии, внутри этой сесии создается процесс с правами, такими же как у сервиса. Код следующий:
var
hToken, hNewToken: Cardinal;
si: STARTUPINFOW;
pi: PROCESS_INFORMATION;
SessionId: Cardinal;
...
SessionId := WTSGetActiveConsoleSessionId;
...
stSystemUserSession: // Текущая терминальная сессия с правами системы.
begin
if not OpenProcessToken(GetCurrentProcess,
TOKEN_QUERY or TOKEN_DUPLICATE, hToken) then
begin
AppendLog('Error WTSStartProcess - OpenProcessToken ' + IntToStr(GetLastError));
Exit;
end;
if not DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, nil, SecurityIdentification,
TokenPrimary, hNewToken) then
begin
AppendLog('Error WTSStartProcess - DuplicateTokenEx ' + IntToStr(GetLastError));
Exit;
end;
if not SetTokenInformation(hNewToken,
TokenSessionId, @SessionId, SizeOf(Cardinal)) then
begin
AppendLog('Error WTSStartProcess - SetTokenInformation ' + IntToStr(GetLastError));
Exit;
end;
// Запуск процесса.
try
si.lpDesktop := '';
if CreateProcessAsUserW(hNewToken, nil, PWideChar(APath),
nil, nil, false, 0, nil, nil, si, pi) then
begin
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
end
else
begin
AppendLog('Error WTSStartProcess - CreateProcessAsUserW ' + IntToStr(GetLastError));
Exit;
end;
finally
CloseHandle(hToken);
CloseHandle(hNewToken);
end;
end;
Теперь о проблеме.
Запускаем данный сервис в ОС WinXP, логиним первого пользователя (данный код не выполняем, т.к. первый пользователь в XP находится в 0 терм. сесии), делаем SwitchUser, логиним второго пользователя - данный код успешно отрабатывает, в 1 терминальной сессии запускается интересующий нас процесс с правами системы. Делаем LogOff этого второго пользователя (при этом создается еще одна терм. сессии, в которой отображается Logon экран после Logoff'а этого юзера) и, как говориться, баста хрю - функция CreateProcessAsUserW возвращает ошибку ERROR_PIPE_NOT_CONNECTED.
Самое удивительное то, что в Висте данный код работает всегда, проблема только в XP (в 2003 не проверял еще).
PS
пробовал CreateProcessAsUser (ANSI версию) - те же грабли.
PPS
Заранее спасибо знатокам внутренностей ОС!
Игорь Шевченко (2007-02-28 22:30:00) [21]Eraser © (28.02.07 22:19) [2]
(на всякий случай) - а какую функциональность надо реализовать, если не очень большой секрет, может, иным способом можно как-нибудь ?
Eraser (2007-02-28 22:19:00) [22]> [1] Игорь Шевченко © (28.02.07 22:11)
> Весьма вероятно, когда пользователь войдет в систему в этой
> сессии.
> а вот в какой момент
Пробовал ставить тайм-ауты вплоть до 10 секунд - эффекта 0.
> Весьма вероятно, когда пользователь войдет в систему в этой
> сессии
проблема в том, что пользователь может никогда не войти в эту терм. сессию, т.к. можно вернуться к 0 терм. сессии (выбрав 1 пользователя, который уже залогинен), тогда эта будет уничтожена. Да и каким-то образом все это работает в Висте и в XP у конкурентов. Может с переменными окружения что-то.. уже сталкивался с подобной проблемой, когда была похожая задача, но нужно было запускать процесс от имени текущего юзера, решилось изпользованием CreateEnvironmentBlock, но и ошибка тогда другая была и только в Висте.. В общем не знаю даже куда, как говориться, копать ))
Игорь Шевченко (2007-02-28 22:11:00) [23]
> CreateProcessAsUserW возвращает ошибку ERROR_PIPE_NOT_CONNECTED
Не может соединиться с \\.\Pipe\TerminalServer\SystemExecSrvr\номер_сеанса
По этому соединению как раз и передается запрос на создание процесса в CreateProcessAsUser.
Насколько я могу судить, эта pipe создается WinLogon'ом, а вот в какой момент - сказать не могу. Весьма вероятно, когда пользователь войдет в систему в этой сессии.