Two-way communication occurs when a VxD receives information from and sends information to a Windows application. A 16-bit application can send information to a VxD by calling the protected-mode API procedure for the VxD. Use Get Device Entry Point Address (Interrupt 2Fh Function 1684h) to retrieve the address of this procedure. A Win32 application can use the DeviceIOControl function to communicate with a VxD.
A VxD can send information to an application by using a variety of shell services. For example, a VxD can use the services associated with appy time events, such as _SHELL_CallDll, to call a DLL and pass it data. A VxD can also use services such as _SHELL_BroadcastSystemMessage and _SHELL_PostMessage, to post messages to the queues of one or more Windows-based applications.
The _SHELL_BroadcastSystemMessage service is a convenient way to send a window message to a list of recipient windows. A VxD can also intercept these broadcast messages by installing a callback procedure using the _SHELL_HookSystemBroadcast service. The system calls the procedure whenever the _SHELL_BroadcastSystemMessage is called. The _SHELL_UnhookSystemBroadcast service removes the callback procedure.
The _SHELL_PostMessage service calls the Windows PostMessage function. If a VxD calls the _SHELL_PostMessage service when the current VM is not the system VM, the system schedules the message and does not actually post the message until the system VM receives CPU time. If the current VM is the system VM, the system may call the PostMessage function immediately.
When the call to PostMessage is actually made, the system notifies the VxD of the message result by calling a callback procedure specified by the VxD when it called _SHELL_PostMessage. The VxD must be prepared for failure at two points: immediate failure returned by _SHELL_PostMessage and eventual failure passed to the callback procedure.
If the current VM is the system VM, the system may call the callback procedure before _SHELL_PostMessage returns. To prevent this, use the SPM_UM_AlwaysSchedule value in the uMsg parameter.
Do not make multiple, successive calls to _SHELL_PostMessage. This can fill up the message queue of the window and exhaust available memory.
Do not block the system VM while waiting for the PostMessage function callback. This will deadlock the system.