Microsoft KB Archive/139292
BUG: VMD_Post_Absolute_Pointer_Message Bug in VMOUSE
The information in this article applies to:
- Microsoft Win32 Device Driver Kit (DDK) Windows 95
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:
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.
;****************************** ; 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
Issue type :
Technology : kbAudDeveloper kbWin95search kbWinDDKSearch kbWin32sSearch kbWin32DDK95 kbWin32DDKSearch
Last Reviewed: March 4, 1999