BUG: VMD_Post_Absolute_Pointer_Message Bug in VMOUSEID: Q139292
|
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.
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:
VMMcall Get_SYS_VM_Handle
mov [VMOUSE_FOCUS_VM],ebx
;******************************
; 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
;=======================================================
VxD_Locked_Data_Seg
lpfnPreviousVMOUSEPMAPI dd 0 ; VMOUSE's PM_API_Proc
; will be non-zero if you hook vmouse.
UserEventHandle dd 0
User_Mouse_Event_Segment dd 0
User_Mouse_Event_Offset dd 0
VxD_Locked_Data_Ends
;In the Device_Init (or sys_dynamic_Device_init, if it
;is a dyna-loaded VxD (loaded by vmouse)) proc of your VxD,
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:
; 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.
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
; 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:
Control_Dispatch Set_Device_Focus, FTG_Set_Device_Focus
; On to 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
;***********************************************************
; 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 ?
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.
; 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
;
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
handled_it: ; handled hardware int.
....
; Now on to the final part. Call User.exe's mouse_event proc
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
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
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.
MSDN Library Compact Disc October 1995
Additional query words: 4.00 absolute VxD win95
Keywords :
Version : 4.00
Platform : WINDOWS
Issue type :
Last Reviewed: March 2, 1999