RB>Есть хендл процесса. RB>Как определить, к какой window station он присоединен в данный момент?
VirtualAllocEx() + WriteProcessMemory() + CreateRemoteThread() + GetProcessWindowStation() + ReadProcessMemory(). Идея понятна? У хендла должны быть права PROCESS_CREATE_THREAD, PROCESS_QUERY_INFORMATION, PROCESS_VM_OPERATION, PROCESS_VM_WRITE и PROCESS_VM_READ. Единственный минус — не сработает для процесса в другом сеансе.
Здравствуйте, x64, Вы писали:
x64>VirtualAllocEx() + WriteProcessMemory() + CreateRemoteThread() + GetProcessWindowStation() + ReadProcessMemory(). Идея понятна? У хендла должны быть права PROCESS_CREATE_THREAD, PROCESS_QUERY_INFORMATION, PROCESS_VM_OPERATION, PROCESS_VM_WRITE и PROCESS_VM_READ. Единственный минус — не сработает для процесса в другом сеансе.
Это слишком просто. В моем случае процесс мой, более того, есть открытый канал IPC к нему, так что передать инфу из процесса не составляет труда.
RB>В моем случае процесс мой, более того, есть открытый канал IPC к нему, так что передать инфу из процесса не составляет труда.
Мсье! Не вводите народ в заблуждение и внимательнее читайте документацию. GetProcessWindowStation() во втором процессе и переслать по IPC первому. Всё просто.
Здравствуйте, x64, Вы писали:
RB>>А если есть хендл на десктоп, как определить, в какой window station он создан?
x64>EnumDesktops() + GetUserObjectInformation(UOI_NAME) + сравниваем имена. Идея понятна?
1. EnumDesktops дает имена десктопов, так что GetUserObjectInformation не требуется.
2. Допустим, мой десктоп называется "default". Еще идеи есть?
Здравствуйте, x64, Вы писали:
x64>Да ну, правда? А как ты узнаешь имя собственного рабочего стола?
В этом смысле... Ну да, есть хендл на десктоп, и соответственно, все его атрибуты.
RB>>Допустим, мой десктоп называется "default". x64>Это к чему сказано было?
К тому, что имена десктопов не уникальны. В разных window stations могут быть десктопы с одинаковым именем. Соответственно, исходный вопрос, как по десктопу найти его window station, остался открытым.
RB>К тому, что имена десктопов не уникальны. В разных window stations могут быть десктопы с одинаковым именем.
Эх, молодёжь. Что-то сегодня много народу в танк засели и вылазить ну решительно не хотят
Повторяю на раз: имена рабочих столов уникальны. Просто нужно немного подумать и придти к выводу, что имя рабочего стола это не "default", а "WinSta0\Default", ага.
Здравствуйте, x64, Вы писали:
x64>Эх, молодёжь. Что-то сегодня много народу в танк засели и вылазить ну решительно не хотят
А-а-а... Ну ок, давай в такой плоскости ...
x64>Повторяю на раз: имена рабочих столов уникальны. Просто нужно немного подумать и придти к выводу, что имя рабочего стола это не "default", а "WinSta0\Default", ага.
Имя короткое, имя длинное, ага...
А не соизволит ли уважаемый джин вылезти из своей бутылки и продемонстрировать фокус с получением полного имени десктопа, включающего имя его window station, по имеющемуся хендлу HDESK ?
RB>А не соизволит ли уважаемый джин вылезти из своей бутылки и продемонстрировать фокус с получением полного имени десктопа, включающего имя его window station, по имеющемуся хендлу HDESK ?
Ну что, готов, пионер? Пишем драйвер. Алгоритм будет примерно следующий:
1. В драйвер передаём хендл рабочего стола. Если кто ещё не знает, — это такой же хендл на объект ядра, как и все прочие нормальные хендлы.
2. Получаем указатель на объект рабочего стола через ObReferenceObjectByHandle(). Структура объекта рабочего стола чуть ниже.
3. Ищем в структуре поле rpwinstaParent (четвёртое сверху) и получаем указатель на объект родительской оконной станции.
4. Открываем объект оконной станции через ObOpenObjectByPointer(). Нам даже не нужно знать структуру её объекта, достаточно указателя.
5. Полученный хендл передаём наверх приложению и делаем с ним что хотим, можно, например, GetUserObjectInformation() позвать.
/*
* Desktop Structure.
*
* This structure is only viewable from the kernel. If any desktop
* information is needed in the client, then they should reference off
* the pDeskInfo field (i.e. pti->pDeskInfo).
*/typedef struct tagDESKTOP
{
PDESKTOPINFO pDeskInfo; // Desktop information
PDISPLAYINFO pDispInfo; //
PDESKTOP rpdeskNext; // Next desktop in list PWINDOWSTATION rpwinstaParent; // Windowstation owner
DWORD dwDTFlags; // Desktop flags
ULONG dwDesktopId; // Needed by GDI to tag display devices
PWND spwndMenu; //
PMENU spmenuSys; //
PMENU spmenuDialogSys; //
PMENU spmenuHScroll;
PMENU spmenuVScroll;
PWND spwndForeground; //
PWND spwndTray;
PWND spwndMessage;
PWND spwndTooltip;
HANDLE hsectionDesktop; //
PWIN32HEAP pheapDesktop; //
DWORD dwConsoleThreadId; //
DWORD dwConsoleIMEThreadId;
CONSOLE_CARET_INFO cciConsole;
LIST_ENTRY PtiList; //
PWND spwndTrack; // xxxTrackMouseMove dataint htEx;
RECT rcMouseHover;
DWORD dwMouseHoverTime;
DWORD dwSessionId;
#ifdef LOGDESKTOPLOCKS
int nLockCount;
int nLogMax;
int nLogCrt;
PLogD pLog;
#endif// LOGDESKTOPLOCKS
}
DESKTOP;
Замечание. Приведённая структура может немного отличаться в современных версиях Windows. Проверять сей факт сейчас лень, но если очень попросите, я это сделаю, и даже драйверок накатать могу. Стучите в icq. А нормальными "легальными" способами сия проблема, насколько мне известно, не решается.
P.S. Функция NtQueryObject() возвращает имя в коротком формате "\<Object Name>", так что для решения нашей задачи не подходит.
Здравствуйте, x64, Вы писали:
x64>Ну что, готов, пионер?
Всегда!
Но с шашкой на танк — только после вас...
x64>Пишем драйвер.
x64>А нормальными "легальными" способами сия проблема, насколько мне известно, не решается.
Ну вот, а то enum desktops, get user information, имена какие-то...
Мне только этот факт и нужен был...
Здравствуйте, xmen, Вы писали:
X>Вот написал, может, подойдет:
Это же GetStartupInfo...
Это же только для хендла самого процесса...
Для этого и GetProcessWindowStation есть...
Спасибо, конечно, но нужно определять станции других процессов
Если точно, то задача звучит так.
Периодически может возникать необходимость в поиске "своих" процессов, и определении параметров их запуска. В частности, на какой станции они были запущены. Или хотя бы, интерактивно они запущены или нет. В API для работы со станциями и десктопами я такой возможности не нашел.
Вот и вопрос — пропустил я что или нет? Может, через WTS как?
ЗЫ
На самом деле, для найденных процессов есть возможность установить "легальный" ipc-канал связи, и запросить нужную информацию явно. Так что путешествия в режим ядра и прочие "фокусы" просто не требуются. Вопрос чисто для интереса...
Здравствуйте, rus blood, Вы писали:
RB>Это же GetStartupInfo... RB>Это же только для хендла самого процесса... RB>Спасибо, конечно, но нужно определять станции других процессов
А затем с помощью ReadProcessMemory читать непосредственно в памяти процесса нужные структуры (RTL_USER_PROCESS_PARAMETERS и т.п.)
Нужно учесть x64 — из wow64 процесса не получится читать память native процесса по адресам, выше 4 гб
Здравствуйте, rus blood, Вы писали: RB>Периодически может возникать необходимость в поиске "своих" процессов, и определении параметров их запуска. В частности, на какой станции они были запущены. Или хотя бы, интерактивно они запущены или нет. В API для работы со станциями и десктопами я такой возможности не нашел.
Можно все считать через ReadProcessMemory примерно так: