Chapter 27: Driver Structure and Development

This chapter concentrates on the basics of driver development for the Windows operating system. The first part of this chapter covers virtual device drivers (VxDs). I do not agree with the common opinion that obsolete materials are not worthy of being considered in contemporary books on computing. On the contrary, in practically all other branches of science, historical information is considered an important part of the knowledge accumulated in a specific area. The student must know how the discipline evolved and must understand the logic of its evolution. Therefore, I didn't exclude the chapter about 16-bit programming, and I preserved material about VxDs. The second part of this chapter concentrates on kernel-mode drivers. This material is important for programmers and has preserved its urgency.

Furthermore, it is important to mention that this chapter is oriented toward MASM32.

Virtual Device Drivers

The "x" character in the VxD abbreviation means "any type of device." Although a new type of driver has been introduced in addition to VxD, the use of VxDs remains important because many users all over the world continue to work with Windows 98 and Windows Millennium Edition. In this chapter, in contrast to my normal practice, I extensively use macro definitions contained in the INC files supplied with Microsoft's Windows Driver Development Kit (DDK). Using this approach allows me to provide all the material in one chapter.

To develop VxDs, you'll need files such as VMM.INC, SHELL.INC, and VCOND.INC, which are supplied with the Windows DDK.

At Windows startup, the WIN.COM program loads the VMM32.VXD driver (VMM stands for Virtual Machine Manager). This driver, in turn , initializes other VxDs. Then, VMM switches the processor to the protected mode and initializes the system virtual machine. In addition, VMM provides services to other VxDs. When the user starts an MS-DOS application, a separate virtual machine is allocated to that application so that the DOS application has the illusion of running on an individual computer. When the user starts normal 32-bit applications, they operate within the framework of the system virtual machine. Applications that run on different virtual machines are unaware of the existence of other virtual machines. The most important goal of virtual drivers is to ensure shared access to the hardware without conflicts for all concurrently running virtual machines. Another task that virtual drivers must carry out is organizing communications between the system virtual machine and other virtual machines running on the same computer.

Note that in Windows, there are also so-called standard drivers that have the DRV filename extension, are characterized by the Dynamic Link Library (DLL) structure, and export API functions for working with some peripheral devices (e.g., a video adapter). These drivers get access to peripheral devices through VxDs. Because VxDs operate in ring 0, they can access any memory region and use input and output ports to directly access peripheral devices.

All virtual drivers are divided into two classesstatic and dynamic. Static drivers are loaded at system startup and remain in the memory until system shutdown. Static drivers existed even in Windows 3. x Dynamic drivers can be loaded and unloaded as needed by the system. Mainly, they are used for serving Plug-and-Play devices and are loaded by the configuration manager. A dynamic virtual driver can also be loaded from a normal application using standard functions for working with files.

There are three mechanisms that can be used by virtual drivers for intercommunication:

  1. Control messages The VMM sends these messages to virtual drivers. Drivers also can exchange information using such messages. This mechanism is similar to the way applications use Windows messages to communicate with each other and with the operating system.

  2. Callback functions The virtual driver can allow another driver to use the callback function.

  3. Virtual drivers and VMM These can export specific functions for calling them from other virtual drivers. To call the function, it is necessary to know the number of the virtual driver exporting this function and the number of this function.

The format of virtual drivers is the Linear Executable (LE) format. This format supports the presence of both 16-bit and 32-bit code. This is urgent for static VxDs, which are initialized in a real ( unprivileged ) mode. In Windows NT, drivers are loaded in the protected mode. Therefore, this format is not used in this operating system.

Code and data in the LE format file are placed in segments. The following list briefly describes possible classes of segments:

  • LCODEThe code or data contained within that code couldn't be paged to the disk.

  • PCODEThe code can be temporarily paged to the disk.

  • PDATESimilar to the previous class, in this case the class is related to data.

  • ICODEThe segment stores the initialization code. After initialization, the segment is removed from the memory.

  • DBOCODEThis is used for starting the driver under the control of the debugger.

  • SCODEStatic code or data. These always remain in the memory, even if the driver is unloaded.

  • RCODEThis contains 16-bit code for real-mode initialization.

  • 16ICODEThis is 16-bit code for protected-mode initialization.

  • MCODEThis contains message strings.

The preceding classes of segments are not specified directly in the program text. Segments and classes are declared in a DEF file. The VMM.INC file contains a vast number of macro definitions, and you can't do without them. However, this allows me to describe all of this material within one chapter.

The Project Description

Consider the contents of the DEF file (Listing 27.1). This listing contains segments for every possible case. Naturally, you do not need to use all segments defined here. Thus, this file can be used for creating practically any virtual driver. Segments belonging to the same class will be joined into the same segment after compiling and building. Only the first string specifying the driver name must be changed. Note that the driver name must be specified in uppercase letters . In addition, in the first line, it is possible to specify the driver type. By default, it is assumed that this is a static driver. If you specify a string such as VXD VXD1 DYNAMIC , the compiler would create a dynamic virtual driver.

Listing 27.1: The VXD.DEF file used for compiling and building a virtual driver
image from book
 VXD VXD1 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   VXD1_DDB @1 
image from book
 

In the end of this file, the only exported variablethe Device Description Block (DDB)is specified. This block is defined in the VMM.INC file. It contains 22 fields and provides information about the virtual driver.

The VMM.INC file defines macro names for all segments listed previously. For example; for the _LTEXT segment, the VxD_LOCKED_CODE_SEG name is specified, and the _RCODE segment has the VxD_REAL_INIT_SEG name. Listings provided in this chapter actively use these macro names.

Now, consider the translation of virtual drivers. To produce a virtual driver, issue the following commands:

 ml /coff /c /Cx /DMASM6 /DBLD_COFF /DIS_32 vxd1.asm     link /vxd /def:vxd.def vxd1.obj 

Constants such as MASM6, BLD_COF, IS_32 are used by conditional translation operators specified in the VMM.INC and VCOND.INC files. Note that if you are using the DEF file in the form specified in Listing 27.1, then warning messages informing you that specific sections are missing might appear in the course of compiling. These warnings can be ignored.

To carry out some actions, you'll often need to use macro definitions from the VMM.INC file. Therefore, it is necessary to become acquainted with the most frequently used ones.

The most important is the Declare_Virtual_Device macro. It fills the DDB structure, thus simplifying the programmer's task. The general format of this macro is as follows (the structure of the macro can be found in the VMM.INC file):

 Declare_Virtual_Device Name, MajorVer, MinorVer, CtrlProc, DeviceID,     InitOrder, V86Proc, PMProc, RefData 

Consider the macro parameters:

  • Name The virtual driver name. This name must match the name specified in the DEF file.

  • MajorVer, MinorVer Major and minor version numbers of the driver.

  • CtrlProc The name of the driver's control procedure. This procedure receives and processes the messages arriving at the driver. The procedure name consists of two parts : the driver name and Control suffix. For example, if the driver name is VXD1 , then the procedure will have the following name: VXD1_Control .

  • DeviceID The 16-bit unique identifier of the virtual driver. It must be specified if the virtual driver must provide services to other drivers. In addition, this identifier might be needed if your driver is intended to operate in real mode.

  • InitOrder The driver's loading order. This is an ordinal number. Drivers with lower ordinal numbers are the first to be loaded. This parameter is meaningful only for static drivers.

  • V86Proc, PMProc Addresses of functions that the driver will export for MS-DOS and standard Windows applications. If the driver won't export functions, these parameters should be omitted.

  • Ref_Data The reference to the data used by the input/output supervisor. As a rule, this parameter is omitted.

To define the control procedure, use the Begin_control_dispatch and End_control_dispatch macros. This can be done as follows:

 Begin_control_dispatch VXD1     Control_Dispatch message, function     End_control_dispatch VXD1 

The Control_Dispatch macro defines, which messages must be processed by which functions. For example:

 Begin_control_dispatch VXD1     Control_Dispatch INIT_CQMPLETE, INIT     End_control_dispatch VXD1 

Thus, you have all the required information to build the simplest driver. To be more precise, this will be the skeleton of the future driver. For the moment, you don't even need to clearly understand how it will work.

