; *** MESSAGE HANDLER *** ; This procedure determines if application has a handler for a particular event. All windows ; procedures are passed to this subroutine except those that have been sub or super classed. ; ENTRY: ESI = Pointer to message map ; ECX = Number of sets in map. ; Each set consists of a 16 bit ID and 32 bit pointer to proceedure. ; LEAVE: EAX = 0 if application handled event, or result of DefWindowProc is not. ; ____________________________________________________________________________________________ ; ESP + 0 = Return address in kernel module ; ESP + 4 = hWnd, this windows 32 bit handle ; ESP + 8 = Msg, Message ID passed by OS. ; ESP + 12 = wParam ; ESP + 16 = lParam MsgHandler mov edx, [esp + 8] ; Get message ID 0 - 1024 or user defined. ; In the unlikely event a null map is passed to this routine, this method of ; testing ECX first will prevent a fatal crash. .NextMsg and ecx, ecx ; Are we at the end yet jz .Default ; ZR = 1, If we are to do default proceesing. dec ecx ; Decrement counter lodsw ; Get 16 bit ID from message map cmp ax, dx ; Is there a match lodsd ; Load pointer jnz .NextMsg ; At this point we've found a match and as many events need wParam & lParam, ; I'm going to establish a pointer to those in EBX. hWnd can be simply addressed ; by EBX - 8 or lParam by EBX + 4. lea ebx, [esp + 12] ; EBX points to wParam call eax ; Execute event jnc .Default ; CY = 0, if event requires default proc. xor eax, eax ; Handled must return 0 ret 16 ; Stack needs to be re-aligned. ; As hWnd, Msg, wParam & lParam are already on the stack I use this method ; as a trace into kernel showed OS handles this appropriately and there is no ; point pushing onto stack what is already there. I've tested this on 98/ME/XP. .Default pop ebx call _DefWindowProcA@16 jmp ebx ; You'll notice at this point we don't need RET 16 as the call to DefWindowProc has already ; done that for us.