;; NEWHEADER structure is used in LookupIconIdFromDir NEWHEADER struc Reserved dw ? ResType dw ? ResCount dw ? NEWHEADER ends ;; RESDIR structure is used in LookupIconIdFromDir RESDIR struc IconOrCursor dd ? ; IconDir or CursorDir structure. Planes dw ? BitCount dw ? BytesInRes dd ? idIcon dw ? RESDIR ends if 0 CHECKHINULL macro x local chn_ex ifdef DEBUG push eax mov eax, x shr eax, 16 jz chn_ex int 3 chn_ex: pop eax endif endm CHECKHISIGN macro x local chs_ex ifdef DEBUG push eax mov eax, x shr eax, 16 inc ax cmp ax, 1 jbe chs_ex int 3 chs_ex: pop eax endif endm endif CodeData equ ifdef IS_16 include thkrp.inc include k32share.inc include public.inc include cbcheck.inc include thkmacro.inc include thkframe.inc include struc.inc include cbcid.inc include usrcbid.inc fLocalFlag equ fUsrLog16 WINABLE equ 1 TIMERINFO_TYPE struct resolution DWORD ? TIMERINFO_TYPE ends MULTIKEYHELP32 STRUC mk32_Size dd ? mk32_Keylist db ? mk32_szKeyPhrase db ? MULTIKEYHELP32 ENDS MULTIKEYHELP16 STRUC mk16_Size dw ? mk16_Keylist db ? mk16_szKeyPhrase db ? MULTIKEYHELP16 ENDS HELPWININFO32 STRUC hwi32_wStructSize dd ? hwi32_x dd ? hwi32_y dd ? hwi32_dx dd ? hwi32_dy dd ? hwi32_wMax dd ? hwi32_rgchMember db ? HELPWININFO32 ENDS HELPWININFO16 STRUC hwi16_wStructSize dw ? hwi16_x dw ? hwi16_y dw ? hwi16_dx dw ? hwi16_dy dw ? hwi16_wMax dw ? hwi16_rgchMember db ? HELPWININFO16 ENDS FLASHWINFO16 STRUC fw16_cbSize dw ? fw16_hwnd dw ? fw16_dwFlags dd ? fw16_uCount dw ? fw16_dwTimeout dd ? FLASHWINFO16 ENDS FLASHWINFO32 STRUC fw32_cbSize dd ? fw32_hwnd dd ? fw32_dwFlags dd ? fw32_uCount dd ? fw32_dwTimeout dd ? FLASHWINFO32 ENDS externDef GetExePtr:far16 ;;;externDef InsertPropAtom:far16 ;;;externDef DeletePropAtom:far16 externDef GlobalAddAtom:far16 externDef GlobalDeleteAtom:far16 externDef GlobalFindAtom:far16 externDef ConvertDialogA:far16 externDef ConvertDialog:far16 externDef ConvertDialog32:far16 externDef CountDialogA:far16 externDef CountDialogU:far16 externDef ConvertMenuA:far16 externDef CountMenuA:far16 externDef CountMenuU:far16 externDef ConvertMenu32:far16 externDef GetNullhInst:far16 externDef GlobalAlloc:far16 externDef GlobalFree:far16 externDef GlobalLock:far16 externDef GlobalUnlock:far16 externDef GlobalFix:far16 externDef GlobalUnfix:far16 externDef MaphinstLS:far16 externDef MaphinstSL:far16 externDef IsClassNameMDICLIENT:far16 externDef ConvertDDEHandleLS:far16 externDef ConvertDDEHandleSL:far16 externDef QueryCallbackAddress:far16 externDef GetStdCBSL:far16 externDef GetStdCBLS:far16 externDef GetCurrentTask:far16 ;!!! temporary? externDef GetCurrentThreadID:far16 externDef timerInfo:TIMERINFO_TYPE externDef CALLBACK_BODY_16:far16 externDef GetCurrentHeap:far16 externDef ConvertMenuItemInfoLS:far16 externDef IsDialog:far16 externDef IsWindowClassType:far16 ;;;externDef aUserData:dword externDef Map32To16:far16 externDef DelMap:far16 externDef LoadLibrary32:far16 externDef ConvertCFDataLS:far16 externDef ConvertCFDataSL:far16 externDef IsThisADDEExecuteHandle:far16 externDef ConvertOleClipData:far16 externDef GetHCONVWindows:far16 ;-----------------------------------------------------------------------; ; DXAX2EAX ; mov dx to eax high word ; ;-----------------------------------------------------------------------; DXAX2EAX macro ror eax,16 xchg ax,dx ror eax,16 endm CF_LCID equ 16 ;-----------------------------------------------------------------------; ; body_SETCLIPBOARDDATA ;-----------------------------------------------------------------------; body_SETCLIPBOARDDATA macro local exit local SetData bp_nFormat equ bp_dwData equ mov eax, dword ptr bp_dwData test eax, eax jz SetData push word ptr bp_nFormat push eax push word ptr 1 ;Nuke old copies of hData call ConvertCFDataLS movzx eax, ax test ax, ax jz exit SetData: push word ptr bp_nFormat push ax push 1 call SetClipboardData32 movzx eax, ax test ax, ax jz exit mov eax, bp_dwData ;Return original hData exit: endm ;-----------------------------------------------------------------------; ; body_GETCLIPBOARDDATA ;-----------------------------------------------------------------------; body_GETCLIPBOARDDATA macro local exit bp_nFormat equ push word ptr bp_nFormat push 1 call GetClipboardData32 movzx eax, ax test ax, ax jz exit push word ptr bp_nFormat push ax ;hnd16 push word ptr 0 ;Don't nuke old copies of hData call ConvertCFDataSL ; Return now in eax. exit: endm ;-----------------------------------------------------------------------; ; ; body_SETWINDOWSHOOKEXA ; ;-----------------------------------------------------------------------; body_SETWINDOWSHOOKEXA macro local type_ok local get_out local inserted_ok local push_task bp_nType equ bp_pfn equ bp_hmod equ bp_hThread equ mov di,word ptr bp_nType ;will need more than once inc di ;make nType 0-based cmp di,CBID_WH_END-CBID_WH_START jb type_ok ;!!! SetExtendedError? sub eax,eax ;error, invalid hook type jmp get_out type_ok: dec di ;restore correct nType push di ;push for SetWindowsHookEx ;map hook type onto callback type movsx edi,di add edi,CBID_WH_START+1 ;hook type --> callback type push dword ptr bp_pfn ;32-bit callback address push edi ;callback type call GetStdCBSL ;create 16-bit callback stub push eax ; ; Use module's or task's _real_ instance/module ; We need to do this in case bp_hmod is 0L, so we get current. ; mov eax, dword ptr bp_hmod call MaphInstLS mov word ptr bp_hmod, ax call MaphInstSL push eax push dword ptr bp_hThread call SetWindowsHookEx32 ;make api call DXAX2EAX get_out: endm ;-----------------------------------------------------------------------; ; body_UNHOOKWINDOWSHOOK ;-----------------------------------------------------------------------; body_UNHOOKWINDOWSHOOK macro bp_nCode equ bp_pfn equ ; Save nCode in eax for CBID_ math later movsx eax, word ptr bp_nCode push ax push dword ptr bp_pfn add eax, CBID_WH_START+1 push eax call QueryCallbackAddress push eax call UnhookWindowsHook cwde endm ;-----------------------------------------------------------------------; ; body_GETSETWINDOWDATA ;-----------------------------------------------------------------------; body_GETSETWINDOWDATA macro local exit local Call_GSWD local GSWD_return local SWD_wndproc local SWD_hinst local GWD_wndproc local GWD_hinst local error local apfnGet local apfnSet bp_hwnd equ bp_nIndex equ bp_dwValue equ bp_nFlags equ bp_isdialog equ <[bp-2]> ; Save space for bp_isdialog xor ax, ax push ax mov bx, word ptr bp_nIndex cmp bx, ax jl @F cmp bx, DWL_DLGPROC jne Call_GSWD ; Is window really a dialog? If not, skip this! push word ptr bp_hwnd call IsDialog mov word ptr bp_isdialog, ax test ax, ax jz Call_GSWD test word ptr bp_nFlags, DATA_SET jz Call_GSWD jmp SWD_wndproc @@: cmp bx,GWL_USERDATA je Call_GSWD neg bx add bx,GWL_WNDPROC .errnz GWL_WNDPROC + 4 jl error cmp bx,MAX_INDEX ja error test bl, 1 jnz error ;Don't allow odd indices. test word ptr bp_nFlags, DATA_SET jz Call_GSWD jmp cs:apfnSet[bx] apfnSet label word dw offset SWD_wndproc ;0 ; -4 GWL_WNDPROC dw offset SWD_hinst ;2 ; -6 GWL_HINSTANCE dw offset Call_GSWD ;4 ; -8 GWL_HWNDPARENT dw offset error ;6 ;-10 dw offset Call_GSWD ;8 ;-12 GWL_ID dw offset error ;10 ;-14 dw offset Call_GSWD ;12 ;-16 GWL_STYLE dw offset error ;14 ;-18 dw offset Call_GSWD ;16 ;-20 GWL_EXSTYLE ;; No need to add one more entry for -21 (GWL_USERDATA) because this is ;; the only Odd index we handle it as a special case eariler. MAX_INDEX equ ($-apfnSet) .errnz GWL_WNDPROC + 4 .errnz GWL_HINSTANCE + 6 .errnz GWL_HWNDPARENT + 8 .errnz GWL_ID + 12 .errnz GWL_STYLE + 16 .errnz GWL_EXSTYLE + 20 .errnz GWL_USERDATA + 21 .errnz GWW_HINSTANCE + 6 .errnz GWW_HWNDPARENT + 8 SWD_wndproc: push dword ptr bp_dwValue mov eax, CBID_WNDPROC cmp word ptr bp_nIndex, DWL_DLGPROC jne @F ; Is window really a dialog! If not, skip this. mov eax, CBID_DLGPROC @@: push eax call GetStdCBSL mov dword ptr bp_dwValue, eax jmp Call_GSWD SWD_hinst: mov eax, dword ptr bp_dwValue call MaphinstLS movzx eax, ax mov dword ptr bp_dwValue, eax ; FALL THRU Call_GSWD: push word ptr bp_hwnd push word ptr bp_nIndex push dword ptr bp_dwValue push word ptr bp_nFlags call GetSetWindowData DXAX2EAX ; ; Now thunk return value. Note that up above, we already did the ; sanity checking on indeces < 0, so we don't have to do it again. ; mov bx, word ptr bp_nIndex cmp bx, 0 jl @F cmp bx, DWL_DLGPROC jne GSWD_return cmp word ptr bp_isdialog, 0 jz GSWD_return jmp GWD_wndproc @@: cmp bx, GWL_USERDATA je GSWD_return neg bx add bx,GWL_WNDPROC jmp cs:apfnGet[bx] apfnGet label word dw offset GWD_wndproc ;0 ; -4 GWL_WNDPROC dw offset GWD_hinst ;2 ; -6 GWL_HINSTANCE dw offset GSWD_return ;4 ; -8 GWL_HWNDPARENT dw offset error ;6 ;-10 dw offset GSWD_return ;8 ;-12 GWL_ID dw offset error ;10 ;-14 dw offset GSWD_return ;12 ;-16 GWL_STYLE dw offset error ;14 ;-18 dw offset GSWD_return ;16 ;-20 GWL_EXSTYLE GWD_wndproc: push eax mov eax, CBID_WNDPROC cmp word ptr bp_nIndex, DWL_DLGPROC jne @F mov eax, CBID_DLGPROC @@: push eax call GetStdCBLS jmp GSWD_return GWD_hinst: call MaphinstSL jmp GSWD_return error: xor eax, eax GSWD_return: ; Get rid of local word storage add sp, 2 endm ;-----------------------------------------------------------------------; ; body_GETSETCLASSDATA ;-----------------------------------------------------------------------; body_GETSETCLASSDATA macro local exit local Call_GCSD local SCD_ptr local SCD_hinst local SCD_wndproc local GCD_ptr local GCD_hinst local GCD_wndproc local error local apfnSet local apfnGet local have_stub local MAX_INDEX bp_hwnd equ bp_nIndex equ bp_dwData equ bp_nFlags equ ; We do this up front for index validation. ; Is index private (>= 0) or not in system range? If so, no thunking. mov bx, word ptr bp_nIndex cmp bx, 0 jge Call_GSCD neg bx add bx,GCL_MENUNAME .errnz GCL_MENUNAME + 8 jl error cmp bx,MAX_INDEX jge error test bl, 1 jnz error ;don't allow odd indices test word ptr bp_nFlags, DATA_SET jz Call_GSCD jmp cs:apfnSet[bx] apfnSet label word dw offset SCD_ptr ;0 ; - 8 GCL_MENUNAME dw offset Call_GSCD ;2 ; -10 GCL_HBRBACKGROUND dw offset Call_GSCD ;4 ; -12 GCL_HCURSOR dw offset Call_GSCD ;6 ; -14 GCL_HICON dw offset SCD_hinst ;8 ; -16 GCL_HMODULE dw offset Call_GSCD ;10 ; -18 GCL_CBWNDEXTRA dw offset Call_GSCD ;12 ; -20 GCL_CBCLSEXTRA dw offset error ;14 dw offset SCD_wndproc ;16 ; -24 GCL_WNDPROC dw offset Call_GSCD ;18 ; -26 GCL_STYLE dw offset error ;20 dw offset error ;22 dw offset Call_GSCD ;24 ; -32 GCW_ATOM dw offset Call_GSCD ;26 ; -34 GCW_HICONSM MAX_INDEX equ ($ - apfnSet) .errnz 8 + GCL_MENUNAME .errnz 10 + GCW_HBRBACKGROUND .errnz 12 + GCW_HCURSOR .errnz 14 + GCW_HICON .errnz 16 + GCW_HMODULE .errnz 18 + GCW_CBWNDEXTRA .errnz 20 + GCW_CBCLSEXTRA .errnz 24 + GCL_WNDPROC .errnz 26 + GCL_STYLE .errnz 32 + GCW_ATOM .errnz 34 + GCW_HICONSM SCD_ptr: push dword ptr bp_dwData call MapLS mov dword ptr bp_dwData, eax jmp Call_GSCD SCD_wndproc: push dword ptr bp_dwData push dword ptr CBID_WNDPROC call GetStdCBSL mov dword ptr bp_dwData, eax jmp Call_GSCD SCD_hinst: mov eax, dword ptr bp_dwData call MaphinstLS movzx eax, ax mov dword ptr bp_dwData, eax ; FALL THRU Call_GSCD: push word ptr bp_hwnd push word ptr bp_nIndex push dword ptr bp_dwData push word ptr bp_nFlags call GetSetClassData DXAX2EAX ; ; Now thunk return value. Note that up above, we already did the ; sanity checking on indeces < 0, so we don't have to do it again. ; mov bx, word ptr bp_nIndex cmp bx, 0 jge GSCD_return neg bx add bx,GCL_MENUNAME jmp cs:apfnGet[bx] apfnGet label word dw offset GCD_ptr ;0 ; - 8 GCL_MENUNAME dw offset GSCD_return ;2 ; -10 GCW_HBRBACKGROUND dw offset GSCD_return ;4 ; -12 GCW_HCURSOR dw offset GSCD_return ;6 ; -14 GCW_HICON dw offset GCD_hinst ;8 ; -16 GCW_HMODULE dw offset GSCD_return ;10 ; -18 GCW_CBWNDEXTRA dw offset GSCD_return ;12 ; -20 GCW_CBCLSEXTRA dw offset error ;14 dw offset GCD_wndproc ;16 ; -24 GCL_WNDPROC dw offset GSCD_return ;18 ; -26 GCL_STYLE dw offset error ;20 dw offset error ;22 dw offset GSCD_return ;24 ; -32 GCW_ATOM dw offset GSCD_return ;26 ; -34 GCW_HICONSM GCD_ptr: ; This is OK. ; User's DS doesn't move in linear memory. And menu strings are ; LocalAlloced() out of User's DS. push eax call MapSL jmp GSCD_return GCD_hinst: call MaphinstSL jmp GSCD_return GCD_wndproc: push eax push dword ptr CBID_WNDPROC call GetStdCBLS jmp GSCD_return error: xor eax, eax GSCD_return: endm ;------------------------------------------------------------------------- ; DdeAccessData(), DdeUnAccessData() ; ; HACK! DDEML stores the data in movable Win16 global handles, so ; *we* have to fix the handle whenever the app holds a linear address to it. ; This means groveling around in ddeml's data structures to retrieve ; the global handle from the DDE data handle. ; ; No, we can't just copy the data either. DdeAccessData() returns a ; read/write pointer. ; ; BUGBUG! Doesn't repack metafiles yet. For M6, write a support routine ; inside ddeml to handle all this stuff, and get rid of this hack. ; ;------------------------------------------------------------------------- HDDEDATA_GHND equ 4 PUSH__DDEACCESSDATA_hData macro iOffset, iJunk push es les bx, [bp + iOffset] mov ax, es:[bx + HDDEDATA_GHND] pop es push ax call GlobalFix push dword ptr [bp + iOffset] endm ;PUSH__DDEACCESSDATA_hData PUSH__DDEUNACCESSDATA_hData macro iOffset, iJunk push es les bx, [bp + iOffset] mov ax, es:[bx + HDDEDATA_GHND] pop es push ax call GlobalUnFix push dword ptr [bp + iOffset] endm ;PUSH__DDEUNACCESSDATA_hData ;*************************************************************************** ; PackDDELParam and friends. ; ; WARNING: A lot of thunking depends on the fact that PackDDELParam requires ; no explicit cleanup whatsoever. If you're thinking of changing that, ; think again. ; ; The value returned by PackDDELParam is a ready-to-be-used Win16 ; DDE lparam. The message thunks pass this through with no further ; translation (*). Through the magic of handle grouping, FreeDDELParam ; has to do absolutely nothing. ; ; (*) Except for WM_DDE_EXECUTE. It will translate the handle in the ; message thunk instead of in PackDDELParam. This allows Win32 apps ; to neglect PackDDELParam for WM_DDE_EXECUTE: which works on both ; NT and Win32s. (They can't ignore it on the WM_DDE_ACK, however. ; NT & Win32s don't allow this either.) ; ;*************************************************************************** ;-----------------------------------------------------------------------; ; body_PACKDDELPARAM ;-----------------------------------------------------------------------; body_PACKDDELPARAM macro local wMsg, dwLo, dwHi local exit local pack_execute local pack_default local pack_ddeack, pack_maplo wMsg equ [bp_top] dwLo equ [bp_top+4] dwHi equ [bp_top+8] mov ax,word ptr wMsg cmp ax, WM_DDE_EXECUTE je pack_execute cmp ax, WM_DDE_ACK je pack_mapddeack cmp ax, WM_DDE_ADVISE je pack_maplo cmp ax, WM_DDE_DATA je pack_maplo cmp ax, WM_DDE_POKE je pack_maplo ; WM_DDE_REQUEST or WM_DDE_UNADVISE ; ; Both dwLo & dwHi are 16-bit significant only, so just mush them ; together. Note that a Win32 app could get away without calling ; PackDDELParam for these messages. But NT and Win32s support this, ; so we will too. pack_default: mov ax, word ptr dwHi shl eax,16 mov ax, word ptr dwLo jmp exit ; WM_DDE_EXECUTE: Just pass it along. Message thunk must do handle ; conversion. We'd prefer to do the conversion here but then, an app ; is forced to use PackDDElParam. But NT and Win32s allow them to ; neglect that -- so we must too. pack_execute: mov eax, dword ptr dwHi jmp exit ; WM_DDE_ACK: ; ; Hi dword is either a Win32 global handle or an atom. Fortunately, ; we can distinguish the two by examining the high word. ; ; pack_mapddeack: cmp word ptr dwHi+2, 0 ;Handle or atom? je pack_default push word ptr wMsg push dword ptr dwHi call ConvertDDEHandleLS ;This routine requires no cleanup movzx eax,ax or ax,ax jz exit shl eax,16 mov ax, word ptr dwLo ;ax == status word jmp exit ; WM_DDE_ADVISE, WM_DDE_DATA, WM_DDE_POKE pack_maplo: push word ptr wMsg push dword ptr dwLo call ConvertDDEHandleLS ;This routine requires no cleanup movzx eax,ax or ax,ax jz exit mov cx,ax mov ax, word ptr dwHi ;ax == status word shl eax,16 mov ax,cx ;Fall thru to exit exit: endm ;body_PACKDDELPARAM ;-----------------------------------------------------------------------; ; body_UNPACKDDELPARAM ;-----------------------------------------------------------------------; body_UNPACKDDELPARAM macro local exit local unpack_execute local unpack_default local unpack_ddeack, unpack_maplo local storeit local didhi,didlo local wMsg,dwLParam,puLo,puHi wMsg equ [bp_top] dwLParam equ [bp_top+4] puLo equ [bp_top+8] puHi equ [bp_top+12] mov ax,word ptr wMsg cmp ax, WM_DDE_EXECUTE je unpack_execute cmp ax, WM_DDE_ACK je unpack_ddeack cmp ax, WM_DDE_ADVISE je unpack_maplo cmp ax, WM_DDE_DATA je unpack_maplo cmp ax, WM_DDE_POKE je unpack_maplo ; WM_DDE_REQUEST or WM_DDE_UNADVISE ; ; Both dwLo & dwHi are 16-bit significant only, so just mush them ; together. Note that a Win32 app could get away without calling ; PackDDELParam for these messages. But NT and Win32s support this, ; so we will too. unpack_default: mov eax,dwLParam mov edx,eax and eax,0ffffh ;EAX = lo word shr edx,16 ;EDX = hi word jmp storeit ; WM_DDE_EXECUTE: Message thunk already converted handle. Put it back ; in puHi. We'd prefer to the conversion here but then, an app ; is forced to use PackDDElParam. But NT and Win32s allow them to ; neglect that -- so we must too. unpack_execute: mov edx, dwLParam xor eax,eax jmp storeit ; WM_DDE_ACK: ; Hi-word is either a global Win16 handle or atom. ; ; No easy way tell which. Pass the buck to kernel. unpack_ddeack: push dword ptr dwLParam call IsThisADDEExecuteHandle or ax,ax jz unpack_default ; Yes, this code is unused for M5 but it's tested and we *will* be using ; it for M6 so don't you dare delete it! push word ptr wMsg push word ptr dwLParam+2 call ConvertDDEHandleSL ;This routine requires no cleanup test eax,eax jz exit mov edx,eax movzx eax, word ptr dwLParam jmp storeit ; WM_DDE_ADVISE, WM_DDE_DATA, WM_DDE_POKE unpack_maplo: push word ptr wMsg push word ptr dwLParam call ConvertDDEHandleSL ;This routine requires no cleanup test eax,eax jz exit movzx edx, word ptr dwLParam+2 ; Fall through to storeit storeit: mov ds,FlatData ; ds:esi == source address mov edi, puLo or edi, edi jz didlo mov [edi],eax didlo: mov edi, puHi or edi, edi jz didhi mov [edi],edx didhi: mov eax,1 jmp exit unpack_badparam: xor eax,eax ;Fall thru to exit exit: endm ;-----------------------------------------------------------------------; ; body_FREEDDELPARAM ; ; Through the magic of handle grouping, no action is required here. ; If you ever change this, you'll also have to make the message thunks ; thunks clean up temporary lparams. ;-----------------------------------------------------------------------; body_FREEDDELPARAM macro xor eax,eax inc eax endm ;-----------------------------------------------------------------------; ; body_DDEQUERYCONVINFO ;-----------------------------------------------------------------------; body_DDEQUERYCONVINFO macro local next, L1, L2 local bp_hConv, bp_idTransaction, bp_lpConvInfo local bp_hwnd, bp_hwndPartner; bp_hConv equ bp_idTransaction equ bp_lpConvInfo equ bp_hwnd equ word ptr [bp-6] bp_hwndPartner equ word ptr [bp-8] xor eax,eax push eax ; ptr param #1 pConvInfo push eax ; store hwnd field push eax ; store hwndPartner field ; pConvInfo ; pointer struct CONVINFO32 --> struct CONVINFO16 cld ; esi, edi will increment sub sp,CONVINFO16_SIZE ; pConvInfo alloc space on stack ; different pointer types mov eax,DWORD ptr bp_lpConvInfo ; base address test eax,eax jz L1 ; skip if null ; structures are not identical ; structures don't have pointers mov [bp-4],sp ; save offset to buffer mov [bp-2],ss ; save selector to buffer mov di,ss mov es,di movzx edi,sp ; es:edi == destination address mov esi,eax mov ds,FlatData ncopyd 7 ncopyt 5 copyd lodsd ds:[esi] mov ax, CONVCONTEXT16_SIZE stosw ncopyt 3 ncopyd 2 L1: ; *** END parameter packing ;------------------------------------- ; create new call frame and make the call ; hConv from: unsigned long push dword ptr bp_hConv ; to unsigned long ; idTransaction from: unsigned long push dword ptr bp_idTransaction ; to unsigned long ; pConvInfo from: struct CONVINFO32 mov eax,[bp-4] push eax test eax,eax jz next movzx eax,ax mov word ptr ss:[eax].ci16_cb,CONVINFO16_SIZE mov word ptr ss:[eax].ci16_ConvCtxt.cc16_cb,CONVCONTEXT16_SIZE next: call DdeQueryConvInfo ; call 16-bit version movzx eax,ax test eax,eax jz L2 ;------------------------------------- ; *** BEGIN parameter unpacking cld ; esi, edi will increment ; pConvInfo ; pointer struct CONVINFO16 --> struct CONVINFO32 mov eax,DWORD ptr bp_lpConvInfo ; base address test eax,eax jz L2 ; skip if null ; structures are not identical ; structures don't have pointers mov si, seg FlatData mov es, si mov es, es:[FlatData] mov edi,eax ; es:edi == destination address mov si,ss mov ds,si movzx esi,word ptr [bp-4] ; ds:esi == source address ; cb ; unsigned long --> unsigned long mov dword ptr ds:[esi], CONVINFO32_SIZE ncopyd 7 ncopyzx 5 copyd mov word ptr ds:[esi], CONVCONTEXT32_SIZE ncopyzx 3 copysx ncopyd 2 xor eax,eax ; Put dummy bytes into SECURITY_QUALITY_OF_SERVICE mov eax, 0ch ;SIZEOF(SECURITY_QUALITY_OF_SERVICE) stosd es:[edi] xor eax,eax stosd es:[edi] stosd es:[edi] push es push edi push dword ptr bp_hConv mov ax, ss push ax lea cx, bp_hwnd push cx mov ax, ss push ax lea cx, bp_hwndPartner push cx call GetHCONVWindows pop edi pop es movzx eax,ax or ax,ax jz L2 movzx eax, bp_hwnd stosd es:[edi] movzx eax, bp_hwndPartner stosd es:[edi] mov eax, CONVINFO32_SIZE L2: endm ;---------------------------------------------------------------------------- ; ; GetClassInfoExA() ; ;---------------------------------------------------------------------------- body_GETCLASSINFOEXA macro local L238 local PushInstance local PushClassName local StoreWndProc local StoreMenuName local Cleanup bp_hInstance equ bp_lpszClassName equ bp_lpwc32 equ bp_lpszClassNameTemp equ <[bp - 4]> ; Skip this if lpsz32 or lpwc32 is NULL mov eax, bp_lpszClassName test eax,eax jz L238 ; skip if null mov eax, bp_lpwc32 test eax, eax jz L238 ; Save space for lpszClassNameTemp xor eax, eax push eax ; Get lpWndClassEx16 sub sp,WNDCLASSEX16_SIZE ; lpWndClassEx alloc space on stack movzx esi,sp ; ds:esi == destination address mov dword ptr ss:[esi], WNDCLASSEX16_SIZE ; ; Push 16-bit parameters ; ; hInstance: can be NULL (for system class) mov eax, bp_hInstance test eax, eax jz PushInstance call MaphInstLS PushInstance: push ax ; lpszClassName: can be atom or string push dword ptr bp_lpszClassName call MapLS mov bp_lpszClassNameTemp, eax push eax ; lpwc16 push ss push si ; ; Make 16-bit call ; ZERO-EXTEND return value. Some apps know it's not really a BOOL, ; it's an ATOM and save the entire DWORD away to compare later. ; call GetClassInfoEx movzx eax, ax ; Save return value push eax test eax, eax jz Cleanup ; ; Convert WNDCLASSEX from 16 to 32 ; mov es, FlatData mov edi, bp_lpwc32 push ds mov ax, ss mov ds, ax cld ;;Skip size add esi, 4 add edi, 4 ; style copyd ; lpfnWndProc lodsd ds:[esi] push es push eax push dword ptr CBID_WNDPROC call GetStdCBLS pop es stosd es:[edi] ; cbClsExtra, cbWndExtra ncopyzx 2 ; hInstance lodsw ds:[esi] ; hInstance mov eax, bp_hInstance stosd es:[edi] ; hIcon, hCursor, hbrBackground ncopyzx 3 ; lpszMenuName lodsd ds:[esi] push eax call MapSL ;BUGBUG! GetClassInfo stosd es:[edi] ; lpszClassName: Just use what was passed in, just like User16 does! lodsd ds:[esi] mov eax, dword ptr bp_lpszClassName stosd es:[edi] ; hIconSm copyzx pop ds Cleanup: pushd bp_lpszClassNameTemp call UnmapLS pop eax L238: endm ;=========================================== ; BOGUS ; Same code for mapping instances everywhere ;=========================================== ;-----------------------------------------------------------------------; ; PUSH__DDECONNECT_pCC ;-----------------------------------------------------------------------; PUSH__DDECONNECT_pCC macro iOffset, iTempOffset local done mov eax,[bp-iTempOffset] push eax test eax,eax jz done movzx eax,ax mov word ptr ss:[eax].cc16_cb,CONVCONTEXT16_SIZE done: endm ;-----------------------------------------------------------------------; ; PUSH__DDECONNECTLIST_pCC ;-----------------------------------------------------------------------; PUSH__DDECONNECTLIST_pCC macro iOffset, iTempOffset local done mov eax,[bp-iTempOffset] push eax test eax,eax jz done movzx eax,ax mov word ptr ss:[eax].cc16_cb,CONVCONTEXT16_SIZE done: endm ;-----------------------------------------------------------------------; ; body_CREATEWINDOWEXA ;-----------------------------------------------------------------------; body_CREATEWINDOWEXA macro local null_ptr1 local store_ptr1 local null_ptr2 local have_x local have_width local ismdi local isnotmdi local done_with_lpParam BODY_PARAM_16 bp_dwExStyle, 0 BODY_PARAM_16 bp_lpClassName, 4 BODY_PARAM_16 bp_lpWindowName, 8 BODY_PARAM_16 bp_dwStyle, 12 BODY_PARAM_16 bp_X, 16 BODY_PARAM_16 bp_Y, 20 BODY_PARAM_16 bp_nWidth, 24 BODY_PARAM_16 bp_nHeight, 28 BODY_PARAM_16 bp_hWndParent, 32 BODY_PARAM_16 bp_hMenu, 36 BODY_PARAM_16 bp_hInstance, 40 BODY_PARAM_16 bp_lpParam, 44 bp_lpClassNameTemp equ <[bp-4]> bp_lpWindowNameTemp equ <[bp-8]> bp_lpParamTemp equ <[bp-12]> bp_couldbemdi equ <[bp-14]> ; temp storage xor eax,eax push eax ; ptr param #1 lpClassNameTemp push eax ; ptr param #2 lpWindowNameTemp push eax ; ptr param #3 lpParamTemp inc ax push ax ; wrd param #4 couldbemdi (set to 1) mov cx, word ptr bp_lpClassName+2 jcxz notmdi ; Passed in an atom? mov eax, dword ptr bp_lpClassName mov es, FlatData mov eax, es:[eax] cmp eax, 'CIDM' ; Check for MDIC je ismdi cmp eax, 'cidm' ; and in lower case... je ismdi notmdi: dec word ptr bp_couldbemdi ; dec to 0 ismdi: push dword ptr bp_lpClassName call MapLS ;PLUGGED mov bp_lpClassNameTemp,eax push dword ptr bp_lpWindowName call MapLS ;PLUGGED mov bp_lpWindowNameTemp,eax ; lpParam is pointer to CLIENTCREATESTRUCT if class is mdiclient, otherwise ; it's just a dword. mov cx, word ptr bp_couldbemdi jcxz isnotmdi push dword ptr bp_lpClassNameTemp call IsClassNameMDICLIENT test ax,ax jnz CreateMdi isnotmdi: push dword ptr bp_lpParam call MapLS mov bp_lpParamTemp, eax mov bp_lpParam, eax jmp done_with_lpParam ; lpParam points to CLIENTCREATESTRUCT, so repack it and update ; bp_lpParamTemp CreateMdi: ;CLIENTCREATESTRUCT: ; HWND ; UINT mov es, FlatData mov ecx,dword ptr bp_lpParam push word ptr es:[ecx+4] ;truncate UINT push word ptr es:[ecx] ;truncate HWND mov bp_lpParam[0],sp ;store new pointer to struct mov bp_lpParam[2],ss done_with_lpParam: push dword ptr bp_dwExStyle push dword ptr bp_lpClassNameTemp push dword ptr bp_lpWindowNameTemp push dword ptr bp_dwStyle ; x, y, cx, cy mov eax, dword ptr bp_X cmp eax, 80000000h ; CW_USEDEFAULT jne have_x ror eax,16 ; map to 8000h have_x: push ax mov eax, dword ptr bp_Y cmp eax, 80000000h jne have_y ror eax,16 have_y: push ax mov eax,dword ptr bp_nWidth cmp eax,80000000h ; CW_USEDEFAULT jne have_cx ror eax,16 ; map to 8000h have_cx: push ax mov eax,dword ptr bp_nHeight cmp eax,80000000h jne have_cy ror eax,16 have_cy: push ax push word ptr bp_hWndParent ; push LOWORD of hMenu push word ptr bp_hMenu.lo ; hInstance MAP_NULL_HINST bp_hInstance push ax ; lpParams push dword ptr bp_lpParam ; push HIWORD of hMenu push word ptr bp_hMenu.hi call CreateWindowEx32 ; call 16-bit version movzx eax,ax push eax pushd bp_lpParamTemp call UnmapLS pushd bp_lpClassNameTemp call UnmapLS pushd bp_lpWindowNameTemp call UnmapLS pop eax endm ;-----------------------------------------------------------------------; ; body_DDECLIENTTRANSACTION ;-----------------------------------------------------------------------; body_DDECLIENTTRANSACTION macro local dometafile local null_ptr1 local null_ptr2 local dct_leave BODY_PARAM_16 bp_pData, 0 BODY_PARAM_16 bp_cbData, 4 BODY_PARAM_16 bp_hConv, 8 BODY_PARAM_16 bp_hszItem, 12 BODY_PARAM_16 bp_wFmt, 16 BODY_PARAM_16 bp_wType, 20 BODY_PARAM_16 bp_dwTimeout, 24 BODY_PARAM_16 bp_pdwResult, 28 bp_pDataTemp equ <[bp-4]> bp_pdwResultTemp equ <[bp-8]> bp_pDataTempSel equ <[bp-12]> xor eax,eax push dword ptr bp_pData ; bp_pDataTemp: ptr param #1 pData push eax ; bp_pdwResultTemp: ptr param #2 pdwResult push eax ; bp_pDataTempSel: Sel for pData ;If cbData == -1, then pData is a handle, not a pointer. cmp dword ptr bp_cbData, -1 jz null_ptr1 cmp dword ptr bp_pData, 0 jz null_ptr1 cmp word ptr bp_wFmt, CF_METAFILEPICT je dometafile push dword ptr bp_pData call MapLS ;PLUGGED mov bp_pDataTemp,eax mov bp_pDataTempSel,eax jmp null_ptr1 dometafile: mov ds, FlatData mov esi, bp_pData push word ptr CF_METAFILEPICT push dword ptr [esi] push word ptr 0 call ConvertCFDataLS movzx eax,ax or ax,ax jz dct_leave ; We'll use bp_pData as our (2-byte) substitute data buffer. mov bp_pData,ax mov word ptr bp_cbData,2 mov ax,ss mov bp_pDataTemp,ax lea di,bp_pData mov bp_pDataTemp+2,di null_ptr1: push dword ptr bp_pdwResult call MapLS ;PLUGGED mov bp_pdwResultTemp,eax null_ptr2: push dword ptr bp_pDataTemp push dword ptr bp_cbData push dword ptr bp_hConv push dword ptr bp_hszItem push word ptr bp_wFmt push word ptr bp_wType push dword ptr bp_dwTimeout push dword ptr bp_pdwResultTemp call DDECLIENTTRANSACTION DXAX2EAX dct_leave: ; We can safely unmap these. The api does not hold either pointer ; after it returns. push eax push dword ptr bp_pDataTempSel call UnMapLS push dword ptr bp_pdwResultTemp call UnMapLS IF 0 ;!!! BUGBUG: The following is a gross M5 workaround for B#9814. ;!!! DdeClientTransaction takes our ss and stuffs it in a long-term data ;!!! structure. To prevent a subsequent GP fault, we'll replace ss ;!!! with a new one so that the thunk dispatcher won't unmap the one ;!!! that DdeClientTransaction so rudely took. mov ax,ss push ax push word ptr 0 call MapSL ;This is ok: part of M5 hack anyway push eax call MapLS mov ss,dx ;!!! End of B#9814 workaround. ENDIF pop eax endm ;-----------------------------------------------------------------------; ; body_SYSTEMPARAMETERSINFOA ;-----------------------------------------------------------------------; body_SYSTEMPARAMETERSINFOA macro local exit, error_exit local anpfnSPI, MAX_ACTION local push_zero_0, push_fuwinini_0 local push_zero_1, push_fuwinini_1 local push_callframe_2, push_ax_2 local push_callframe_3, done_3 bp_uAction equ bp_uParam equ bp_lParam equ bp_fuWinIni equ ;BP=SP upon entry bp_pTmp equ mov ebx,dword ptr bp_uAction cmp ebx,MAX_ACTION ja check_new_actions add bx,bx jmp word ptr cs:anpfnSPI[bx] check_new_actions: mov dx, bx shr bx, 12 and bx, 2 and dx, 1 add bx, dx cmp bx,MAX_NEWACTION ja error_exit add bx,bx jmp word ptr cs:anpfnNewSPI[bx] anpfnNewSPI label word dw offset thk_SPI_GETBOOLUSERPREFERENCE dw offset thk_SPI_SETBOOLUSERPREFERENCE dw offset thk_SPI_GETDWORDUSERPREFERENCE dw offset thk_SPI_SETDWORDUSERPREFERENCE MAX_NEWACTION equ ($ - anpfnNewSPI)/2 anpfnSPI label word dw offset error_exit dw offset thk_SPI_GETBEEP dw offset thk_SPI_SETBEEP dw offset thk_SPI_GETMOUSE dw offset thk_SPI_SETMOUSE dw offset thk_SPI_GETBORDER dw offset thk_SPI_SETBORDER dw offset error_exit dw offset error_exit dw offset error_exit dw offset thk_SPI_GETKEYBOARDSPEED dw offset thk_SPI_SETKEYBOARDSPEED dw offset thk_SPI_LANGDRIVER dw offset thk_SPI_ICONHORIZONTALSPACING dw offset thk_SPI_GETSCREENSAVETIMEOUT dw offset thk_SPI_SETSCREENSAVETIMEOUT dw offset thk_SPI_GETSCREENSAVEACTIVE dw offset thk_SPI_SETSCREENSAVEACTIVE dw offset thk_SPI_GETGRIDGRANULARITY dw offset thk_SPI_SETGRIDGRANULARITY dw offset thk_SPI_SETDESKWALLPAPER dw offset thk_SPI_SETDESKPATTERN dw offset thk_SPI_GETKEYBOARDDELAY dw offset thk_SPI_SETKEYBOARDDELAY dw offset thk_SPI_ICONVERTICALSPACING dw offset thk_SPI_GETICONTITLEWRAP dw offset thk_SPI_SETICONTITLEWRAP dw offset thk_SPI_GETMENUDROPALIGNMENT dw offset thk_SPI_SETMENUDROPALIGNMENT dw offset thk_SPI_SETDOUBLECLKWIDTH dw offset thk_SPI_SETDOUBLECLKHEIGHT dw offset thk_SPI_GETICONTITLELOGFONT dw offset thk_SPI_SETDOUBLECLICKTIME dw offset thk_SPI_SETMOUSEBUTTONSWAP dw offset thk_SPI_SETICONTITLELOGFONT dw offset thk_SPI_GETFASTTASKSWITCH dw offset thk_SPI_SETFASTTASKSWITCH dw offset thk_SPI_SETDRAGFULLWINDOWS dw offset thk_SPI_GETDRAGFULLWINDOWS dw offset thk_SPI_GETKEYBOARDLAYOUT dw offset thk_SPI_SETKEYBOARDLAYOUT dw offset thk_SPI_GETNONCLIENTMETRICS dw offset thk_SPI_SETNONCLIENTMETRICS dw offset thk_SPI_GETMINIMIZEDMETRICS dw offset thk_SPI_SETMINIMIZEDMETRICS dw offset thk_SPI_GETICONMETRICS dw offset thk_SPI_SETICONMETRICS dw offset thk_SPI_SETWORKAREA dw offset thk_SPI_GETWORKAREA dw offset thk_SPI_SETPENWINDOWS dw offset thk_SPI_GETFILTERKEYS dw offset thk_SPI_SETFILTERKEYS dw offset thk_SPI_GETTOGGLEKEYS dw offset thk_SPI_SETTOGGLEKEYS dw offset thk_SPI_GETMOUSEKEYS dw offset thk_SPI_SETMOUSEKEYS dw offset thk_SPI_GETSHOWSOUNDS dw offset thk_SPI_SETSHOWSOUNDS dw offset thk_SPI_GETSTICKYKEYS dw offset thk_SPI_SETSTICKYKEYS dw offset thk_SPI_GETACCESSTIMEOUT dw offset thk_SPI_SETACCESSTIMEOUT dw offset thk_SPI_GETSERIALKEYS dw offset thk_SPI_SETSERIALKEYS dw offset thk_SPI_GETSOUNDSENTRY dw offset thk_SPI_SETSOUNDSENTRY dw offset thk_SPI_GETHIGHCONTRAST dw offset thk_SPI_SETHIGHCONTRAST dw offset thk_SPI_GETKEYBOARDPREF dw offset thk_SPI_SETKEYBOARDPREF dw offset thk_SPI_GETSCREENREADER dw offset thk_SPI_SETSCREENREADER dw offset thk_SPI_GETANIMATION dw offset thk_SPI_SETANIMATION dw offset thk_SPI_GETFONTSMOOTHING dw offset thk_SPI_SETFONTSMOOTHING dw offset thk_SPI_SETDRAGWIDTH dw offset thk_SPI_SETDRAGHEIGHT dw offset thk_SPI_SETHANDHELD dw offset thk_SPI_GETLOWPOWERTIMEOUT dw offset thk_SPI_GETPOWEROFFTIMEOUT dw offset thk_SPI_SETLOWPOWERTIMEOUT dw offset thk_SPI_SETPOWEROFFTIMEOUT dw offset thk_SPI_GETLOWPOWERACTIVE dw offset thk_SPI_GETPOWEROFFACTIVE dw offset thk_SPI_SETLOWPOWERACTIVE dw offset thk_SPI_SETPOWEROFFACTIVE dw offset thk_SPI_SETCURSORS dw offset thk_SPI_SETICONS dw offset thk_SPI_GETDEFAULTINPUTLANG dw offset thk_SPI_SETDEFAULTINPUTLANG dw offset thk_SPI_SETLANGTOGGLE dw offset thk_SPI_GETWINDOWSEXTENSION dw offset thk_SPI_SETMOUSETRAILS dw offset thk_SPI_GETMOUSETRAILS dw offset thk_SPI_GETSNAPTODEFBUTTON dw offset thk_SPI_SETSNAPTODEFBUTTON dw offset thk_SPI_SETSCREENSAVERRUNNING ; 97 dw offset thk_SPI_GETMOUSEHOVERWIDTH ; 98 dw offset thk_SPI_SETMOUSEHOVERWIDTH ; 99 dw offset thk_SPI_GETMOUSEHOVERHEIGHT ; 100 dw offset thk_SPI_SETMOUSEHOVERHEIGHT ; 101 dw offset thk_SPI_GETMOUSEHOVERTIME ; 102 dw offset thk_SPI_SETMOUSEHOVERTIME ; 103 dw offset thk_SPI_GETWHEELSCROLLLINES ; 104 dw offset thk_SPI_SETWHEELSCROLLLINES ; 105 dw offset thk_SPI_GETMENUSHOWDELAY ; 106 dw offset thk_SPI_SETMENUSHOWDELAY ; 107 dw offset thk_SPI_GETUSERPREFERENCE ; 108 dw offset thk_SPI_SETUSERPREFERENCE ; 109 ifdef FE_IME dw offset thk_SPI_GETSHOWIMEUI ; 110 dw offset thk_SPI_SETSHOWIMEUI ; 111 else dw offset error_exit ; 110 dw offset error_exit ; 111 endif dw offset thk_SPI_GETMOUSESPEED ; 112 dw offset thk_SPI_SETMOUSESPEED ; 113 dw offset thk_SPI_GETSCREENSAVERRUNNING ; 114 MAX_ACTION equ ($ - anpfnSPI)/2 ;-----------------------------------------------------------------------; ; UNIMPLEMENTED ;-----------------------------------------------------------------------; thk_SPI_GETMOUSEHOVERWIDTH: thk_SPI_SETMOUSEHOVERWIDTH: thk_SPI_GETMOUSEHOVERHEIGHT: thk_SPI_SETMOUSEHOVERHEIGHT: thk_SPI_GETMOUSEHOVERTIME: thk_SPI_SETMOUSEHOVERTIME: thk_SPI_GETUSERPREFERENCE: thk_SPI_SETUSERPREFERENCE: error_exit: sub eax,eax jmp exit ;-----------------------------------------------------------------------; ; uParam = UINT ; lParam = LPINT ;-----------------------------------------------------------------------; thk_SPI_GETBEEP: thk_SPI_GETBORDER: thk_SPI_GETFASTTASKSWITCH: thk_SPI_GETGRIDGRANULARITY: thk_SPI_GETICONTITLEWRAP: thk_SPI_GETKEYBOARDDELAY: thk_SPI_GETKEYBOARDSPEED: thk_SPI_GETMENUDROPALIGNMENT: thk_SPI_GETSCREENSAVEACTIVE: thk_SPI_GETSCREENSAVETIMEOUT: thk_SPI_ICONHORIZONTALSPACING: thk_SPI_ICONVERTICALSPACING: thk_SPI_GETDRAGFULLWINDOWS: thk_SPI_GETFONTSMOOTHING: thk_SPI_GETMOUSETRAILS: thk_SPI_GETSNAPTODEFBUTTON: thk_SPI_SETSCREENSAVERRUNNING: thk_SPI_GETBOOLUSERPREFERENCE: thk_SPI_GETSCREENSAVERRUNNING: ifdef FE_IME thk_SPI_GETSHOWIMEUI: endif push byte ptr 0 ;reserve and init local var mov ax,sp ;save addr of local var push dword ptr bp_uAction push word ptr bp_uParam mov esi,bp_lParam test esi,esi jz push_zero_0 push ss push ax jmp short push_fuwinini_0 push_zero_0: push esi push_fuwinini_0: push word ptr bp_fuWinIni call SystemParametersInfo32 cwde pop cx ;recover local var value, clean stack mov esi,bp_lParam test esi,esi jz exit ;if 0, all done mov es,FlatData movsx ecx,cx mov es:[esi],ecx jmp exit ;-----------------------------------------------------------------------; ; uParam = UINT ; lParam = DWORD ;-----------------------------------------------------------------------; thk_SPI_SETBEEP: thk_SPI_SETBORDER: thk_SPI_SETDOUBLECLKHEIGHT: thk_SPI_SETDOUBLECLICKTIME: thk_SPI_SETDOUBLECLKWIDTH: thk_SPI_SETFASTTASKSWITCH: thk_SPI_SETGRIDGRANULARITY: thk_SPI_SETICONTITLEWRAP: thk_SPI_SETKEYBOARDDELAY: thk_SPI_SETKEYBOARDSPEED: thk_SPI_SETMENUDROPALIGNMENT: thk_SPI_SETMOUSEBUTTONSWAP: thk_SPI_SETSCREENSAVEACTIVE: thk_SPI_SETSCREENSAVETIMEOUT: thk_SPI_SETLOWPOWERTIMEOUT: thk_SPI_SETPOWEROFFTIMEOUT: thk_SPI_SETLOWPOWERACTIVE: thk_SPI_SETPOWEROFFACTIVE: thk_SPI_SETDRAGFULLWINDOWS: thk_SPI_SETFONTSMOOTHING: thk_SPI_SETPENWINDOWS: thk_SPI_SETSHOWSOUNDS: thk_SPI_SETKEYBOARDPREF: thk_SPI_SETSCREENREADER: thk_SPI_SETDRAGWIDTH: thk_SPI_SETDRAGHEIGHT: thk_SPI_SETCURSORS: thk_SPI_SETICONS: thk_SPI_SETLANGTOGGLE: thk_SPI_GETWINDOWSEXTENSION: thk_SPI_SETMOUSETRAILS: thk_SPI_SETSNAPTODEFBUTTON: thk_SPI_SETWHEELSCROLLLINES: thk_SPI_SETMENUSHOWDELAY: ifdef FE_IME thk_SPI_SETSHOWIMEUI: endif thk_SPI_SETBOOLUSERPREFERENCE: thk_SPI_SETDWORDUSERPREFERENCE: thk_SPI_SETMOUSESPEED: push dword ptr bp_uAction push word ptr bp_uParam push dword ptr bp_lParam push word ptr bp_fuWinIni call SystemParametersInfo32 cwde jmp exit ;-----------------------------------------------------------------------; ; uParam = WORD ; lParam = LPRECT ;-----------------------------------------------------------------------; thk_SPI_SETWORKAREA: thk_SPI_GETWORKAREA: ; We need scratch space for RECT16 sub sp, RECT16_SIZE mov di,sp push dword ptr bp_uAction push word ptr bp_uParam mov esi,bp_lParam test esi,esi jnz pack_lprect push esi jmp after_lprect pack_lprect: ; Stick lprect16 address on stack first push ss push di ; Convert lprect32 (ds:esi) to lprect16 (es:di) before push ds mov ds, FlatData mov ax, ss mov es, ax cld PACK_RECT_32_16 pop ds after_lprect: push word ptr bp_fuWinIni call SystemParametersInfo32 cwde test esi, esi jz stack_clean ; Save return value and DS push eax push ds ; Setup lprc16 in DS:SI (remember--PACK_RECT_32_16 changed DI) ; Setup lprc32 in ES:EDI (remember--PACK_RECT_32_16 changed ESI) push ss sub di, RECT16_SIZE push di mov edi, esi sub edi, RECT32_SIZE mov es, FlatData pop si pop ds cld PACK_RECT_16_32 pop ds pop eax stack_clean: ; Clean the stack add sp, RECT16_SIZE jmp exit ;-----------------------------------------------------------------------; ; uParam = 0 ; lParam = INT[3] ;-----------------------------------------------------------------------; thk_SPI_GETMOUSE: thk_SPI_SETMOUSE: sub sp,6 ;make space for local array mov bx,sp ;save addr of local var push dword ptr bp_uAction push word ptr bp_uParam mov esi,bp_lParam test esi,esi jz push_zero_1 mov es,FlatData mov ax,es:[esi+0] mov ss:[bx+0],ax mov ax,es:[esi+4] mov ss:[bx+2],ax mov ax,es:[esi+8] mov ss:[bx+4],ax push ss push bx jmp short push_fuwinini_1 push_zero_1: push esi push_fuwinini_1: push word ptr bp_fuWinIni call SystemParametersInfo32 cwde pop bx ;recover local vars value, clean stack pop cx pop dx mov esi,bp_lParam test esi,esi jz exit ;if 0, all done mov es,FlatData movsx ebx,bx mov es:[esi+0],ebx movsx ecx,cx mov es:[esi+4],ecx movsx edx,dx mov es:[esi+8],edx jmp exit ;-----------------------------------------------------------------------; ; uParam = 0 ; lParam = LPFN ;-----------------------------------------------------------------------; thk_SPI_SETHANDHELD: push dword ptr bp_uAction ;pass uAction push word ptr bp_uParam ;pass uParam push dword ptr bp_lParam ;convert lParam to 16:16 push dword ptr CBID_SENDMSGCALLBACK ;sendmsg-type callback stub call GetStdCBSL push eax ;pass pfn16 as lParam push word ptr bp_fuWinIni call SystemParametersInfo32 cwde jmp exit ;-----------------------------------------------------------------------; ; uParam = INT (if cbSize, 16-bit & 32-bit structs have to be ==) ; lParam = LPVOID ;-----------------------------------------------------------------------; thk_SPI_LANGDRIVER: thk_SPI_SETKEYBOARDLAYOUT: thk_SPI_GETKEYBOARDLAYOUT: thk_SPI_SETDESKPATTERN: thk_SPI_SETDESKWALLPAPER: thk_SPI_GETNONCLIENTMETRICS: thk_SPI_SETNONCLIENTMETRICS: thk_SPI_GETMINIMIZEDMETRICS: thk_SPI_SETMINIMIZEDMETRICS: thk_SPI_GETANIMATION: thk_SPI_SETANIMATION: thk_SPI_GETICONMETRICS: thk_SPI_SETICONMETRICS: thk_SPI_GETFILTERKEYS: thk_SPI_SETFILTERKEYS: thk_SPI_GETTOGGLEKEYS: thk_SPI_SETTOGGLEKEYS: thk_SPI_GETMOUSEKEYS: thk_SPI_SETMOUSEKEYS: thk_SPI_GETSHOWSOUNDS: thk_SPI_GETSTICKYKEYS: thk_SPI_SETSTICKYKEYS: thk_SPI_GETACCESSTIMEOUT: thk_SPI_SETACCESSTIMEOUT: thk_SPI_GETSERIALKEYS: thk_SPI_SETSERIALKEYS: thk_SPI_GETSOUNDSENTRY: thk_SPI_SETSOUNDSENTRY: thk_SPI_GETHIGHCONTRAST: thk_SPI_SETHIGHCONTRAST: thk_SPI_GETKEYBOARDPREF: thk_SPI_GETSCREENREADER: thk_SPI_GETDEFAULTINPUTLANG: thk_SPI_SETDEFAULTINPUTLANG: thk_SPI_GETWHEELSCROLLLINES: thk_SPI_GETMENUSHOWDELAY: thk_SPI_GETLOWPOWERACTIVE: thk_SPI_GETPOWEROFFACTIVE: thk_SPI_GETLOWPOWERTIMEOUT: thk_SPI_GETPOWEROFFTIMEOUT: thk_SPI_GETDWORDUSERPREFERENCE: thk_SPI_GETMOUSESPEED: push dword ptr bp_uAction push word ptr bp_uParam push dword ptr bp_lParam call MapLS ;PLUGGED mov dword ptr bp_lParam,eax push eax push word ptr bp_fuWinIni call SystemParametersInfo32 cwde push eax push dword ptr bp_lParam call UnmapLS pop eax jmp exit ;-----------------------------------------------------------------------; ; uParam = sizeof LOGFONT or 0 ; lParam = input LPLOGFONT or 0 ;-----------------------------------------------------------------------; thk_SPI_SETICONTITLELOGFONT: sub eax,eax push eax ;reserve and init bp_pTmp mov esi,bp_lParam test esi,esi jz push_callframe_2 sub sp,LOGFONT16_SIZE mov ax,sp push ds mov ds,FlatData ;DS:ESI --> 32-bit source mov di,ss mov es,di movzx edi,ax ;ES:EDI --> 16-bit dest mov word ptr bp_pTmp[0],di mov word ptr bp_pTmp[2],es cld PACK_MLOGFONT_32_16 pop ds push_callframe_2: push dword ptr bp_uAction mov ax,word ptr bp_uParam test ax,ax jz push_ax_2 mov ax,LOGFONT16_SIZE push_ax_2: push ax push dword ptr bp_pTmp push word ptr bp_fuWinIni call SystemParametersInfo32 cwde jmp short exit ;-----------------------------------------------------------------------; ; uParam = sizeof LOGFONT ; lParam = output LPLOGFONT ;-----------------------------------------------------------------------; thk_SPI_GETICONTITLELOGFONT: sub eax,eax push eax ;reserve and init bp_pTmp mov edi,bp_lParam test edi,edi jz push_callframe_3 sub sp,LOGFONT16_SIZE mov word ptr bp_pTmp[0],sp mov word ptr bp_pTmp[2],ss push_callframe_3: push dword ptr bp_uAction push byte ptr LOGFONT16_SIZE push dword ptr bp_pTmp push word ptr bp_fuWinIni call SystemParametersInfo32 cwde mov edi,bp_lParam test edi,edi jz exit push ds mov es,FlatData ;ES:EDI --> 32-bit source lds si,bp_pTmp ;DS:SI --> 16-bit dest movzx esi,si ;DS:ESI --> 16-bit dest cld PACK_MLOGFONT_16_32 pop ds exit: mov sp,bp endm ;-----------------------------------------------------------------------; ; body_LOADMENUINDIRECTA ;-----------------------------------------------------------------------; body_LOADMENUINDIRECTA macro local done bp_lpmt equ bp_lpmt32Tmp equ bp_hmem16Tmp equ < word ptr [bp-6]> bp_cbmt equ < word ptr [bp-8]> bp_mem32Menu equ xor eax,eax push eax push eax push eax push dword ptr bp_lpmt call MapLS ;PLUGGED mov bp_lpmt32Tmp,eax push eax call CountMenuU mov bp_cbmt,ax push byte ptr GHND movzx eax,ax push eax call GlobalAlloc ;if no scratch space, return no hmenu movzx eax,ax ;prepare for error test ax,ax jz done mov bp_hmem16Tmp,ax push ax push ax call GlobalFix call GlobalLock push dx push ax call MapSL ;SAFE mov bp_mem32Menu, eax mov eax, bp_lpmt push eax mov ax, bp_cbmt movzx eax, ax push eax mov eax, bp_mem32Menu push eax call ConvertMenu32 mov ax, bp_hmem16Tmp GMH2Sel ax ;push this ahead of time for LoadMenuIndirect push ax push byte ptr 0 ;push bp_cbmt ;cbIn ;push ax ;pOut ;push byte ptr 0 ; ;push bp_lpmt32Tmp ;pIn ;call ConvertMenuA ;convert menu to win3.1 format call LoadMenuIndirect ;param already pushed movzx eax,ax push eax push bp_hmem16Tmp ;cannot be null push bp_hmem16Tmp push bp_hmem16Tmp call GlobalUnlock call GlobalUnfix call GlobalFree pop eax done: push eax pushd bp_lpmt32Tmp call UnmapLS pop eax endm ;-----------------------------------------------------------------------; ; body_CREATEDIALOGINDIRECTPARAMA ;-----------------------------------------------------------------------; body_CREATEDIALOGINDIRECTPARAMA macro local done local done_with_dlgproc bp_hInstance equ bp_hDialogTemplate equ bp_hWndParent equ bp_lpDialogFunc equ bp_dwInitParam equ bp_lpdt32Tmp equ bp_hmem16Tmp equ < word ptr [bp-6]> bp_cbdt equ < word ptr [bp-8]> bp_mem32Dlg equ xor eax,eax push eax push eax push eax push dword ptr bp_lpDialogTemplate call MapLS ;PLUGGED mov bp_lpdt32Tmp,eax push eax call CountDialogU mov bp_cbdt,ax push byte ptr GPTR movzx eax,ax push eax call GlobalAlloc ;if no scratch space, return no hmenu movzx eax,ax ;prepare for error test ax,ax jz done mov bp_hmem16Tmp,ax ; GPTR is GMEM_FIXED, so MapSL is safe push ax push 0 call MapSL mov bp_mem32Dlg, eax ;push bp_cbdt ;cbIn ;push ax ;pOut ;push byte ptr 0 ; ;push bp_lpdt32Tmp ;pIn ;call ConvertDialogA ;convert menu to win3.1 format pushd bp_hDialogTemplate push 0 push bp_cbdt pushd bp_mem32Dlg call ConvertDialog32 ; create new call frame and make the call ; hInstance MAP_NULL_HINST bp_hInstance push ax ; lpDlgTemplate push word ptr bp_hmem16Tmp push 0 ; hwndOwner push word ptr bp_hWndParent ; lpfnDialog pushd bp_lpDialogFunc pushd CBID_DLGPROC call GetStdCBSL push eax push dword ptr bp_dwInitParam call GetCurrentHeap ; mov ds,ax ; set by func call CreateDialogIndirectParam ; call 16-bit version ; Save zero-extended return value movzx eax,ax push eax push bp_hmem16Tmp call GlobalFree ; Restore return value pop eax done: ; Save return value push eax pushd bp_lpdt32Tmp call UnmapLS ; Restore return value pop eax ;locals discarded by next instruction endm ;-----------------------------------------------------------------------; ; body_DIALOGBOXINDIRECTPARAMA ;-----------------------------------------------------------------------; body_DIALOGBOXINDIRECTPARAMA macro local done local ret_ok local cont local done_with_dlgproc local dlgproc_freed bp_hInstance equ bp_lpDialogTemplate equ bp_hWndParent equ bp_lpDialogFunc equ bp_dwInitParam equ bp_lpdt32Tmp equ bp_hmem16Tmp equ < word ptr [bp-6]> bp_cbdt equ < word ptr [bp-8]> bp_mem32Dlg equ xor eax,eax push eax push eax push eax push dword ptr bp_lpDialogTemplate call MapLS ;PLUGGED mov bp_lpdt32Tmp,eax push eax call CountDialogU mov bp_cbdt,ax push byte ptr GPTR movzx eax,ax push eax call GlobalAlloc ;if no scratch space, return no hmenu movzx eax,ax ;prepare for error test ax,ax jz done mov bp_hmem16Tmp,ax ; GPTR is GMEM_FIXED, so MapSL is safe push ax push 0 call MapSL mov bp_mem32Dlg, eax pushd bp_lpDialogTemplate push 0 push bp_cbdt pushd bp_mem32Dlg call ConvertDialog32 ; create new call frame and make the call ;hInst MAP_NULL_HINST bp_hInstance push ax ; hTemplate push word ptr bp_hmem16Tmp ; hwndOwner push word ptr bp_hWndParent ; lpfnDialog push dword ptr bp_lpDialogFunc push dword ptr CBID_DLGPROC call GetStdCBSL push eax push dword ptr bp_dwInitParam call GetCurrentHeap ; mov ds,ax ; set by func call DialogBoxIndirectParam ; call 16-bit version DXAX2EAX ;; 16-bit version returns in DX:AX. ;; So, move it to EAX. cont: ; Save return value push eax push bp_hmem16Tmp ;cannot be null call GlobalFree ; Restore return value pop eax done: ; Save return value push eax pushd bp_lpdt32Tmp call UnmapLS ; Restore return value pop eax ;locals discarded by next instruction endm ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; Inputs: eax = 32-bit lpNewItem from Win32 app. ; wFlags = MF flags passed to API (in cx for ChangeMenu!!) ; SegVarAddr = address of thunk-created local ; ; Output: eax = mapped version: ; -- input eax if MF_OWNERDRAW ; -- hi-word zeroed if MF_BITMAP ; -- MapLS's if MF_STRING ; ; SegVarAddr set to seg:offset if MF_STRING. ; MAP_MENU_LPNEWITEM macro wFlags,SegVarAddr local exit,isstring ; Assumes SegVarAddr initialized to 0. mov dx,wFlags test dx,MF_OWNERDRAW or MF_SEPARATOR jnz exit test dx,MF_BITMAP jz isstring movzx eax,ax jmp exit isstring: push eax call MapLS ;PLUGGED mov dword ptr SegVarAddr,eax exit: endm ;MAP_MENU_LPNEWITEM ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; RAWPACK__MODIFYMENUA_lpNewItem macro iOffset,iOffsetTemp mov eax,[bp+iOffset] MAP_MENU_LPNEWITEM [bp_top+8],LOCAL__MODIFYMENUA_lpNewItemSeg mov [bp-iOffsetTemp],eax endm; RAWPACK__MODIFYMENUA_lpNewItem RAWUNPACK__MODIFYMENUA_lpNewItem macro iOffset,iOffsetTemp push dword ptr LOCAL__MODIFYMENUA_lpNewItemSeg call UnmapLS endm; RAWUNPACK__MODIFYMENUA_lpNewItem ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; RAWPACK__INSERTMENUA_lpNewItem macro iOffset,iOffsetTemp mov eax,[bp+iOffset] MAP_MENU_LPNEWITEM [bp_top+8],LOCAL__INSERTMENUA_lpNewItemSeg mov [bp-iOffsetTemp],eax endm; RAWPACK__INSERTMENUA_lpNewItem RAWUNPACK__INSERTMENUA_lpNewItem macro iOffset,iOffsetTemp push dword ptr LOCAL__INSERTMENUA_lpNewItemSeg call UnmapLS endm; RAWUNPACK__INSERTMENUA_lpNewItem ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; RAWPACK__CHANGEMENUA_lpNewItem macro iOffset,iOffsetTemp mov eax,[bp+iOffset] ; HACK: The same flag bit that means MF_OWNERDRAW for ; every other *Menu() api means MF_APPEND for ChangeMenu(). To prevent ; MAP_MENU_LPNEWITEM from getting confused, turn off the bit in the ; flag we give to it. mov cx,[bp_top+16] and cx,not MF_OWNERDRAW MAP_MENU_LPNEWITEM cx,LOCAL__CHANGEMENUA_lpNewItemSeg mov [bp-iOffsetTemp],eax endm; RAWPACK__CHANGEMENUA_lpNewItem RAWUNPACK__CHANGEMENUA_lpNewItem macro iOffset,iOffsetTemp push dword ptr LOCAL__CHANGEMENUA_lpNewItemSeg call UnmapLS endm; RAWUNPACK__CHANGEMENUA_lpNewItem ;------------------------------------------------------------------------; ;body_WINHELPA ;------------------------------------------------------------------------; body_WINHELPA macro local its_a_pointer local its_lpmultikeyhelp local its_lphelpwininfo local leave_alone local call_winhelp local push_with_ssdi local loop_top local loop_top_2 bp_hwnd equ bp_lpHelpFile equ bp_wCommand equ bp_dwData equ bp_lpHelpFileTmp equ <[bp-4]> bp_dwDataTmp equ <[bp-8]> xor eax,eax push eax push eax ;;The various HELP_* constants are not arranged nicely for a jump ;;table, so just check for each of the known types needing special ;;thunking. If wCommand is not recognized, mov bx,word ptr bp_wCommand and bx, not HELP_TCARD cmp bx, HELP_CONTEXTMENU jb leave_alone je its_a_pointer cmp bx, HELP_WM_HELP je its_a_pointer cmp bx,HELP_KEY je its_a_pointer cmp bx,HELP_COMMAND je its_a_pointer cmp bx,HELP_PARTIALKEY je its_a_pointer cmp bx,HELP_MULTIKEY je its_lpmultikeyhelp cmp bx,HELP_SETWINPOS je its_lphelpwininfo ;; Push dwData as a dword. leave_alone: push word ptr bp_hwnd push dword ptr bp_lpHelpFile call MapLS ;PLUGGED mov dword ptr bp_lpHelpFileTmp,eax push eax push word ptr bp_wCommand push dword ptr bp_dwData jmp call_winhelp ;; Push dwData as LPSTR, so call MapLS its_a_pointer: push word ptr bp_hwnd push dword ptr bp_lpHelpFile call MapLS ;PLUGGED mov dword ptr bp_lpHelpFileTmp,eax push eax push word ptr bp_wCommand push dword ptr bp_dwData call MapLS ;PLUGGED mov dword ptr bp_dwDataTmp,eax push eax jmp call_winhelp ;;Push dwData as LPMULTIKEYHELP, which needs to be repacked. its_lpmultikeyhelp: mov esi,bp_dwData test esi,esi ;;if zero, just push it jz leave_alone mov es,FlatData mov ax,word ptr es:[esi].mk32_Size mov cx,ax ;;save for loop count add cx,(size MULTIKEYHELP16 - size MULTIKEYHELP32) sub sp,cx ;;subtract adjusted size for 16-bit struct mov di,sp ;;will access 16-bit struct thru SS:DI mov ss:[di].mk16_Size,cx mov cl,es:[esi].mk32_Keylist mov ss:[di].mk16_Keylist,cl mov cx,ax ;;32-bit struct size sub cx,mk32_szKeyphrase ;;skip header fields add esi,mk32_szKeyphrase add di,mk16_szKeyphrase loop_top: mov al,es:[esi] mov ss:[di],al inc esi inc di loop loop_top mov di,sp ;;SP --> base of structure jmp short push_with_ssdi ;;Push dwData as LPHELPWININFO, which needs to be repacked. its_lphelpwininfo: mov esi,bp_dwData test esi,esi ;;if zero, just push it jz leave_alone mov es,FlatData mov ax,word ptr es:[esi].hwi32_wStructSize mov cx,ax ;;save for loop count add cx,(size HELPWININFO16 - size HELPWININFO32) sub sp,cx ;;subtract adjusted size for 16-bit struct mov di,sp ;;will access 16-bit struct thru SS:DI mov ss:[di].hwi16_wStructSize,cx ;;Truncate all fields except for rgchMember to 16-bits. mov cx,word ptr es:[esi].hwi32_x mov ss:[di].hwi16_x,cx mov cx,word ptr es:[esi].hwi32_y mov ss:[di].hwi16_y,cx mov cx,word ptr es:[esi].hwi32_dx mov ss:[di].hwi16_dx,cx mov cx,word ptr es:[esi].hwi32_dy mov ss:[di].hwi16_dy,cx mov cx,word ptr es:[esi].hwi32_wMax mov ss:[di].hwi16_wMax,cx mov cx,ax ;;32-bit struct size sub cx,hwi32_rgchMember ;;skip header fields add esi,hwi32_rgchMember add di,hwi16_rgchMember loop_top_2: mov al,es:[esi] mov ss:[di],al inc esi inc di loop loop_top_2 mov di,sp ;;SP --> base of structure push_with_ssdi: push word ptr bp_hwnd push dword ptr bp_lpHelpFile call MapLS ;PLUGGED mov dword ptr bp_lpHelpFileTmp,eax push eax push word ptr bp_wCommand push ss ;;SS:DI --> thunked structure push di call_winhelp: call WinHelp cwde push eax push dword ptr bp_lpHelpFileTmp call UnmapLS push dword ptr bp_dwDataTmp call UnmapLS pop eax ;;The first instruction at Exit_16 clears temporary variables off stack. endm ;============================================================================== ; ; InsertMenuItemA() ; ;============================================================================== body_INSERTMENUITEMA macro local ConvertMiim local MakeCall bp_hMenu equ bp_nIndex equ bp_fByPosition equ bp_lpMiim32 equ bp_SavePtr equ <[bp-4]> xor eax,eax push eax ;bp_SavePtr ; We need scratch space for MENUITEMINFO16 sub sp, MENUITEMINFO16_SIZE mov di, sp ; Push 16bit parms push word ptr bp_hMenu ;hMenu 16 push word ptr bp_nIndex ;nIndex 16 push word ptr bp_fByPosition ;fByPosition 16 ; Is lpMenuItemInfo NULL? mov eax, dword ptr bp_lpMiim32 test eax, eax jnz ConvertMiim push eax jmp MakeCall ConvertMiim: push ss ;lpMenuItemInfo 16 push di ; Convert MENUITEMINFO LS push eax push di lea ax, bp_SavePtr push ax call ConvertMenuItemInfoLS MakeCall: call InsertMenuItem32 cwde ;Save return value push eax ;Cleanup push dword ptr bp_SavePtr call UnMapLS ;Restore return value pop eax endm ;============================================================================== ; ; SetMenuItemInfoA() ; ;============================================================================== body_SETMENUITEMINFOA macro local ConvertMiim local MakeCall bp_hMenu equ bp_nIndex equ bp_fByPosition equ bp_lpMiim32 equ bp_SavePtr equ <[bp-4]> xor eax,eax push eax ;bp_SavePtr ; We need scratch space for MENUITEMINFO16 sub sp, MENUITEMINFO16_SIZE mov di, sp ;Push 16bit parms push word ptr bp_hMenu push word ptr bp_nIndex push word ptr bp_fByPosition ; Is lpMenuItemInfo NULL? mov eax, dword ptr bp_lpMiim32 test eax, eax jnz ConvertMiim push eax jmp MakeCall ConvertMiim: push ss push di ;Convert MENUITEMINFO LS push eax push di lea ax, bp_SavePtr push ax call ConvertMenuItemInfoLS MakeCall: call SetMenuItemInfo32 cwde ;Save return value push eax ;Cleanup push dword ptr bp_SavePtr call UnMapLS ;Restore return value pop eax endm ;============================================================================== ; ; GetMenuItemInfoA() ; ;============================================================================== body_GETMENUITEMINFOA macro local ConvertMiim local MakeCall local GetDone local MenuTypeData local MenuItemCch local MenuItemEnd bp_hMenu equ bp_nIndex equ bp_fByPosition equ bp_lpMiim32 equ bp_SavePtr equ <[bp-4]> xor eax,eax push eax ; We need scratch space for MENUITEMINFO16 sub sp, MENUITEMINFO16_SIZE movzx edi, sp ; Push 16bit parms push word ptr bp_hMenu push word ptr bp_nIndex push word ptr bp_fByPosition ; Is lpMiim32 NULL? mov eax, dword ptr bp_lpMiim32 test eax, eax jnz ConvertMiim push eax jmp MakeCall ConvertMiim: push ss push di ; HACK ; If MIIM_TYPE is specified in the mask for a 95-sized structure, we ; need to add MIIM_STRING and MIIM_BITMAP to the mask so that we fill ; those fields mov es, FlatData mov esi, bp_lpMiim32 .errnz mii_32_fType - mii_32_cbSize - 8 mov ecx, dword ptr es:[esi+4] test cx, 00010h ; if (fMask & MIIM_TYPE) jz @F or cx, 001C0h ; fMask |= MIIM_FTYPE | mov dword ptr es:[esi+4], ecx ; MIIM_STRING | MIIM_BITMAP @@: ; Convert MENUITEMINFO LS push esi push di lea ax, bp_SavePtr push ax call ConvertMenuItemInfoLS MakeCall: call GetMenuItemInfo32 cwde ; Save return value push eax ; Is bp_lpMiim32 NULL? mov eax, bp_lpMiim32 test eax, eax jz GetDone mov es, FlatData ; DO THIS FIRST: FlatData is DS-relative push ds mov cx, ss mov ds, cx mov esi, edi mov edi, eax ; DO THIS LAST: We need to move DI to SI first cld ; cbSize - skip it add esi, 4 add edi, 4 ;fMask - save it lodsd ds:[esi] mov ecx, eax add edi, 4 ;fType xor eax, eax ;Zero out HIWORD lodsw ds:[esi] mov edx, eax ; save fType stosd es:[edi] ;fState,wID,hSubMenu,hbmpChecked,hbmpUnchecked push ecx ncopyzx 5 pop ecx ;dwItemData copyd test cx, 00010h ; if (!(fMask & MIIM_TYPE)) jz SkipTypeData ; goto SkipTypeData mov eax,es:[edi-020h] and ax,0FE3Fh ; fMask &= ~(MIIM_FTYPE | MIIM_STRING | mov es:[edi-020h],eax ; MIIM_BITMAP); xor eax,eax mov ax,ds:[esi+006h] or ax,ax ; if (!lpmii16->hbmpItem) jz CheckString ; goto CheckString stosd es:[edi] ; lpmii32->dwTypeData = lpmii16->hbmpItem or dx, 00004h ; lpmii32->fType |= MFT_BITMAP mov es:[edi-020h], edx jmp MenuItemCch CheckString: mov ax,ds:[esi+004h] or ax,ax ; if (!lpmii16->cch) jz ZeroTypeData ; goto ZeroTypeData SkipTypeData: add esi, 4 ; it's a string -- so leave it as is add edi, 4 jmp MenuItemCch ZeroTypeData: add esi, 4 xor eax,eax stosd es:[edi] MenuItemCch: copyzx ; Check hbmpItem test cx, 00010h ; if ((fMask & MIIM_TYPE)) jnz MenuItemEnd ; skip hbmpItem mov eax,es:[edi-02ch] cmp eax, 030h ; if old MENUITEMINFO jc MenuItemEnd ; skip hbmpItem mov eax,es:[edi-028h] test ax,080h ; if not MIIM_BITMAP jz MenuItemEnd ; skip hbmpItem copyzx ; copy hbmpItem MenuItemEnd: pop ds ; Unmap pointer since we mapped dwTypeData no matter what! push dword ptr bp_SavePtr call UnmapLS GetDone: ; Restore return value pop eax endm ;------------------------------------------------------------------------------ ; RET__GETDLGITEMINT ; ; Either zero-extend or sign-extend ax into eax, depending on ; the value of the "bSigned" argument. ;------------------------------------------------------------------------------ RET__GETDLGITEMINT macro local exit local unsigned cmp word ptr [bp_top + 12],0 ; bSigned je unsigned cwde jmp exit unsigned: movzx eax,ax exit: endm ;RET__GETDLGITEMINT ;============================================================================== ; ; mouse_event ; ;============================================================================== body_MOUSE_EVENT macro bp_dwFlags equ bp_dx equ bp_dy equ bp_cButtons equ bp_dwExtraInfo equ mov ax,word ptr bp_dwFlags mov bx,word ptr bp_dx mov cx,word ptr bp_dy mov dx,word ptr bp_cButtons mov si,word ptr bp_dwExtraInfo mov di,word ptr bp_dwExtraInfo+2 call mouse_event endm ;============================================================================== ; ; keybd_event ; ;============================================================================== body_KEYBD_EVENT macro bp_dwVirtualKey equ bp_dwScanCode equ bp_dwFlags equ bp_dwExtraInfo equ xor ax,ax xor bx,bx mov al,byte ptr bp_dwVirtualKey test word ptr bp_dwFlags,KEYEVENTF_KEYUP jz keybd_keydown mov ah,80 keybd_keydown: mov bl,byte ptr bp_dwScanCode test word ptr bp_dwFlags,KEYEVENTF_EXTENDEDKEY jz keybd_notextendedkey mov bh,1 keybd_notextendedkey: mov si,word ptr bp_dwExtraInfo mov di,word ptr bp_dwExtraInfo+2 call keybd_event endm ;============================================================================== ; ; AlignRects() ; ;============================================================================== body_ALIGNRECTS macro local done local ar_loop1 local ar_loop2 bp_lprect equ bp_count equ bp_iPrimary equ bp_flags equ bp_hmem16Tmp equ < word ptr [bp-2]> bp_Ret equ < word ptr [bp-4]> bp_lprectTmp equ < dword ptr [bp-8]> xor eax,eax push eax push eax mov eax,bp_count ;prepare for error test eax,eax jz done push byte ptr GPTR shl eax, 3 push eax call GlobalAlloc ;if no scratch space, return no hmenu movzx eax,ax ;prepare for error test ax,ax jz done mov bp_hmem16Tmp,ax push dword ptr bp_lprect call MapLS ;PLUGGED mov dword ptr bp_lprectTmp,eax movzx edi, ax mov ax,dx mov es, bp_hmem16Tmp xor esi,esi mov ecx,bp_count shl ecx, 2 push ecx push edi push esi push ax push es push ds mov ds, ax cld ar_loop1: lodsd ds:[esi] stosw es:[di] loop ar_loop1 pop ds push bp_hmem16Tmp ;cannot be null push 0 push word ptr bp_count push word ptr bp_iPrimary push word ptr bp_flags call CleanUpDesktopRectangles mov bp_Ret,ax pop ax pop es pop edi pop esi pop ecx push ds mov ds, ax cld ar_loop2: lodsw ds:[si] cwde stosd es:[edi] loop ar_loop2 pop ds push bp_hmem16Tmp ;cannot be null call GlobalFree push dword ptr bp_lprectTmp call UnMapLS movzx eax, bp_Ret done: endm ;============================================================================== ; ; FlashWindowEx() ; ;============================================================================== body_FLASHWINDOWEX macro local done bp_lpfw equ bp_fwSave equ < word ptr [bp-2]> xor eax,eax push eax ; lpfw->cbSize, lpfw->hwnd push eax ; lpfw->dwFlags push eax ; lpfw->uCount mov esi,bp_lpfw test esi,esi ;;if zero, just push it jz done mov es,FlatData mov ecx, es:[esi] ; get fw32_cbSize to ecx cmp cx, size FLASHWINFO32 jnz done add esi, 4 mov di, sp mov ss:[di].fw16_cbSize, (size FLASHWINFO16) lodsd es:[esi] ; get fw32_hwnd to eax mov ss:[di].fw16_hwnd, ax lodsd es:[esi] ; get fw32_dwFlags to eax mov ss:[di].fw16_dwFlags, eax lodsd es:[esi] ; get fw32_uCount to eax mov ss:[di].fw16_uCount, ax push ss push di call FlashWindowEx done: endm endif ;IS_16