|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Сен 7, 2004 17:09:17 [ bogrus: Т.е. я правильно понимаю, что после этого вызова ядра мы имеем очередь сообщений, а если в нашем процессе нету gdi32.dll, то нет и очереди? ] Возможно вызов каких то функций из gdi32.dll тоже приводит к конвертации потока в GUI-поток, но в основном это функции user32.dll. Тут надо ставить бряк на изменение поля KTHREAD.ServiceTable и звать функцию, ну или просто после каждого вызова смотреть это поле. |
|
|
Дата: Сен 7, 2004 17:43:19 [ bogrus: уже три раза его ставил и потом три раза сносил , не могу вытерпеть его интерфейс ] Ну да, по-началу жутковато: кругом темно и ничего не понятно :) Потом привыкнешь. |
|
|
Дата: Сен 7, 2004 17:47:15 · Поправил: bogrus Возможно вызов каких то функций из gdi32.dll тоже приводит к конвертации потока в GUI-поток, но в основном это функции user32.dll. Да , теперь я понял , так и происходит . Я нашёл ещё в user32.dll вызовы ядра , которые так делают . Из юзера видно , что они заполняют [fs:40h] . После CreateThread оно действительно ещё пустое , а после вызова некоторых гди-юзер ф-ций уже заполнено . |
|
|
Дата: Сен 8, 2004 00:51:0477F4224D B8 D4100000 MOV EAX, 10D4 Собсна всё несколько проще. Я как-то сразу не сообразил. Индекс 10D4 однозначно говорит о том, что поток будет преобразован в GUI, если он конечно уже не GUI. Индексы в диапазоне 0-0FFFh - это индексы сервисов в ntoskrnl.exe, в диапазоне 1000-1FFFh - индексы сервисов в win32k.sys. При первом же вызове любого сервиса из win32k.sys поток конвертится в GUI. Вот кусок кода обработчика int2E: #define NUMBER_SERVICE_TABLES 4
#define SERVICE_NUMBER_MASK ((1 << 12) - 1)
#define SYSTEM_SERVICE_INDEX 0
#define WIN32K_SERVICE_INDEX 1
#define SERVICE_TABLE_SHIFT (12 - 4)
#define SERVICE_TABLE_MASK (((1 << 2) - 1) << 4)
#define SERVICE_TABLE_TEST (WIN32K_SERVICE_INDEX << 4)
_KiSystemService proc
;
; (eax) = Service number
; (edx) = Callers stack pointer
; (esi) = Current thread address
;
_KiSystemServiceRepeat:
mov edi, eax ; copy system service number
shr edi, SERVICE_TABLE_SHIFT ; isolate service table number
and edi, SERVICE_TABLE_MASK ;
mov ecx, edi ; save service table number
add edi, [esi]+ThServiceTable ; compute service descriptor address
mov ebx, eax ; save system service number
and eax, SERVICE_NUMBER_MASK ; isolate service table offset
;
; If the specified system service number is not within range, then attempt
; to convert the thread to a GUI thread and retry the service dispatch.
;
cmp eax, [edi]+SdLimit ; check if valid service
jae Kss_ErrorHandler ; if ae, try to convert to GUI thread
. . .
;
; The specified system service number is not within range. Attempt to
; convert the thread to a GUI thread if the specified system service is
; not a base service and the thread has not already been converted to a
; GUI thread.
;
Kss_ErrorHandler:
cmp ecx, SERVICE_TABLE_TEST ; test if GUI service
jne short Kss_LimitError ; if ne, not GUI service
push edx ; save argument registers
push ebx ;
stdcall _PsConvertToGuiThread ; attempt to convert to GUI thread |
|
|
Дата: Сен 11, 2004 03:59:58 · Поправил: Oleg_SK [Four-F: Запусти тот же notepad и выбери там любой диалог из меню.] Да, действительно, в приведенном тобой примере функция MessageBox работает вполне логично (во время своей работы, позволяет окну владельцу перерисовываться и т.д., т.е. обрабатывать свои сообщения). С другой стороны, когда она начинает вести себя так в процессе работы процедуры обработки исключений, то, IMHO, это поведение уже нельзя назвать логичным, потому что нет смысла пытаться обрабатывать оконные сообщения в условиях когда весьма вероятно повторное исключения (которое, кстати, может произойти и при обработке сообщения WM_PAINT). Мне кажется, что гораздо логичнее было бы, если бы в этом случае выполнение кода в проблемном потоке блокировалось (пусть даже в ущерб интерфейсу пользователя). Ладно, это все лирика. Приношу огромную благодарность всем участникам! По сути, вопрос исчерпан. |
|
|
Дата: Сен 11, 2004 08:28:47 Хочу, до кучи, добавить еще третий возможный способ решения этой проблемы (БОГ троицу любит:)): 3. В процедуре обработчика можно создать отдельный поток и уже в нем вызвать MessageBox. В этом случае, сразу после создания этого потока можно явно усыпить проблемный поток одной из ожидающих функций (например: WaitForSingleObject) до окончания новоиспеченного потока, который завершится сразу после отработки MessageBox. |
|
|
Дата: Окт 16, 2004 12:54:46 Oleg_SK Твой перевод у меня на стадии завершения правки. Ты где? :) |
|
|
Дата: Окт 20, 2004 22:19:17 Edmond Сегодня и ближайшие несколько дней я буду здесь появляться. З.Ы.: Извени за задержку с ответом. |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.056 |