Listing 27.2: A virtual driver's "skeleton"
image from book
 .586P include vmm.inc include vcond.inc DECLARE_VIRTUAL_DEVICE. VXD1, 1, 0, VXD1_Control, UNDEFINED_DEVICE_ID, UNDEFINED_INIT_ORDER Begin_control_dispatch VXD1 Control_Dispatch INIT_COMPLETE, INIT End_control_dispatch VXD1 VxD_LOCKED_CODE_SEG BeginProc INIT EndProc INIT VxD_LOCKED_CODE_ENDS end 
image from book
 

Now, translate the driver provided in Listing 27.2 according to the algorithm described earlier. Do not forget to add the /MAP command-line option. As a result, the VXD1.MAP file will appear in your working directory in addition to the VXD1.VXD file. The contents of this file are shown in Listing 27.3.

Listing 27.3: The contents of the VXD 1.MAP file
image from book
 VXD1 Timestamp is 3bb5ad7a (Sat Sep 29 17:16:10 2001) Preferred load address is 00400000 Start    Length  Name         Class 0001:00000000 00000050H _LDATA         CODE 0001:00000050 00000007H _LTEXT         CODE Address  Publics by Value Rva+Base  Lib:Object 0001:00000000 VXD1_DDB      00401000  vxd1.obj 0001:00000050 VXD1_Control  00401050 f vxd1.obj 0001:00000057 INIT          00401057 f vxd1.obj entry point at    0000:00000000 Static symbols 
image from book
 

When viewing the MAP file, note that there are two segments defined there: _LDATA and _LTEXT . Both segments relate to the same class.

To conclude this listing, I'd like to mention that instead of the standard name proc/name endp combination, the BeginProc and EndProc macros are used here. Definitions of these macros are provided in the VMM.INC file.

Virtual drivers can provide services to other drivers. In other words, virtual drivers export their functions. The call to an exported function is a 6-byte value, shown as follows:

 int 2Oh     DD 00110002H 

Here, 11H is the virtual driver identifier, and 02H is the service number (the index in the table of services). However, I won't write the call in this form. Instead, I'll use the VMMCall and VxDCall macros. The first macro is intended for calling VMM services, and the second macro is used for calling services of other virtual drivers.

A Sample Driver

Now you have all the information required for writing a simple but usable static driver. The text of this driver is provided in Listing 27.3. After the listing, I provide comments about this driver and cover the basic principles of building static virtual drivers.

Listing 27.3: A sample static virtual driver
image from book
 .586P include vmm.inc include shell.inc include vcond.inc ; Fill the DDB structure DECLARE_VIRTUAL_DEVICE VXD2, 1, 0, VXD2_Control, \ UNDEFINED_DEVICE_ID, UNDEFINED_INIT_ORDER ; Declare the received messages ; and the procedures to process them Begin_control_dispatch VXD2   Control_Dispatch Create_VM, OnVMCreate   Control_Dispatch VM_Terminate2, OnVMClose End_control_dispatch VXD2 ; Segment for storing messages VxD_PAGEABLE_DATA_SEG   MsgTitle db "Message from a VXD driver", 0   VMCreated db "Creating a virtual machine", 0   VMDestroyed db "Destroying a virtual machine", 0   VMFocus db "Changing a virtual machine focus" VxD_PAGEABLE_DATA_ENDS ; Segment containing code VxD_PAGEABLE_CODE_SEG ; Procedure that reacts to virtual machine creation BeginProc OnVMCreate ; Your code goes here         MOV   ECX, OFFSET VMCreated         CALL  MES         RET EndProc OnVMCreate ; Procedure that reacts to the closing of a virtual machine BeginProc OnVMClose ; Your code goes here         MOV   ECX, OFFSET VMDestroyed         CALL  MES         RET EndProc OnVMClose ; Procedure that outputs a message MES PROC ; Get the system virtual machine handle         VMMCall Get_sys_vm_handle ; The handle is returned in EBX, ; and the message flag is returned in EAX         MOV   EAX, MB_OK ; Message header address         MOV   EDI, OFFSET MsgTitle ; Address of the CallBack function, NULL in this case         XOR   ESI, ESI ; Reference to the CallBack function data         XOR   EDX, EDX ; VxD service function -- message window         VxDCall SHELL_Message MES ENDP VxD_PAGEABLE_CODE_ENDS end 
image from book
 

