<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=299218&amp;view=findpost&amp;p=2553748</guid>
        <pubDate>Wed, 31 Mar 2010 16:05:24 +0000</pubDate>
        <title>Список окон</title>
        <link>https://forum.sources.ru/index.php?showtopic=299218&amp;view=findpost&amp;p=2553748</link>
        <description><![CDATA[ALXR: Итак, сегодня мы окунемся в мир MS, мир недокументированный. Обычно, для получения списка окон или свойств окна мы используем API навроде:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">EnumWindows();</div><div class="code_line">GetWindow();</div><div class="code_line">GetWindowLong();</div><div class="code_line">GetWindowText();</div><div class="code_line">SetWindowLong();</div><div class="code_line">SetWindowText();</div><div class="code_line">SendMessage(); // (в некоторых случаях. Например, WM_CHANGEUISTATE)</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
<br>
В данном примере мы используем всего две ф-ции из недр Windows. Одну для получения массива некоторых данных, другую - для удобства (дабы не лезть в ядро).<br>
Если погуглить, например по слову &quot;ValidateHwnd&quot;, то можно найти много информации на эту тему. Однако она весьма разрознена и, хоть и авторы пытались ее развернуть по максимуму, получилось это слабо. Отчего-то многие, по привычке (видимо, на wasm.ru всегда идут в лоб) ищут данные дизассемблированием подсистемы win32k и user32. В принципе, даже нашли универсальные способы (для всех версий WinNT, начиная с win2k) поиска нужных участков кода и получения из него данных. ЕМНИП, способ хоть и железный, но некрасивый. Мы пойдем другим путем.<br>
Впрочем, без проверки версии ОС нам тоже не обойтись, ибо структура, коей будем пользоваться недокументирована и в ней от версии к версии добавляются/удаляются какие-то поля. Но на мой взгляд - это мелочи, - данные мы получим верные, надо будет только в зависимости от версии ОС их разобрать.<br>
<br>
Итак. Начнем с того, что нам известно.<br>
Все ф-ции по работе с окошками используют некий описатель HWND, который объявлен как opaque в MSDN и больше там информации нет. На самом деле HWND состоит из двух полей типа USHORT. Старшее слово - это уникальный индекс, который был введен разработчиками MS для внутренних целей, но потом они от него отказались, потому что много софта, писавшегося под win передавали HWND в виде USHORT и этот индекс всегда терялся, поэтому в данный момент он не используется, хотя и всегда добавляется в HWND. Более интересно младшее слово - это индекс в таблице описателей графической подсистемы win32. По этому индексу мы можем получить структуру, описывающую объект. Между прочим, в этой таблице хранятся описатели не только окон, но и:<br>
- Таймеры; (те самые, что создаются через SetTimer())<br>
- Меню;<br>
- Хуки;<br>
- Данные буфера обмена;<br>
- Акселлераторы;<br>
<br>
Ну и прочие объекты, в данном моменте нам неинтересные (кому интересно - могут глянуть на сайте reactos, например).<br>
А вот теперь, самое интересное. Тут, как говорится, есть две новости - одна плохая, другая - хорошая. Данная таблица описателей (точнее объекты, на которые она ссылается) хранится в памяти ядра (конкретнее по адресам 0xbfXXXXXX - зависит от версии ОС, но в winxp sp2/3 там). Но, однако, некоторая часть этой таблицы отображена в user-mode пространство и может быть прочитана (но не изменена&#33;). Этой некоторой части таблицы нам будет достаточно. Во-первых, то, что мы можем подсмотреть - это окна, меню, хуки и еще пара типов объектов. Причем, отображены не все описатели для этих объектов, а только те, которые представлены на текущей для процесса оконной станции (WinStation).<br>
Ну, для начала этих окон будет достаточно.<br>
Теперь, задачи перед нами стоят следующие: получить адрес этой таблицы (а она будет в user-mode пространстве), найти указатель на объект по HWND, а затем по этому указателю (который указывает в область ядра) найти указатель на копию объекта в user-mode.<br>
Начнем с первого: получим адрес таблицы. В гуглах обычно пишут следующее: для таких-то версий ОС адреса этой таблицы (в user32.dll) такие-то, либо по GetProcAddress ищем такую-то функцию в user32.dll, а там по сигнатурам ищем нужный участок кода и из этого участка получаем адрес этой самой таблицы. Как я уже говорил - эти методы не для нас. Мы же белые люди?<br>
Для получения адреса этой самой штуки надо подключится к серверу csrss (раньше он отвечал за всю графическую подсистему, сейчас, насколько мне известно, из него вынули б0льшую часть функционала и перенесли в другие места). Несмотря на то, что user32 при инициализации подключается к серверу, мы можем сделать это еще раз и получить свою собственную копию данных.<br>
Подключение выполняется с помощью недокументированной функции <strong class='tag-b'>CsrClientConnectToServer</strong>. Описание найти в интернете сложно, поэтому приведу его здесь:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">NTSTATUS</div><div class="code_line">WINAPI</div><div class="code_line">CsrClientConnectToServer(</div><div class="code_line">&nbsp;&nbsp; &nbsp;IN PWSTR ObjectDirectory, &nbsp;// объектная директория, из которой получать данные</div><div class="code_line">&nbsp;&nbsp; &nbsp;IN ULONG ServerDllIndex, &nbsp; // тип запрашиваемой информации</div><div class="code_line">&nbsp;&nbsp; &nbsp;IN OUT PVOID ConnectionInformation, &nbsp;// структура, в которой мы получим необходимые данные</div><div class="code_line">&nbsp;&nbsp; &nbsp;IN OUT PULONG ConnectionInformationLength, // ее длина</div><div class="code_line">&nbsp;&nbsp; &nbsp;OUT PBOOLEAN CalledFromServer // мы - есть сервер?</div><div class="code_line">&nbsp;&nbsp; &nbsp;);</div></ol></div></div></div></div><br>
Какие поля тут имеются. Ну во-первых, ObjectDirectory. В нашем случае нас интересуют объекты графической подсистемы, а они хранятся в директории &#092;Windows (не путать с папкой Windows&#33;):<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">#define WINSS_OBJECT_DIRECTORY_NAME &nbsp; &nbsp; L&quot;\Windows&quot;</div></ol></div></div></div></div><br>
Тип запрашиваемой информации: объекты USER<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">#define USERSRV_SERVERDLL_INDEX &nbsp; &nbsp; &nbsp; &nbsp; 3</div></ol></div></div></div></div><br>
<br>
Структура данных:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">typedef struct _tagUSERCONNECT</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;ULONG ulVersion; &nbsp; &nbsp; &nbsp; &nbsp;// &nbsp;Версия подсистемы (как правило это 0x50000000. Хотя на Vista и 7 могло поменяться на 0x60000000, но данный момент меня мало интересовал).</div><div class="code_line">&nbsp;&nbsp; &nbsp;ULONG ulCurrentVersion; &nbsp; &nbsp; // &nbsp;Not required</div><div class="code_line">&nbsp;&nbsp; &nbsp;DWORD dwDispatchCount; &nbsp; &nbsp; &nbsp;// &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;SHAREDINFO siClient; &nbsp; &nbsp; &nbsp; &nbsp;// &nbsp;А здесь хранится самая важная структура. В интернете упоминания о ней можно найти по названию переменной gSharedInfo.</div><div class="code_line">} USERCONNECT, *PUSERCONNECT;</div></ol></div></div></div></div><br>
<br>
Здесь важно следующее:<br>
- во-первых, версия должна быть указана обязательно;<br>
- во-вторых, размер структуры при вызове ф-ции должен _точно_ соответствовать нашей, иначе нам покажут STATUS_UNSUCCESSFUL и больше ничего.<br>
Если все ОК, то *siClient = FALSE (как правило, ибо мы не сервер CSRSS), в ConnectionInformation запишется требуемая нами информация.<br>
<br>
Итак:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// undocumented.cpp</div><div class="code_line">&nbsp;</div><div class="code_line">SHAREDINFO gSharedInfo;</div><div class="code_line">PSERVERINFO gpsi;</div><div class="code_line">&nbsp;</div><div class="code_line">BOOL RetreiveSharedInfo()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp; ULONG sz = sizeof(USERCONNECT);</div><div class="code_line">&nbsp;&nbsp; &nbsp; BOOLEAN pserv = FALSE;</div><div class="code_line">&nbsp;&nbsp; &nbsp; USERCONNECT uc = { 0 };</div><div class="code_line">&nbsp;&nbsp; &nbsp; uc.ulVersion = 0x50000000;</div><div class="code_line">&nbsp;&nbsp; &nbsp; </div><div class="code_line">&nbsp;&nbsp; &nbsp; if ( STATUS_SUCCESS != CsrClientConnectToServer(WINSS_OBJECT_DIRECTORY_NAME, USERSRV_SERVERDLL_INDEX, &amp;uc, &amp;sz, &amp;pserv) )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return FALSE;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;gSharedInfo = uc.siClient;</div><div class="code_line">&nbsp;&nbsp; &nbsp;gpsi = uc.psi;</div><div class="code_line">&nbsp;&nbsp; &nbsp;return TRUE;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
Обратимся к структуре SHAREDINFO:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">typedef struct tagSHAREDINFO {</div><div class="code_line">&nbsp;&nbsp; &nbsp;PSERVERINFO psi; &nbsp; &nbsp; &nbsp; &nbsp;// здесь лежит некоторая интересующая нас информация, см. ниже</div><div class="code_line">&nbsp;&nbsp; &nbsp;struct _HANDLEENTRY &nbsp; *aheList; &nbsp; &nbsp; &nbsp; &nbsp; // таблица описателей</div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID *pDispInfo; &nbsp; &nbsp; &nbsp; // информация о текущем дисплее</div><div class="code_line">&nbsp;&nbsp; &nbsp;ULONG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ulSharedDelta; &nbsp; // Эта дельта - разница между значением указателя на ядро и значением указателя на пользовательскую память (маппинг)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Сложно сказать, что это за дельта, но нам она не понадобится. </div><div class="code_line">&nbsp;&nbsp; &nbsp;LPWSTR pszDllList; &nbsp; &nbsp; &nbsp;// все нижележащие поля нам неинтересны</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WNDMSG awmControl[FNID_END - FNID_START + 1];</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WNDMSG DefWindowMsgs;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WNDMSG DefWindowSpecMsgs;</div><div class="code_line">} SHAREDINFO, *PSHAREDINFO;</div></ol></div></div></div></div><br>
<br>
<br>
Далее приведу только часть структуры PSERVERINFO, где лежит информация, которая нам интересна:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">typedef struct tagSERVERINFO { &nbsp; &nbsp; &nbsp;// si</div><div class="code_line">&nbsp;&nbsp; &nbsp;WORD &nbsp; &nbsp;wRIPFlags; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// RIPF_ flags</div><div class="code_line">&nbsp;&nbsp; &nbsp;WORD &nbsp; &nbsp;wSRVIFlags; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // SRVIF_ flags</div><div class="code_line">&nbsp;&nbsp; &nbsp;WORD &nbsp; &nbsp;wRIPPID; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// PID of process to apply RIP flags to (zero means all)</div><div class="code_line">&nbsp;&nbsp; &nbsp;WORD &nbsp; &nbsp;wRIPError; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Error to break on (zero means all errors are treated equal)</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DWORD &nbsp; cHandleEntries; &nbsp; &nbsp; &nbsp; &nbsp; // count of handle entries in array</div><div class="code_line">} SERVERINFO, *PSERVERINFO;</div></ol></div></div></div></div><br>
Здесь нам интересно поле cHandleEntries, которое обозначает размер таблицы aheList.<br>
<br>
Ну и наконец, что у нас лежит в элементах массива:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">typedef struct _HANDLEENTRY {</div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID &nbsp; phead; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* указатель на объект. Указывает в область ядра!!! */</div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID &nbsp; pOwner; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* владелец объекта (процесс или поток) */</div><div class="code_line">&nbsp;&nbsp; &nbsp;BYTE &nbsp; &nbsp;bType; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* тип объекта (TYPE_WINDOW, TYPE_MENU, etc) */</div><div class="code_line">&nbsp;&nbsp; &nbsp;BYTE &nbsp; &nbsp;bFlags; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* флаги (например, HANDLEF_DESTROY) */</div><div class="code_line">&nbsp;&nbsp; &nbsp;WORD &nbsp; &nbsp;wUniq; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* индекс уникальности (не используется) */</div><div class="code_line">} HANDLEENTRY, *PHE;</div></ol></div></div></div></div><br>
<br>
Интересующая нас информация об окне лежит в памяти по указателю phead. Для окна эта структура выглядит следующим образом:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">typedef struct tagCOMMON_WNDCLASS</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;int &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cWndReferenceCount; // число окошек, созданных этим классом</div><div class="code_line">&nbsp;&nbsp; &nbsp;UINT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;style; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WNDPROC_PWND &nbsp;lpfnWndProc; &nbsp; &nbsp; &nbsp; </div><div class="code_line">&nbsp;&nbsp; &nbsp;int &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbclsExtra;</div><div class="code_line">&nbsp;&nbsp; &nbsp;int &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbwndExtra;</div><div class="code_line">&nbsp;&nbsp; &nbsp;HANDLE &nbsp; &nbsp; &nbsp; &nbsp;hModule;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID &nbsp; &nbsp; &nbsp; &nbsp; spicn;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID &nbsp; &nbsp; &nbsp; &nbsp; spcur;</div><div class="code_line">&nbsp;&nbsp; &nbsp;HBRUSH &nbsp; &nbsp; &nbsp; &nbsp;hbrBackground;</div><div class="code_line">&nbsp;&nbsp; &nbsp;LPWSTR &nbsp; &nbsp; &nbsp; &nbsp;lpszMenuName;</div><div class="code_line">&nbsp;&nbsp; &nbsp;LPSTR &nbsp; &nbsp; &nbsp; &nbsp; lpszAnsiClassName; &nbsp;// самое главное - имя класса! </div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID &nbsp; &nbsp; &nbsp; &nbsp; spicnSm;</div><div class="code_line">} COMMON_WNDCLASS;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">typedef struct tagCLS {</div><div class="code_line">&nbsp;&nbsp; &nbsp;struct tagCLS * &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pclsNext; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // указатель а следующий класс</div><div class="code_line">&nbsp;&nbsp; &nbsp;ATOM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;atomClassName;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fnid; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rpdeskParent; &nbsp; &nbsp;/* десктоп */ </div><div class="code_line">&nbsp;&nbsp; &nbsp;PDCE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdce; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* объект DC (Device Context) */</div><div class="code_line">&nbsp;&nbsp; &nbsp;WORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hTaskWow;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CSF_flags; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* внутренние флаги */</div><div class="code_line">&nbsp;&nbsp; &nbsp;LPSTR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lpszClientAnsiMenuName; &nbsp; &nbsp; /* имя ресурса меню ansi */</div><div class="code_line">&nbsp;&nbsp; &nbsp;LPWSTR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lpszClientUnicodeMenuName; &nbsp;/* имя ресурса меню unicode */</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PCALLPROCDATA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spcpdFirst; &nbsp; &nbsp; &nbsp; /* процедура обработчика */</div><div class="code_line">&nbsp;&nbsp; &nbsp;struct tagCLS * &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pclsBase; &nbsp; &nbsp; &nbsp; &nbsp;/* Начало массива классов */</div><div class="code_line">&nbsp;&nbsp; &nbsp;struct tagCLS * &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pclsClone; &nbsp; &nbsp; &nbsp; /* Начало копии массива классов */</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;BOOL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fFlag;</div><div class="code_line">&nbsp;&nbsp; &nbsp;COMMON_WNDCLASS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wc; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// пользовательские данные класса (похожа на WNDCLASS, но есть некоторые отличия)</div><div class="code_line">} CLS, *PCLS, **PPCLS;</div><div class="code_line">&nbsp;</div><div class="code_line">typedef struct _WW</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;ULONG &nbsp; &nbsp; &nbsp; state1;</div><div class="code_line">&nbsp;&nbsp; &nbsp;ULONG &nbsp; &nbsp; &nbsp; state2;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DWORD &nbsp; &nbsp; &nbsp; dwStyleEx;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DWORD &nbsp; &nbsp; &nbsp; dwStyle;</div><div class="code_line">&nbsp;&nbsp; &nbsp;HMODULE &nbsp; &nbsp; hInstance;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WORD &nbsp; &nbsp; &nbsp; &nbsp;hMod16;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WORD &nbsp; &nbsp; &nbsp; &nbsp;fnid;</div><div class="code_line">} WW, *PWW;</div><div class="code_line">&nbsp;</div><div class="code_line">typedef struct tagWND { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// wnd</div><div class="code_line">&nbsp;&nbsp; &nbsp;THRDESKHEAD &nbsp; head; &nbsp; &nbsp;// информация о текущем десктопе и потоке, которому принадлежит окошко</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WW &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ww; &nbsp; &nbsp; &nbsp; // различная оконная информация: стили, hInstance и т.п.</div><div class="code_line">&nbsp;&nbsp; &nbsp;struct tagWND * &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spwndNext; &nbsp; &nbsp;// указатель на объект следующего окна</div><div class="code_line">&nbsp;&nbsp; &nbsp;struct tagWND * &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spwndPrev; &nbsp; &nbsp;// ...предыдущего</div><div class="code_line">&nbsp;&nbsp; &nbsp;struct tagWND * &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spwndParent; &nbsp;// ...родительского</div><div class="code_line">&nbsp;&nbsp; &nbsp;struct tagWND * &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spwndChild; &nbsp; // ...дочернего</div><div class="code_line">&nbsp;&nbsp; &nbsp;struct tagWND * &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spwndOwner; &nbsp; // ...&quot;босс&quot; для нашего окна</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;RECT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rcWindow; &nbsp; &nbsp; // размеры окна</div><div class="code_line">&nbsp;&nbsp; &nbsp;RECT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rcClient; &nbsp; &nbsp; // ...и его клиентской части</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lpfnWndProc; &nbsp; // указатель на процедуру-обработчика окна</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PCLS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcls; &nbsp; &nbsp; &nbsp; &nbsp; // информация о классе окна</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;HRGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hrgnUpdate; &nbsp; // регион отрисовки</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ppropList; &nbsp; &nbsp;// Указатель на PropList (SetProp/GetProp итд)</div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pSBInfo; &nbsp; // указатель на данные полос прокрутки</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;spmenuSys; &nbsp;// Указатель на объект системного меню</div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;spmenu; &nbsp; &nbsp; // Menu handle or ID</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;HRGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hrgnClip; &nbsp; &nbsp; // еще один регион для отрисовки</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;LARGE_UNICODE_STRING strName; &nbsp; &nbsp; &nbsp;// текст окна (не тот, который задается через WM_SET/GETTEXT, а тот, что через Set/GetWindowText </div><div class="code_line">&nbsp;&nbsp; &nbsp;int &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbwndExtra; &nbsp; // Размер пользовательских данных (Get/SetWindowLong).</div><div class="code_line">&nbsp;&nbsp; &nbsp;struct tagWND * &nbsp; &nbsp; &nbsp;spwndLastActive; // Последний активный попап</div><div class="code_line">&nbsp;&nbsp; &nbsp;HIMC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hImc; &nbsp; &nbsp; &nbsp; &nbsp; // input context</div><div class="code_line">&nbsp;&nbsp; &nbsp;ULONG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwUserData; &nbsp; // Пользовательские данный (Get/SetWindowLong(GWL_USERDATA)</div><div class="code_line">} WND,*PWND;</div></ol></div></div></div></div><br>
<br>
Итак, мы все знаем. Осталось только получить указатель на эту структуру в юзер-спэйсе (мы ведь помним, что они хранятся вне адресного пространства юзер-мода, но отмаплены на юзер-память).<br>
Этот указатель получается следующим образом: есть некая дельта, которую необходимо вычесть из адреса ядра и мы получим валидный адрес в юзер-моде:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">PWND pwnd = PWND(ULONG(p-&#62;phead) - g_uDelta); // &#60;&#60;-- все, здесь мы можем получить доступ к данным</div></ol></div></div></div></div><br>
Несмотря на то, что сервер csrss нам дал какую-то дельту, но, как ни странно - это не она. :) Нужная нам дельта есть в TEB. Приводить структуру TEB я не буду (можно поглядеть на нее <a class='tag-url' href='http://www.nirsoft.net/kernel_struct/vista/TEB.html' target='_blank'>здесь</a>. Там нас мало что интересует, кроме поля Win32ClientInfo. По непонятным причинам оно везде обозначено так <strong class='tag-b'>ULONG Win32ClientInfo[62];</strong>. Однако это не массив лонгов, а самая обычная структура, которая выглядит так:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">#define CVKKEYCACHE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 32</div><div class="code_line">#define CBKEYCACHE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(CVKKEYCACHE &#62;&#62; 2)</div><div class="code_line">&nbsp;</div><div class="code_line">#define CVKASYNCKEYCACHE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;16</div><div class="code_line">#define CBASYNCKEYCACHE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (CVKASYNCKEYCACHE &#62;&#62; 2)</div><div class="code_line">&nbsp;</div><div class="code_line">typedef struct _CLIENTINFO {</div><div class="code_line">&nbsp;&nbsp; &nbsp;DWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CI_flags; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Needs to be first because CSR</div><div class="code_line">&nbsp;&nbsp; &nbsp;DWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cSpins;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwExpWinVer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DWORD &nbsp; &nbsp; &nbsp; dwUnknownFlags;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwCompatFlags;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwTIFlags;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID &nbsp; &nbsp; &nbsp; pDeskInfo;</div><div class="code_line">&nbsp;&nbsp; &nbsp;ULONG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ulClientDelta;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; phkCurrent;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fsHooks;</div><div class="code_line">&nbsp;&nbsp; &nbsp;CALLBACKWND &nbsp; &nbsp; &nbsp; &nbsp; CallbackWnd;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwHookCurrent;</div><div class="code_line">&nbsp;&nbsp; &nbsp;int &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cInDDEMLCallback;</div><div class="code_line">&nbsp;&nbsp; &nbsp;HANDLE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hDdemlCallbackInst;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pClientThreadInfo;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwHookData;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwKeyCache;</div><div class="code_line">&nbsp;&nbsp; &nbsp;BYTE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;afKeyState[CBKEYCACHE];</div><div class="code_line">&nbsp;&nbsp; &nbsp;DWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwAsyncKeyCache;</div><div class="code_line">&nbsp;&nbsp; &nbsp;BYTE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;afAsyncKeyState[CBASYNCKEYCACHE];</div><div class="code_line">&nbsp;&nbsp; &nbsp;BYTE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;afAsyncKeyStateRecentDown[CBASYNCKEYCACHE];</div><div class="code_line">&nbsp;&nbsp; &nbsp;WORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CodePage;</div><div class="code_line">&nbsp;&nbsp; &nbsp;HKL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hKL;</div><div class="code_line">&nbsp;&nbsp; &nbsp;BYTE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;achDbcsCF[2]; </div><div class="code_line">&nbsp;&nbsp; &nbsp;MSG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msgDbcsCB;</div><div class="code_line">} CLIENTINFO, *PCLIENTINFO;</div></ol></div></div></div></div><br>
Здесь тоже мало интересного, кроме поля <strong class='tag-b'>ulClientDelta</strong> - это и есть нужная нам дельта. Получим ее так:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">g_uDelta = PCLIENTINFO(&amp;PTEB(NtCurrentTeb())-&#62;Win32ClientInfo)-&#62;ulClientDelta;</div></ol></div></div></div></div><br>
<br>
Вот теперь мы во всеоружии&#33;<br>
Тут, правда, необходимо учесть вот что: не все объекты отмаплены в наше пространство, поэтому надо как-то отделить мух от котлет. Для начала вспомним, что мы можем получить информацию только о тех окнах, которые присутствуют на нашем десктопе. В THRDESKHEAD структуры tagWND есть поле rpdesk - указатель на объект десктопа (что там лежит - неважно, важен сам указатель). Будем сравнивать его с указателем окна нашего десктопа (GetDesktopWindow()). Но для того, чтобы коснуться этого, надо написать ту самую ValidateHwnd:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">PWND ValidateHwnd(HWND hWnd)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp; USHORT index = LOWORD(hWnd), wUniq = HIWORD(hWnd);</div><div class="code_line">&nbsp;&nbsp; &nbsp; if ( index &#62;= 0 &amp;&amp; index &#60; gpsi-&#62;cHandleEntries )</div><div class="code_line">&nbsp;&nbsp; &nbsp; {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ( gSharedInfo.aheList[index].bType == TYPE_WINDOW ) </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return PWND(ULONG(gSharedInfo.aheList[index].phead) - g_uDelta);</div><div class="code_line">&nbsp;&nbsp; &nbsp; }</div><div class="code_line">&nbsp;&nbsp; &nbsp; return NULL;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
Разберем структуру THRDESKHEAD:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">typedef struct _HEAD {</div><div class="code_line">&nbsp;&nbsp; &nbsp;HANDLE h; &nbsp; &nbsp; &nbsp; &nbsp;// здесь h = hWnd</div><div class="code_line">&nbsp;&nbsp; &nbsp;DWORD &nbsp; cLockObj;</div><div class="code_line">} HEAD, *PHEAD;</div><div class="code_line">&nbsp;</div><div class="code_line">typedef struct _THROBJHEAD {</div><div class="code_line">&nbsp;&nbsp; &nbsp;HEAD head;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID pti; &nbsp; &nbsp; &nbsp;// PTHREADINFO</div><div class="code_line">} THROBJHEAD, *PTHROBJHEAD;</div><div class="code_line">&nbsp;</div><div class="code_line">typedef struct _DESKHEAD {</div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID &nbsp; &nbsp;rpdesk;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PBYTE &nbsp; &nbsp;pSelf;</div><div class="code_line">} DESKHEAD, *PDESKHEAD;</div><div class="code_line">&nbsp;</div><div class="code_line">typedef struct _THRDESKHEAD {</div><div class="code_line">&nbsp;&nbsp; &nbsp;THROBJHEAD thr;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DESKHEAD deskhead;</div><div class="code_line">} THRDESKHEAD, *PTHRDESKHEAD;</div></ol></div></div></div></div><br>
И тут есть поле rpdesk, которое нам и нужно.<br>
Ну что ж, попробуем написать перечисление окошек:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">void MyEnumWindows()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;HWND hDesktop = GetDesktopWindow();</div><div class="code_line">&nbsp;&nbsp; &nbsp;PWND pDesktop = ValidateHwnd(hDesktop);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PVOID rpdesk = pDesktop-&#62;head.deskhead.rpdesk;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;ULONG count = gpsi-&#62;cHandleEntries;</div><div class="code_line">&nbsp;&nbsp; &nbsp;for(ULONG c = 0; c &#60; count; ++c)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ( gSharedInfo.aheList[c].bType == TYPE_WINDOW )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PWND pwnd = PWND(ULONG(gSharedInfo.aheList[c].phead) - g_uDelta);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;__try &nbsp; &nbsp;// здесь поступаем не очень красиво. Если объект не отмаплен в юзер-спейс - он может указать на мусор</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ( pwnd-&#62;head.deskhead.rpdesk == rpdesk ) // наше окно! (и здесь возможно исключение, либо какой-нибудь NULL, который будет отсеян)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LPWSTR strName = LPWSTR(ULONG(pwnd-&#62;strName.Buffer) - g_uDelta);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PCLS pcls = PCLS(ULONG(pwnd-&#62;pcls) - g_uDelta); // да-да! Нам придется вычислять смещения для всех указателей структуры!</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LPSTR strClassname = LPSTR(ULONG(pcls-&#62;lpszAnsiClassName) - g_uDelta);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(&quot;Window: hwnd = 0x%08x; class: `%s`; title: `%ws`\n&quot;, pwnd-&#62;head.thr.h, strClassname, strName);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;__except(EXCEPTION_EXECUTE_HANDLER)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // не наше окно :(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">}</div></ol></div></div></div></div><br>
Реализация перечисления окон не очень хороша. В данном случае, подход в последней процедуре не очень красивый, но хочется сделать побыстрее и покороче. В действительности нужно было бы весьма заковыристыми путями получить десктоп потока (pOwner в HANDLEENTRY, который, кстати, тоже указывает в ядро) и сравнить с десктопом DesktopWindow.<br>
<br>
Пока все. (позже добавлю информацию на тему структуры WW из tagWND, там тоже есть интересная информация). Исходники добавлю позже&#33;<br>
<br>
&copy; ALXR<br>
<br>
<span class="tag-color tag-color-named" data-value="gray" style="color: gray"><span class='tag-size' data-value='7' style='font-size:7pt;'>Сообщения были разделены в тему &quot;<a class='tag-url' href='http://forum.sources.ru/index.php?showtopic=406459' target='_blank'>spam</a>&quot;</span></span>]]></description>
        <author>ALXR</author>
        <category>C/C++ FAQ</category>
      </item>
	
      </channel>
      </rss>
	