несколько вопросов про session
От: SergH Россия  
Дата: 28.03.02 01:28
Оценка:
Здравствуйте.

В связи с появлением в Windows XP возможности Switch User есть вопросы. В основном теоретические, так как все мои практические попытки что-то сделать провалились. В MSDN написано, что эта возможность реализована так же, как и Terminal Server, так что если кто-то про него что-то знает, тоже пишите.

1. Я правильно понимаю, что есть сессии, им принадлежать оконные станции (window station), а им уже десктопы?
2. Когда я перебираю все оконные станции и дестопы из первого зашедшего пользователя, я получаю следующее:

WinSta0
    Default
    Disconnect
    Winlogon
Service-0x0-3e7$
    WinSta0
    Service-0x0-3e7$
    Service-0x0-3e4$
    Service-0x0-3e5$
    SAWinSta
Service-0x0-3e4$
    WinSta0
    Service-0x0-3e7$
    Service-0x0-3e4$
    Service-0x0-3e5$
    SAWinSta
Service-0x0-3e5$
    WinSta0
    Service-0x0-3e7$
    Service-0x0-3e4$
    Service-0x0-3e5$
    SAWinSta
SAWinSta
    SADesktop


из второго пользователя:

WinSta0
    Default
    Disconnect
    Winlogon


a) Откуда у первого столько оконных станций и почему их имена и имена десктопов так странно совпадают?
б) Правильно ли я понял, что службы запускаются в сессии первого вошедшего пользователя? Для меня это странно, они ведь запускаются до его входа и под другим аккаунтом.

3. Есть ли такое понятие "активная сессия"? Теоретически, есть возможность из процесса, первоночально запущеного в первой сессии выводить на десктоп второй, если она активна? Если да, то как? OpenInputDesktop не пашет (у меня), перебор оконных станций тоже не помогает. А если это не просто процесс, а служба под LocalSystem?

4. Можно как-то определить что существует несколько сессий, перечислить их?
Делай что должно, и будь что будет
Re: несколько вопросов про session
От: Alex Fedotov США  
Дата: 28.03.02 01:39
Оценка: 3 (1)
Здравствуйте SergH, Вы писали:

SH>1. Я правильно понимаю, что есть сессии, им принадлежать оконные станции (window station), а им уже десктопы?


Да.

SH>2. Когда я перебираю все оконные станции и дестопы из первого зашедшего пользователя, я получаю следующее:


SH>
SH>WinSta0
SH>    Default
SH>    Disconnect
SH>    Winlogon
SH>Service-0x0-3e7$
SH>    WinSta0
SH>    Service-0x0-3e7$
SH>    Service-0x0-3e4$
SH>    Service-0x0-3e5$
SH>    SAWinSta
SH>Service-0x0-3e4$
SH>    WinSta0
SH>    Service-0x0-3e7$
SH>    Service-0x0-3e4$
SH>    Service-0x0-3e5$
SH>    SAWinSta
SH>Service-0x0-3e5$
SH>    WinSta0
SH>    Service-0x0-3e7$
SH>    Service-0x0-3e4$
SH>    Service-0x0-3e5$
SH>    SAWinSta
SH>SAWinSta
SH>    SADesktop
SH>


SH>из второго пользователя:


SH>
SH>WinSta0
SH>    Default
SH>    Disconnect
SH>    Winlogon
SH>


SH>a) Откуда у первого столько оконных станций и почему их имена и имена десктопов так странно совпадают?


Ты где-то ошибся в программе или в выводе.

SH>б) Правильно ли я понял, что службы запускаются в сессии первого вошедшего пользователя? Для меня это странно, они ведь запускаются до его входа и под другим аккаунтом.


Службы запускаются в сессии 0. Первый вошедший пользователь тоже попадает в сессию 0.

SH>3. Есть ли такое понятие "активная сессия"? Теоретически, есть возможность из процесса, первоночально запущеного в первой сессии выводить на десктоп второй, если она активна? Если да, то как?


Нет. Там слишком сложно все внутри устроено. Скажу лишь, что каждая сессия имеет свою копию csrss.exe и win32k.sys, поэтому напрямую вывести в другую сессию процесс ничего не может. Но (теоретически) можно запустить процесс, ассоциированный с нужной сессией.