As already mentioned, a static driver is loaded at system startup and remains in memory until system shutdown. The most convenient way of loading such a driver is inserting a string such as device=driver_name into the [386enh] section of the SYSTEM.INI file. You can also use the system registry by including the following value entry there:

 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\key\ StaticVxD=pathname 

However, the first approach is more convenient because, in case of error, your VxD can be easily disabled by editing the SYSTEM.INI file under MS-DOS.

When installing VxDs, VMM sends the following messages to the drivers:

  • SysCriticalInit This message is sent when switching to the protected mode but before enabling interrupts.

  • Device_Init This message is sent after enabling interrupts. This message is used most frequently by virtual drivers for startup initialization.

  • Init_Complete This is the last message sent to virtual drivers at system startup.

    Having received the message and carried out all required tasks , the driver must reset the carry flag and return control to the operating system.

    Before unloading, static virtual drivers also must receive several messages.

  • System_Exit2 This message is sent before the system shutdown. The microprocessor at that time is still in the protected mode.

  • Sys_Critical_Exit2 This is the next message sent to virtual drivers before system shutdown.

  • Device_Reboot_Notify2 This message informs virtual drivers that the system is going to shut down. However, interrupts are still available.

  • Crit_Reboot_Notify2 This is similar to the previous message, but interrupts are no longer available.

Now, consider the program provided in Listing 27.3. This driver outputs the message about activation of the virtual machine (e.g., the creation of a console or startup of an MS-DOS application) and its deactivation . The following two service functions were used in this driver: get the handle to the system virtual machine and output the message. Consider these functions in more detail:

  • Get_sys_vm_handle Get the handle to the system virtual machine. The handle is returned in the EBX register.

  • SHELL_Message Output the message. Parameters are stored in the following registers:

    • EBX The handle to the virtual machine

    • EAX The message flag (e.g., MB_OK )

    • ECX The 32-bit address of the message string

    • EDI The 32-bit address of the header string

    • ESI The address of the function that reacts to user input (if such a function is missing, this parameter is equal to zero)

    • EDX The address of the data to be sent to the function

Finally, when exiting, the driver must clear the carry flag. In this case, this operation depends on the correct execution of the SHELL_Message function.

Dynamic Virtual Drives

In this section, I cover dynamic virtual drivers. There are three methods of loading such drivers:

  • Place a driver into the \SYSTEM\IOSUBSYS directory. Drivers residing in this directory are loaded by the input/output manager.

  • Use the VxDLDR service. This service function can be called only from virtual drivers.

  • Use the CreateFile function.

The latter method of loading dynamic drivers is the one I will explain in detail now. The sequence of steps that you need to carry out to complete this task is as follows:

  1. Open the driver using the CreateFile function. In the case of success, the function returns the identifier that will then be used when calling the functions exported by this driver.

  2. Use the dynamic driver function by calling the DeviceIoControl API function.

  3. Close the driver by calling the CloseHandle function; the driver will then be automatically unloaded from the memory.

Now, consider the program that loads a dynamic driver. This program is shown in Listing 27.4. It loads the MSG.VXD driver and calls its service number 3.

