VxD initialization and Termination

Source: Internet
Author: User


VxD Program There are two types: static and dynamic. Each loading method is different, and the received initialization and end control messages are also different.
Static VxD:
In the following cases, the vmm loads a Static VxD:
A real-mode resident program calls VxD by calling 2fh, 1605 H.
The VxD is defined in the following position in the registry:
HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ VxD \ key \ staticvxd = VxD with path file name
This VxD is defined under the [ENH] Line in system. ini: [ENH] section:

Device = VxD with path file name
During development, we recommend that you. INI loads the VxD program, because if your VxD program is wrong and Windows cannot be started, you can modify the system in DOS. INI, but if you use the registry loading method, you cannot modify it.
When vmm loads your Static VxD program, your VxD program receives three system control messages in the following order:
After sys_critical_init vmm is transferred to the protection mode, this control message is sent before the interruption is enabled. Most VxD programs do not use this message unless:
Your VxD program will take over the interruptions required by other VxD programs or protection mode programs. Since the interrupt is not enabled when you process the message, you can determine that the interrupt will not be called when you take over the interrupt.
Your VxD program provides some VxD services for other VxD programs. For example, some VxD programs loaded after your VxD program need to call some of your VxD services when processing device_init control messages. Since sys_critical_init control messages are sent before the device_init message, therefore, you should initialize your program when the sys_critical_init message is sent.
If you want to process the message, you should finish initialization as quickly as possible to avoid the loss of hard interruption caused by too long execution time. (Remember: The interrupt is not enabled yet)
Device_init vmm sends this message after the service is interrupted. Most VxD programs initialize this message. Because the interruptions are open, time-consuming operations can also be executed here without fear of loss of hard interruptions. You can perform initialization at this time (if necessary ).
After all VxD programs process the device_init message, vmm sends this control message before the vmm releases the initialization segment (icode and RCODE segment class. There are only a few VxD messages to process.
After successful initialization, your VxD program must clear the return flag. Otherwise, it must set the return flag as an error message before returning. If your VxD does not require initialization, you do not have to process the messages.
To end Static VxD, vmm sends the following control message:
System_exit2 when your VxD program receives this message, Windows95 is shutting down the system, and all other virtual machines except the system virtual machine have exited. Even so, the CPU is still in the protection mode, and it is safe to execute the real-mode encoding on the system virtual machine. At this time, kernel32.dll has also been uninstalled.
Sys_critical_exit2 when all VxD completes the response to system_exit2 and the interruption is disabled, your VxD receives the message.
Many VxD programs do not respond to these two messages unless you want to prepare the system for the conversion to the real mode. You know, when window95 is disabled, it enters the real mode. So if your VxD program performs some operations on the Real-mode image that will cause instability, it needs to be restored at this time.
You may wonder why the two messages are followed by "2 \"". This is because, when the vmm loads the VxD program, it loads the program in the order of loading the VxD program in a small initial order, in this way, The VxD program can use the services provided by the VxD program loaded before them. For example, if vxd2 needs to use the service in vxd1, it must define its initialization sequence value smaller than VxD. The loading sequence is:
... Vxd1 ==> vxd2 ==> vxd3 .....
When uninstalling, The VxD program with a large initialization order is uninstalled first, so that they can still use services provided by the VxD programs loaded later. In the preceding example, the order is:
... Vxd3 ==> vxd2 ==> vxd1 .....
In the above example, if vxd2 calls some services in vxd1 during initialization, it may need to use some services in vxd1 again during uninstallation. System_exit2 and sys_critical_exit2 are sent in reverse initialization order. This indicates that when vxd2 receives these messages, vxd1 has not been uninstalled and can still call the vxd1 service, while system_exit and sys_critical_exit messages are not sent in the reverse initialization order. This means that you are not sure whether you can still call the VxD service provided by the VxD loaded before you. The next generation of VxD programs should not use these messages.
There are two types of exit messages:
Device_reboot_policy2 tells the VxD program that vmm is preparing to restart the system. At this time, the interruption is still open.
Crit_reboot_cmdy2 tells the VxD program vmm that it is preparing to restart the system. At this time, the interruption has been disabled.
At this point, you can guess that there are still device_reboot_notify and crit_reboot_notify messages, but they are not sent in reverse initialization order like messages of the "2" version.
Dynamic VxD:
Dynamic VxD can be dynamically loaded and detached in Windows9x. This feature is unavailable in window3.x. The dynamic VxD program is mainly used to support reinstallation of some dynamic hardware devices, such as plug-and-play devices. However, you can load/uninstall it from your Win32 program, or think of it as an extension of your program to ring-0.
The example we mentioned in the previous section is a Static VxD. You can convert it into a dynamic VxD by adding the keyword dynamic after the VxD mark in the. Def file.
VxD firstvxd dynamic
This is what you need to do to convert a Static VxD into a dynamic VxD.
A dynamic VxD can be loaded as follows:
Put it in the \ System \ iosubsys directory under your Windows directory. VxD in this directory will be loaded by the input/output Monitor (IOS. These VxD must support layer device drivers. So loading your dynamic VxD using this method is not a good solution.
Use Vxd to load the service. Vxdldr is a Static VxD that can load dynamic VxD. You can use other VxD or 16-bit Code It calls its service.
Use the createfile API in the Win32 application. When you call createfile, enter the following format for your dynamic VxD:

\. \ VxD complete path name

For example, if you want to load a dynamic VxD named firstvxd in the current directory, you need to do the following:

. Data
Vxdname dB \ "\. \ firstvxd. VxD \", 0
......
. Data?
Hdevice dd?
.....
. Code
.....
Invoke createfile, ADDR vxdname, 0, 0, 0, file_flag_delete_on_close, 0
MoV hdevice, eax
......
Invoke closehandle, hdevice
......

File_flag_delete_on_close indicates that the VxD is uninstalled when the handle returned by createfile is closed.
If you use createfile to load a dynamic VxD, the dynamic VxD must process the w32_deviceiocontrol message. When your dynamic VxD is loaded by the createfile function for the first time, vwin32 sends this message to your VxD. When your VxD responds to this message, the value in eax must be zero. When an application calls the deviceiocontrol API to communicate with a dynamic VxD, The w32_deviceiocontrol message is also sent. We will talk about the deviceiocontrol interface in the next chapter.
A dynamic VxD receives a message during initialization:
Sys_dynamic_device_init
A control message is also received at the end:
Sys_dynamic_device_exit
Dynamic VxD will not receive sys_critical_init, device_init, and init_complete control messages because these messages are sent during System Virtual Machine initialization. In addition to the three messages, the dynamic VxD can receive all the control messages as long as they are still in the memory. It can do everything Static VxD can do. In short, in addition to the loading mechanism and the received initialization/End message, the dynamic VxD can do everything that the Static VxD can do.
Other System Control Messages
When VxD is in the memory, in addition to receiving and initializing and ending messages, it also receives many other control messages. Some messages are about the virtual machine manager and some are about various events. For example, the message about a virtual machine is as follows:
Create_vm
Vm_critical_init
Vm_suspend
Vm_resume
Close_vm_notify
Destroy_vm
It is your responsibility to selectively respond to the messages you are interested in.
Create a function in VxD
You need to define your function in a segment. You should first define a segment and then put your function in it. For example, if you want to put your function in a callable page segment. You should first define an adjustable page segment, as shown in the following code:
Vxd_pageable_code_seg
(Your function is written here)

Vxd_pageable_code_ends

You can insert multiple functions in a segment. As a VxD compiler, you must decide which segment each function should be placed in. If your functions must always exist in the memory, such as some hardware interrupt handlers, put them in the locked page segment. Otherwise, you should put them in the adjustable page segment.
You must use beginproc and endproc macros to define your function:
Beginproc function name
Endproc function name

You can add some parameters to the inproc macro. For more information, see the Win95 DDK document. Most of the time, you only need to enter the function name.
Because beginproc-endproc macro is more powerful than proc-endp command, you should use beginproc-endproc macro to replace proc-endp command
VxD programming conventions
Register usage
Your VxD program can use all registers, FS and Gs. But be careful when changing the segment register. In particular, do not change the content of CS and SS unless you have absolute confidence in what will happen. You can use DS and ES, but remember to restore their initial values when returning them. It is particularly important to have two feature bits: Direction and interrupt feature bits. Do not block interruptions for a long time. Also, if you want to change the direction feature bit, do not forget to restore its initial value before returning it.
Parameter transfer conventions
There are two call conventions for VxD service functions: Register Method and stack method. When you call a register-based service function, you use various registers to pass the parameters of the service function. In addition, after the call is complete, check the register value to see if the operation is successful. Do not always think that the value of the main Register is the same after the service function is called. When calling the service function of the stack method, you need to push the parameter to the stack and obtain the return value in eax. The service functions of the stack call method save the values of EBX, ESI, EDI, and EBP. Many register calling methods of service functions are derived from the Windows 3.x era. Most of the time, you can distinguish these two service functions by name. If a function name starts with an underscore, such as _ heapallocate, it is a service function of the stack method (except for a few functions exported from vwin32.vxd ). If the function name does not start with an underscore, It is a register-based service function.
Call the VxD service function
You can use the vmmcall and vxdcall macros to call the vmm and VxD services. The syntax of these two macros is the same. When you want to call the VxD service function exported by vmm, use vmmcall. If you want to use the VxD service function exported by other VxD programs, use vxdcall.
Vmmcall service; call Register Method service function E
Vmmcall _ service,; call the service function of the stack method
As I mentioned earlier, vmmcall and vxdcall break down a 20 h interrupt followed by a dual word, which is very convenient to use. When you call the stack method service, you must enclose your parameters in parentheses.
Vmmcall _ heapallocate, <, heaplockedifdp>
_ Heapallocate is a service function of the stack method. It has two parameters, which must be enclosed in parentheses. Since the first parameter is an expression that cannot be correctly interpreted by the macro, We Need To enclose it with parentheses.
Flat address
In the old compilation tool, when you use the offset operator, the compiler and the connector generate an error address, so the VxD writer uses offset flat: to replace offset. Imm. inc includes a macro that makes this simpler: offset32 to replace offset flat :. Therefore, if you want to use the address operation, use offset32 instead of the Offset operator.
Note: When I wrote this tutorial, I tried using the offset operator. It can generate the correct address. So I want masm6.14 to fix this bug. However, to ensure security, you should use the offset32 macro instead of offset.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.