SH>4. Можно как-то определить что существует несколько сессий, перечислить их?


WTSEnumerateSessions
-- Alex Fedotov
Re[2]: несколько вопросов про session
От: SergH Россия  
Дата: 28.03.02 02:01
Оценка:
Здравствуйте Alex Fedotov, Вы писали:

Большое спасибо.


SH>>a) Откуда у первого столько оконных станций и почему их имена и имена десктопов так странно совпадают?


AF>Ты где-то ошибся в программе или в выводе.


Я не нашёл. Если не сложно подскажи где.

#include <windows.h>
#include <stdio.h>
#include <conio.h>

BOOL CALLBACK EnumWindowStationProc(
  LPTSTR lpszWindowStation,  // window station name
  LPARAM lParam             // user-defined value
);

BOOL CALLBACK EnumDesktopProc(
    LPTSTR lpszDesktop,  // desktop name
    LPARAM lParam        // user-defined value
);

void main()
{
    EnumWindowStations(EnumWindowStationProc, 0);
    getch();
}


BOOL CALLBACK EnumWindowStationProc(LPTSTR name, LPARAM lParam)
{
    printf("%s\n", name);

    HWINSTA hWinSta;

    hWinSta = OpenWindowStation(name, FALSE, WINSTA_ENUMDESKTOPS);

    EnumDesktops(hWinSta, EnumDesktopProc, 0);

    CloseWindowStation(hWinSta);

    return TRUE;
}

BOOL CALLBACK EnumDesktopProc(LPTSTR name, LPARAM lParam)
{
    printf("    %s\n", name);
    return TRUE;
}



SH>>3. Есть ли такое понятие "активная сессия"? Теоретически, есть возможность из процесса, первоночально запущеного в первой сессии выводить на десктоп второй, если она активна? Если да, то как?


AF>Нет. Там слишком сложно все внутри устроено. Скажу лишь, что каждая сессия имеет свою копию csrss.exe и win32k.sys, поэтому напрямую вывести в другую сессию процесс ничего не может. Но (теоретически) можно запустить процесс, ассоциированный с нужной сессией.


Вариант с отдельным процессом пришёл мне в голову, но я думал что для запуска в текущей (с точки зрения пользователя) сессии ничего сложного не надо. Но, если активной сессии нет, то непонятно, точку зрения какого пользователя учитывать... Если исходить из того, что пользователи бывают только локальные (XP — не совсем Terminal Server), активной будет сессия, состояние которой WTSActive. Как запустить процесс ассоциированный с нужной сессией? Или это настолько теоретически, что лучше искать другое решение?
Делай что должно, и будь что будет
Re[3]: несколько вопросов про session
От: Alex Fedotov США  
Дата: 28.03.02 02:16
Оценка:
Здравствуйте SergH, Вы писали:

SH>>>a) Откуда у первого столько оконных станций и почему их имена и имена десктопов так странно совпадают?


AF>>Ты где-то ошибся в программе или в выводе.


А может и не ошибся. Может они на самом деле так называются.

SH>>>3. Есть ли такое понятие "активная сессия"? Теоретически, есть возможность из процесса, первоночально запущеного в первой сессии выводить на десктоп второй, если она активна? Если да, то как?


AF>>Нет. Там слишком сложно все внутри устроено. Скажу лишь, что каждая сессия имеет свою копию csrss.exe и win32k.sys, поэтому напрямую вывести в другую сессию процесс ничего не может. Но (теоретически) можно запустить процесс, ассоциированный с нужной сессией.


SH>Вариант с отдельным процессом пришёл мне в голову, но я думал что для запуска в текущей (с точки зрения пользователя) сессии ничего сложного не надо. Но, если активной сессии нет, то непонятно, точку зрения какого пользователя учитывать...


Я не совсем понимаю, что ты имеешь в виду под "если активной сессии нет".

SH>Как запустить процесс ассоциированный с нужной сессией? Или это настолько теоретически, что лучше искать другое решение?


Я, пожалуй, проверю сначала, чтобы глупости при всем честном народе не говорить. Проверю — скажу.
-- Alex Fedotov
Re[4]: несколько вопросов про session
От: SergH Россия  
Дата: 28.03.02 06:09
Оценка:
Здравствуйте Alex Fedotov, Вы писали:

