CreateProcessAsUserW и ошибка ERROR_PIPE_NOT_CONNECTED
От: alex-eraser Россия http://rmansys.ru/
Дата: 01.03.07 21:35
Оценка:
Имеется сервис, который работает с правами системы. Он отслеживает подключение терминальных сессий, при подключении новой терминальной сесии, внутри этой сесии создается процесс с правами, такими же как у сервиса. Код следующий:
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.
Так же пробовал запускать с токеном winlogon'a текущей терм. сессии — то же самое.

Самое удивительное то, что в Висте данный код работает всегда, проблема только в XP (в 2003 не проверял еще).

PS
пробовал CreateProcessAsUser (ANSI версию) — те же грабли.

PPS
Заранее спасибо знатокам внутренностей ОС!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.