Listing 27.4: The program that loads, uses, then unloads the virtual driver from the memory
image from book
 ; The FILES1.ASM file .586P ; Flat memory model .MODEL FLAT, stdcall ; Constants STD_INPUT_HANDLE equ -10 FILE_FLAG_DELETE_ON_CLOSE   equ 4000000h ; Prototypes of external procedures EXTERN  GetStdHandle@4:NEAR EXTERN  ExitProcess@4:NEAR EXTERN  GetCommandLineA@0:NEAR EXTERN  CreateFileA@28:NEAR EXTERN  CloseHandle@4:NEAR EXTERN  MessageBoxA@16:NEAR EXTERN  ReadConsoleA@20:NEAR EXTERN  DeviceIoControl@32:NEAR ; ;--------------------------------------------- ; INCLUDELIB directives for the linker includelib c: \masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib ;--------------------------------------------- ; ; Data segment _DATA SEGMENT HANDL DWORD ? HFILE DWORD ? BUF DB "\.\msg.vxd", 0        CAP  DB "Message box", 0        MES  DB "Error loading the driver", 0        BUFER DB 20 DUP(0)        LENS DWORD ? ; Number of characters for output        MES1 DB "Service call OK!", 0 _DATA ENDS ; Code segment _TEXT SEGMENT START: ; Get the output handle         PUSH  STD_INPUT_HANDLE         CALL  GetStdHandle@4         MOV   HANDL, EAX ; Open the file         PUSH  0         PUSH  FILE_FLAG_DELETE_ON_CLOSE         PUSH  0         PUSH  0         PUSH  0         PUSH  0         PUSH  OFFSET BUF         CALL  CreateFileA@28         CMP   EAX, -1         JE    _ERR         MOV   HFILE, EAX ; Call the VxD service         PUSH  0         PUSH  0         PUSH  0         PUSH  0         PUSH  18         PUSH  OFFSET MES1         PUSH  3 ; Service number         PUSH  HFILE         CALL  DeviceIoControl@32 ; Wait for the <ENTER> key         PUSH  0         PUSH  OFFSET LENS         PUSH  200         PUSH  OFFSET BUFER         PUSH  HANDL         CALL  ReadConsoleA@20 ; Close and unload the driver         PUSH  HFILE         CALL  CloseHandle@4 _EXIT: ; Program termination         PUSH  0         CALL  ExitProcess@4 _ERR:         PUSH  0 ; MB_OK         PUSH  OFFSET CAP         PUSH  OFFSET MES         PUSH  0 ; Window handle         CALL  MessageBoxA@16         JMP   _EXIT _TEXT ENDS END START 
image from book
 

The program presented in Listing 27.4 requires some comments. The most important role is delegated to the DeviceIoControl function. Here are the parameters of this function:

  • First parameterThe descriptor of the driver obtained using the CreateFile function

  • Second parameterThe number of the required operation

  • Third parameterThe address of the data for the driver

  • Fourth parameterThe data length

  • Fifth parameterThe buffer, in which the driver will store its data

  • Sixth parameterThe buffer length

  • Seventh parameterThe address of the variable that will store the number of bytes loaded into the buffer by the driver

  • Eighth parameterThe address of the OVERLAPPED structure

As you can see, when calling the function, you pass the pointer to the MES1 string.

I hope that you won't experience any difficulties understanding how the driver loading program operates. Now, it is time to consider the driver. This driver carries out a simple function. When its service is called, this driver displays a message on the screen. At the same time, the message text is passed by the calling program. When calling the DeviceIoControl function with the driver handle, the w32_deviceIoControl message is delivered to the driver. The EBX register contains the virtual machine handle, and ESI points to the structure, the contents of which will be covered in detail later in this section. It is necessary to bear in mind that when the driver is unloaded, the same message arrives to it, which also needs to be processed. Now, consider the structure referenced by the ESI register.

 DIOCParams         STRUC             Internal1          DD         ?             VMHandle           DD         ?             Internal2          DD         ?             dwIoControlCode    DD         ?             lpvInBuffer        DD         ?             cbInBuffer         DD         ?             lpvOutBuffer       DD         ?             cbOutBuffer        DD         ?             lpcbBytesReturned  DD         ?             lpoOverlapped      DD         ?             hDevice            DD         ?             tagProcess         DD         ?     DIOCParams                ENDS 

The fields of this structure are as follows.

  • Internall The pointer to the Client_Reg_Struc structure that defines the registers of the calling application (see Listing 27.6 and the comments about it)

  • VMHandle The virtual machine handle

  • Internal2 The pointer to the DDB

  • dwIoControlCode The number of the required operation

  • lpvInBuffer The pointer to the buffer containing information about the calling program

  • cbInBuffer The number of bytes sent in the buffer

  • lpvOutBuffer The pointer to the buffer, in which the driver can store the information for the calling program

  • cbOutBuffer The number of bytes in the buffer

  • lpcbBytesReturned The number of bytes to be returned

  • lpoOverlapped The pointer to the Overlapped structure

  • hDevice The driver handle returned by the CreateFile function

  • tagProcess The process tag