SH>>Вариант с отдельным процессом пришёл мне в голову, но я думал что для запуска в текущей (с точки зрения пользователя) сессии ничего сложного не надо. Но, если активной сессии нет, то непонятно, точку зрения какого пользователя учитывать...


AF>Я не совсем понимаю, что ты имеешь в виду под "если активной сессии нет".


Если не существует единственной сессии у которой установлен флажок "активна" или "интерактивна" (это слово лучше), не известно, какая из них меня интересует. Насколько я понимаю, в Windows XP все пользователи локальные, поэтому "интерактивная" сессия в каждый момент только одна. Про Terminal Server я почти ничего не знаю, поэтому предпологаю более общий подход.
Делай что должно, и будь что будет
Re[4]: несколько вопросов про session
От: SergH Россия  
Дата: 29.03.02 06:58
Оценка:
Здравствуйте Alex Fedotov, Вы писали:

Я тут почитал MSDN, кое что понял. Судя по MSDN'у запустить процесс в другой сессии нельзя. В качестве взаимодействйя предлягаются три варианта: virtual channel, какой-то ActiveX (не разбирался), любые методы, позволяющие соеденить несколько машин. Я, наверное, выберу named pipes, так как без TS virtual channel работать не будут.

Проблема потеряла остроту, но есть ещё несколько вопросов.

1. сессии бывают console и remote. В Win 2000 TS console — та, которая на сервере, её id всегда 0, remote — все остальные. В Win XP на сервере может быть несколько сессий. Я правильно понимаю, что они все console и для получения id активной используется WTSGetActiveConsoleSessionId?

2. Я не могу похвастаться хорошим (даже нормальным) английским, но обычно на MSDN хватает. Но тут, по-моему, написано нечто странное (статья Terminal Services Client/Server Support):


Processes spawned from multiple sessions can send data to and receive data from each other through the use of shared memory blocks. This is done by calling CreateFileMapping. If you do this, keep in mind that shared memory cannot be used in situations where the following conditions exist:

— All of the processes using the shared memory block were not spawned by one session.
— All of the sessions share the same user authentication credential.


Т.е.
Процессы, ассоциированные с несколькими сессиями могут использовать разделяемую память для обмена данными. Это делается CreateFileMapping'ом. Но помните, она не может быть использована для разделения памяти, если:
— Процессы ассоциированы с разными сессиями (ну это понятное условие, так бы и написали что в TS работать будет, но только в пределах сессии. А то "Processes spawned from multiple sessions can ...")
— Разные сессии относятся к одному пользоватедю (а тут я просто не понимаю. Если бы это было условием, при котором возможно использование CreateFileMapping, то ладно. Но это условие, когда нельзя.)

Что я неправильно перевёл? Или так и надо?
Делай что должно, и будь что будет
Re[5]: несколько вопросов про session
От: Alex Fedotov США  
Дата: 29.03.02 07:10
Оценка:
Здравствуйте SergH, Вы писали:

SH>Я тут почитал MSDN, кое что понял. Судя по MSDN'у запустить процесс в другой сессии нельзя.


Ну это мы еще поэкспериментируем... Native API привлечем, если надо.

SH>Проблема потеряла остроту, но есть ещё несколько вопросов.


SH>1. сессии бывают console и remote. В Win 2000 TS console — та, которая на сервере, её id всегда 0, remote — все остальные. В Win XP на сервере может быть несколько сессий. Я правильно понимаю, что они все console и для получения id активной используется WTSGetActiveConsoleSessionId?


Я понимаю не так. Я понимаю, что на Win2K id консольной сессии всегда был 0. На XP консольная сессия может иметь любой id. Но больше одной консольной сессии быть не может.

SH>2. Я не могу похвастаться хорошим (даже нормальным) английским, но обычно на MSDN хватает. Но тут, по-моему, написано нечто странное (статья Terminal Services Client/Server Support):


SH>

SH>Processes spawned from multiple sessions can send data to and receive data from each other through the use of shared memory blocks. This is done by calling CreateFileMapping. If you do this, keep in mind that shared memory cannot be used in situations where the following conditions exist:

SH>- All of the processes using the shared memory block were not spawned by one session.

SH>- All of the sessions share the same user authentication credential.
SH>


