|
|
/*++
* * WOW v1.0 * * Copyright (c) 1991, Microsoft Corporation * * WMDISP32.C * WOW32 32-bit message thunks * * History: * Created 19-Feb-1992 by Chandan S. Chauhan (ChandanC) * Changed 12-May-1992 by Mike Tricker (MikeTri) Added MultiMedia thunks * Changed 09-Jul-1992 by v-cjones Added msg profiling debugger extension --*/
#include "precomp.h"
#pragma hdrstop
#ifdef FE_IME
#include "wownls.h"
#include "ime.h"
#include "prshtp.h"
#endif // FE_IME
MODNAME(wmdisp32.c);
BOOL fThunkDDEmsg = TRUE;
extern WORD msgFINDREPLACE; // see WCOMMDLG.C
#ifdef WOWPROFILE // for MSG profiling only (debugger extension)
INT fWMsgProfRT = 0; #endif
BOOL W32Win16DlgProcEx(HWND hdlg, UINT uMsg, UINT uParam, LONG lParam, VPWNDPROC vpDlgProc16, // Next WndProc to call or NULL if default
PWW pww) // hwnd's PWW if already known or NULL
{ BOOL fSuccess; register PTD ptd; WM32MSGPARAMEX wm32mpex; BOOL fMessageNeedsThunking;
#ifdef WOWPROFILE // for MSG profiling only (debugger extension)
DWORD dwTics; #endif
ptd = CURRENTPTD();
WOW32ASSERT(vpDlgProc16);
// take out the marker bits and fix the RPL bits
UnMarkWOWProc (vpDlgProc16,vpDlgProc16);
// If the app has GP Faulted we don't want to pass it any more input
// This should be removed when USER32 does clean up on task death so
// it doesn't call us - mattfe june 24 92 HACK32
if (ptd->dwFlags & TDF_IGNOREINPUT) { LOGDEBUG(6,(" W32Dlg16WndProc Ignoring Input Messsage %04X\n",uMsg)); WOW32ASSERTMSG(gfIgnoreInputAssertGiven, "W32Dlg16WndProc: TDF_IGNOREINPUT hack was used, shouldn't be, " "please email DaveHart with repro instructions. Hit 'g' to ignore this " "and suppress this assertion from now on.\n"); gfIgnoreInputAssertGiven = TRUE; return FALSE; }
wm32mpex.Parm16.WndProc.hwnd = GETHWND16(hdlg); wm32mpex.Parm16.WndProc.wMsg = (WORD)uMsg; wm32mpex.Parm16.WndProc.wParam = (WORD)uParam; wm32mpex.Parm16.WndProc.lParam = (LONG)lParam; wm32mpex.Parm16.WndProc.hInst = 0; // Forces AX = SS on WndProc entry,
// for Win 3.1 compatibility.
fMessageNeedsThunking = (uMsg < 0x400) && (aw32Msg[uMsg].lpfnM32 != WM32NoThunking);
if (fMessageNeedsThunking) { LOGDEBUG(3,("%04X (%s)\n", CURRENTPTD()->htask16, (aw32Msg[uMsg].lpszW32)));
#ifdef WOWPROFILE // for MSG profiling only (debugger extension)
dwTics = GetWOWTicDiff(0L); #endif
wm32mpex.fThunk = THUNKMSG; wm32mpex.hwnd = hdlg; wm32mpex.uMsg = uMsg; wm32mpex.uParam = uParam; wm32mpex.lParam = lParam; wm32mpex.pww = pww; wm32mpex.fFree = TRUE; wm32mpex.lpfnM32 = aw32Msg[uMsg].lpfnM32; if (!(wm32mpex.lpfnM32)(&wm32mpex)) { LOGDEBUG(LOG_ERROR,(" W32Win16DlgProcEx ERROR: cannot thunk 32-bit message %04x\n", uMsg)); goto Error; }
#ifdef WOWPROFILE // for MSG profiling only (debugger extension)
if( !fWMsgProfRT ) { // only if not profiling round trip
aw32Msg[uMsg].cTics += GetWOWTicDiff(dwTics); } #endif
} else { LOGDEBUG(6,(" No Thunking was required for the 32-bit message %s(%04x)\n", (LPSZ)GetWMMsgName(uMsg), uMsg)); }
BlockWOWIdle(FALSE);
fSuccess = CallBack16(RET_WNDPROC, &wm32mpex.Parm16, vpDlgProc16, (PVPVOID)&wm32mpex.lReturn);
BlockWOWIdle(TRUE);
// the callback function of a dialog is of type FARPROC whose return value
// is of type 'int'. Since dx:ax is copied into lReturn in the above
// CallBack16 call, we need to zero out the hiword, otherwise we will be
// returning an erroneous value.
wm32mpex.lReturn = (LONG)((SHORT)(LOWORD(wm32mpex.lReturn)));
if (fMessageNeedsThunking) {
#ifdef WOWPROFILE // for MSG profiling only (debugger extension)
if( !fWMsgProfRT ) { // only if not round trip profiling
dwTics = GetWOWTicDiff(0L); } #endif // WOWPROFILE
//
// if you send a message to a dialog what gets returned
// to the caller is the dlg's msgresult window long.
// app dialog functions will call
// SetWindowLong(hdlg, DWL_MSGRESULT, n);
// during message processing so the right thing gets returned.
// scottlu says we only need to do this for wm_gettext, it's
// the only message whose result is an output count.
//
if (uMsg == WM_GETTEXT && wm32mpex.lReturn != 0) { wm32mpex.lReturn = GetWindowLong(hdlg, DWL_MSGRESULT); }
wm32mpex.fThunk = UNTHUNKMSG; (wm32mpex.lpfnM32)(&wm32mpex);
#ifdef WOWPROFILE // for MSG profiling only (debugger extension)
aw32Msg[uMsg].cTics += GetWOWTicDiff(dwTics); aw32Msg[uMsg].cCalls++; // increment # times message passed
#endif // WOWPROFILE
}
if (!fSuccess) goto Error;
Done:
return wm32mpex.lReturn;
Error: LOGDEBUG(6,(" W32Win16DlgProcEx WARNING: cannot call back, using default message handling\n")); wm32mpex.lReturn = 0; goto Done; }
LONG W32Win16WndProcEx(HWND hwnd, UINT uMsg, UINT uParam, LONG lParam, VPWNDPROC vpWndProc16, // Next WndProc to call or NULL if default
PWW pww) // hwnd's PWW if already known or NULL
{ BOOL fSuccess; LONG ulReturn; register PTD ptd; WM32MSGPARAMEX wm32mpex; BOOL fMessageNeedsThunking; //#ifdef DEBUG
// CHAR szClassName[80];
//#endif
#ifdef WOWPROFILE // for MSG profiling only (debugger extension)
DWORD dwTics; #endif
ptd = CURRENTPTD();
WOW32ASSERT(vpWndProc16);
// take out the marker bits and fix the RPL bits
UnMarkWOWProc (vpWndProc16,vpWndProc16);
//
// If the app has GP Faulted we don't want to pass it any more input
// This should be removed when USER32 does clean up on task death so
// it doesn't call us - mattfe june 24 92 HACK32
//
// It's not a problem if the callback is going to a 16:16 proc in user.exe
// like DefWindowProc.
//
if (ptd->dwFlags & TDF_IGNOREINPUT && HIWORD(vpWndProc16) != HIWORD(gpfn16GetProcModule)) {
LOGDEBUG(6,(" W32Win16WndProcEx Ignoring Input Messsage %04X\n",uMsg)); WOW32ASSERTMSG(gfIgnoreInputAssertGiven, "W32Win16WndProcEx: TDF_IGNOREINPUT hack was used, shouldn't be, " "please email DaveHart with repro instructions. Hit 'g' to ignore this " "and suppress this assertion from now on.\n"); gfIgnoreInputAssertGiven = TRUE; goto SilentError; }
//
// Don't send WM_DEVMODECHANGE if TDF_EATDEVMODEMSG is set
// access2.0 faults if it is in EnumMetaFile and receives WM_DEVMODECHANGE
// while in it whistler bug 189703
//
if (( ptd->dwFlags & TDF_EATDEVMODEMSG ) && ( uMsg == WM_DEVMODECHANGE )) { return 0; }
//
// Figure out the class for this hwnd if we haven't seen it before
//
if (!pww) { if (!(pww = (PWW) GetWindowLong(hwnd, GWL_WOWWORDS))) { LOGDEBUG(LOG_ALWAYS,("WOW :: W32Win16WndProcEx ERROR: GetWindowLong(0x%x, GWL_WOWWORDS) fails\n", hwnd)); goto Error; } } #ifdef FE_IME
if (( uMsg == WM_IME_REPORT ) && ( uParam == IR_STRINGEX )) { HANDLE hInstance;
hInstance = (HANDLE)(ULONG)GetWindowLong(hwnd, GWL_HINSTANCE); hInstance = (HANDLE)(ULONG)VALIDHMOD(hInstance); if (W32GetExpWinVer(hInstance) < 0x030a) return 0; }
//
// Don't dispatch Version 4.0 IMM Messages to 16bit apps.
//
// WM_IME_STARTCOMPOSITION 0x010D
// WM_IME_ENDCOMPOSITION 0x010E
// WM_IME_COMPOSITION 0x010F
// WM_IME_SETCONTEXT 0x0281
// WM_IME_NOTIFY 0x0282
// WM_IME_CONTROL 0x0283
// WM_IME_COMPOSITIONFULL 0x0284
// WM_IME_SELECT 0x0285
// WM_IME_CHAR 0x0286
// WM_IME_SYSTEM 0x0287
//
if ((( uMsg >= WM_IME_STARTCOMPOSITION ) && ( uMsg <= WM_IME_COMPOSITION )) || (( uMsg >= WM_IME_SETCONTEXT ) && (uMsg <= WM_IME_SYSTEM ))) {
// Korean Edit conrol need to dispatch new IMM messages.
if ( !(GetStdClassWndProc(WOWCLASS_EDIT) && GetSystemDefaultLangID()==0x412) ) { HANDLE hInstance; hInstance = (HANDLE)(ULONG)GetWindowLong(hwnd, GWL_HINSTANCE); hInstance = (HANDLE)(ULONG)VALIDHMOD(hInstance); if (W32GetExpWinVer(hInstance) < 0x0400) goto Error; } } #endif // FE_IME
// This message is WIN32 only. It is sent by WOW32 during the processing
// of an EM_SETSEL in WU32Send/PostMessage. If an MLE is subclassed the
// message will come through here attempting to travel back to the 16-bit
// app's wndproc. Instead of sending back a message that the 16-bit app
// doesn't understand it will be intercepted here and sent directly to the
// standard EditWindowProc. I'm not adding a Thunk because it shouldn't
// go to the app.
if (uMsg == EM_SCROLLCARET) { WNDPROC EditWndProc;
// find the 32-bit EditWindowProc
// We should only be in this state if the app has subclassed so this
// call should be safe.
EditWndProc = (WNDPROC)GetStdClassWndProc(WOWCLASS_EDIT);
if (EditWndProc) { CallWindowProc(EditWndProc, hwnd, EM_SCROLLCARET, 0, 0); } else { LOGDEBUG(LOG_ALWAYS,(" W32Win16WndProcEx ERROR: cannot find 32-bit EditWindowProc\n")); } return 0; // notification message, no return code
} // Thunk this 32 bit message to 16 bit message
LOGDEBUG(6,(" Thunking window %x message %s\n", hwnd, GetWMMsgName(uMsg))); #ifdef DEBUG
if((uMsg & WOWPRIVATEMSG) && ((uMsg & ~WOWPRIVATEMSG) < 0x400)) { LOGDEBUG(6,(" -- private WOW bit set for %s\n", GetWMMsgName(uMsg & ~WOWPRIVATEMSG))); } #endif
wm32mpex.Parm16.WndProc.hwnd = GETHWND16(hwnd); wm32mpex.Parm16.WndProc.wMsg = (WORD)uMsg; wm32mpex.Parm16.WndProc.wParam = (WORD)uParam; wm32mpex.Parm16.WndProc.lParam = (LONG)lParam; wm32mpex.Parm16.WndProc.hInst = LOWORD(pww->hModule);
// An app can send one of its private class windows a message say 401.
// This message will not be thunked in WMSG16.C because the
// messages >= 0x400 and we did not want to thunk it in WMSG16.C
//
fMessageNeedsThunking = (uMsg < 0x400) && (aw32Msg[uMsg].lpfnM32 != WM32NoThunking);
if (fMessageNeedsThunking) { LOGDEBUG(6,("%04X (%s)\n", ptd->htask16, (aw32Msg[uMsg].lpszW32)));
#ifdef WOWPROFILE // for MSG profiling only (debugger extension)
dwTics = GetWOWTicDiff(0L); #endif
wm32mpex.fThunk = THUNKMSG; wm32mpex.hwnd = hwnd; wm32mpex.uMsg = uMsg; wm32mpex.uParam = uParam; wm32mpex.lParam = lParam; wm32mpex.pww = pww; wm32mpex.fFree = TRUE; wm32mpex.lpfnM32 = aw32Msg[uMsg].lpfnM32; ulReturn = (wm32mpex.lpfnM32)(&wm32mpex);
#ifdef WOWPROFILE // for MSG profiling only (debugger extension)
if( !fWMsgProfRT ) { // only if not profiling round trip
aw32Msg[uMsg].cTics += GetWOWTicDiff(dwTics); } #endif
if (!ulReturn) { LOGDEBUG(LOG_ALWAYS,(" W32Win16WndProcEx ERROR: cannot thunk 32-bit message %s (%x)\n", GetWMMsgName(uMsg), uMsg)); goto Error; } }
if (vpWndProc16 == (VPVOID)NULL) { WOW32ASSERT(vpWndProc16); goto SilentError; }
LOGDEBUG(6,("16-bit Window Proc = %08lX\n", vpWndProc16));
BlockWOWIdle(FALSE);
fSuccess = CallBack16(RET_WNDPROC, &wm32mpex.Parm16, vpWndProc16, (PVPVOID)&wm32mpex.lReturn);
BlockWOWIdle(TRUE);
// During CreateWindow some apps draw their own non-client area and don't
// pass WM_NCCALCSIZE to DefWindowProc which causes Win 95 and NT's user to
// not set some needed window flags. Mavis Beacon is an example. We'll pass
// the message for them.
if (uMsg == WM_NCCALCSIZE) { if (CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_DEFWNDPROCNCCALCSIZE) { DefWindowProc(hwnd, uMsg, uParam, lParam); } }
// UnThunk this 32 bit message
LOGDEBUG(6,(" UnThunking window %x message %s\n", hwnd, (LPSZ)GetWMMsgName(uMsg))); #ifdef DEBUG
if((uMsg & WOWPRIVATEMSG) && ((uMsg - WOWPRIVATEMSG) < 0x400)) { LOGDEBUG(6,(" -- private WOW bit set for %s\n", (LPSZ)GetWMMsgName(uMsg))); } #endif
if (fMessageNeedsThunking) {
#ifdef WOWPROFILE // for MSG profiling only (debugger extension)
if( !fWMsgProfRT ) { // only if not profiling round trip
dwTics = GetWOWTicDiff(0L); } #endif
wm32mpex.fThunk = UNTHUNKMSG; (wm32mpex.lpfnM32)(&wm32mpex);
#ifdef WOWPROFILE // for MSG profiling only (debugger extension)
aw32Msg[uMsg].cTics += GetWOWTicDiff(dwTics); aw32Msg[uMsg].cCalls++; // increment # times message passed
#endif
}
if (!fSuccess) { goto Error; }
return (wm32mpex.lReturn);
Error: LOGDEBUG(LOG_ALWAYS,(" W32Win16WndProcEx ERROR: cannot call back, using default message handling\n")); SilentError: return DefWindowProc(hwnd, uMsg, uParam, lParam); }
// The following functions are used to "thunk" a 32 bit message to 16 bit
// message.
//
// To add a thunk function for a 32 bit message,
// - Modify the entry for the message in "aw32Msg" function array
// (in wmtbl32.c) to point to the new thunk function.
// - Define the new thunk function in this file.
//
// These messages do not require any thunking so just copy the 32 bit wParam
// and lParam to 16 bit wParam and lParam.
//
//
// WM_CANCELMODE
// WM_CHAR
// WM_CHILDACTIVATE
// WM_CLEAR
// WM_CLOSE
// WM_COMMNOTIFY
// WM_COMPACTING
// WM_COPY
// WM_CUT
// WM_DEADCHAR
// WM_DESTROY
// WM_DRAWCLIPBOARD
// WM_ENABLE
// WM_ENDSESSION
// WM_FONTCHANGE
// WM_GETFONT
// WM_GETTEXTLENGTH
// WM_HOTKEY
// WM_INPUTFOCUS
// WM_ISACTIVEICON (undocumented)
// WM_KEYDOWN
// WM_KEYUP
// WM_LBTRACKPOINT (undocumented)
// WM_LBUTTONDBLCLK
// WM_LBUTTONDOWN
// WM_LBUTTONUP
// WM_MBUTTONDBLCLK
// WM_MBUTTONDOWN
// WM_MBUTTONUP
// WM_MDICASCADE
// WM_MDIICONARRANGE
// WM_MDINEXT
// WM_MDITILE
// WM_MOUSEENTER
// WM_MOUSELEAVE
// WM_MOUSEMOVE
// WM_MOVE
// WM_NCCALCRGN
// WM_NCDESTROY
// WM_NCHITTEST
// WM_NCLBUTTONDBLCLK
// WM_NCLBUTTONDOWN
// WM_NCLBUTTONUP
// WM_NCMBUTTONDBLCLK
// WM_NCMBUTTONDOWN
// WM_NCMBUTTONUP
// WM_NCMOUSEMOVE
// WM_NCRBUTTONDBLCLK
// WM_NCRBUTTONDOWN
// WM_NCRBUTTONUP
// WM_PAINTICON
// WM_PASTE
// WM_POWER
// WM_QUERYENDSESSION
// WM_QUERYNEWPALETTE
// WM_QUERYOPEN
// WM_QUERYPARKICON (undocumented)
// WM_QUEUESYNC
// WM_QUIT
// WM_RBUTTONDBLCLK
// WM_RBUTTONDOWN
// WM_RBUTTONUP
// WM_RENDERALLFORMATS
// WM_RENDERFORMAT
// WM_SETREDRAW
// WM_SHOWWINDOW
// WM_SIZE
// WM_SPOOLERSTATUS (double-check lParam conversion on this one -JTP)
// WM_SYSCHAR
// WM_SYSCOLORCHANGE
// WM_SYSCOMMAND
// WM_SYSDEADCHAR
// WM_SYSKEYDOWN
// WM_SYSKEYUP
// WM_SYSTEMERROR
// WM_TIMECHANGE
// WM_UNDO
// MM_JOY1BUTTONDOWN - MultiMedia messages
// MM_JOY1BUTTONUP
// MM_JOY1MOVE
// MM_JOY1ZMOVE
// MM_JOY2BUTTONDOWN
// MM_JOY2BUTTONUP
// MM_JOY2MOVE
// MM_JOY2ZMOVE
// MM_MCINOTIFY - MultiMedia messages
BOOL FASTCALL WM32NoThunking(LPWM32MSGPARAMEX lpwm32mpex) {
#if 0
//
// this routine is never called! It's used as a placeholder.
// if you want to make a change here, you have to make the change
// to the places where we compare the thunk routine to WM32NoThunking
// and only call the thunk routine if it's not this. also make sure
// that this 'default' thunking happens for NoThunking messages.
//
if (lpwm32mpex->fThunk) { LOGDEBUG(6,(" No Thunking was required for the 32-bit message %s(%04x)\n", (LPSZ)GetWMMsgName(lpwm32mpex->uMsg), lpwm32mpex->uMsg));
lpwm32mpex->Parm16.WndProc.wMsg = (WORD)lpwm32mpex->uMsg; lpwm32mpex->Parm16.WndProc.wParam = (WORD)lpwm32mpex->uParam; lpwm32mpex->Parm16.WndProc.lParam = (LONG)lpwm32mpex->lParam; }
//
// this routine is never called! It's used as a placeholder.
// if you want to make a change here, you have to make the change
// to the places where we compare the thunk routine to WM32NoThunking
// and only call the thunk routine if it's not this.
//
#endif
//
// Return FALSE, so if for some reason this routine gets used
// the failure to thunk will be apparent.
//
return FALSE; }
#ifdef DEBUG // see the macro WM32UNDOCUMENTED
// These are undocumented messages for Win 3.0 so take a look at the app
// who is using them.
BOOL FASTCALL WM32Undocumented(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { LOGDEBUG(3,(" Window %08lX is receiving Undocumented Message %s\n", lpwm32mpex->hwnd, (LPSZ)GetWMMsgName(lpwm32mpex->uMsg), lpwm32mpex->uMsg));
lpwm32mpex->Parm16.WndProc.wMsg = (WORD)lpwm32mpex->uMsg; lpwm32mpex->Parm16.WndProc.wParam = (WORD)lpwm32mpex->uParam; lpwm32mpex->Parm16.WndProc.lParam = (LONG)lpwm32mpex->lParam; }
return (TRUE); }
#endif
// This function thunks the messages,
//
// WM_CREATE
// WM_NCCREATE
//
BOOL FASTCALL WM32Create(LPWM32MSGPARAMEX lpwm32mpex) {
INT cb; VPVOID vpClass = 0; VPVOID vpName = 0; VPVOID vpCreateParams = 0; register PCREATESTRUCT16 pcws16; LPCREATESTRUCT lParam = (LPCREATESTRUCT) lpwm32mpex->lParam;
if (lpwm32mpex->fThunk) {
if (HIWORD(lParam)) {
// BUGBUG -- The assumption here is that GlobalAlloc will never
// return a memory object that isn't word-aligned, so that we can
// assign word-aligned words directly; we have no idea whether the
// memory is dword-aligned or not however, so dwords must always
// be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
if (lParam->lpszClass) { if ( HIWORD(lParam->lpszClass) == 0 ) { vpClass = (VPVOID)lParam->lpszClass; } else { cb = strlen(lParam->lpszClass)+1; if (!(vpClass = malloc16(cb))) goto Error; putstr16(vpClass, lParam->lpszClass, cb); } }
if (lParam->lpszName) { cb = strlen(lParam->lpszName)+1; if (!(vpName = malloc16(cb))) goto Error; putstr16(vpName, lParam->lpszName, cb); }
if (lpwm32mpex->pww == NULL) { lpwm32mpex->pww = (PWW)GetWindowLong(lpwm32mpex->hwnd, GWL_WOWWORDS); if (lpwm32mpex->pww == NULL) return FALSE; // Window is dead
}
if (lParam->lpCreateParams && (lpwm32mpex->pww->ExStyle & WS_EX_MDICHILD) ) { // This works because wm32mdicreate thunk doesn't use any
// parameters except lParam
WM32MSGPARAMEX wm32mpexT; wm32mpexT.fThunk = lpwm32mpex->fThunk; wm32mpexT.hwnd = lpwm32mpex->hwnd; wm32mpexT.uMsg = WM_MDICREATE; wm32mpexT.uParam = lpwm32mpex->uParam; wm32mpexT.lParam = (LONG)lParam->lpCreateParams; wm32mpexT.pww = lpwm32mpex->pww; wm32mpexT.fFree = lpwm32mpex->fFree; wm32mpexT.Parm16.WndProc.lParam = 0; WM32MDICreate(&wm32mpexT); lpwm32mpex->dwParam = wm32mpexT.dwParam; vpCreateParams = wm32mpexT.Parm16.WndProc.lParam; } else { vpCreateParams = (VPVOID)lParam->lpCreateParams; }
// be sure allocation size matches stackfree16() size below
if (!(lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(CREATESTRUCT16)))) return FALSE;
GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(CREATESTRUCT16), pcws16);
STOREDWORD(pcws16->vpszClass, vpClass); STOREDWORD(pcws16->vpszWindow, vpName); STOREDWORD(pcws16->vpCreateParams, vpCreateParams);
lpwm32mpex->dwTmp[0] = vpClass; // store for later freeing
lpwm32mpex->dwTmp[1] = vpName;
// BUGBUG 08-Apr-91 JeffPar -- What if hModule is for a 32-bit task?
pcws16->hInstance = GETHINST16(lParam->hInstance); pcws16->hMenu = GETHMENU16(lParam->hMenu); pcws16->hwndParent = GETHWND16(lParam->hwndParent); pcws16->cy = (SHORT)lParam->cy; pcws16->cx = (SHORT)lParam->cx; pcws16->y = (SHORT)lParam->y; pcws16->x = (SHORT)lParam->x; STOREDWORD(pcws16->dwStyle, lParam->style); STOREDWORD(pcws16->dwExStyle, lParam->dwExStyle);
FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(CREATESTRUCT16), pcws16); FREEVDMPTR(pcws16);
return TRUE;
Error: LOGDEBUG(LOG_ALWAYS,(" !!!! WM32Create, WM_CREATE thunking failed !!!! Window %08lX ", lpwm32mpex->hwnd)); if (HIW(vpClass)) free16(vpClass); if (vpName) free16(vpName); return (FALSE);
// do some clean up
// UnThunkWMCreate32(lParam, lpwm32mpex->Parm16.WndProc.lParam);
} else { return TRUE; }
} else {
if (lpwm32mpex->Parm16.WndProc.lParam) {
if (lpwm32mpex->pww == NULL) { lpwm32mpex->pww = (PWW)GetWindowLong(lpwm32mpex->hwnd, GWL_WOWWORDS); if (lpwm32mpex->pww == NULL) return FALSE; // Window is dead
}
if (lParam->lpCreateParams && (lpwm32mpex->pww->ExStyle & WS_EX_MDICHILD) ) { WM32MSGPARAMEX wm32mpexT; GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(CREATESTRUCT16), pcws16); wm32mpexT.fThunk = lpwm32mpex->fThunk; wm32mpexT.hwnd = lpwm32mpex->hwnd; wm32mpexT.uMsg = WM_MDICREATE; wm32mpexT.uParam = lpwm32mpex->uParam; wm32mpexT.lParam = (LONG)lParam->lpCreateParams; wm32mpexT.pww = lpwm32mpex->pww; wm32mpexT.fFree = lpwm32mpex->fFree; wm32mpexT.Parm16.WndProc.lParam = (VPVOID)FETCHDWORD(pcws16->vpCreateParams); wm32mpexT.lReturn = 0; wm32mpexT.dwParam = lpwm32mpex->dwParam; WM32MDICreate(&wm32mpexT); FREEVDMPTR(pcws16); }
vpClass = lpwm32mpex->dwTmp[0]; vpName = lpwm32mpex->dwTmp[1];
// if HIWORD(class) is zero, class is an atom, else a pointer.
if (HIW16(vpClass)) { free16(vpClass); }
if (vpName) { free16(vpName); }
stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam, sizeof(CREATESTRUCT16)); }
return TRUE; }
}
// This function thunks the messages,
//
// WM_NCACTIVATE
// WM_ACTIVATE
//
BOOL FASTCALL WM32Activate(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.wParam = LOWORD(lpwm32mpex->uParam); LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam); HIW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam); }
return (TRUE); }
// This function thunks the messages,
//
// WM_VKEYTOITEM
// WM_CHARTOITEM
// WM_BEGINDRAG
//
BOOL FASTCALL WM32VKeyToItem(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam); HIW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam); } else { lpwm32mpex->lReturn = (INT)(SHORT)(lpwm32mpex->lReturn); // sign extend.
}
return (TRUE); }
// This function thunks the messages,
//
// WM_SETFOCUS
// WM_KILLFOCUS
// WM_SETCURSOR
// WM_MOUSEACTIVATE
// WM_MDIDESTROY
// WM_MDIRESTORE
// WM_MDIMAXIMIZE
// WM_VSCROLLCLIPBOARD
// WM_HSCROLLCLIPBOARD
// WM_PALETTECHANGED
// WM_PALETTEISCHANGING
// WM_INITDIALOG
//
BOOL FASTCALL WM32SetFocus(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam); }
return (TRUE); }
// This function thunks the messages,
//
// WM_SETTEXT
// WM_WININICHANGE
// WM_DEVMODECHANGE
//
BOOL FASTCALL WM32SetText(LPWM32MSGPARAMEX lpwm32mpex) { INT cb;
if (lpwm32mpex->fThunk) { if (lpwm32mpex->lParam) {
LONG lParam = (LONG)GetParam16(lpwm32mpex->lParam); if (lParam) { lpwm32mpex->Parm16.WndProc.lParam = lParam; return (TRUE); }
cb = strlen((LPSZ)lpwm32mpex->lParam)+1; lpwm32mpex->dwTmp[0] = (DWORD)cb;
// winworks2.0a requires DS based string pointers for this message
if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_DSBASEDSTRINGPOINTERS) {
// be sure allocation size matches stackfree16() size below
if (!(lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(cb))) return FALSE;
} else { if (!(lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb))) return FALSE; } putstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, cb); } } else { // BUGBUG 09-Apr-91 -- Should I copy back?
if (DeleteParamMap(lpwm32mpex->Parm16.WndProc.lParam, PARAM_16, NULL)) { return TRUE; }
if (lpwm32mpex->Parm16.WndProc.lParam) { if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_DSBASEDSTRINGPOINTERS) { stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam, ((UINT)lpwm32mpex->dwTmp[0])); } else { free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam); } } }
return (TRUE); }
// This function thunks the message,
//
// WM_GETTEXT
//
BOOL FASTCALL WM32GetText(LPWM32MSGPARAMEX lpwm32mpex) { INT cb; LPSTR psz; INT cbWrote;
if (lpwm32mpex->fThunk) {
if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_DSBASEDSTRINGPOINTERS) { //
// msworks 2.0a has a wndproc called EdWnProc() which when it gets
// a WM_GETTEXT, assumes lParam is a based pointer whose segment
// value is equal to winwork's ds. That is true under win3.1, but
// if wow calls malloc16, it'll have a different segment value.
// so instead alloc the space on the caller's stack. Since most
// apps have SS == DS, this will fix apps that do this, including
// msworks 2.0a.
//
// be sure allocation size matches stackfree16() size below
lpwm32mpex->dwTmp[0] = (DWORD)lpwm32mpex->Parm16.WndProc.wParam; lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(lpwm32mpex->dwTmp[0]);
} else { lpwm32mpex->Parm16.WndProc.lParam = malloc16(lpwm32mpex->Parm16.WndProc.wParam); }
//
// non-zero fill to detect people who write more than they
// say that they do!
//
GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, lpwm32mpex->Parm16.WndProc.wParam, psz); RtlFillMemory(psz, lpwm32mpex->Parm16.WndProc.wParam, 0xff); FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, lpwm32mpex->Parm16.WndProc.wParam, psz); FREEVDMPTR(psz); return (BOOL)lpwm32mpex->Parm16.WndProc.lParam; } else { // some apps return garbage in the high word. safely assume
// that cbWindowText < 64K
HIW(lpwm32mpex->lReturn) = 0;
// it is necessary to check the length of the buffer, specified in
// lpwm32mpex->uParam. if number of bytes (lpwm32mpex->lReturn) that are to be copied is
// EQUAL to the length of the buffer, then copy ONLY the bytes EQUAL
// to the length of the buffer.
//
// Paradox is one of the apps where this condition is hit.
// bug # 4272.
//
if (lpwm32mpex->Parm16.WndProc.lParam) {
cb = lpwm32mpex->lReturn + 1;
if (lpwm32mpex->uParam == 0) { // cb = 0 if lReturn == 0 && uParam == 0
if (cb == 1) cb--; } else if (cb == 2 || cb == 1) { // Here only if uParam != 0
//
// Determine how much of the buffer they touched!
//
// MyAdvancedLabelMaker returns 1 when they really return
// more than 1. Since the return 1, cb will be 2. Then
// We check to see how much of the buffer they really modified.
// Then we lie and say that they really filled in that much
// of the buffer.
//
// Sql administator also does this, except it returns 0
// bug 7731
GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, lpwm32mpex->Parm16.WndProc.wParam, psz);
cbWrote = lpwm32mpex->uParam; while (cbWrote && (psz[cbWrote-1] == '\xff')) { cbWrote--; } // copy out as many bytes as they wrote
// distinguish between 'zerobytes written vs. one byte written'
lpwm32mpex->lReturn = (cbWrote) ? (cbWrote - 1) : 0; cb = cbWrote;
FREEVDMPTR(psz); }
// cb = min(cb, wparam) only if wparam != 0
// MSPROFIT: does
// ret = sendmessage(hwnd, wm_gettest, wparam = 0, lparam);
// where ret != 0. so we have to copy the necessary bytes into
// lparam eventhough wparam is zero. It does this for reading
// those ominprseent "$0.00" strings in the app (ledgers etc).
//
// - nanduri
if (lpwm32mpex->uParam && (UINT)cb > lpwm32mpex->uParam) { cb = lpwm32mpex->uParam; }
getstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, cb);
if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_DSBASEDSTRINGPOINTERS) { stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam, ((UINT)lpwm32mpex->dwTmp[0])); } else { free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam); } } }
return (TRUE); }
// This function thunks the messages,
//
// WM_ERASEBKGND
// WM_ICONERASEBKGND
//
BOOL FASTCALL WM32EraseBkGnd(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.wParam = GETHDC16(lpwm32mpex->uParam); }
return (TRUE); }
// This function thunks the message
//
// WM_CHANGEUISTATE
// WM_UPDATEUISTATE
// WM_QUERYUISTATE
//
BOOL FASTCALL WM32xxxUIState(LPWM32MSGPARAMEX lpwm32mpex) {
// just copy the wParam into the lParam
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.lParam = (LONG)lpwm32mpex->uParam; lpwm32mpex->Parm16.WndProc.wParam = 0;
// this is here because there is talk that they might extend this
// message to use lParam -- heck, they didn't even tell us that they
// implemented this message in the first place!! (shame on shell!!)
WOW32WARNMSG((lpwm32mpex->lParam == 0), ("WOW::WM32xxxUIState:lParam != 0. Better investigate!\n")); }
// now just reverse the process
else { lpwm32mpex->uParam = (UINT)lpwm32mpex->Parm16.WndProc.lParam; lpwm32mpex->lParam = 0; }
return (TRUE); }
// This function thunks the messages,
//
// WM_ACTIVATEAPP
//
BOOL FASTCALL WM32ActivateApp(LPWM32MSGPARAMEX lpwm32mpex) { extern void UpdateInt16State(void);
if (lpwm32mpex->fThunk) {
LOW(lpwm32mpex->Parm16.WndProc.lParam) = lpwm32mpex->lParam ? ThreadID32toHtask16((DWORD)lpwm32mpex->lParam) : 0;
// We need to update wow int 16 bios when I wow app gets the focus.
UpdateInt16State(); }
return (TRUE); }
// This function thunks the messages,
//
// WM_GETMINMAXINFO
//
BOOL FASTCALL WM32GetMinMaxInfo(LPWM32MSGPARAMEX lpwm32mpex) { LPPOINT lParam = (LPPOINT) lpwm32mpex->lParam;
if (lpwm32mpex->fThunk) { if (lParam) {
// be sure allocation size matches stackfree16() size below
lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(POINT16)*5);
UnThunkWMGetMinMaxInfo16(lpwm32mpex->Parm16.WndProc.lParam, lParam); } } else { ThunkWMGetMinMaxInfo16(lpwm32mpex->Parm16.WndProc.lParam, &lParam); if(lpwm32mpex->Parm16.WndProc.lParam) { stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam, sizeof(POINT16)*5); } }
return(TRUE); }
// This function thunks the messages,
//
// WM_NCPAINT
//
BOOL FASTCALL WM32NCPaint(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.wParam = (lpwm32mpex->uParam == 1) ? 1 : GETHDC16(lpwm32mpex->uParam); } return (TRUE); }
// This function thunks the messages,
//
// WM_NCDESTROY
//
BOOL FASTCALL WM32NCDestroy(LPWM32MSGPARAMEX lpwm32mpex) {
// destroy any timers associated with this window
if (!lpwm32mpex->fThunk) { FreeWindowTimers16(lpwm32mpex->hwnd); } return (TRUE); }
// This function thunks the messages,
//
// WM_GETDLGCODE
//
BOOL FASTCALL WM32GetDlgCode(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { if (lpwm32mpex->lParam) {
// BUGBUG -- The assumption here is that GlobalAlloc will never
// return a memory object that isn't word-aligned, so that we can
// assign word-aligned words directly; we have no idea whether the
// memory is dword-aligned or not however, so dwords must always
// be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
if (!(lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(MSG16)))) return FALSE;
putmsg16(lpwm32mpex->Parm16.WndProc.lParam, (LPMSG)lpwm32mpex->lParam);
return TRUE; } } else { // Message structure doesn't need to be copied back does it? -Bob
if (lpwm32mpex->Parm16.WndProc.lParam) { free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam); }
} return (TRUE); }
// This function thunks the messages,
//
// WM_NEXTDLGCTL
//
BOOL FASTCALL WM32NextDlgCtl(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { if (lpwm32mpex->lParam) { lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam); } } return (TRUE); }
// This function thunks the messages,
//
// WM_DRAWITEM
//
BOOL FASTCALL WM32DrawItem(LPWM32MSGPARAMEX lpwm32mpex) { LPDRAWITEMSTRUCT lParam = (LPDRAWITEMSTRUCT) lpwm32mpex->lParam;
if (lpwm32mpex->fThunk) { if (lParam) {
// be sure allocation size matches stackfree16() size below
lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(DRAWITEMSTRUCT16)); putdrawitem16(lpwm32mpex->Parm16.WndProc.lParam, lParam); } } else { // BUGBUG 08-Apr-91 JeffPar -- Reflect changes back to 32-bit structure?
if (lpwm32mpex->Parm16.WndProc.lParam) stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam, sizeof(DRAWITEMSTRUCT16)); }
return(TRUE); }
// This function thunks the messages,
//
// WM_MEASUREITEM
//
BOOL FASTCALL WM32MeasureItem(LPWM32MSGPARAMEX lpwm32mpex) { PMEASUREITEMSTRUCT16 pmis16; LPMEASUREITEMSTRUCT lParam = (LPMEASUREITEMSTRUCT) lpwm32mpex->lParam; BOOL fHasStrings; DWORD cSize;
//
// Compatibility hack
//
// CrossTalk 2.0 has a bug where it fails to distinguish between
// WM_MEASUREITEM and WM_INITDIALOG when doing file.open
// on WM_MEASUREITEM it calls CallWindowProc() to send what it
// thinks is lpOpenFileName->lpCust but is really random stack.
// currently the high word of this random pointer is an hInstance
// and gets through the validation layer, whereas on Win31 it doesn't.
// if this WM_MEASUREITEM gets to the app's proc then the app will
// initialize incorrectly and take a GP. i have increased the stack
// allocation by XTALKHACK to ensure that the random data does is not
// a valid pointer.
//
#define XTALKHACK (sizeof(OPENFILENAME16)-sizeof(MEASUREITEMSTRUCT16))
if (lpwm32mpex->fThunk) { if (lParam) {
fHasStrings = FALSE; if ( lParam->CtlType == ODT_COMBOBOX || lParam->CtlType == ODT_LISTBOX ) { if (lParam->itemWidth == MIFLAG_FLAT) { fHasStrings = TRUE; } }
cSize = sizeof(MEASUREITEMSTRUCT16); if ( fHasStrings ) { cSize += strlen((LPSTR)lParam->itemData) + 1; }
if ( cSize < XTALKHACK+sizeof(MEASUREITEMSTRUCT16) ) { cSize = XTALKHACK+sizeof(MEASUREITEMSTRUCT16); }
// be sure allocation size matches stackfree16() size below
lpwm32mpex->dwTmp[0] = cSize; if ( !(lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(cSize)) ) return FALSE;
GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, cSize, pmis16);
pmis16->CtlType = (WORD)lParam->CtlType; pmis16->CtlID = (WORD)lParam->CtlID; pmis16->itemID = (WORD)lParam->itemID; pmis16->itemWidth = (WORD)lParam->itemWidth; pmis16->itemHeight = (WORD)lParam->itemHeight;
#ifdef XTALKHACK
((POPENFILENAME16)pmis16)->lCustData = 7; // invalid far pointer
#endif
if ( fHasStrings ) { pmis16->itemData = lpwm32mpex->Parm16.WndProc.lParam+sizeof(MEASUREITEMSTRUCT16); strcpy( (LPSTR)(pmis16+1), (LPSTR)lParam->itemData ); } else { STOREDWORD(pmis16->itemData, lParam->itemData); }
WOW32ASSERT(HIWORD(cSize) == 0); FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, (USHORT) cSize, pmis16); FREEVDMPTR(pmis16); } } else { if (lpwm32mpex->Parm16.WndProc.lParam) { GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(MEASUREITEMSTRUCT16), pmis16);
lParam->CtlType = WORD32(pmis16->CtlType); lParam->CtlID = WORD32(pmis16->CtlID); lParam->itemID = WORD32(pmis16->itemID);
// itemWidth must sign extend (PPT3 bug & Win3.1 treats it as signed!)
lParam->itemWidth = INT32(pmis16->itemWidth);
lParam->itemHeight = WORD32(pmis16->itemHeight); lParam->itemData = pmis16->itemData;
FREEVDMPTR(pmis16);
stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam, ((UINT)lpwm32mpex->dwTmp[0])); } }
return(TRUE); }
// This function thunks the messages,
//
// WM_DELETEITEM
//
BOOL FASTCALL WM32DeleteItem(LPWM32MSGPARAMEX lpwm32mpex) { register PDELETEITEMSTRUCT16 pdes16; LPDELETEITEMSTRUCT lParam = (LPDELETEITEMSTRUCT) lpwm32mpex->lParam;
if (lpwm32mpex->fThunk) { if (lParam) {
// BUGBUG -- The assumption here is that GlobalAlloc will never
// return a memory object that isn't word-aligned, so that we can
// assign word-aligned words directly; we have no idea whether the
// memory is dword-aligned or not however, so dwords must always
// be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
// be sure allocation size matches stackfree16() size below
lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(DELETEITEMSTRUCT16)); GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(DELETEITEMSTRUCT16), pdes16);
pdes16->CtlType = (WORD)lParam->CtlType; pdes16->CtlID = (WORD)lParam->CtlID; pdes16->itemID = (WORD)lParam->itemID; pdes16->hwndItem = GETHWND16(lParam->hwndItem); STOREDWORD(pdes16->itemData, lParam->itemData);
FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(DELETEITEMSTRUCT16), pdes16); FREEVDMPTR(pdes16); } } else { if (lpwm32mpex->Parm16.WndProc.lParam) stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam, sizeof(DELETEITEMSTRUCT16)); }
return(TRUE); }
// This function thunks the messages,
//
// WM_SETFONT
//
BOOL FASTCALL WM32SetFont(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.wParam = GETHFONT16(lpwm32mpex->uParam); }
return (TRUE); }
// This function thunks the messages,
//
// WM_QUERYDRAGICON
BOOL FASTCALL WM32QueryDragIcon(LPWM32MSGPARAMEX lpwm32mpex) {
if (!lpwm32mpex->fThunk) { lpwm32mpex->lReturn = (LONG)HICON32(lpwm32mpex->lReturn); }
return (TRUE); }
// This function thunks the messages,
//
// WM_COMPAREITEM
//
BOOL FASTCALL WM32CompareItem(LPWM32MSGPARAMEX lpwm32mpex) { LPCOMPAREITEMSTRUCT lParam = (LPCOMPAREITEMSTRUCT) lpwm32mpex->lParam;
if (lpwm32mpex->fThunk) { if (lParam) {
// BUGBUG -- The assumption here is that GlobalAlloc will never
// return a memory object that isn't word-aligned, so that we can
// assign word-aligned words directly; we have no idea whether the
// memory is dword-aligned or not however, so dwords must always
// be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
// be sure allocation size matches stackfree16() size below
lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(COMPAREITEMSTRUCT16)); putcompareitem16(lpwm32mpex->Parm16.WndProc.lParam, lParam); } } else { // BUGBUG 08-Apr-91 JeffPar -- Reflect changes back to 32-bit structure?
if (lpwm32mpex->Parm16.WndProc.lParam) stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam, sizeof(COMPAREITEMSTRUCT16)); }
return (TRUE); }
// This function thunks the messages,
//
// WM_SIZING
//
BOOL FASTCALL WM32Sizing(LPWM32MSGPARAMEX lpwm32mpex) { VPRECT16 vpRect16;
if (lpwm32mpex->fThunk) {
if (lpwm32mpex->lParam) {
// be sure allocation size matches stackfree16() size below
vpRect16 = (VPVOID)stackalloc16(sizeof(RECT16));
if(vpRect16) { putrect16(vpRect16, (LPRECT)lpwm32mpex->lParam);
lpwm32mpex->Parm16.WndProc.lParam = (LONG)vpRect16; } } } else {
if (lpwm32mpex->lParam) {
vpRect16 = (VPVOID)lpwm32mpex->Parm16.WndProc.lParam;
if(vpRect16) { getrect16(vpRect16, (LPRECT)lpwm32mpex->lParam);
stackfree16(vpRect16, sizeof(RECT16)); } } }
return (TRUE); }
// This function thunks the messages,
//
// WM_NCCALCSIZE
//
BOOL FASTCALL WM32NCCalcSize(LPWM32MSGPARAMEX lpwm32mpex) { PNCCALCSIZE_PARAMS16 pnc16; PNCCALCSIZE_PARAMS16 lpnc16; VPWINDOWPOS16 vpwp16; LPNCCALCSIZE_PARAMS lParam = (LPNCCALCSIZE_PARAMS)lpwm32mpex->lParam; UINT cb; VPVOID vp;
// lpwm32mpex->uParam == TRUE ? (lParam is LPNCCALCSIZE_PARAMS) : (lParam is LPRECT);
//
if (lpwm32mpex->fThunk) { if (lParam) { if (lpwm32mpex->uParam) cb = sizeof(NCCALCSIZE_PARAMS16) + sizeof(WINDOWPOS16); else cb = sizeof(RECT16);
// be sure allocation size matches stackfree16() size below
lpwm32mpex->dwTmp[0] = cb; vp = (VPVOID)stackalloc16(cb);
lpwm32mpex->Parm16.WndProc.lParam = (LONG)vp;
putrect16((VPRECT16)vp, (LPRECT)lParam); if (lpwm32mpex->uParam) { pnc16 = (PNCCALCSIZE_PARAMS16)vp; putrect16((VPRECT16)(&pnc16->rgrc[1]), &lParam->rgrc[1]); putrect16((VPRECT16)(&pnc16->rgrc[2]), &lParam->rgrc[2]);
GETVDMPTR( pnc16, sizeof(NCCALCSIZE_PARAMS16), lpnc16 );
vpwp16 = (VPWINDOWPOS16)(pnc16+1); lpnc16->lppos = (PWINDOWPOS16)vpwp16;
FREEVDMPTR( lpnc16 );
putwindowpos16( vpwp16, lParam->lppos );
} } } else { vp = (VPVOID)lpwm32mpex->Parm16.WndProc.lParam; getrect16((VPRECT16)vp, (LPRECT)lParam); if (lpwm32mpex->uParam) { pnc16 = (PNCCALCSIZE_PARAMS16)vp;
getrect16((VPRECT16)(&pnc16->rgrc[1]), &lParam->rgrc[1]); getrect16((VPRECT16)(&pnc16->rgrc[2]), &lParam->rgrc[2]);
GETVDMPTR( pnc16, sizeof(NCCALCSIZE_PARAMS16), lpnc16 );
vpwp16 = (VPWINDOWPOS16)lpnc16->lppos;
FREEVDMPTR( lpnc16 );
getwindowpos16( vpwp16, lParam->lppos );
} if(vp) { stackfree16(vp, ((UINT)lpwm32mpex->dwTmp[0])); } }
return (TRUE); }
// This function thunks the messages,
//
// WM_COMMAND
//
BOOL FASTCALL WM32Command(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { // it's from a control
HIW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam); LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam); }
return (TRUE); }
// This function thunks the messages,
//
// WM_TIMER
//
BOOL FASTCALL WM32Timer(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) {
/*
** map the timer number and the timer proc address (cause its easy) */ PTMR ptmr;
ptmr = FindTimer32((HAND16)GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->uParam);
if ( !ptmr ) { /*
** Edit controls create their own timer, which can safely be ** thunked to itself. */ if ( lpwm32mpex->lParam || HIWORD(lpwm32mpex->uParam) ) { LOGDEBUG(LOG_WARNING,(" WM32Timer ERROR: cannot find timer %08x\n", lpwm32mpex->uParam)); } return TRUE; }
lpwm32mpex->Parm16.WndProc.lParam = ptmr->vpfnTimerProc; }
return (TRUE); }
// This function thunks the messages,
//
// WM_HSCROLL
// WM_VSCROLL
//
BOOL FASTCALL WM32HScroll(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { LOW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam); HIW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam); }
return (TRUE); }
// This function thunks the messages,
//
// WM_INITMENU
// WM_INITMENUPOPUP
//
BOOL FASTCALL WM32InitMenu(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.wParam = GETHMENU16(lpwm32mpex->uParam); }
return (TRUE); }
// This function thunks the messages,
//
// WM_MENUSELECT
//
BOOL FASTCALL WM32MenuSelect(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) {
// Copy the menu flags
LOW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam);
// Copy the "main" menu
HIW(lpwm32mpex->Parm16.WndProc.lParam) = GETHMENU16(lpwm32mpex->lParam);
if (HIWORD(lpwm32mpex->uParam) == 0xFFFF || !(HIWORD(lpwm32mpex->uParam) & MF_POPUP)) { lpwm32mpex->Parm16.WndProc.wParam = LOWORD(lpwm32mpex->uParam); // Its an ID
} else { // convert menu index into menu handle
lpwm32mpex->Parm16.WndProc.wParam = GETHMENU16(GetSubMenu((HMENU)lpwm32mpex->lParam, LOWORD(lpwm32mpex->uParam))); } }
return (TRUE); }
// This function thunks the messages,
//
// WM_MENUCHAR
//
BOOL FASTCALL WM32MenuChar(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { LOW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam); HIW(lpwm32mpex->Parm16.WndProc.lParam) = GETHMENU16(lpwm32mpex->lParam); }
return (TRUE); }
// This function thunks the messages,
//
// WM_ENTERIDLE
//
BOOL FASTCALL WM32EnterIdle(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { if ((lpwm32mpex->uParam == MSGF_DIALOGBOX) || (lpwm32mpex->uParam == MSGF_MENU)) { LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam); HIW(lpwm32mpex->Parm16.WndProc.lParam) = 0; } else { LOGDEBUG(LOG_ALWAYS,(" WOW::WM_ENTERIDLE: wParam has unknown value, wParam=%08x, Contact ChandanC\n", lpwm32mpex->uParam)); } } return (TRUE); }
// This function thunks the messages,
//
// WM_PARENTNOTIFY
//
BOOL FASTCALL WM32ParentNotify(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { if ((LOWORD(lpwm32mpex->uParam) == WM_CREATE) || (LOWORD(lpwm32mpex->uParam) == WM_DESTROY)) { HIW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam); LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam); } }
return (TRUE); }
// This function thunks the messages,
//
// WM_MDICreate
//
BOOL FASTCALL WM32MDICreate(LPWM32MSGPARAMEX lpwm32mpex) { INT cb; VPVOID vp; register PMDICREATESTRUCT16 pmcs16; LPMDICREATESTRUCT lParam = (LPMDICREATESTRUCT) lpwm32mpex->lParam;
if (lpwm32mpex->fThunk) { if (lParam) {
lpwm32mpex->dwParam = (DWORD)0; if (lParam->szClass) { if ( HIWORD(lParam->szClass) == 0 ) { vp = (VPVOID)lParam->szClass; } else { cb = strlen(lParam->szClass)+1; if (!(vp = malloc16(cb))) goto Error; putstr16(vp, lParam->szClass, cb); } } else { vp = (VPVOID)NULL; }
//
// pfs:windowsworks overwrite pszclass, so we need to save the
// so that we can free the memory we just alloced
//
lpwm32mpex->dwParam = (DWORD)vp;
if (lParam->szTitle) { cb = strlen(lParam->szTitle)+1; if (!(vp = malloc16(cb))) goto Error; putstr16(vp, lParam->szTitle, cb); } else { vp = (VPVOID)NULL; }
// BUGBUG -- The assumption here is that GlobalAlloc will never
// return a memory object that isn't word-aligned, so that we can
// assign word-aligned words directly; we have no idea whether the
// memory is dword-aligned or not however, so dwords must always
// be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
if (!(lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(MDICREATESTRUCT16)))) goto Error;
GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(MDICREATESTRUCT16), pmcs16); STOREDWORD(pmcs16->vpszClass, lpwm32mpex->dwParam); STOREDWORD(pmcs16->vpszTitle, vp); pmcs16->hOwner = GETHINST16(lParam->hOwner); pmcs16->x = (SHORT)lParam->x; pmcs16->y = (SHORT)lParam->y; pmcs16->cx = (SHORT)lParam->cx; pmcs16->cy = (SHORT)lParam->cy; STORELONG(pmcs16->style, lParam->style); STORELONG(pmcs16->lParam, lParam->lParam);
FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(MDICREATESTRUCT16), pmcs16); FREEVDMPTR(pmcs16);
return (TRUE);
Error: LOGDEBUG(LOG_ALWAYS,(" !!!! WM32MDICreate, WM_MDICREATE thunking failed !!!! Window %08lX ", lpwm32mpex->hwnd)); if (HIW16(lpwm32mpex->dwParam)) free16(lpwm32mpex->dwParam); if (vp) free16(vp); return FALSE; } } else { if (lpwm32mpex->Parm16.WndProc.lParam) { GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(MDICREATESTRUCT16), pmcs16);
if (FETCHDWORD(pmcs16->vpszTitle)) { free16(FETCHDWORD(pmcs16->vpszTitle)); }
FREEVDMPTR(pmcs16);
// if HIWORD(class) is zero, class is an atom, else a pointer.
if (HIW16(lpwm32mpex->dwParam)) { free16(lpwm32mpex->dwParam); }
lpwm32mpex->lReturn = (LONG)HWND32(LOWORD(lpwm32mpex->lReturn)); free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam); } }
return (TRUE); }
// This function thunks the messages,
//
// WM_MDIActivate
//
BOOL FASTCALL WM32MDIActivate(LPWM32MSGPARAMEX lpwm32mpex) { BOOL fHwndIsMdiChild;
if (lpwm32mpex->fThunk) {
// the format of the message is different based on the window that's
// receiving the message. If 'hwnd' is a MdiClient window it is of one
// form and if 'hwnd' is MdiChild it is of another form. We need to
// distinguish between the formats to correctly thunk the message.
//
// NOTE: we donot make calls like GetClassName because they are
// expensive and also I think we came across a case where a
// window of 'wow private class' processes these messages
//
// - Nanduri
if (lpwm32mpex->lParam) {
// lParam != NULL. The message is definitely going to a MdiChild.
//
fHwndIsMdiChild = TRUE; } else {
// lParam == NULL, doesnot necessarily mean that the message is
// going to a MdiClient window. So distinguish...
if (lpwm32mpex->uParam && (GETHWND16(lpwm32mpex->hwnd) == GETHWND16(lpwm32mpex->uParam))) {
// if hwnd is same as uParam then definitely hwnd is a MdiChild
// window. (because if hwnd is a MdiClient then uParam will be
// a MdiChild and thus they will not be equal)
fHwndIsMdiChild = TRUE; } else { fHwndIsMdiChild = FALSE; }
}
if (fHwndIsMdiChild) { lpwm32mpex->Parm16.WndProc.wParam = (WORD)(GETHWND16(lpwm32mpex->hwnd) == GETHWND16(lpwm32mpex->lParam)); LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam); HIW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->uParam); } else { lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam); lpwm32mpex->Parm16.WndProc.lParam = 0; } }
return (TRUE); }
// This function thunks the messages,
//
// WM_MDIGETACTIVE
//
BOOL FASTCALL WM32MDIGetActive(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.lParam = 0; } else {
if (lpwm32mpex->lParam != 0) *((LPBOOL)lpwm32mpex->lParam) = (BOOL)HIWORD(lpwm32mpex->lReturn);
lpwm32mpex->lReturn = (LONG)HWND32(LOWORD(lpwm32mpex->lReturn)); }
return (TRUE); }
// This function thunks the messages,
//
// WM_MDISETMENU
//
BOOL FASTCALL WM32MDISetMenu(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { if (lpwm32mpex->uMsg == WM_MDIREFRESHMENU) { lpwm32mpex->Parm16.WndProc.wParam = TRUE; lpwm32mpex->Parm16.WndProc.wMsg = WM_MDISETMENU; } else { lpwm32mpex->Parm16.WndProc.wParam = 0; } LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHMENU16(lpwm32mpex->uParam); HIW(lpwm32mpex->Parm16.WndProc.lParam) = GETHMENU16(lpwm32mpex->lParam); } else { lpwm32mpex->lReturn = (LONG)HMENU32(lpwm32mpex->lReturn); }
return (TRUE); }
// This function thunks the messages,
//
// WM_SIZECLIPBOARD
// WM_PAINTCLIPBOARD
//
BOOL FASTCALL WM32SizeClipBoard(LPWM32MSGPARAMEX lpwm32mpex) { HAND16 hMem16 = 0; VPVOID vp; LPRECT lp;
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
vp = GlobalAllocLock16(GMEM_MOVEABLE, (lpwm32mpex->uMsg == WM_SIZECLIPBOARD) ? sizeof(RECT) : sizeof(PAINTSTRUCT), &hMem16); if (vp) { if (lp = (LPRECT) GlobalLock((HANDLE) lpwm32mpex->lParam)) { if (lpwm32mpex->uMsg == WM_SIZECLIPBOARD) { PUTRECT16(vp, lp); } else { putpaintstruct16(vp, (LPPAINTSTRUCT) lp); } GlobalUnlock((HANDLE) lpwm32mpex->lParam); } else { LOGDEBUG(LOG_ALWAYS, ("WOW::WM32SizeClipboard: Couldn't lock 32 bit memory handle!\n")); // WOW32ASSERT (FALSE);
}
GlobalUnlock16(hMem16); } else { hMem16 = 0; LOGDEBUG(LOG_ALWAYS, ("WOW::WM32SizeClipboard: Couldn't allocate memory !\n")); WOW32ASSERT (FALSE); }
LOW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) hMem16; } else { if (LOW(lpwm32mpex->Parm16.WndProc.lParam)) { GlobalUnlockFree16(GlobalLock16(LOW(lpwm32mpex->Parm16.WndProc.lParam), NULL)); } }
return (TRUE); }
// This function thunks the messages,
//
// WM_ASKCBFORMATNAME
//
BOOL FASTCALL WM32AskCBFormatName(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.lParam = malloc16(lpwm32mpex->Parm16.WndProc.wParam); if (lpwm32mpex->Parm16.WndProc.lParam) { putstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, lpwm32mpex->uParam); }
return (BOOL)lpwm32mpex->Parm16.WndProc.lParam; } else { if (lpwm32mpex->Parm16.WndProc.lParam) { getstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, lpwm32mpex->uParam); free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam); } }
return (TRUE); }
// This function thunks the messages,
//
// WM_CHANGECBCHAIN
//
BOOL FASTCALL WM32ChangeCBChain(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam); lpwm32mpex->Parm16.WndProc.lParam = GETHWND16(lpwm32mpex->lParam); }
return (TRUE); }
// This function thunks the messages,
//
// WM_DDEINITIATE
//
BOOL FASTCALL WM32DDEInitiate(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam); lpwm32mpex->Parm16.WndProc.lParam = lpwm32mpex->lParam; WI32DDEAddInitiator(lpwm32mpex->Parm16.WndProc.wParam); } else { WI32DDEDeleteInitiator((HAND16)GETHWND16(lpwm32mpex->uParam)); }
return (TRUE); }
// This function thunks the messages,
//
// WM_DDEACK
//
BOOL FASTCALL WM32DDEAck(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
if (WI32DDEInitiate((HAND16)GETHWND16(lpwm32mpex->hwnd))) { //
// Initiate ACK
//
lpwm32mpex->Parm16.WndProc.lParam = lpwm32mpex->lParam; } else { //
// NON-Initiate ACK
//
UINT lLo = 0; UINT lHi = 0; PHDDE pDdeNode;
UnpackDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam, &lLo, &lHi);
if (!HIWORD(lHi)) { //
// NON-Execute ACK
//
HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lHi; } else { //
// Execute ACK
//
//
// The order of To_hwnd and From_hwnd is reversed in the following
// DDEFirstPair16(), below. This is done to locate the h32.
//
pDdeNode = DDEFindAckNode ((HAND16)lpwm32mpex->Parm16.WndProc.wParam, (HAND16)GETHWND16(lpwm32mpex->hwnd), (HANDLE) lHi);
if (!pDdeNode) {
//
// When ShellExecute does DDE_EXECUTE to open a document,
// we don't see its Win32 PostMessage calls so we have no
// record of the conversation. This is our first opportunity
// to rectify that, the context of WU32GetMessage thunking
// a WM_DDE_ACK message. We could also get here for other
// kinds of ACKs, fortunately the Win32 message alone gives
// enough context to distinguish the various flavors, unlike
// the Win16 WM_DDE_ACK.
//
if (lpwm32mpex->lParam >= 0xc0000000) {
//
// ack responding to initiate
//
lpwm32mpex->Parm16.WndProc.lParam = lpwm32mpex->lParam; }
if (lHi > 0xffff) {
//
// ack responding to execute: global handle in hiword
//
HAND16 h16 = 0; DWORD cb; VPVOID vp; LPBYTE lpMem16, lpMem32; DDEINFO DdeInfo;
if (!lpwm32mpex->fFree) { cb = GlobalSize((HANDLE)lHi); vp = GlobalAllocLock16(GMEM_DDESHARE, cb, &h16); if (vp) { GETMISCPTR(vp, lpMem16); lpMem32 = GlobalLock((HANDLE)lHi); RtlCopyMemory(lpMem16, lpMem32, cb); GlobalUnlock((HANDLE)lHi); GlobalUnlock16(h16); FREEMISCPTR(lpMem16);
DdeInfo.Msg = WM_DDE_EXECUTE; DdeInfo.Format = 0; DdeInfo.Flags = DDE_PACKET; DdeInfo.h16 = 0;
DDEAddhandle( lpwm32mpex->Parm16.WndProc.wParam, GETHWND16(lpwm32mpex->hwnd), h16, (HANDLE)lHi, &DdeInfo );
pDdeNode = DDEFindAckNode ( (HAND16)lpwm32mpex->Parm16.WndProc.wParam, (HAND16)GETHWND16(lpwm32mpex->hwnd), (HANDLE) lHi);
WOW32ASSERTMSG(pDdeNode, "WM32DDEAck: Can't find just-added DDE node.\n"); } }
lpwm32mpex->Parm16.WndProc.lParam = MAKELONG(LOWORD(lLo), h16);
} else {
//
// All other acks have same form: status in loword and
// item atom in hiword.
//
lpwm32mpex->Parm16.WndProc.lParam = MAKELONG(LOWORD(lLo), lHi); }
}
if (pDdeNode && pDdeNode->DdeMsg == WM_DDE_EXECUTE) {
HIW(lpwm32mpex->Parm16.WndProc.lParam) = pDdeNode->hMem16;
if (lpwm32mpex->fFree) { if (lHi) { if (pDdeNode->DdeFlags & DDE_EXECUTE_FREE_MEM) { LOGDEBUG (12, ("WOW::W32DDEAck : Freeing EXECUTE pair h16 = %04x, h32 = %08x\n", pDdeNode->hMem16, lHi)); W32UnMarkDDEHandle (pDdeNode->hMem16); GlobalUnlockFree16(GlobalLock16(pDdeNode->hMem16, NULL)); if (DDEDeletehandle(pDdeNode->hMem16, (HANDLE) lHi)) { WOWGLOBALFREE((HANDLE)lHi); } else { LOGDEBUG (0, ("WOW::DDE Ack : Ack can't find 16 - 32 aliasing : %04x, %04x, %04x, %08lx, %08lx\n", lpwm32mpex->hwnd, lpwm32mpex->uMsg, lpwm32mpex->Parm16.WndProc.wParam, lpwm32mpex->Parm16.WndProc.lParam, lHi )); } } else { if (pDdeNode->DdeFlags & DDE_EXECUTE_FREE_H16) { W32UnMarkDDEHandle (pDdeNode->hMem16); GlobalUnlockFree16(GlobalLock16(pDdeNode->hMem16, NULL));
HIW(lpwm32mpex->Parm16.WndProc.lParam) = pDdeNode->h16; }
if (DDEDeletehandle(pDdeNode->hMem16, (HANDLE) lHi)) { WOWGLOBALFREE((HANDLE)lHi); } else { LOGDEBUG (0, ("WOW::DDE Ack : Ack can't find 16 - 32 aliasing : %04x, %04x, %04x, %08lx, %08lx\n", lpwm32mpex->hwnd, lpwm32mpex->uMsg, lpwm32mpex->Parm16.WndProc.wParam, lpwm32mpex->Parm16.WndProc.lParam, lHi )); }
} } else { LOGDEBUG (2, ("WOW::W32DDEAck : h32 is NULL \n")); WOW32ASSERT (FALSE); } } } else { LOGDEBUG (2, ("WOW::DDE Ack : Ack received unexpectedly : %x, %04x, %04x, %08lx, %08lx\n", lpwm32mpex->hwnd, lpwm32mpex->uMsg, lpwm32mpex->Parm16.WndProc.wParam, lpwm32mpex->Parm16.WndProc.lParam, lHi)); } }
LOW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lLo;
if (fThunkDDEmsg) { FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam); }
LOGDEBUG (12, ("WOW::DDE Ack : %04x, %04x, %04x, %08lx, %08lx\n", lpwm32mpex->hwnd, lpwm32mpex->uMsg, lpwm32mpex->Parm16.WndProc.wParam, lpwm32mpex->Parm16.WndProc.lParam, lHi)); } } else { //
// We will execute this scenario only if the app ate the message,
// because we need to free up the memory.
//
if (!fThunkDDEmsg) { if (lpwm32mpex->lReturn) { FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam); } } }
return (TRUE); }
// This function thunks the messages,
//
// WM_DDEREQUEST
// WM_DDETERMINATE
// WM_DDEUNADVISE
//
BOOL FASTCALL WM32DDERequest(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam); }
return (TRUE); }
// This function thunks the messages,
//
// WM_DDEADVISE
//
BOOL FASTCALL WM32DDEAdvise(LPWM32MSGPARAMEX lpwm32mpex) { HAND16 h16; VPVOID vp; LPBYTE lpMem16; LPBYTE lpMem32; UINT lLo = 0; UINT lHi = 0; DDEINFO DdeInfo;
if (lpwm32mpex->fThunk) { UnpackDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam, &lLo, &lHi); lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
if (h16 = DDEFindPair16((HAND16)GETHWND16(lpwm32mpex->hwnd), (HAND16)lpwm32mpex->Parm16.WndProc.wParam, (HANDLE) lLo)) { LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16; } else { vp = GlobalAllocLock16(GMEM_DDESHARE, sizeof(DDEADVISE), &h16); if (vp) { GETMISCPTR(vp, lpMem16); lpMem32 = GlobalLock((HANDLE) lLo); RtlCopyMemory(lpMem16, lpMem32, sizeof(DDEADVISE)); GlobalUnlock((HANDLE) lLo); GlobalUnlock16(h16); DdeInfo.Msg = LOW(lpwm32mpex->uMsg); DdeInfo.Format = 0; DdeInfo.Flags = DDE_PACKET; DdeInfo.h16 = 0; DDEAddhandle((HAND16)GETHWND16(lpwm32mpex->hwnd), (HAND16)lpwm32mpex->Parm16.WndProc.wParam, h16, (HANDLE) lLo, &DdeInfo); LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16; } }
HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lHi;
if (fThunkDDEmsg) { FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam); } } else { //
// We will execute this scenario only if the app ate the message,
// because we need to free up the memory.
//
if (!fThunkDDEmsg) { if (lpwm32mpex->lReturn) { FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam); } } }
return (TRUE); }
// This function thunks the messages,
//
// WM_DDEDATA
//
BOOL FASTCALL WM32DDEData(LPWM32MSGPARAMEX lpwm32mpex) { HAND16 h16; UINT lLo = 0; UINT lHi = 0; DDEINFO DdeInfo;
if (lpwm32mpex->fThunk) { UnpackDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam, &lLo, &lHi); lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
if (!lLo) { LOW(lpwm32mpex->Parm16.WndProc.lParam) = 0; } else if (h16 = DDEFindPair16((HAND16)GETHWND16(lpwm32mpex->hwnd), (HAND16)lpwm32mpex->Parm16.WndProc.wParam, (HANDLE) lLo)) { LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16; } else { DdeInfo.Msg = LOW(lpwm32mpex->uMsg); h16 = DDECopyhData16((HAND16)GETHWND16(lpwm32mpex->hwnd), (HAND16)lpwm32mpex->Parm16.WndProc.wParam, (HANDLE) lLo, &DdeInfo);
//
// If we could not allocate 16 bit memory, then return NULL to the
// caller.
//
if (!h16) { if (fThunkDDEmsg) { FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam); }
lpwm32mpex->Parm16.WndProc.wParam = (WORD) lHi; lpwm32mpex->Parm16.WndProc.lParam = lLo; return (0); }
DdeInfo.Flags = DDE_PACKET; DdeInfo.h16 = 0; DDEAddhandle((HAND16)GETHWND16(lpwm32mpex->hwnd), (HAND16)lpwm32mpex->Parm16.WndProc.wParam, h16, (HANDLE) lLo, &DdeInfo);
LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16; }
HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lHi;
if (fThunkDDEmsg) { FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam); }
} else {
//
// We will execute this scenario only if the app ate the message,
// because we need to free up the memory.
//
if (!fThunkDDEmsg) { if (lpwm32mpex->lReturn) { FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam); } } }
return (TRUE); }
// This function thunks the messages,
//
// WM_POKE
//
BOOL FASTCALL WM32DDEPoke(LPWM32MSGPARAMEX lpwm32mpex) {
HAND16 h16; UINT lLo = 0; UINT lHi = 0; DDEINFO DdeInfo;
if (lpwm32mpex->fThunk) { UnpackDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam, &lLo, &lHi); lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
// sudeepb 03-Apr-1996
// House Design Gold Edition sends a DDE_POKE message with lParam
// being 0. We are suppose to thunk this message with lParam being
// zero. Without this check, the below code will fail this call
// and the message will not be thunked to the app.
if (lLo == 0) { LOW(lpwm32mpex->Parm16.WndProc.lParam) = 0; HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lHi; return (TRUE); }
if (h16 = DDEFindPair16((HAND16)GETHWND16(lpwm32mpex->hwnd), (HAND16)lpwm32mpex->Parm16.WndProc.wParam, (HANDLE) lLo)) { LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16; } else { DdeInfo.Msg = LOW(lpwm32mpex->uMsg); h16 = DDECopyhData16((HAND16)GETHWND16(lpwm32mpex->hwnd), (HAND16)lpwm32mpex->Parm16.WndProc.wParam, (HANDLE) lLo, &DdeInfo);
//
// If we could not allocate 16 bit memory, then return NULL to the
// caller.
//
if (!h16) { if (fThunkDDEmsg) { FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam); }
lpwm32mpex->Parm16.WndProc.lParam = lLo; return (0); }
DdeInfo.Flags = DDE_PACKET; DdeInfo.h16 = 0; DDEAddhandle((HAND16)GETHWND16(lpwm32mpex->hwnd), (HAND16)lpwm32mpex->Parm16.WndProc.wParam, h16, (HANDLE) lLo, &DdeInfo);
LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16; }
HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lHi;
if (fThunkDDEmsg) { FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam); } } else { //
// We will execute this scenario only if the app ate the message,
// because we need to free up the memory.
//
if (!fThunkDDEmsg) { if (lpwm32mpex->lReturn) { FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam); } } }
return (TRUE); }
// This function thunks the messages,
//
// WM_DDE_EXECUTE
//
BOOL FASTCALL WM32DDEExecute(LPWM32MSGPARAMEX lpwm32mpex) {
HAND16 h16; VPVOID vp; LPBYTE lpMem16; LPBYTE lpMem32; DDEINFO DdeInfo;
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
if (h16 = DDEFindPair16((HAND16)GETHWND16(lpwm32mpex->hwnd), (HAND16)lpwm32mpex->Parm16.WndProc.wParam, (HANDLE) lpwm32mpex->lParam)) { HIW(lpwm32mpex->Parm16.WndProc.lParam) = h16; } else { vp = GlobalAllocLock16(GMEM_DDESHARE, GlobalSize((HANDLE) lpwm32mpex->lParam), &h16); if (vp) { GETMISCPTR(vp, lpMem16); lpMem32 = GlobalLock((HANDLE) lpwm32mpex->lParam); RtlCopyMemory(lpMem16, lpMem32, GlobalSize((HANDLE) lpwm32mpex->lParam)); GlobalUnlock((HANDLE) lpwm32mpex->lParam); GlobalUnlock16(h16);
DdeInfo.Msg = LOW(lpwm32mpex->uMsg); DdeInfo.Format = 0; DdeInfo.Flags = DDE_PACKET; DdeInfo.h16 = 0; DDEAddhandle((HAND16)GETHWND16(lpwm32mpex->hwnd), (HAND16)lpwm32mpex->Parm16.WndProc.wParam, h16, (HANDLE) lpwm32mpex->lParam, &DdeInfo);
HIW(lpwm32mpex->Parm16.WndProc.lParam) = h16; } } LOW(lpwm32mpex->Parm16.WndProc.lParam) = 0; }
return (TRUE); }
// This function thunks the messages,
//
// WM_CTLCOLORMSGBOX
// WM_CTLCOLOREDIT
// WM_CTLCOLORLISTBOX
// WM_CTLCOLORBTN
// WM_CTLCOLORDLG
// WM_CTLCOLORSCROLLBAR
// WM_CTLCOLORSTATIC
//
// into WM_CTLCOLOR and the high word of lParam specifies the
// control type.
//
BOOL FASTCALL WM32CtlColor(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.wMsg = WM_CTLCOLOR; if(lpwm32mpex->uMsg != WM_CTLCOLOR) { // see 16-bit thunk for this special case
lpwm32mpex->Parm16.WndProc.wParam = GETHDC16(lpwm32mpex->uParam); LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam); HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) (lpwm32mpex->uMsg - WM_CTLCOLORMSGBOX); } } else { if ((ULONG)lpwm32mpex->lReturn > COLOR_ENDCOLORS) { lpwm32mpex->lReturn = (LONG) HBRUSH32(lpwm32mpex->lReturn); } }
return (TRUE); }
// This function thunks the messages,
//
// WM_GETFONT
//
BOOL FASTCALL WM32GetFont(LPWM32MSGPARAMEX lpwm32mpex) {
if (!lpwm32mpex->fThunk) { lpwm32mpex->lReturn = (LONG)HFONT32(lpwm32mpex->lReturn); }
return (TRUE); }
// This function thunks the messages,
//
// WM_NEXTMENU
//
// Win16 NT
// wParam VK_KEY VK_KEY
// lParam.l hmenu PMDINEXTMENU
// lParam.h 0
// return.l menu BOOL
// return.h window
//
BOOL FASTCALL WM32NextMenu(LPWM32MSGPARAMEX lpwm32mpex) {
if (lpwm32mpex->fThunk) { if (lpwm32mpex->lParam) { LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHMENU16(((PMDINEXTMENU)lpwm32mpex->lParam)->hmenuIn); HIW(lpwm32mpex->Parm16.WndProc.lParam) = 0; } } else { if (lpwm32mpex->lParam) { ((PMDINEXTMENU)lpwm32mpex->lParam)->hmenuNext = HMENU32(LOWORD(lpwm32mpex->lReturn)); ((PMDINEXTMENU)lpwm32mpex->lParam)->hwndNext = HWND32(HIWORD(lpwm32mpex->lReturn)); lpwm32mpex->lReturn = TRUE; } else { lpwm32mpex->lReturn = FALSE; } }
return (TRUE); }
BOOL FASTCALL WM32Destroy (LPWM32MSGPARAMEX lpwm32mpex) {
if (!lpwm32mpex->fThunk) { if (CACHENOTEMPTY()) { // because of our method of window aliasing, 'hwnd' may or may
// not be a real 32bit handle. ie. it may be (hwnd16 | 0xffff0000).
// So always use hwnd16.
ReleaseCachedDCs((CURRENTPTD())->htask16, GETHWND16(lpwm32mpex->hwnd), 0, (HWND)0, SRCHDC_TASK16_HWND16); } } return (TRUE); }
// This function thunks the messages,
// WM_DROPFILES
BOOL FASTCALL WM32DropFiles(LPWM32MSGPARAMEX lpwm32mpex) { if (lpwm32mpex->fThunk) { return (BOOL)(lpwm32mpex->Parm16.WndProc.wParam = GETHDROP16(lpwm32mpex->uParam)); }
return (TRUE); }
// This function thunks the messages,
// WM_PRINT
// WM_PRINTCLIENT
BOOL FASTCALL WM32PrintClient(LPWM32MSGPARAMEX lpwm32mpex) { if (lpwm32mpex->fThunk) { return (BOOL)(lpwm32mpex->Parm16.WndProc.wParam = GETHDC16(lpwm32mpex->uParam)); }
return (TRUE); }
// This function thunks the messages,
//
// WM_DROPOBJECT
// WM_QUERYDROPOBJECT
// WM_DRAGLOOP
// WM_DRAGSELECT
// WM_DRAGMOVE
//
BOOL FASTCALL WM32DropObject(LPWM32MSGPARAMEX lpwm32mpex) { register PDROPSTRUCT16 pds16; register LPDROPSTRUCT lParam = (LPDROPSTRUCT)lpwm32mpex->lParam;
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wParam = (WORD)lpwm32mpex->uParam;
// BUGBUG -- The assumption here is that GlobalAlloc will never
// return a memory object that isn't word-aligned, so that we can
// assign word-aligned words directly; we have no idea whether the
// memory is dword-aligned or not however, so dwords must always
// be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
if (!(lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(DROPSTRUCT16)))) return FALSE;
GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(DROPSTRUCT16), pds16);
pds16->hwndSource = GETHWND16(lParam->hwndSource); pds16->hwndSink = GETHWND16(lParam->hwndSink); pds16->wFmt = (WORD) lParam->wFmt; STOREDWORD(pds16->dwData, lParam->dwData);
pds16->ptDrop.x = (SHORT)lParam->ptDrop.x; pds16->ptDrop.y = (SHORT)lParam->ptDrop.y; STOREDWORD(pds16->dwControlData, lParam->dwControlData);
FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(DROPSTRUCT16), pds16); FREEVDMPTR(pds16);
} else {
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
if (lpwm32mpex->uMsg == WM_QUERYDROPOBJECT) {
//
// Return value is either TRUE, FALSE,
// or a cursor!
//
if (lpwm32mpex->lReturn && lpwm32mpex->lReturn != (LONG)TRUE) { lpwm32mpex->lReturn = (LONG)HCURSOR32(lpwm32mpex->lReturn); } } }
return (TRUE); }
// This function thunks the messages,
//
// WM_WINDOWPOSCHANGING
// WM_WINDOWPOSCHANGED
//
BOOL FASTCALL WM32WindowPosChanging (LPWM32MSGPARAMEX lpwm32mpex) { LPWINDOWPOS lParam = (LPWINDOWPOS) lpwm32mpex->lParam;
if (lpwm32mpex->fThunk) {
// be sure allocation size matches stackfree16() size below
lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(WINDOWPOS16));
putwindowpos16( (VPWINDOWPOS16)lpwm32mpex->Parm16.WndProc.lParam, lParam );
} else { getwindowpos16( (VPWINDOWPOS16)lpwm32mpex->Parm16.WndProc.lParam, lParam ); if(lpwm32mpex->Parm16.WndProc.lParam) { stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam, sizeof(WINDOWPOS16)); } }
return (TRUE); }
// This function thunks the message,
//
// WM_COPYDATA
//
BOOL FASTCALL WM32CopyData (LPWM32MSGPARAMEX lpwm32mpex) {
HAND16 h16; HAND16 hMem16; VPVOID vpCDS16; VPVOID vpData16; LPBYTE lpMem16; PCOPYDATASTRUCT lpCDS32; PCOPYDATASTRUCT lpCDS16; PCPDATA pTemp;
if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
if (vpCDS16 = CopyDataFindData16 (GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->Parm16.WndProc.wParam, lpwm32mpex->lParam)) { lpwm32mpex->Parm16.WndProc.lParam = vpCDS16; } else { vpCDS16 = GlobalAllocLock16(GMEM_DDESHARE, sizeof(COPYDATASTRUCT), &h16); if (vpCDS16) { GETMISCPTR(vpCDS16, lpCDS16); lpCDS32 = (PCOPYDATASTRUCT) lpwm32mpex->lParam; lpCDS16->dwData = lpCDS32->dwData; if (lpCDS16->cbData = lpCDS32->cbData) {
FREEMISCPTR(lpCDS16);
vpData16 = GlobalAllocLock16(GMEM_DDESHARE, lpCDS32->cbData, &hMem16); GETMISCPTR(vpData16, lpMem16); if (lpMem16 && lpCDS32->lpData) { RtlCopyMemory(lpMem16, lpCDS32->lpData, lpCDS32->cbData); CopyDataAddNode (GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->Parm16.WndProc.wParam, vpData16, (DWORD) lpCDS32->lpData, 0); } FREEMISCPTR(lpMem16);
GETMISCPTR(vpCDS16, lpCDS16); lpCDS16->lpData = (PVOID) vpData16; } else { lpCDS16->lpData = NULL; } FREEMISCPTR(lpCDS16); }
lpwm32mpex->Parm16.WndProc.lParam = vpCDS16; CopyDataAddNode (GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->Parm16.WndProc.wParam, vpCDS16, lpwm32mpex->lParam, 0); } } else { if (lpwm32mpex->fFree) { pTemp = CopyDataFindData32 (GETHWND16(lpwm32mpex->hwnd), GETHWND16(lpwm32mpex->uParam), lpwm32mpex->Parm16.WndProc.lParam); if (pTemp && (!(pTemp->Flags))) { GETMISCPTR(lpwm32mpex->Parm16.WndProc.lParam, lpCDS16); GlobalUnlockFree16 ((VPVOID)lpCDS16->lpData); CopyDataDeleteNode (GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->Parm16.WndProc.wParam, (DWORD) ((PCOPYDATASTRUCT)lpwm32mpex->lParam)->lpData); GlobalUnlockFree16 ((VPVOID)lpwm32mpex->Parm16.WndProc.lParam); CopyDataDeleteNode (GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->Parm16.WndProc.wParam, (DWORD) lpwm32mpex->lParam); FREEMISCPTR(lpCDS16); } } }
return (TRUE); }
// This function thunks the message,
//
// WM_WINHELP
//
BOOL FASTCALL WM32WinHelp (LPWM32MSGPARAMEX lpwm32mpex) { static WORD msgWinHelp = 0; if (lpwm32mpex->fThunk) { lpwm32mpex->Parm16.WndProc.wMsg = msgWinHelp ? msgWinHelp : (msgWinHelp = (WORD)RegisterWindowMessage("WM_WINHELP")); lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam); if (lpwm32mpex->lParam) { // lpwm32mpex->lParam is LPHLP - however we need only the firstword,ie the size of data
HAND16 hMem16; VPVOID vp; LPBYTE lpT; WORD cb;
cb = ((LPHLP)lpwm32mpex->lParam)->cbData; if (vp = GlobalAllocLock16(GMEM_DDESHARE | GMEM_MOVEABLE, cb, &hMem16)) { GETMISCPTR(vp, lpT); RtlCopyMemory(lpT, (PVOID)lpwm32mpex->lParam, cb); FREEMISCPTR(lpT); } lpwm32mpex->Parm16.WndProc.lParam = hMem16; lpwm32mpex->dwParam = vp; } } else { // Make sure WinHelp is in the foreground
SetForegroundWindow(lpwm32mpex->hwnd); if (lpwm32mpex->Parm16.WndProc.lParam) { GlobalUnlockFree16((VPVOID)lpwm32mpex->dwParam); } }
return (TRUE); }
//
// Thunk the undocumented MM_CALCSCROLL MDI message. Message has no parameters,
// but has different message values; 32-bit msg: 0x3F, 16-bit msg: 0x10AC.
//
BOOL FASTCALL WM32MMCalcScroll (LPWM32MSGPARAMEX lpwm32mpex) { if ( lpwm32mpex->fThunk ) { lpwm32mpex->Parm16.WndProc.wMsg = (WORD) WIN31_MM_CALCSCROLL; }
return (TRUE); }
// Calculate the size of the structure passed with WM_NOTIFY based
// on the code field in NMHDR.
// NOTE: Do NOT rely on the documentation for the size of the struct passed in
// lParam. In some cases the struct is actually part of a larger struct
// and we need to copy all of it. See PSN_xxxx codes in comctl32\prsht.c
// They are documented to be NMHDR but are really a PSHNOTIFY which has
// NMHDR as the first field. Also watch for some of the WIDE UNICODE
// char cases -- the struct may or may not be the same size as the ANSI
// version of the struct.
// Heaven help us when they start adding more of these codes!
UINT GetNMHDRextensionSize(LPNMHDR pnmhdr32) { #ifdef DEBUG
char szLabel[40] = " WOW:WM_NOTIFY code: "; #endif
// Caller already checked against NM_LAST.
if (pnmhdr32->code >= LVN_LAST) { LOGDEBUG(2,("%sLVN_ %x\n", szLabel, pnmhdr32->code)); switch (pnmhdr32->code) {
case LVN_ITEMCHANGING: case LVN_ITEMCHANGED: case LVN_INSERTITEM: case LVN_DELETEITEM: case LVN_DELETEALLITEMS: case LVN_COLUMNCLICK: case LVN_BEGINDRAG: case LVN_BEGINRDRAG: case LVN_HOTTRACK: return sizeof(NM_LISTVIEW);
case LVN_BEGINLABELEDITA: case LVN_ENDLABELEDITA: case LVN_GETDISPINFOA: case LVN_SETDISPINFOA: case LVN_BEGINLABELEDITW: case LVN_ENDLABELEDITW: case LVN_GETDISPINFOW: case LVN_SETDISPINFOW: return sizeof(LV_DISPINFO);
case LVN_KEYDOWN: return sizeof(LV_KEYDOWN);
case LVN_ODCACHEHINT: return sizeof(NM_CACHEHINT);
case LVN_ODFINDITEMA: case LVN_ODFINDITEMW: return sizeof(NM_FINDITEM);
case LVN_ODSTATECHANGED: return sizeof(NM_ODSTATECHANGE);
case LVN_ITEMACTIVATE: return sizeof(NMKEY);
default: goto unknown_nmhdr_code; } }
if (pnmhdr32->code >= PSN_LAST) { LOGDEBUG(2,("%sPSN_ %x\n", szLabel, pnmhdr32->code)); switch (pnmhdr32->code) { case PSN_SETACTIVE: case PSN_KILLACTIVE: case PSN_APPLY: case PSN_RESET: case PSN_HELP: case PSN_WIZBACK: case PSN_WIZNEXT: case PSN_WIZFINISH: case PSN_QUERYCANCEL: case PSN_TRANSLATEACCELERATOR: case PSN_QUERYINITIALFOCUS: case PSN_HASHELP: // this one "is dead" - RaymondC
return sizeof(PSHNOTIFY);
case PSN_GETOBJECT: return sizeof(NMOBJECTNOTIFY);
case PSN_LASTCHANCEAPPLY: // this is undocumented
return sizeof(NMHDR); // (in widows\inc\prshtp.h)
default: goto unknown_nmhdr_code; } }
if (pnmhdr32->code >= HDN_LAST) { LOGDEBUG(2,("%sHDN_ %x\n", szLabel, pnmhdr32->code)); switch (pnmhdr32->code) { case HDN_ITEMCHANGINGA: case HDN_ITEMCHANGEDA: case HDN_ITEMCLICKA: case HDN_DIVIDERDBLCLICKA: case HDN_BEGINTRACKA: case HDN_ENDTRACKA: case HDN_TRACKA: case HDN_ITEMCHANGINGW: case HDN_ITEMCHANGEDW: case HDN_ITEMCLICKW: case HDN_DIVIDERDBLCLICKW: case HDN_BEGINTRACKW: case HDN_ENDTRACKW: case HDN_TRACKW: case HDN_BEGINDRAG: case HDN_ENDDRAG: case HDN_ITEMDBLCLICKA: case HDN_ITEMDBLCLICKW: return sizeof(HD_NOTIFY);
case HDN_GETDISPINFOA: case HDN_GETDISPINFOW: return sizeof(NMHDDISPINFO);
default: goto unknown_nmhdr_code; } }
if (pnmhdr32->code >= TVN_LAST) { LOGDEBUG(2,("%sTVN_ %x\n", szLabel, pnmhdr32->code)); switch (pnmhdr32->code) { case TVN_SELCHANGINGA: case TVN_SELCHANGEDA: case TVN_ITEMEXPANDINGA: case TVN_ITEMEXPANDEDA: case TVN_BEGINDRAGA: case TVN_BEGINRDRAGA: case TVN_DELETEITEMA: case TVN_SELCHANGINGW: case TVN_SELCHANGEDW: case TVN_ITEMEXPANDINGW: case TVN_ITEMEXPANDEDW: case TVN_BEGINDRAGW: case TVN_BEGINRDRAGW: case TVN_DELETEITEMW: case TVN_SINGLEEXPAND: return sizeof(NM_TREEVIEW);
case TVN_GETDISPINFOA: case TVN_SETDISPINFOA: case TVN_BEGINLABELEDITA: case TVN_ENDLABELEDITA: case TVN_GETDISPINFOW: case TVN_SETDISPINFOW: case TVN_BEGINLABELEDITW: case TVN_ENDLABELEDITW: return sizeof(TV_DISPINFO);
case TVN_KEYDOWN: return sizeof(TV_KEYDOWN);
case TVN_GETINFOTIPA: case TVN_GETINFOTIPW: return sizeof(NMTVGETINFOTIP);
default: goto unknown_nmhdr_code; } }
if (pnmhdr32->code >= TTN_LAST) { LOGDEBUG(2,("%sTTN_ %x\n", szLabel, pnmhdr32->code)); switch (pnmhdr32->code) { case TTN_NEEDTEXTA: // (aka TTN_GETDISPINFO)
return sizeof(TOOLTIPTEXTA);
case TTN_NEEDTEXTW: return sizeof(TOOLTIPTEXTW);
case TTN_SHOW: case TTN_POP: return sizeof(NMHDR);
default: goto unknown_nmhdr_code; } }
if (pnmhdr32->code >= TCN_LAST) { LOGDEBUG(2,("%sTCN_ %x\n", szLabel, pnmhdr32->code)); switch (pnmhdr32->code) { case TCN_KEYDOWN: return sizeof(TC_KEYDOWN);
case TCN_SELCHANGE: case TCN_SELCHANGING: return sizeof(NMHDR);
default: goto unknown_nmhdr_code; } }
if (pnmhdr32->code >= UDN_LAST) { LOGDEBUG(2,("%sUDN_ %x\n", szLabel, pnmhdr32->code)); switch (pnmhdr32->code) { case UDN_DELTAPOS: return sizeof(NM_UPDOWN);
default: goto unknown_nmhdr_code; } }
unknown_nmhdr_code: LOGDEBUG(LOG_ALWAYS, ("WOW:GetNMHDRextensionSize unknown nmhdr->code: %d!\n", pnmhdr32->code)); WOW32ASSERT(FALSE); return sizeof(NMHDR); // the first field of most of the structs is NMHDR
}
//
// This function thunks the 32-bit message WM_NOTIFY. This message existed
// but was undocumented in Win3.1. Win95 thunks it by translating lParam
// from a flat to 16:16 pointer without thunking the contents. That's tricky
// for us since on RISC we can't map random linear memory into the VDM without
// a lot of overhead. We'll use the code field in NMHDR to calculate the size
// of the passed structure.
//
BOOL FASTCALL WM32Notify(LPWM32MSGPARAMEX lpwm32mpex) { LPNMHDR pnmhdr32; LPNMHDR pnmhdr16;
if (lpwm32mpex->fThunk) {
pnmhdr32 = (LPNMHDR) lpwm32mpex->Parm16.WndProc.lParam;
// Save the original 32-bit flat pointer for unthunking.
lpwm32mpex->dwTmp[0] = (DWORD) pnmhdr32;
// If this 32bit message came from WOW, we have the original
// 16:16 lparam squirrelled away. (mapped to the original 32-bit lParam)
// Note: If the mapping is found, the ref count gets incremented.
lpwm32mpex->Parm16.WndProc.lParam = (LONG)GetParam16(lpwm32mpex->lParam);
// if we don't already have a 16:16 ptr for this -- create one
// This means we are seeing this message for the 1st time -- coming
// from the 32-bit world.
if ( ! lpwm32mpex->Parm16.WndProc.lParam) { if (pnmhdr32->code >= NM_LAST) { lpwm32mpex->dwParam = sizeof(NMHDR); } else { lpwm32mpex->dwParam = GetNMHDRextensionSize(pnmhdr32); }
// be sure allocation size matches stackfree16() size below
lpwm32mpex->dwTmp[1] = (DWORD)lpwm32mpex->dwParam; lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(lpwm32mpex->dwTmp[1]); GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, lpwm32mpex->dwParam, pnmhdr16); CopyMemory(pnmhdr16, pnmhdr32, lpwm32mpex->dwParam); FREEVDMPTR(pnmhdr16);
// else don't allocate (or free) another 16:16 ptr
} else {
// set to FALSE so we don't free this thing too soon
lpwm32mpex->fFree = FALSE; }
} else {
if (lpwm32mpex->fFree) { GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, lpwm32mpex->dwParam, pnmhdr16); // retrieve original 32-bit pointer
pnmhdr32 = (LPNMHDR) lpwm32mpex->dwTmp[0]; CopyMemory(pnmhdr32, pnmhdr16, lpwm32mpex->dwParam); FREEVDMPTR(pnmhdr16); if(lpwm32mpex->Parm16.WndProc.lParam) { stackfree16(lpwm32mpex->Parm16.WndProc.lParam, lpwm32mpex->dwTmp[1]); } } else {
// Decrement the ref count. If the ref count goes to zero, the
// mapping is nuked.
DeleteParamMap(lpwm32mpex->Parm16.WndProc.lParam, PARAM_16, NULL); } }
return TRUE; }
// This function thunks the 32-bit message WM_NOTIFYWOW.
// uParam dictates where the notification should be dispatched.
//
BOOL FASTCALL WM32NotifyWow(LPWM32MSGPARAMEX lpwm32mpex) { switch (lpwm32mpex->uParam) { case WMNW_UPDATEFINDREPLACE: if (lpwm32mpex->fThunk) { // Update the 16-bit FINDREPLACE struct.
lpwm32mpex->Parm16.WndProc.lParam = WCD32UpdateFindReplaceTextAndFlags(lpwm32mpex->hwnd, lpwm32mpex->lParam); lpwm32mpex->Parm16.WndProc.wMsg = msgFINDREPLACE; return(TRUE); } break;
default: LOGDEBUG(LOG_ALWAYS, ("WOW::WM32NotifyWow: Unknown dispatch parameter!\n")); WOW32ASSERT (FALSE);
}
return (FALSE); }
//
// In ThunkMsg16 we use the data in 32->16 message thunk table to optimize
// thunking process based on 'WM32NoThunking'.
//
// This is place holder for those messages which need nothunking on 32-16
// trasitions but need some kind of thunking on 16->32 transistions.
//
// So this marks the message as 'this message needs 16-32 thunking but
// not 32-16 thunking'
//
// - nanduri
BOOL FASTCALL WM32Thunk16To32(LPWM32MSGPARAMEX lpwm32mpex) { return (TRUE); } #ifdef FE_IME
//
// This function thunks the messages,
//
// WM_IME_REPORT
/*
BOOL FASTCALL WM32IMEReport (HWND hwnd, UINT uMsg, UINT uParam, LONG lParam, PWORD pwMsgNew, PWORD pwParamNew, PLONG plParamNew, PLONG plReturn, BOOL fThunk, LPWM32MSGPARAMEX lpwm32mpex) */ BOOL FASTCALL WM32IMEReport (LPWM32MSGPARAMEX lpwm32mpex) { //lpwm32mpex->hwnd
//lpwm32mpex->uMsg
//lpwm32mpex->uParam
//lpwm32mpex->lParam
//lpwm32mpex->Param16.WndProc.wMsg
//lpwm32mpex->Param16.WndProc.wParam
//lpwm32mpex->Param16.WndProc.lParam
//&lpwm32mpex->lReturn
//lpwm32mpex->fThunk
//
INT cb; INT i; HMEM16 hMem16 = 0; LPBYTE lpMem32 = 0; LPBYTE lpMem16 = 0; VPVOID vp;
if (lpwm32mpex->fThunk) { if (lpwm32mpex->uParam == IR_STRING) { lpMem32 = GlobalLock((HANDLE)lpwm32mpex->lParam); if (lpMem32 == NULL) goto Err;
cb = strlen( lpMem32 ) + 1; if (!(lpwm32mpex->Parm16.WndProc.lParam = GlobalAllocLock16(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, cb, &hMem16 ))) goto Err; putstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, lpMem32, cb); LOW( lpwm32mpex->Parm16.WndProc.lParam ) = hMem16; HIW( lpwm32mpex->Parm16.WndProc.lParam ) = 0; // must be zero
GlobalUnlock( (HANDLE)lpwm32mpex->lParam ); GlobalUnlock16( hMem16 ); } /**** IR_STRINGEX ****/ else if ( lpwm32mpex->uParam == IR_STRINGEX ) { LPSTRINGEXSTRUCT pss32; PSTRINGEXSTRUCT16 pss16;
lpMem32 = GlobalLock((HANDLE)lpwm32mpex->lParam); if (lpMem32 == NULL) goto Err;
pss32 = (LPSTRINGEXSTRUCT)lpMem32;
cb = pss32->dwSize; if ( cb >= ( 64 * K )) { // It's problem !
LOGDEBUG(0,(" WOW:: WM_IME_REPORT:IR_STRINGEX data size must be less than 64K on WOW. cb = %d\n", cb )); /** goto Err; **/ } // Shuld I pack size of this structure ?
if (!(vp = GlobalAllocLock16(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, cb, &hMem16 ))) return FALSE;
GETVDMPTR(vp, cb, lpMem16 ); pss16 = (PSTRINGEXSTRUCT16)lpMem16;
STOREDWORD( pss16->dwSize, pss32->dwSize ); STOREWORD( pss16->uDeterminePos, pss32->uDeterminePos ); STOREWORD( pss16->uDetermineDelimPos, pss32->uDetermineDelimPos ); STOREWORD( pss16->uYomiPos, pss32->uYomiPos ); STOREWORD( pss16->uYomiDelimPos, pss32->uYomiDelimPos );
if ( pss32->uDeterminePos ) { cb = strlen( (LPBYTE)&lpMem32[ pss32->uDeterminePos ] ); RtlCopyMemory( &lpMem16[ pss16->uDeterminePos ], &lpMem32[ pss32->uDeterminePos ], cb + 1 ); if ( pss32->uDetermineDelimPos ) { for ( i = 0; pss32->uDetermineDelimPos + i * sizeof(INT) < pss32->dwSize; i++ ) { WORDOF16( lpMem16[ pss16->uDetermineDelimPos ], i ) = (WORD) INTOF( lpMem32[ pss32->uDetermineDelimPos ], i ); if ( INTOF( lpMem32[ pss32->uDetermineDelimPos ], i ) >= cb ) break; } } }
if ( pss32->uYomiPos ) { cb = strlen( (LPBYTE)&lpMem32[ pss32->uYomiPos ] ); RtlCopyMemory( &lpMem16[ pss16->uYomiPos ], &lpMem32[ pss32->uYomiPos ], cb + 1 ); if ( pss32->uYomiDelimPos ) { for ( i = 0; pss32->uYomiDelimPos + i * sizeof(INT) < pss32->dwSize; i++ ) { WORDOF16( lpMem16[ pss16->uYomiDelimPos ], i ) = (WORD) INTOF( lpMem32[ pss32->uYomiDelimPos ], i ); if ( INTOF( lpMem32[ pss32->uYomiDelimPos ], i ) >= cb ) break; } } }
FLUSHVDMPTR(vp, cb, lpMem16); FREEVDMPTR(lpMem16);
LOW( lpwm32mpex->Parm16.WndProc.lParam ) = hMem16; HIW( lpwm32mpex->Parm16.WndProc.lParam ) = 0; // must be zero
GlobalUnlock( (HANDLE)lpwm32mpex->lParam ); GlobalUnlock16( hMem16 ); } /**** IR_UNDETERMINE ****/ else if (lpwm32mpex->uParam == IR_UNDETERMINE) { PUNDETERMINESTRUCT16 pus16; LPUNDETERMINESTRUCT pus32;
lpMem32 = GlobalLock( (HANDLE)lpwm32mpex->lParam ); if (lpMem32 == NULL) goto Err;
pus32 = (LPUNDETERMINESTRUCT)lpMem32; cb = pus32->dwSize;
if ( cb >= ( 64 * K )) { // It's problem !
LOGDEBUG(0,(" WOW:: WM_IME_REPORT:IR_UNDETERMINE data size must be less than 64K on WOW. cb = %d\n", cb )); /** goto Err; **/ } if (!( vp = GlobalAllocLock16(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, cb, &hMem16 ))) goto Err;
GETVDMPTR(vp, cb, lpMem16 ); pus16 = (PUNDETERMINESTRUCT16)lpMem16;
STOREDWORD( pus16->dwSize, (pus32)->dwSize ); STOREWORD( pus16->uDefIMESize, (pus32)->uDefIMESize ); STOREWORD( pus16->uDefIMEPos, (pus32)->uDefIMEPos ); STOREWORD( pus16->uUndetTextLen, (pus32)->uUndetTextLen ); STOREWORD( pus16->uUndetTextPos, (pus32)->uUndetTextPos ); STOREWORD( pus16->uUndetAttrPos, (pus32)->uUndetAttrPos ); STOREWORD( pus16->uCursorPos, (pus32)->uCursorPos ); STOREWORD( pus16->uDeltaStart, (pus32)->uDeltaStart ); STOREWORD( pus16->uDetermineTextLen, (pus32)->uDetermineTextLen ); STOREWORD( pus16->uDetermineTextPos, (pus32)->uDetermineTextPos ); STOREWORD( pus16->uDetermineDelimPos, (pus32)->uDetermineDelimPos ); STOREWORD( pus16->uYomiTextLen, (pus32)->uYomiTextLen ); STOREWORD( pus16->uYomiTextPos, (pus32)->uYomiTextPos ); STOREWORD( pus16->uYomiDelimPos, (pus32)->uYomiDelimPos );
// dada copy
RtlCopyMemory( &lpMem16[ sizeof(UNDETERMINESTRUCT) ], &lpMem32[ sizeof(UNDETERMINESTRUCT) ], cb - sizeof( UNDETERMINESTRUCT ));
//adjustment
if ( pus32->uDetermineDelimPos ) { cb = pus32->uDetermineTextLen; for ( i = 0; pus32->uDetermineDelimPos + i * sizeof(INT) < pus32->dwSize; i++ ) { INTOF( lpMem16[ pus16->uDetermineDelimPos ], i ) = 0; WORDOF16( lpMem16[ pus16->uDetermineDelimPos ], i ) = (WORD) INTOF( lpMem32[ pus32->uDetermineDelimPos ], i ); if ( INTOF( lpMem32[ pus32->uDetermineDelimPos ], i ) >= cb ) break; } } if ( pus32->uYomiDelimPos ) { cb = pus32->uYomiTextLen; for ( i = 0; pus32->uYomiDelimPos + i * sizeof(INT) < pus32->dwSize; i++ ) { INTOF( lpMem16[ pus16->uYomiDelimPos ], i ) = 0; WORDOF16( lpMem16[ pus16->uYomiDelimPos ], i ) = (WORD) INTOF( lpMem32[ pus32->uYomiDelimPos ], i ); if ( INTOF( lpMem32[ pus32->uYomiDelimPos ], i ) >= cb ) break; } }
FLUSHVDMPTR(vp, cb, lpMem16); FREEVDMPTR(lpMem16);
LOW( lpwm32mpex->Parm16.WndProc.lParam ) = hMem16; HIW( lpwm32mpex->Parm16.WndProc.lParam ) = 0; // must be zero
GlobalUnlock( (HANDLE)lpwm32mpex->lParam ); GlobalUnlock16( hMem16 );
} } else { // fThunk
if (lpwm32mpex->Parm16.WndProc.lParam) { GlobalUnlockFree16(GlobalLock16(LOW(lpwm32mpex->Parm16.WndProc.lParam), NULL)); } } return (TRUE);
Err: if ( lpMem32 && lpwm32mpex->lParam ) GlobalUnlock( (HANDLE)lpwm32mpex->lParam ); return FALSE;
} #endif // FE_IME
|