Мониторинг обменных курсов валют
18c0693f

Формат LE


VxD использует формат линейных исполняемых файлов (linear executable file format - LE). Этот формат был спроектирован для OS/2 вверсии 2.0. Он может содержать как 16-битный, так и 32-битный код, что является одним из требований к VxD. Помните, что VxD начали свою историю еще в эпоху Windows 3.x. В то время Windows загружалась из DOS'а, поэтому VxD должны были выполнять определенные действия в реальном режиме, прежде чем Windows переключала машину в защищенный режим. 16-битный код реального режима должен был находиться в том же файле, что и 32-битный код защищенного режима. Поэтому файловый LE-формат был очевидным выбором. Драйвера Windows NT не имеют дела с pеальным pежимом, поэтому им не надо использовать LE-формат. Вместо этого они используют PE-формат.

Код и данные в LE-файле хранятся в сегментах с различными аттрибутами выполнения. Они приводятся ниже.


Все это не значит, что ваш VxD обязан иметь все эти сегменты. Вы можете выбрать те сегменты, которые вы хотите использовать в вашем VxD. Hапример, если ваш VxD не имеет инициализации pеального pежима, у него не будет секции RCODE. Как правило, вы будете использовать LCODE, PCODE и PDATA. За вами, как за создателем VxD, остается выбоp нужных сегментов. Обычно вам следует использовать PCODE и PDATA так часто, как это возможно, потому что тогда VMM сможет выгружать сегменты из памяти и загружать их обратно, когда им это понадобится. Вы должны использовать LCODE для обработчиков хардварных прерываний и сервисов, которые будут вызываться этими обработчиками.

Вам не нужно использовать эти классы сегментов напрямую. Вы должны объявить сегменты на основе этих классов. Объявления сегментов находятся в файле определения модуля. (.def). Вот пример такого файла для VxD:

VXD FIRSTVXD

SEGMENTS _LPTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE _LTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE _LDATA CLASS 'LCODE' PRELOAD NONDISCARDABLE

_TEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE _DATA CLASS 'LCODE' PRELOAD NONDISCARDABLE CONST CLASS 'LCODE' PRELOAD NONDISCARDABLE _TLS CLASS 'LCODE' PRELOAD NONDISCARDABLE

_BSS CLASS 'LCODE' PRELOAD NONDISCARDABLE _LMGTABLE CLASS 'MCODE' PRELOAD NONDISCARDABLE IOPL _LMSGDATA CLASS 'MCODE' PRELOAD NONDISCARDABLE IOPL _IMSGTABLE CLASS 'MCODE' PRELOAD DISCARDABLE IOPL

_IMSGDATA CLASS 'MCODE' PRELOAD DISCARDABLE IOPL _ITEXT CLASS 'ICODE' DISCARDABLE _IDATA CLASS 'ICODE' DISCARDABLE _PTEXT CLASS 'PCODE' NONDISCARDABLE

_PMSGTABLE CLASS 'MCODE' NONDISCARDABLE IOPL _PMSGDATA CLASS 'MCODE' NONDISCARDABLE IOPL _PDATA CLASS 'PDATA' NONDISCARDABLE SHARED _STEXT CLASS 'SCODE' RESIDENT

_SDATA CLASS 'SCODE' RESIDENT _DBOSTART CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING _DBOCODE CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING _DBODATA CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING

_16ICODE CLASS '16ICODE' PRELOAD DISCARDABLE _RCODE CLASS 'RCODE' EXPORTS FIRSTVXD_DDB @1



Первое утверждение задает имя VxD. Имя VxD должно быть заданно в верхнем регистре. Я экспериментировал с именами в нижнем регистре, и VxD отказывался делать что-либо кроме как загрузки самого себя в память. Затем идут определения сегментов. Определение состоит из трех частей: имя сегмента, класс сегмента и желаемые свойства выполнения сегмента. Вы можете видеть, что многие сегменты основываются на одном классе, например, _LPTEXT, _LTEXT, _LDATA основываются на классе LCODE и имеют одни и те же свойства. Эти сегменты объявлены для того, чтобы сделать программирование легче. Hапрмер, LCODE может содержать и код и данные. Программисту будет проще поместить данные _LDATA, а код в _LTEXT. В конце концов, оба сегмента будут объединены в один при компиляции исполняемого файла.

VxD экспортирует один и только один символ - это device descriрtor block (DDB). Фактически, DDB - это структура, которая содержит все, что VMM должна знать о VxD. Вы должны экспортировать DDB в файле определения модуля. Большую часть времени вы будете использовать вышеприведенный .DEF файл в своих новых VxD-проектах. Вам следует только изменить имя VxD в первой и последней линиях .DEF-файла. Определения сегментов - это перегиб в asm'овском VxD-проекте. Вы получите много предупреждений, но это будет компилироваться.

Вы можете избавиться от назойливых предупреждений, удалив те определения сегментов, которые вы не используете в своих проектах.

vmm.inc содержит множество макросов для объявления сегментов в вашем исходнике.

_LTEXT VxD_LOCKED_CODE_SEG

_PTEXT VxD_PAGEABLE_CODE_SEG _DBOCODE VxD_DEBUG_ONLY_CODE_SEG

_ITEXT VxD_INIT_CODE_SEG

_LDATA VxD_LOCKED_DATA_SEG

_IDATA VxD_IDATA_SEG

_PDATA VxD_PAGEABLE_DATA_SEG

_STEXT VxD_STATIC_CODE_SEG

_SDATA VxD_STATIC_DATA_SEG

_DBODATA VxD_DEBUG_ONLY_DATA_SEG

_16ICODE VxD_16BIT_INIT_SEG

_RCODE VxD_REAL_INIT_SEG

У каждого макроса есть необходимая завершающая часть. Например, если вы хотите объявить сегмент _LTEXT в вашем исходнике, вам нужно это сделать так:

VxD_LOCKED_CODE_SEG <поместите сюда свой код> VxD_LOCKED_CODE_ENDS





Самый выгодный курс обмена валюты