Я тоже не понимаю, что они хотели сказать. Если нужно использовать file mapping между процессами, принадлежащим разным сессиям, то объект должен быть именован и иметь префикс "Global\". Если нужно работать с объектом из процессов, ассоциированных с разными пользователями, то нужно настроить DACL объекта соотвествующим образом.
-- Alex Fedotov
Re[6]: несколько вопросов про session
От: Alex Fedotov США  
Дата: 29.03.02 07:20
Оценка:
Здравствуйте Alex Fedotov, Вы писали:

SH>>Я тут почитал MSDN, кое что понял. Судя по MSDN'у запустить процесс в другой сессии нельзя.


AF>Ну это мы еще поэкспериментируем... Native API привлечем, если надо.


Не нужно никакого Native API, все написано в MSDN.

[msdn]CreateProcessAsUser[msdn]:

hToken
...
Terminal Services: The process is run in the session specified in this token.

То есть нужно всего лишь получить токен пользователя, ассоциированного с нужной сессией. В XP это делается тривиально благодаря наличию функции WTSQueryUserToken. В Win2K можно просто перечислить все процессы, найти explorer.exe в нужной сессии и взять его токен (правильнее будет иметь программу, которая автоматически запустится при входе пользователя в систему и вызовет сервис, чтобы тот имел возможность получить токен; это уже обсуждалось здесь неоднократно).

В воскресенье (суббота уже распланирована) постараюсь сделать демонстрашку.
-- Alex Fedotov
Re[6]: несколько вопросов про session
От: SergH Россия  
Дата: 30.03.02 21:27
Оценка:
Здравствуйте Alex Fedotov, Вы писали:

SH>>1. сессии бывают console и remote. В Win 2000 TS console — та, которая на сервере, её id всегда 0, remote — все остальные. В Win XP на сервере может быть несколько сессий. Я правильно понимаю, что они все console и для получения id активной используется WTSGetActiveConsoleSessionId?


AF>Я понимаю не так. Я понимаю, что на Win2K id консольной сессии всегда был 0. На XP консольная сессия может иметь любой id. Но больше одной консольной сессии быть не может.


Похоже, мой вариант ближе к истине. При запуске Win XP из разных сессий (локальных) программка, выводящая значение, полученное от WTSGetActiveConsoleSessionId фактически выводит номер сессии из которой запущена, т.е. WTSGetActiveConsoleSessionId возвращает номер текущей активной сессии на сервере.

AF>Terminal Services: The process is run in the session specified in this token.


AF>То есть нужно всего лишь получить токен пользователя, ассоциированного с нужной сессией. В XP это делается тривиально благодаря наличию функции [msdn]WTSQueryUserToken. В Win2K можно просто перечислить все процессы, найти explorer.exe в нужной сессии и взять его токен (правильнее будет иметь программу, которая автоматически запустится при входе пользователя в систему и вызовет сервис, чтобы тот имел возможность получить токен; это уже обсуждалось здесь неоднократно).


Тут у меня возник небольшой вопрос... Я понимаю, что нормальный ответ на него — go to MSDN. Если бы задача решалась запуском процесса в нужной сессии, я бы, конечно, сам разобрался. Но мне, похоже, придётся внедрять в клиента dll и связываться с ней по именованным каналам. Поэтому самому разбираться лень.

Собственно, вопрос: токен это штука, идентифицирующая пользователя или сессию? Т.е. если в Terminal Service я получу токен через LogonUser, процесс запустится в другой сессии? А если её не существует, она что, создастся? Помоему бред. Единственное разумное предположение, которое пришло мне в голову — токен, получаемый через LogonUser и через WTSQueryUserToken чем-то отличаются друг от друга. Чем?

AF>В воскресенье (суббота уже распланирована) постараюсь сделать демонстрашку.

Здорово! А как насчёт статьи? В связи с появлением XP и Fast user switching'а эта тема преобретает большую актуальность. Живого Win NT/2000 TS я не видел, а XP на каждом углу.
Делай что должно, и будь что будет
Re[7]: несколько вопросов про session
От: Alex Fedotov США  
Дата: 30.03.02 21:48
Оценка: 2 (1)
Здравствуйте SergH, Вы писали:

SH>>>1. сессии бывают console и remote. В Win 2000 TS console — та, которая на сервере, её id всегда 0, remote — все остальные. В Win XP на сервере может быть несколько сессий. Я правильно понимаю, что они все console и для получения id активной используется WTSGetActiveConsoleSessionId?


