Текущий вход в систему

Ответить

Код подтверждения
Введите код в точности так, как вы его видите. Регистр символов не имеет значения.

BBCode ВКЛЮЧЁН
[img] ВКЛЮЧЁН
[flash] ОТКЛЮЧЕН
[url] ВКЛЮЧЁН
Смайлики ОТКЛЮЧЕНЫ

Обзор темы
   

Развернуть Обзор темы: Текущий вход в систему

Absurd » 04 мар 2004, 15:42

Спасибо, именно это (100%) мне и надо.

Eugie » 04 мар 2004, 14:41

Absurd, все-таки для какого процесса тебе нужно узнать терминал?

Если для своего (возможно, запущенного под чужим логином), то это просто:

Код: Выделить всё

  HWINSTA hWinSta;
  TCHAR name[100];
  DWORD dwNeededSize;

  hWinSta = GetProcessWindowStation();
  if (GetUserObjectInformation(
        hWinSta,      // handle to object
        UOI_NAME,     // type of information to retrieve
        (PVOID)name,  // information buffer
        sizeof(name), // size of the buffer
        &dwNeededSize // receives required buffer size
      ))
  {
    cout << "Current process window station name:\t" << name << endl;

    // Note: "winsta0" - standard name for an interactive window station

    if (lstrcmpi(name, "winsta0") == 0)
      cout << "Current process window station is interactive" << endl;
    else
      cout << "Current process window station is not interactive" << endl;
  }
А вот для произвольного процесса в системе все сложнее...

Насчет того, какой процесс гарантированно выполняется на интерактивном терминале - любой, запущенный залогиненным в данный момент пользователем, либо сервис, запущенный под локальным системным аккаунтом с флагом SERVICE_INTERACTIVE_PROCESS.

Absurd » 04 мар 2004, 00:35

То есть надо инжектнуть свой код внутрь процесса, гарантированно подключенного к активному терминалу, получить его хендл терминала, и сравнить этот хендл со своим хендлом терминала?
Какой процесс годится на эту роль?

PS: Короче, если OpenWindowStation("winsta0",...) возвращает NULL, то порисовать видимо не удастся. Я остановился на этом.

Eugie » 03 мар 2004, 18:46

Так я же не обещал, что будет легко :)

На самом деле, в том и проблема, что нет в API функции, которая выдает терминал для произвольного процесса - есть только GetProcessWindowStation, но она работает только для процесса, в контексте которого вызвана. Поэтому я не знаю/вижу другого способа, кроме как создать тред в контексте нужного процесса (CreateRemoteThread) и уже либо в нем вызывать GetProcessWindowStation, либо юзать для него GetThreadDesktop. Будет ли так работать - ??? Попробуй ;)

Absurd » 03 мар 2004, 18:17

А как узнать - тот терминал, который мне предоставила система, - интерактивен или нет?
Чего - то я там не нашел ничего вроде GetWindowStationInfo()/GetWindowStationStatus() ...

Eugie » 03 мар 2004, 14:11

Опять немного не то... надо определить, какому пользователю принадлежит десктоп, и принадлежит ли он кому-нубудь.
Более конкретно, процессу 'yyy' надо знать, может ли процесс, запущенный от пользователя 'xxx', рисовать чего-нибудь на экране. Процесс 'yyy' запускается через шедулер от пользователя 'xxx'.
Absurd, вопрос несколько отклонился от первоначального, однако :)

В WinNT/2000/XP есть специальные объекты для безопасного разделения доступа к системным ресурсам процессов, запущенных под разными логинами (в основном, сервисов): window stations
(терминалы) и desktops (рабочие столы). В рамках ОС могут существовать одновременно несколько терминалов, но только один из них - интерактивный - является видимым и именно с ним
взаимодействует пользователь. У каждого терминала может быть одновременно несколько десктопов, но
только один из них - активный - является видимым и служит для взаимодействия с пользователем. При создании процесса ОС назначает ему терминал, при этом сам процесс также может переназначить себе терминал. По умолчанию, доступ к активному десктопу интерактивного терминала получают только процессы, запущенные под логином текущего пользователя и сервисы под учетной записью LocalSystem. Процессам, запущенным под другими логинами, по умолчанию назначаются неинтерактивные терминалы, но при выполнении некоторых условий они также могут получит доступ к интерактивному.

Теперь от теории к практике. Task Scheduler как раз поступает в соответствии с умолчаниями: если процесс запускается под текущим логоном, ему назначается интерактивный терминал, а если под другим логоном - неинтерактивный. Поэтому в простейшем случае, если сам процесс не переназначил себе терминал и десктоп, достаточно узнать логин, под которым он запущен. В противном случае нужно непосредственно получать текущий десктоп в контексте интересующего процесса и сравнивать с десктопом интерактивного процесса.

К сожалению, простого способа получить десктоп/терминал нетекущего процесса WinAPI не предоставляет. Я могу предложить такие варианты: создать тред в контексте интересующего процесса, 1) и уже для нее использовать GetThreadDesktop, 2) либо в ThreadFunc вызывать GetProcessWindowStation.

Absurd » 02 мар 2004, 11:25

Тогда используй функцию NetWkstaUserGetInfo. Она возвращает информацию именно о текущем залогиненном пользователе, см. пример:
Опять немного не то... надо определить, какому пользователю принадлежит десктоп, и принадлежит ли он кому-нубудь.
Более конкретно, процессу 'yyy' надо знать, может ли процесс, запущенный от пользователя 'xxx', рисовать чего-нибудь на экране. Процесс 'yyy' запускается через шедулер от пользователя 'xxx'.

Eugie » 29 фев 2004, 23:44

Тогда используй функцию NetWkstaUserGetInfo. Она возвращает информацию именно о текущем залогиненном пользователе, см. пример:

Код: Выделить всё

#include <windows.h> 
#include <lm.h>
#include <iostream>

using namespace std;

int wmain(void)
{
   LPWKSTA_USER_INFO_1 pBuf = NULL;

   if (NetWkstaUserGetInfo(NULL, 1, (LPBYTE *)&pBuf) == NERR_Success)
   {
      wcout << L"User:\t"   << (LPCWSTR) pBuf->wkui1_username << endl;
      wcout << L"Domain:\t" << (LPCWSTR) pBuf->wkui1_logon_domain << endl;
      wcout << L"Other Domains:\t" << (LPCWSTR) pBuf->wkui1_oth_domains << endl;
      wcout << L"Logon Server:\t" << (LPCWSTR) pBuf->wkui1_logon_server << endl;
      NetApiBufferFree(pBuf);
   }

   return 0;
}

Absurd » 27 фев 2004, 16:32

Andy писал(а): Ну дык ведь подсказали же - юзай API GetUserName/GetUserNameEx :-)
Если в шедулере стоит, что процесс запускается от пользователя "Администратор" , то функция GetUserName() будет всегда возвращать "Администратор", даже если в момент запуска за компьютером залогинен и сидит , например, ВасяПупкин. А помощью GetUserNameEx() я получу что-то типа OurSys\Администратор (в различных форматах) что тоже не годится. Мне надо определить имя залогиненного пользователя, а не пользователя, от которого запускается процесс.

Andy » 27 фев 2004, 14:45

Процесс запускается шедюлером под одним и тем же логином, с одними и теми же привилегиями.
Надо определить, кто на данный момент залогинен локально, и залогинен ли кто-нибудь.
Ну дык ведь подсказали же - юзай API GetUserName/GetUserNameEx :-)

Вернуться к началу