;++ ; ; WOW v1.0 ; ; Copyright (c) 1991, Microsoft Corporation ; ; USER.ASM ; Win16 USER thunks ; ; History: ; ; Created 25-Jan-1991 by Jeff Parsons (jeffpar) ; Added Win 31 thunks 22nd-March-1992 by Chandan S. Chauhan (ChandanC) ; ;-- TITLE USER.ASM PAGE ,132 ; Some applications require that USER have a heap. This means ; we must always have: LIBINIT equ 1 LIBINIT equ 1 .286p .xlist include wow.inc include wowusr.inc include cmacros.inc NOEXTERNS=1 ; to suppress including most of the stuff in user.inc include user.inc .list __acrtused = 0 public __acrtused ;satisfy external C ref. ifdef LIBINIT externFP LocalInit endif externFP LW_InitNetInfo ifndef WOW externNP LW_DriversInit endif externFP GetModuleHandle externFP SetTaskSignalProc externFP NewSignalProc externFP IsWindow externFP CreateQueue externFP WOW16Call externFP TileWindows externFP CascadeWindows createSeg _TEXT,CODE,WORD,PUBLIC,CODE createSeg _DATA,DATA,WORD,PUBLIC,DATA,DGROUP defgrp DGROUP,DATA sBegin DATA DontMove db 2 dup (0) ; <<< WARNING 2 bytes *must* be reserved at the start ; users DS for compatability >>>> Reserved db 16 dup (0) ;reserved for Windows USER_Identifier db 'USER16 Data Segment' fFirstApp db 1 externD LPCHECKMETAFILE; ExternW ExternW GlobalW hwndSysModal,0 sEnd DATA ; ; GP fault exception handler table definition ; sBegin GPFIX0 __GP label word public __GP sEnd GPFIX0 sBegin CODE assumes CS,CODE assumes DS,DATA assumes ES,NOTHING ifdef LIBINIT externFP LibMain endif ifdef WOW externFP EnableSystemTimers externFP SetDivZero endif cProc USER16, cBegin ifdef WOW call EnableSystemTimers endif IFDEF LIBINIT ; push params and call user initialisation code push di ;hModule mov hInstanceWin, di ; if we have a local heap declared then initialize it jcxz no_heap push 0 ;segment push 0 ;start push cx ;length call LocalInit no_heap: call LibMain ;return exit code from LibMain ELSE mov ax,1 ;are we dressed for success or WHAT?! ENDIF push ax cmp hInstanceWin, 0 jne hInstNotNull mov hInstanceWin, di hInstNotNull: ifndef WOW call LW_DriversInit endif pop ax ret cEnd cProc InitApp, parmW hInst ; App's hInstance cBegin mov ax,8 ; MAGIC Win3.1 default message queue size push ax ; NOTE Win3.1 (and User32) read the size call CreateQueue ; from win.ini, we don't. cmp ax,0 ; hq jne IA_HaveQ mov ax,0 ; return FALSE jmp IA_Ret IA_HaveQ: push ds mov ax, _DATA ; set USER16's DS mov ds,ax assumes ds, DATA xor dx,dx push dx push seg NewSignalProc push offset NewSignalProc call SetTaskSignalProc ; ; Init WNET apis. ; cmp fFirstApp, 1 jne IA_notfirstapp mov fFirstApp, 0 call LW_InitNetInfo IA_notfirstapp: ; ; Setup Divide By Zero handler ; call SetDivZero mov ax,1 xor dx,dx pop ds IA_Ret: cEnd assumes DS,NOTHING cProc WEP, parmW iExit ;DLL exit code cBegin mov ax,1 ;always indicate success cEnd ;*--------------------------------------------------------------------------* ;* ;* LFillStruct() - ;* ;*--------------------------------------------------------------------------* cProc LFillStruct, , parmD lpStruct parmW cb parmW fillChar cBegin les di,lpStruct mov cx,cb mov ax,fillChar cld rep stosb cEnd ;*--------------------------------------------------------------------------* ;* * ;* GetSysModalWindow() - * ;* * ;*--------------------------------------------------------------------------* cProc GetSysModalWindow, cBegin nogen mov ax,_DATA nop mov es,ax mov ax,es:[hwndSysModal] or ax,ax jz GSMW_ItsZero push es push ax ; make sure we only return valid call IsWindow ; windows. pop es or ax,ax jnz GSMW_ItsNotZero mov es:[hwndSysModal], ax ; zero out hwndSysModal GSMW_ItsNotZero: mov ax,es:[hwndSysModal] GSMW_ItsZero: retf cEnd nogen ;*--------------------------------------------------------------------------* ;* * ;* SetSysModalWindow() - * ;* * ;*--------------------------------------------------------------------------* cProc ISetSysModalWindow, ParmW hwnd cBegin nogen mov ax,_DATA nop mov es,ax mov bx,sp mov ax,ss:[bx+4] xchg ax,es:[hwndSysModal] retf 2 cEnd nogen ; ; The DWPBits table defines which messages have actual processing for ; DefWindowProc. We get these bits from user32. User32 assumes the ; buffer passed in is zero-initialized, hence the DUP(0) below. ; DWPBits DB 101 DUP(0) ; Room for bits for msgs 0 - 807 (decimal) public DWPBits cbDWPBits DW ($ - codeoffset DWPBits) public cbDWPBits MaxDWPMsg DW 0 public MaxDWPMsg ;*--------------------------------------------------------------------------* ;* ;* CheckDefWindowProc() ;* ;* Checks to see if the message gets processed by DefWindowProc. If not, ;* the API returns 0. ;* ;*--------------------------------------------------------------------------* ALIGN 4 cProc CheckDefWindowProc, parmW hWnd parmW wMsg parmW wParam parmD lParam parmD lpReturn ; Callers Return Address ;parmW wBP ; Thunk saved BP ;parmW wDS ; Thunk saved DS cBegin mov bx,wMsg cmp bx,cs:MaxDWPMsg ja @f ; jump if above (return with 0) mov cx,bx shr bx,3 ; make byte index into table mov al,cs:[bx+DWPBits] ; get proper 8-bits and cx,0007H shr al,cl ; get proper bit into bit 0 of al test al,1 jz @f mov sp,bp ; Do cEnd without Ret count (leave parameters there) pop bp ret @@: pop bp xor ax,ax ; return (ULONG)0 to flag no window processing add sp,2 ; skip thunk IP xor dx,dx ; return (ULONG)0 to flag no window processing retf 10 ; 10 bytes to pop cEnd UserThunk ADJUSTWINDOWRECT UserThunk ADJUSTWINDOWRECTEX ; Hack to use original IDs. These functions have local implementations ; that thunk to Win32 if the locale is other than U.S. English. FUN_WIN32ANSILOWER equ FUN_ANSILOWER FUN_WIN32ANSILOWERBUFF equ FUN_ANSILOWERBUFF FUN_WIN32ANSINEXT equ FUN_ANSINEXT FUN_WIN32ANSIPREV equ FUN_ANSIPREV FUN_WIN32ANSIUPPER equ FUN_ANSIUPPER FUN_WIN32ANSIUPPERBUFF equ FUN_ANSIUPPERBUFF DUserThunk WIN32ANSILOWER, %(size ANSILOWER16) DUserThunk WIN32ANSILOWERBUFF, %(size ANSILOWERBUFF16) DUserThunk WIN32ANSINEXT, %(size ANSINEXT16) DUserThunk WIN32ANSIPREV, %(size ANSIPREV16) DUserThunk WIN32ANSIUPPER, %(size ANSIUPPER16) DUserThunk WIN32ANSIUPPERBUFF, %(size ANSIUPPERBUFF16) DUserThunk ANYPOPUP,0 UserThunk APPENDMENU UserThunk ARRANGEICONICWINDOWS DUserThunk BEGINDEFERWINDOWPOS UserThunk BEGINPAINT UserThunk BRINGWINDOWTOTOP UserThunk BROADCASTMESSAGE UserThunk BUILDCOMMDCB ;;; UserThunk BUTTONWNDPROC ;LOCALAPI in wsubcls.c DUserThunk CALCCHILDSCROLL UserThunk CALLMSGFILTER UserThunk CALLWINDOWPROC UserThunk CARETBLINKPROC UserThunk CHANGECLIPBOARDCHAIN UserThunk CHANGEMENU UserThunk CHECKDLGBUTTON UserThunk CHECKMENUITEM UserThunk CHECKRADIOBUTTON UserThunk CHILDWINDOWFROMPOINT UserThunk CLEARCOMMBREAK UserThunk CLIPCURSOR DUserThunk CLOSECLIPBOARD,0 FUN_WOWCLOSECOMM EQU FUN_CLOSECOMM DUserThunk WOWCLOSECOMM %(size CLOSECOMM16) UserThunk CLOSEWINDOW ;;; UserThunk COMBOBOXCTLWNDPROC ;LOCALAPI in wsubcls.c UserThunk COMPUPDATERECT UserThunk COMPUPDATERGN DUserThunk CONTROLPANELINFO UserThunk CONTSCROLL ;;; UserThunk COPYRECT ; LOCALAPI in winrect.asm DUserThunk COUNTCLIPBOARDFORMATS,0 UserThunk CREATECARET UserThunk CREATECURSOR DUserThunk CREATECURSORICONINDIRECT ; UserThunk CREATEDIALOG ; defined in fastres.c ; UserThunk CREATEDIALOGINDIRECT ; UserThunk CREATEDIALOGINDIRECTPARAM ;FUN_WOWCREATEDIALOGPARAM EQU FUN_CREATEDIALOGPARAM ; DUserThunk WOWCREATEDIALOGPARAM, %(size CREATEDIALOGPARAM16) UserThunk CREATEICON DUserThunk CREATEMENU,0 DUserThunk CREATEPOPUPMENU,0 UserThunk CREATEWINDOW UserThunk CREATEWINDOWEX DUserThunk DCHOOK UserThunk DEFDLGPROC UserThunk DEFERWINDOWPOS UserThunk DEFFRAMEPROC UserThunk DEFMDICHILDPROC PUserThunk DEFWINDOWPROC,CheckDefWindowProc .386p LabelFP xor edx, edx pop eax ; save caller's return addr push edx ; lpRect == NULL push dx ; chwnd == 0 push edx ; ahwnd == NULL push eax jmp CascadeWindows LabelFP xor edx, edx pop eax ; save caller's return addr push edx ; lpRect == NULL push dx ; chwnd == 0 push edx ; ahwnd == NULL push eax jmp TileWindows .286p ; From Win 3.1 final inentry.asm - mattfe ;========================================================================= ; OldExitWindows() ; ; This function is at the same ordinal value as the old 2.x ExitWindows. This ; does nothing more than terminate the app. If it is the only app running the ; system will go away too. LabelFP mov ax,4c00h int 21h retf ; just in case the int21 returns... sEnd CODE end USER16