AF>>Я понимаю не так. Я понимаю, что на Win2K id консольной сессии всегда был 0. На XP консольная сессия может иметь любой id. Но больше одной консольной сессии быть не может.


SH>Похоже, мой вариант ближе к истине. При запуске Win XP из разных сессий (локальных) программка, выводящая значение, полученное от WTSGetActiveConsoleSessionId фактически выводит номер сессии из которой запущена, т.е. WTSGetActiveConsoleSessionId возвращает номер текущей активной сессии на сервере.


Ну еще бы, ты ведь программу запускаешь из текущей консольной сессии. А ты сделай сервис, который по таймеру будет вызывать WTSGetActiveConsoleSessionId и выводить в файл. Тогда ты увидишь, что он выдает разные значения, в зависимости от того, какая сессия сейчас видна на экране.

AF>>Terminal Services: The process is run in the session specified in this token.


AF>>То есть нужно всего лишь получить токен пользователя, ассоциированного с нужной сессией. В XP это делается тривиально благодаря наличию функции [msdn]WTSQueryUserToken. В Win2K можно просто перечислить все процессы, найти explorer.exe в нужной сессии и взять его токен (правильнее будет иметь программу, которая автоматически запустится при входе пользователя в систему и вызовет сервис, чтобы тот имел возможность получить токен; это уже обсуждалось здесь неоднократно).


SH>Тут у меня возник небольшой вопрос... Я понимаю, что нормальный ответ на него — go to MSDN. Если бы задача решалась запуском процесса в нужной сессии, я бы, конечно, сам разобрался. Но мне, похоже, придётся внедрять в клиента dll и связываться с ней по именованным каналам. Поэтому самому разбираться лень.


SH>Собственно, вопрос: токен это штука, идентифицирующая пользователя или сессию?


Токен — это штука, идентифицирующая логон-сессию (не путать с терминальной сессией, о которой мы до этого говорили!), то есть не просто пользователя, а "экземпляр пользователя, вошедшего в систему". Логон-сессии и терминальные сессии ортогональны друг другу.

SH>Т.е. если в Terminal Service я получу токен через LogonUser, процесс запустится в другой сессии?


С токеном ассоциирован terminal session id. По умолчанию, я думаю, он совпадает с session id вызывающего LogonUser. Тем не менее, его можно изменить с помощью SetTokenInformation(TokenSessionId), правда, для этого нужна SeTcbPrivilege.

SH>А если её не существует, она что, создастся? Помоему бред.


Нет, не создастся. Скорее, попытка назначить токену несуществующий session id закончится с ошибкой.

SH>Единственное разумное предположение, которое пришло мне в голову — токен, получаемый через LogonUser и через WTSQueryUserToken чем-то отличаются друг от друга. Чем?


Концептуально — ничем. Просто у них может оказаться разный terminal session id.

AF>>В воскресенье (суббота уже распланирована) постараюсь сделать демонстрашку.


К сожалению, это воскресенье придется вычеркнуть.

SH>Здорово! А как насчёт статьи? В связи с появлением XP и Fast user switching'а эта тема преобретает большую актуальность. Живого Win NT/2000 TS я не видел, а XP на каждом углу.


Можно и статью, надо только подумать над содержанием.
-- Alex Fedotov
Re[8]: несколько вопросов про session
От: SergH Россия  
Дата: 30.03.02 21:58
Оценка:
Здравствуйте Alex Fedotov, Вы писали:

Спасибо. В ближайшем будующем вопросов больше не предвидится.

Поскольку эта тема очень слабо освещена, я думаю, в статье можно писать почти что угодно.
Делай что должно, и будь что будет
Re[8]: несколько вопросов про session
От: SergH Россия  
Дата: 04.04.02 11:46
Оценка: 18 (1)
Здравствуйте Alex Fedotov, Вы писали:

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


AF>>>В воскресенье (суббота уже распланирована) постараюсь сделать демонстрашку.


AF>К сожалению, это воскресенье придется вычеркнуть.


Я написал. Лежит здесь, весит 12 Кб. Это службочка, самое забовное в ней — способ взаимодействия с пользователем. Писать нормальный было лень...
Делай что должно, и будь что будет
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.