· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.WIN32 —› Помогите разобраться с работой API-функции MessageBox.

<< . 1 . 2 . 3 .

Посл.отвђт Сообщен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:04

77F4224D    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
Сегодня и ближайшие несколько дней я буду здесь появляться.
З.Ы.: Извени за задержку с ответом.

<< . 1 . 2 . 3 .


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.056