diff options
Diffstat (limited to '')
-rw-r--r-- | private/mvdm/wow32/wuman.c | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/private/mvdm/wow32/wuman.c b/private/mvdm/wow32/wuman.c new file mode 100644 index 000000000..46763a589 --- /dev/null +++ b/private/mvdm/wow32/wuman.c @@ -0,0 +1,287 @@ +/*++ + * + * WOW v1.0 + * + * Copyright (c) 1991, Microsoft Corporation + * + * WUMAN.C + * WOW32 16-bit User API support (manually-coded thunks) + * + * History: + * Created 27-Jan-1991 by Jeff Parsons (jeffpar) +--*/ + + +#include "precomp.h" +#pragma hdrstop + +MODNAME(wuman.c); + +WBP W32WordBreakProc = NULL; + +extern DWORD fThunkStrRtns; + + +/* Called By Kernel When Initialization is Complete */ + +ULONG FASTCALL WU32FinalUserInit(PVDMFRAME pFrame) +{ + UNREFERENCED_PARAMETER(pFrame); + return TRUE; +} + + +ULONG FASTCALL WU32ExitWindows(PVDMFRAME pFrame) +// BUGBUG mattfe 4-mar-92, this routine should not return if we close down +// all the apps successfully. +{ + ULONG ul; + register PEXITWINDOWS16 parg16; + + GETARGPTR(pFrame, sizeof(EXITWINDOWS16), parg16); + + ul = GETBOOL16(ExitWindows( + DWORD32(parg16->dwReserved), + WORD32(parg16->wReturnCode) + )); + + FREEARGPTR(parg16); + + RETURN(ul); +} + +WORD gUser16CS = 0; + +ULONG FASTCALL WU32NotifyWow(PVDMFRAME pFrame) +{ + ULONG ul; + register PNOTIFYWOW16 parg16; + + GETARGPTR(pFrame, sizeof(NOTIFYWOW16), parg16); + + switch (FETCHWORD(parg16->Id)) { + case FUN_LOADACCELERATORS: + ul = WU32LoadAccelerators(FETCHDWORD(parg16->pData)); + break; + + case FUN_LOADICON: + case FUN_LOADCURSOR: + ul = (ULONG) W32CheckIfAlreadyLoaded(parg16->pData, FETCHWORD(parg16->Id)); + break; + + case FUN_WINHELP: + { + // this call is made from IWinHelp in USER.exe to find the + // '16bit' help window if it exists. + // + + LPSZ lpszClass; + GETMISCPTR(parg16->pData, lpszClass); + ul = (ULONG)(pfnOut.pfnWOWFindWindow)((LPCSTR)lpszClass, (LPCSTR)NULL); + if (ul) { + // check if hwndWinHelp belongs to this process or not. + DWORD pid, pidT; + pid = pidT = GetCurrentProcessId(); + GetWindowThreadProcessId((HWND)ul, &pid); + ul = (ULONG)MAKELONG((WORD)GETHWND16(ul),(WORD)(pid == pidT)); + } + FREEMISCPTR(lpszClass); + } + break; + + case FUN_FINALUSERINIT: + { + static BYTE CallCsrFlag = 0; + extern DWORD gpsi; + PUSERCLIENTGLOBALS pfinit16; + WORD UNALIGNED *pwMaxDWPMsg; + PBYTE pDWPBits; +#ifdef DEBUG + WORD wMsg; + int i; + PSZ pszFormat; +#endif + + GETVDMPTR(parg16->pData, sizeof(USERCLIENTGLOBALS), pfinit16); + GETVDMPTR(pfinit16->lpwMaxDWPMsg, sizeof(WORD), pwMaxDWPMsg); + GETVDMPTR(pfinit16->lpDWPBits, pfinit16->cbDWPBits, pDWPBits); + + // store the 16bit hmod of user.exe + gUser16hInstance = (WORD)pfinit16->hInstance; + WOW32ASSERTMSGF((gUser16hInstance), + ("WOW Error gUser16hInstance == NULL!\n")); + + // store the 16bit CS of user.exe + gUser16CS = HIWORD(pFrame->vpCSIP); + + // initialize user16client globals + + if (pfinit16->lpgpsi) { + BYTE **lpT; + GETVDMPTR(pfinit16->lpgpsi, sizeof(DWORD), lpT); + *lpT = (BYTE *)gpsi; + FLUSHVDMCODEPTR((ULONG)pfinit16->lpgpsi, sizeof(DWORD), lpT); + FREEVDMPTR(lpT); + } + if (pfinit16->lpCsrFlag) { + BYTE **lpT; + GETVDMPTR(pfinit16->lpCsrFlag, sizeof(DWORD), lpT); + *lpT = (LPSTR)&CallCsrFlag; + FLUSHVDMCODEPTR((ULONG)pfinit16->lpCsrFlag, sizeof(DWORD), lpT); + FREEVDMPTR(lpT); + } + + if (HIWORD(pfinit16->dwBldInfo) != HIWORD(pfnOut.dwBldInfo)) { + MessageBeep(0); + MessageBoxA(NULL, "user.exe and user32.dll are mismatched.", + "WOW Error", MB_OK | MB_ICONEXCLAMATION); + } + + *pwMaxDWPMsg = (pfnOut.pfnWowGetDefWindowProcBits)(pDWPBits, pfinit16->cbDWPBits); + + FLUSHVDMCODEPTR(pfinit16->lpwMaxDWPMsg, sizeof(WORD), pwMaxDWPMsg); + FLUSHVDMCODEPTR(pfinit16->lpDWPBits, pfinit16->cbDWPBits, pDWPBits); + +#ifdef DEBUG + LOGDEBUG(LOG_TRACE, ("WU32NotifyWow: got DefWindowProc bits, wMaxDWPMsg = 0x%x.\n", *pwMaxDWPMsg)); + LOGDEBUG(LOG_TRACE, ("The following messages will be passed on to 32-bit DefWindowProc:\n")); + +#define FPASSTODWP32(msg) \ + (pDWPBits[msg >> 3] & (1 << (msg & 7))) + + wMsg = 0; + i = 0; + + while (wMsg <= *pwMaxDWPMsg) { + if (FPASSTODWP32(wMsg)) { + if ( i & 3 ) { + pszFormat = ", %s"; + } else { + pszFormat = "\n%s"; + } + LOGDEBUG(LOG_TRACE, (pszFormat, aw32Msg[wMsg].lpszW32)); + i++; + } + wMsg++; + } + + LOGDEBUG(LOG_TRACE, ("\n\n")); +#endif + + // + // Return value tells User16 whether to thunk + // string routines to Win32 or use the fast + // US-only versions. TRUE means thunk. + // + // If the locale is U.S. English, we default to + // not thunking, outside the U.S. we default to + // thunking. See wow32.c's use of fThunkStrRtns. + // + // We engage in this nastiness because the Winstone 94 + // Access 1.1 test takes *twice* as long to run in + // the US if we thunk lstrcmp and lstrcmpi to Win32. + // + // By adding a value "ThunkNLS" to the WOW registry + // key of type REG_DWORD, the user can force thunking + // to Win32 (value 1) or use the fast US-only ones (value 0). + // + + ul = fThunkStrRtns; + + FREEVDMPTR(pDWPBits); + FREEVDMPTR(pwMaxDWPMsg); + FREEVDMPTR(pfinit16); + + } + break; + + default: + ul = 0; + break; + } + + FREEARGPTR(parg16); + return ul; +} + + +ULONG FASTCALL WU32WordBreakProc(PVDMFRAME pFrame) +{ + PSZ psz1; + ULONG ul; + register PWORDBREAKPROC16 parg16; + + GETARGPTR(pFrame, sizeof(WORDBREAKPROC16), parg16); + GETPSZPTR(parg16->lpszEditText, psz1); + + ul = (*W32WordBreakProc)(psz1, parg16->ichCurrentWord, parg16->cbEditText, + parg16->action); + + FREEPSZPTR(psz1); + FREEARGPTR(parg16); + RETURN(ul); +} + +// +// WU32MouseEvent: Thunk for 16-bit register-based API mouse_event, +// with the help of user16 function mouse_event (in +// winmisc2.asm). +// + +ULONG FASTCALL WU32MouseEvent(PVDMFRAME pFrame) +{ + ULONG ul; + register PMOUSEEVENT16 parg16; + typedef ULONG (WINAPI *PFMOUSE_EVENT)(DWORD, DWORD, DWORD, DWORD, DWORD); + + GETARGPTR(pFrame, sizeof(PMOUSEEVENT16), parg16); + + // + // mouse_event is declared void, but we'll return the same value as + // user32. + // + + ul = ((PFMOUSE_EVENT)(PVOID)mouse_event)( + parg16->wFlags, + parg16->dx, + parg16->dy, + parg16->cButtons, + parg16->dwExtraInfo + ); + + FREEARGPTR(parg16); + RETURN(ul); +} + + + +// +// WU32KeybdEvent: Thunk for 16-bit register-based API keybd_event, +// with the help of user16 function keybd_event (in +// winmisc2.asm). +// + +ULONG FASTCALL WU32KeybdEvent(PVDMFRAME pFrame) +{ + ULONG ul; + register PKEYBDEVENT16 parg16; + typedef ULONG (WINAPI *PFKEYBD_EVENT)(BYTE, BYTE, DWORD, DWORD); + + GETARGPTR(pFrame, sizeof(PKEYBDEVENT16), parg16); + + // + // keybd_event is declared void, but we'll return the same value as + // user32. + // + + ul = ((PFKEYBD_EVENT)(PVOID)keybd_event)( + LOBYTE(parg16->bVirtualKey), + LOBYTE(parg16->bScanCode), + ((HIBYTE(parg16->bVirtualKey) == 0x80) ? KEYEVENTF_KEYUP : 0) | + ((HIBYTE(parg16->bScanCode) == 0x1) ? KEYEVENTF_EXTENDEDKEY : 0), + parg16->dwExtraInfo + ); + + FREEARGPTR(parg16); + RETURN(ul); +} |