Listing 27.5: An example dynamic driver
image from book
 .586P include vmm.inc include vcond.inc include vwin32.inc include shell.inc DECLARE_VIRTUAL_DEVICE MSG, 1, 0, MSG_Control, \   UNDEFINED_DEVICE_ID, UNDEFINED_INIT_ORDER Begin_control_dispatch MSG ; The w32_DeviceIoControl message ; will be processed by the PROC1 procedure Control_Dispatch w32_DeviceIoControl, PROC1 End_control_dispatch MSG ; Data segment VxD_PAGEABLE_DATA_SEG         CAP1  DB "Message box", 0         MES1  DB 50 DUP(0) VxD_PAGEABLE_DATA_ENDS ; Code segment VxD_PAGEABLE_CODE_SEG BeginProc PROC1         CMP   DWORD PTR [ESI]+12, DIOC_Open         JNE   L1         XOR   EAX, EAX         JMP   _EXIT L1:         CMP   DWORD PTR [ESI]+12, 3         JNZ   _EXIT ; String length         MOV   EDI, DWORD PTR [ESI]+16         VMMCall _lstrlen,<EDI> ; Copy to buffer         INC   EAX ; Length         VMMCall _lstrcpyn, <OFFSET MES1, EDI, EAX> ; Call the SHELL_Message function         MOV   ECX, OFFSET MES1 ; DWORD PTR [ESI]+14         MOV   EDI, OFFSET CAP1         MOV   EAX, MB_OK+MB_ICONEXCLAMATION         VMMCall Get_Sys_VM_Handle ; Address of the CallBack function, NULL in this case         XOR   ESI, ESI ; Reference to the data for the CallBack function         XOR   EDX, EDX         VxDCall SHELL_Message         XOR   EAX, EAX _EXIT:         RET EndProc PROC1 VxD_PAGEABLE_CODE_ENDS end 
image from book
 

The program in Listing 27.5 requires some comments.

As I pointed out earlier, when the driver loads, it receives the w32_DeviceIoControl message, and the ESI register points to the message structure. The dwIoControlCode field will contain the DIOC_Open number, which is equal to zero. The dwIoControlCode field is located by the offset ESI+12 . After making sure that this location contains zero the driver returns control after resetting EAX to zero (this is required).

When calling the driver from the program, you use number 3. After making sure that the dwIoControlCode field contains 3, the driver must carry out the actions expected by the program.

The task of this driver is to display a message containing the string received from the calling program. The string address and its length are specified. To demonstrate some functions of a VxD service, you define the string length again and copy it into the buffer prepared in the driver body.

Finally, it is necessary to output the message and return the control after resetting the EAX register to zero.

It is time to provide a listing and some comments about the Client_Reg_Struc structure.

Listing 27.6: The structure containing the values of registers of the calling application
image from book
 Client_Reg_Struc STRUC         Client_EDI         DD  ?         Client_ESI         DD  ?         Client_EBP         DD  ?         Client_res0        DD  ?         Client_EBX         DD  ?         Client_EDX         DD  ?         Client_ECX         DD  ?         Client_EAX         DD  ?         Client_Error       DD  ?         Client_EIP         DD  ?         Client_CS          DW  ?         Client_res1        DW  ?         Client_EFlags      DD  ?         Client_ESP         DD  ?         Client_SS          DW  ?         Client_res2        DW  ?         Client_ES          DW  ?         Client_res 3       DW  ?         Client_DS          DW  ?         Client_res4        DW  ?         Client_FS          DW  ?         Client_res5        DW  ?         Client_GS          DW  ?         Client_res6        DW  ?         Client_Alt_EIP     DD  ?         Client_Alt_CS      DW  ?         Client_res7        DW  ?         Client_Alt_EFlags  DD  ?         Client_Alt_ESP     DD  ?         Client_Alt_SS      DW  ?         Client_res8        DW  ?         Client_Alt_ES      DW  ?         Client_res9        DW  ?         Client_Alt_DS      DW  ?         Client_res10       DW  ?         Client_Alt_FS      DW  ?         Client_res11       DW  ?         Client_Alt_GS      DW  ?         Client_res12       DW  ? Client_Reg_Struc ENDS 
image from book
 

The structure in Listing 27.6 contains three types of fields:

  • Client_resX Reserved fields

  • Client_XXX Registers of the program started within a virtual machine

  • Client_Alt_XXX Registers of a 32-bit program started in the system virtual machine

At this point, the description of virtual drivers comes to a logical end.



The Assembly Programming Master Book
The Assembly Programming Master Book
ISBN: 8170088178
EAN: 2147483647
Year: 2004
Pages: 140
Authors: Vlad Pirogov

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net