Microsoft KB Archive/139292

{|
 * width="100%"|

BUG: VMD_Post_Absolute_Pointer_Message Bug in VMOUSE

 * }

Q139292

-

The information in this article applies to:


 * Microsoft Win32 Device Driver Kit (DDK) Windows 95

-

SYMPTOMS
The VMOUSE VxDCall VMD_Post_absolute_Pointer_Message does not correctly call the USER API Mouse_Event as documented in the MSDN Library compact disc and elsewhere. The other VxD calls to VMOUSE are not affected by this problem. Programmers using the Mouse_Event call to the USER API directly as from a DLL are not affected by this problem.

RESOLUTION
The developers generated the following workaround sample code. In general, it ends up calling the Mouse_Event API. A number of customers have used this sample to guide them and have met with success. There are, however, two important caveats:

  The value in VMOUSE_FOCUS_VM is never initialized. In your initialization code, you should default it to the current VM by using something like this:

  VMMcall Get_SYS_VM_Handle mov [VMOUSE_FOCUS_VM],ebx  The hook call VMMCall Hook_Device_PM_API does not currently have a corresponding unhook call. Therefore your VxD will need to be static.

Sample Code
;****************************** VxD_Locked_Data_Seg lpfnPreviousVMOUSEPMAPI  dd   0   ; VMOUSE's PM_API_Proc ; will be non-zero if you hook vmouse.
 * Microsoft Corp. (C) 1991-1996
 * Your driver may already have the following code to track MOUSE
 * Ownership. This code needs to be there because even as advertized, VMD_
 * Post_Absolute_Message won't handle MS-DOS VMs. So your VxD needs to track
 * mouse ownership and selectively call VMD_Post_Absolute_Pointer_Message
 * mouse ownership and selectively call VMD_Post_Absolute_Pointer_Message

UserEventHandle  dd   0 User_Mouse_Event_Segment  dd   0 User_Mouse_Event_Offset     dd   0 VxD_Locked_Data_Ends VxDCall  VMD_Get_Version      ; get version of VMOUSE cmp  eax, 400h      ; Q: correct support ABS coords? jne  done         ;   Y: Get out mov  eax, VMD_Device_ID      ; N: hook vmouse's service. mov  esi, OFFSET32 FTG_PM_API VMMCall  Hook_Device_PM_API      ; Hook VMOUSE's PM API mov  [lpfnPreviousVMOUSEPMAPI], esi   ; Save old address done: BeginProc FTG_PM_API movzx  eax, [ebp.Client_AX] cmp  eax, VMDAPI_SET_MOUSE_EVENT_CALLBACK jne  @F movzx  eax, [ebp.Client_DX] mov  [USER_Mouse_Event_Offset], eax mov  eax, [ebp.Client_ECX] mov  [USER_Mouse_Event_Segment], ax   jmp   goto_previous @@:  cmp   eax, VMDAPI_SET_MOUSE_FOCUS jne  goto_previous mov  eax, [ebp.Client_EBX]      ; contains the VM handle mov  [VMOUSE_FOCUS_VM], eax goto_previous: jmp  [lpfnPreviousVMOUSEPMAPI] EndProc FTG_PM_API Control_Dispatch Set_Device_Focus, FTG_Set_Device_Focus BeginProc FTG_Set_Device_Focus or  edx, edx      ; Q: Critical set focus ? jz  fsdf_set      ;    Y: set it   cmp   edx, VMD_Device_ID   ;    N: Q: Is it for VMD ? jne  fsdf_exit fsdf_set: mov  [VMOUSE_FOCUS_VM], ebx fsdf_exit: ret EndProc FTG_Set_Device_Focus mov  ebx, [VMOUSE_FOCUS_VM] VMMCall  Test_Sys_VM_Handle   ; Q: Is this System VM ? jnz  Handle_DOS_VMs      ;    N: do what you would have done. xor  eax, eax cmp  [lpfnpreviousVMOUSEPMAPI], eax   ; Q: good vmouse ? je  call_it cmp  [UserEventHandle], eax      ; Q: Event scheduled already? jne  handled_it mov  esi, OFFSET32 CallUserProc mov  eax, TIME_CRITICAL_BOOST mov  ecx, PEF_Wait_For_STI OR PEF_Always_Sched VMMCall  Call_Priority_VM_Event mov  [UserEventHandle], esi jmp  handled_it call_it: mov  al, [Buttons] mov  esi, [XPos] mov  edi, [YPos] VxDCall  VMD_Post_Absolute_Pointer_Message
 * In the Device_Init (or sys_dynamic_Device_init, if it
 * is a dyna-loaded VxD (loaded by vmouse)) proc of your VxD,
 * Now on to FTG_PM_API. This will watch for Mouse.drv telling VMOUSE
 * about User.exe's entry point. This entry point used to be called
 * by your Mouse.drv in Windows 3.1.
 * Now on to mouse focus tracking. FTG needs to track mouse
 * focus, because if the mouse focus is on SYS_VM, then it
 * wants to handle the absolute device in one way, otherwise
 * in a different way.
 * Add to your CONTROL_PROC, the following line:
 * On to FTG_Set_Device_Focus
 * All the previous code needed to be there in your VxD anyway because,
 * even as advertized, VMD_Post_Absolute_Pointer_Message, didn't work for
 * MS-DOS VMs. The following code will circumvent VMD_Post_Abso...
 * Say that you are at this decision point
 * Q: Should I call VMOUSE or should I do the relative motion stuff
 * or whatever for the MS-DOS VMs ?
 * Q: Should I call VMOUSE or should I do the relative motion stuff
 * or whatever for the MS-DOS VMs ?
 * Handle Windows VM absolute motion here.
 * Assumption: You are at interrupt time. AND
 * Buttons = button state (button state as desired by User.exe's
 * mouse_event procedure.)
 * (without the absolute bit set).
 * XPos = X position
 * YPos = Y position
 * YPos = Y position

handled_it:              ; handled hardware int.

....

BeginProc CallUserProc movzx  ecx, [USER_Mouse_Event_Segment] jecxz  cup_done Push_Client_State VMMCall  Begin_Nest_Exec movzx  eax, [Buttons]      ; buttons or  ax, 8000h      ; set absolute bit mov  [ebp.Client_EAX], eax mov  eax, [XPos]      ; send X position mov  [ebp.Client_EBX], eax mov  eax, [YPos]      ; send Y position mov  [ebp.Client_ECX], eax
 * Now on to the final part. Call User.exe's mouse_event proc

movzx  eax, [ButtonCount]   ; How many buttons ? mov  [ebp.Client_EDX], eax   ; send # buttons xor  eax, eax mov  [ebp.Client_EDI], eax   ; These need to be 0 mov  [ebp.Client_ESI], eax

mov  edx, [USER_Mouse_Event_Offset]   ; ECX Still contains SEGMENT

VMMCall  Simulate_Far_Call VMMCall  Resume_Exec

VMMCall  End_Nest_Exec Pop_Client_State

cup_done: mov  [UserEventHandle], 0      ; Reset flag so new messages ; can go in  ret

EndProc CallUserProc

STATUS
Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. We are researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available.