Уроки Iczelion'а



Hемного теории


Если ваш VxD работает с некоторыми V86-процедураи, рано или поздно ему потребуется передать и получить большой объем данных от V86-программы. Использовать регистры для этой цели неудобно. Вашей следующей попыткой может стать резервирование блока памяти в ring0 и передача указателя на блок памяти через какой-нибудь регистр, чтобы V86-код мог воспользоваться этими данными. Если вы сделаете так, это, вполне вероятно, вызовет крах системы, потому что адресация режима V86 требует пару segment:offset, а не линейный адрес.

Есть много способов решить эту проблему. Тем не менее, я выбрал простой путь, чтобы показать сервисы, предоставляемые менеджером V86-памяти. Если каким-то образом вы сможете найти свободный блок памяти в V86-регионе, который вы захотите использовать в качестве буфера передачи данных, это решит одну из проблем. Тем не менее, останется проблема трансляции указателя в надлежащий формат. Вы можете решить обе проблемы, используя сервисы менеджера V86-памяти.

Менеджер V86-памяти - это статический VxD, который управляет памятью для V86-приложений. Он также предоставляет сервисы EMS и XMS V86-приложениям и API-сервисы трансляции другим VxD. API-трансляция, фактически, является процессом копирования данных из ring0 в буфер в V86-регионе и затем передача V86-адреса данных V86-коду. Никакого волшебства.

Менеджер V86-памяти управляет буфером трансляции, который является блоком памяти в V86-регионе для копирования данных от VxD в V86-регион и обратно. Изначально этот буфер трансляции равен четырем килобайтам. Вы можете повысить размер этого буфера, вызвав V86MMGR_Set_Maрing_Info.

Теперь, когда вы знаете о буфере трансляции, как мы можем скопировать данные туда и обратно? Это вопрос вовлекает два сервиса: V86MMGR_Allocate_Buffer и V86MMGR_Free_Buffer.

V86MMGR_Allocate_Buffer резервирует блок памяти из буфера трансляции и опционально копирует данные из ring0 в зарезервированный V86-блок. V86MMGR_Free_Buffer делает обратное: он опционально копирует данные из зарезервированного V86-блока в rin0-буфер и освобождает блок памяти, зарезервированный V86MMGR_Allocate_Buffer.

Заметьте, что менеджер V86-памяти управляет зарезервированными буферами как стеком. Это означает, что резервирование/освобождение должны соблюдать правило "первый вошел/первый вышел". Поэтому, если вы сделаете два вызова V86MMGR_Allocate_Buffer, первый вызов V86MMGR_Free_Buffer освободит буфер зарезервированный вторым вызовом V86MMGR_Allocate_Buffer.

Теперь мы можем перейти к анализированию определения V86MMGR_Allocate_Buffer. Этот сервис получает данные через регистры.