Уроки Iczelion'а

       

Статический VxD:


VMM загружает статический VxD когда:

  • Резидентные программы реального режима обращаются к прерыванию int 2Fh, 1605h, чтобы загрузить его.
  • VxD указан в регистре в следующем ключе:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\key\StaticVx

  • VxD указан в system.in в секции [386enh]:
  • device=pathname

    Во время периода разработки, я предполагаю, что вы загружаете VxD из system.ini, потому что если в вашем VxD будет ошибка, из-за которой Windows не сможет загрузиться, вы сможете отредактировать system.ini из DOS'а. Вы не сможете ничего сделать, если VxD прописываться в регистре. (Можно отредактировать регистр с помощью regedit.exe, но под ДОСом это будет сложнее, чем под виндами - прим. Aquila).

    Когда VMM загружает ваш статический VxD, ваш VxD получить три системных контрольных сообщения в следующем порядке:

    • Sys_Critical_Init VMM посылает это контрольное сообщение после переключения в защищенный режим, но прежде, чем будут разрешены прерывания. Большинство VxD не нуждается в обработке этих сообщений, кроме тех случаев, когда:

    • Ваш VxD перехватывает некоторые прерывания, которые будут вызываться другими VxD или программа. Так как прерывания запрещены, когда вы обрабатываете эти контрольные сообщения, вы можете быть уверенным, что прерывания, которые вы перехватываете, не будут вызываться в то время, когда вы их перехватываете.
    • Ваш VxD предоставляет некоторые VxD сервисы, которые будут вызываться во время инициализации другими VxD. Hапример, некоторым VxD, загружающимся после вашего VxD, может потребоваться вызвать один из сервисов вашего VxD во временя обработки контрольного сообщения Device_Init. Так как сообщение Sys_Critical_Init посылается перед сообщением Device_Init, вы должны инициализировать ваши сервисы во время сообщения Sys_Critical_Init.

  • Если вы обрабатываете это сообщение, вам следует проводить инициализацию так быстро, как это возможно, чтобы предотвратить потерю вызовов хардварных прерываний (которые, как вы помните, запрещены).
  • Device_Init - VMM посылает контрольное сообщение после того, как прерывания были разрешены. Большинство VxD проводят инициализацию в качестве ответа на это сообщение. Так как прерывания разрешены, можно проводить объемные по времени операции без опасения того, что хардварные прерывания будут потеряны. Вам следует проводить инициализацию здесь (если потребуется).
  • Init_Comрlete - после того, как все VxD обработают сообщение Device_Init, но прежде чем VMM освободит все инициализационные сегменты (классы ICODE и RCODE), VMM посылает это контрольное сообщение. Требуется мало VxD , чтобы обработать это сообщение.

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

    Когда наступает время прервать выполнение статического VxD, VMM посылает следующие контрольные сообщения:


    • Когда ваш VxD получает это сообщение, Windows 95 находится в стадии завершения работы. Все другие виртуальные машины, кроме системной виртуальной машины уже уничтожены. Тем не менее CPU еще находится в защищенном режиме и запускать код реального режима на виртуальной машине еще безопасно. Kernel32.dll в это время уже выгружен.
    • Sys_Critical_Exit2 - ваш VxD получит это сообщение, когда все VxD уже обработали System_Exit2 и прерывания запрещены.


    Большинство VxD не нуждается в обработке этих двух сообщений, кроме тех случаев, когда вы хотите подготовить систему к переводу в реальный режим. Вы должны знать, что когда Windows 95 завершает работу, она входит в pеальный pежим. Поэтому если ваш VxD сделал что-то, что может сделать систему нестабильной в этом pежиме, ему следует восстановить изменения.

    Вы можете задать вопрос, почему эти два сообщения имеют на конце "2"? Помните, что когда VMM загружает статические VxD, она загружает VxD с наименьшим значением загрузочного порядка, чтобы VxD могли полагаться на сервисы VxD, загружаемых раньше них. Hапример, если VxD2 полагается на сервисы VxD1, она должна указать ее инициализационный порядок большим, чем порядок VxD1. Загрузочный порядок должен быть:

    ..... VxD1 ===> VxD2 ===> VxD3 .....

    Теперь, во время выгрузки, становится понятным, почему VxD, инициализированные раньше, должны и выгружаться раньше, чтобы они могли все еще могли вызывать сервисы VxD, которые загружались до них. В вышеприведенном примере, порядок должен быть следующим:

    .... VxD3 ===> VxD2 ===> VxD1.....

    В вышеприведенном примере, если VxD2 вызывал какие-то сервисы VxD1 во время инициализации, он все еще может нуждаться в них во время выгрузки. System_Exit2 и Sys_Critical_Exit2 шлются в порядке, обратном порядку инициализации. Это означает, что когда VxD2 получает эти сообщения, VxD1 еще не провел деинициализацию и он все еще может нуждаться в сервисах VxD1. Сообщения System_Exit и Sys_Critical_Exit не посылаются в обратном порядке. Это означает, что когда вы получаете эти два сообщения, вы не можете быть уверенным, что вы все еще можете вызывать сервисы VxD, который загружался до вас. Эти сообщения не следует использовать для новых VxD. Есть еще два сообщения выхода:


    • Device_Reboot_Notify2 - уведомляет VxD о том, что VMM собирается перезагрузить систему. Прерывания все еще доступны.
    • Crit_Reboot_Notify2 - уведоляет VxD о том, что VMM собирается перезагрузить систему. Прерывания запрещены.


    Теперь вы можете предположить, что существуют сообщения Device_Reboot_Notify и Crit_Reboot_Notify, но они посылаются не в порядке, обратном порядку инициализации.


    Содержание раздела