windows-nt/Source/XPSP1/NT/base/mvdm/wow32/wcntl32.c
2020-09-26 16:20:57 +08:00

1119 lines
32 KiB
C

/*++
*
* WOW v1.0
*
* Copyright (c) 1991, Microsoft Corporation
*
* WMSG32.C
* WOW32 32-bit message thunks
*
* History:
* Created 19-Feb-1992 by Chandan Chauhan (ChandanC)
--*/
#include "precomp.h"
#pragma hdrstop
MODNAME(wcntl32.c);
// This function thunks the button control messages,
//
// BM_GETCHECK
// BM_SETCHECK
// BM_GETSTATE
// BM_SETSTATE
// BM_SETSTYLE
//
BOOL FASTCALL WM32BMControl(LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - BM_GETCHECK));
}
return (TRUE);
}
BOOL FASTCALL WM32BMClick (LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WIN31_BM_CLICK);
}
return (TRUE);
}
// This function thunks the following edit control messages,
//
// EM_GETSEL
// EM_GETMODIFY
// EM_SETMODIFY
// EM_GETLINECOUNT
// EM_GETLINEINDEX
// EM_LINELENGTH
// EM_LIMITTEX
// EM_CANUNDO
// EM_UNDO
// EM_FMTLINES
// EM_LINEFROMCHAR
// EM_SETPASSWORDCHAR
// EM_EMPTYUNDOBUFFER
BOOL FASTCALL WM32EMControl(LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
}
return (TRUE);
}
// This function thunks the button control messages,
//
// EM_SETSEL
//
BOOL FASTCALL WM32EMSetSel (LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
LOW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lpwm32mpex->uParam;
HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD)
((lpwm32mpex->lParam != -1) ? lpwm32mpex->lParam : 32767);
}
return (TRUE);
}
// This function thunks the edit control messages,
//
// EM_GETRECT
//
BOOL FASTCALL WM32EMGetRect (LPWM32MSGPARAMEX lpwm32mpex)
{
if ( lpwm32mpex->fThunk ) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(RECT16));
if (!(lpwm32mpex->Parm16.WndProc.lParam))
return FALSE;
} else {
GETRECT16( lpwm32mpex->Parm16.WndProc.lParam, (LPRECT)lpwm32mpex->lParam );
if (lpwm32mpex->Parm16.WndProc.lParam)
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
}
return (TRUE);
}
// This function thunks the edit control messages,
//
// EM_SETRECT
// EM_SETRECTNP
//
BOOL FASTCALL WM32EMSetRect (LPWM32MSGPARAMEX lpwm32mpex)
{
if ( lpwm32mpex->fThunk ) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(RECT16));
if (!(lpwm32mpex->Parm16.WndProc.lParam))
return FALSE;
PUTRECT16( lpwm32mpex->Parm16.WndProc.lParam, (LPRECT)lpwm32mpex->lParam );
} else {
if (lpwm32mpex->Parm16.WndProc.lParam)
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
}
return (TRUE);
}
// This function thunks the edit control messages,
//
// EM_LINESCROLL
//
BOOL FASTCALL WM32EMLineScroll (LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
LOW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lpwm32mpex->lParam;
HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lpwm32mpex->uParam;
}
return (TRUE);
}
// This function thunks the edit control messages,
//
// EM_REPLACESEL
//
BOOL FASTCALL WM32EMReplaceSel (LPWM32MSGPARAMEX lpwm32mpex)
{
if ( lpwm32mpex->fThunk ) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
if (lpwm32mpex->lParam) {
INT cb;
cb = strlen((LPSZ)lpwm32mpex->lParam)+1;
lpwm32mpex->dwTmp[0] = (DWORD)cb; // save allocation size
// winworks2.0a requires DS based string pointers for this message
if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_DSBASEDSTRINGPOINTERS) {
// be sure allocation size matches stackfree16() size below
lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(cb);
} else {
lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb);
}
if (!(lpwm32mpex->Parm16.WndProc.lParam))
return FALSE;
putstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, cb);
}
} else {
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);
}
BOOL FASTCALL WM32EMSetFont (LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
}
LOGDEBUG(0,(" Window %08lX is receiving Control Message %s(%08x)\n", lpwm32mpex->hwnd, (LPSZ)GetWMMsgName(lpwm32mpex->uMsg), lpwm32mpex->uMsg));
return (TRUE);
}
// This function thunks the edit control messages,
//
// EM_GETLINE
//
BOOL FASTCALL WM32EMGetLine (LPWM32MSGPARAMEX lpwm32mpex)
{
if ( lpwm32mpex->fThunk ) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
if (lpwm32mpex->lParam) {
INT cb;
PBYTE lp;
// the first WORD is what USER uses.
cb = *(UNALIGNED WORD *)(lpwm32mpex->lParam);
lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb);
if (!(lpwm32mpex->Parm16.WndProc.lParam))
return FALSE;
ALLOCVDMPTR(lpwm32mpex->Parm16.WndProc.lParam,2,lp);
*((UNALIGNED WORD *)lp) = (WORD)cb;
FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam,2,lp); /* first 2 bytes modified */
}
} else {
if (lpwm32mpex->Parm16.WndProc.lParam) {
PBYTE lp;
GETMISCPTR(lpwm32mpex->Parm16.WndProc.lParam,lp);
RtlCopyMemory((PBYTE)lpwm32mpex->lParam,lp,lpwm32mpex->lReturn);
FREEVDMPTR(lp);
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
}
}
LOGDEBUG(3,(" Window %08lX is receiving Control Message %s(%08x)\n", lpwm32mpex->hwnd, (LPSZ)GetWMMsgName(lpwm32mpex->uMsg), lpwm32mpex->uMsg));
return (TRUE);
}
BOOL FASTCALL WM32EMSetWordBreakProc (LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
// take out the marker bits and fix the RPL bits
UnMarkWOWProc (lpwm32mpex->lParam,lpwm32mpex->Parm16.WndProc.lParam);
LOGDEBUG(3,(" Window %08lX is receiving Control Message %s(%08x)\n", lpwm32mpex->hwnd, (LPSZ)GetWMMsgName(lpwm32mpex->uMsg), lpwm32mpex->uMsg));
}
return (TRUE);
}
BOOL FASTCALL WM32EMGetWordBreakProc (LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
LOGDEBUG(3,(" Window %08lX is receiving Control Message %s(%08x)\n", lpwm32mpex->hwnd, (LPSZ)GetWMMsgName(lpwm32mpex->uMsg), lpwm32mpex->uMsg));
}
else {
// Mark the address as WOW Proc and store the high bits in the RPL field
MarkWOWProc (lpwm32mpex->lReturn,lpwm32mpex->lReturn);
}
return (TRUE);
}
// This function thunks the edit control messages,
//
// EM_SETTABSTOPS
//
BOOL FASTCALL WM32EMSetTabStops (LPWM32MSGPARAMEX lpwm32mpex)
{
if ( lpwm32mpex->fThunk ) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
if (lpwm32mpex->uParam != 0) {
lpwm32mpex->Parm16.WndProc.lParam = malloc16(lpwm32mpex->uParam * sizeof(WORD));
if (!(lpwm32mpex->Parm16.WndProc.lParam))
return FALSE;
putintarray16((VPINT16)lpwm32mpex->Parm16.WndProc.lParam, (INT)lpwm32mpex->uParam, (LPINT)lpwm32mpex->lParam);
}
} else {
if (lpwm32mpex->Parm16.WndProc.lParam)
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
}
return (TRUE);
}
// This function thunks the following combo box control messages,
//
// CB_GETEDITSEL
// CB_LIMITTEXT
// CB_SETEDITSEL
// CB_DELETESTRING
// CB_GETCOUNT
// CB_GETCURSEL
// CB_GETLBTEXTLEN
// CB_SETCURSEL
// CB_SHOWDROPDOWN
// CB_GETITEMDATA
// CB_SETITEMDATA
BOOL FASTCALL WM32CBControl (LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - CB_GETEDITSEL));
}
return (TRUE);
}
// This function thunks the following combo box control messages,
//
// CB_ADDSTRING
// CB_INSERTSTRING
// CB_FINDSTRING
// CB_SELECTSTRING
BOOL FASTCALL WM32CBAddString (LPWM32MSGPARAMEX lpwm32mpex)
{
PWW pww;
if ( lpwm32mpex->fThunk ) {
if (!(pww = lpwm32mpex->pww)) {
if (pww = FindPWW (lpwm32mpex->hwnd))
lpwm32mpex->pww = pww;
else
return FALSE;
}
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - CB_GETEDITSEL));
//
// Determine if this combobox has string pointers or handles passed
// in with CB_ADDSTRING messages. Normal comboboxes have string
// pointers passed. Owner-draw comboboxes that don't have the
// CBS_HASSTRINGS style bit set have handles passed in. These handles
// are simply passed back to the owner at paint time. If the
// CBS_HASSTRINGS style bit is set, strings are used instead of
// handles as the "cookie" which is passed back to the application
// at paint time.
//
// We treat lpwm32mpex->dwParam as a BOOL indicating this combobox
// takes handles instead of strings.
//
lpwm32mpex->dwParam =
(pww->style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) &&
!(pww->style & CBS_HASSTRINGS);
if ( !lpwm32mpex->dwParam ) { // if strings are used
if (lpwm32mpex->lParam) {
INT cb;
cb = strlen((LPSZ)lpwm32mpex->lParam)+1;
lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb);
if (!(lpwm32mpex->Parm16.WndProc.lParam))
return FALSE;
putstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, cb);
}
}
} else {
if ( !lpwm32mpex->dwParam ) { // if strings are used
if (lpwm32mpex->Parm16.WndProc.lParam) {
getstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, -1);
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
}
}
}
LOGDEBUG(3,(" Window %08lX is receiving Control Message %s(%08x)\n", lpwm32mpex->hwnd, (LPSZ)GetWMMsgName(lpwm32mpex->uMsg), lpwm32mpex->uMsg));
return(TRUE);
}
// This function thunks the following combo box control messages,
//
// CB_DIR
//
// Code in this routine references code in wparam.c in order to circumvent
// copying memory to 16-bit memory space.
// GetParam16 verifies that the parameter we get (lparam) had not originated
// in 16-bit code. If it did come from 16-bit code, then we send an original
// 16:16 pointer to the application.
// This fixes PagePlus 3.0 application and (if implemented on a broader scale)
// will positively affect performance of applications which send a lot of
// standard messages and use subclassing a lot.
// -- VadimB
BOOL FASTCALL WM32CBDir (LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - CB_GETEDITSEL));
if (lpwm32mpex->lParam) {
INT cb;
if (W32CheckThunkParamFlag()) {
LONG lParam = (LONG)GetParam16(lpwm32mpex->lParam);
if (lParam) {
lpwm32mpex->Parm16.WndProc.lParam = lParam;
return (TRUE);
}
}
cb = strlen((LPSZ)lpwm32mpex->lParam)+1;
lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb);
if (!(lpwm32mpex->Parm16.WndProc.lParam))
return FALSE;
putstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, cb);
}
} else {
if (W32CheckThunkParamFlag()) {
if (DeleteParamMap(lpwm32mpex->Parm16.WndProc.lParam, PARAM_16, NULL)) {
return TRUE;
}
}
if (lpwm32mpex->Parm16.WndProc.lParam)
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
}
return(TRUE);
}
// This function thunks the following combo box control messages,
//
// CB_GETLBTEXT
BOOL FASTCALL WM32CBGetLBText (LPWM32MSGPARAMEX lpwm32mpex)
{
PWW pww;
if ( lpwm32mpex->fThunk ) {
INT cb;
if (!(pww = lpwm32mpex->pww)) {
if (pww = FindPWW (lpwm32mpex->hwnd))
lpwm32mpex->pww = pww;
else
return FALSE;
}
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - CB_GETEDITSEL));
//
// Determine if this combobox has string pointers or handles passed
// in with CB_ADDSTRING messages. Normal comboboxes have string
// pointers passed. Owner-draw comboboxes that don't have the
// CBS_HASSTRINGS style bit set have handles passed in. These handles
// are simply passed back to the owner at paint time. If the
// CBS_HASSTRINGS style bit is set, strings are used instead of
// handles as the "cookie" which is passed back to the application
// at paint time.
//
// We treat lpwm32mpex->dwParam as a BOOL indicating this combobox
// takes handles instead of strings.
//
lpwm32mpex->dwParam =
(pww->style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) &&
!(pww->style & CBS_HASSTRINGS);
//
// Determine the size of the buffer to allocate on the 16-bit side
// to receive the text.
//
if (lpwm32mpex->dwParam) { // if handles are used
cb = 4;
} else {
cb = SendMessage(lpwm32mpex->hwnd, CB_GETLBTEXTLEN, lpwm32mpex->uParam, 0);
if (cb == CB_ERR) {
//
// lpwm32mpex->dwTmp[0] is initialized to 0 so that nothing
// gets copied to the buffer by getstr16() while unthunking
// this message.
//
// bug # 24415, ChandanC
//
cb = SIZE_BOGUS;
lpwm32mpex->dwTmp[0] = 0;
}
else {
//
// Add one for NULL character.
//
cb = cb + 1;
(INT) lpwm32mpex->dwTmp[0] = (INT) -1;
}
}
if (lpwm32mpex->lParam) {
BYTE *lpT;
// See comment on similar code below
lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb);
if (!(lpwm32mpex->Parm16.WndProc.lParam))
return FALSE;
GETVDMPTR((lpwm32mpex->Parm16.WndProc.lParam), sizeof(BYTE), lpT);
*lpT = 0;
FREEVDMPTR(lpT);
}
}
else {
if (lpwm32mpex->lParam && lpwm32mpex->Parm16.WndProc.lParam) {
if (lpwm32mpex->dwParam) { // if handles are used
UNALIGNED DWORD *lpT;
GETVDMPTR((lpwm32mpex->Parm16.WndProc.lParam), sizeof(DWORD), lpT);
*(UNALIGNED DWORD *)lpwm32mpex->lParam = *lpT;
FREEVDMPTR(lpT);
}
else {
getstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam,
(INT) lpwm32mpex->dwTmp[0]);
}
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
}
}
return(TRUE);
}
// This function thunks the following combo box control messages,
//
// CB_GETDROPPEDCONTROLRECT
BOOL FASTCALL WM32CBGetDropDownControlRect (LPWM32MSGPARAMEX lpwm32mpex)
{
if ( lpwm32mpex->fThunk ) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - CB_GETEDITSEL));
lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(RECT16));
if (!(lpwm32mpex->Parm16.WndProc.lParam))
return FALSE;
} else {
GETRECT16( lpwm32mpex->Parm16.WndProc.lParam, (LPRECT)lpwm32mpex->lParam );
if (lpwm32mpex->Parm16.WndProc.lParam)
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
}
return(TRUE);
}
// This function thunks the following combo box control messages,
//
// CBEC_SETCOMBOFOCUS (WM_USER+CB_MSGMAX+1)
// CBEC_KILLCOMBOFOCUS (WM_USER+CB_MSGMAX+2)
// These undocumented messages are used by Excel 5.0
//
BOOL FASTCALL WM32CBComboFocus (LPWM32MSGPARAMEX lpwm32mpex)
{
#if (CBEC_SETCOMBOFOCUS != 0x166)
#error The USER Guys changed CBEC_SETCOMBOFOCUS again
#endif
#if (CBEC_KILLCOMBOFOCUS != 0x167)
#error The USER Guys changed CBEC_KILLCOMBOFOCUS again
#endif
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg =
(WORD)((lpwm32mpex->uMsg-CBEC_SETCOMBOFOCUS) + OLDCBEC_SETCOMBOFOCUS);
}
return (TRUE);
}
// This function thunks the list box control messages
//
// LB_RESETCONTENT
// LB_SETCURSEL
// LB_GETSEL
// LB_GETCURSEL
// LB_GETTEXTLEN
// LB_GETCOUNT
// LB_GETCARETINDEX
// LB_GETTOPINDEX
// LB_GETSELCOUNT
// LB_GETHORIZONTALEXTENT
// LB_SETHORIZONTALEXTENT
// LB_SETCOLUMNWIDTH
// LB_SETTOPINDEX
// LB_SETCARETINDEX
// LB_SETITEMDATA
// LB_SELITEMRANGE
// LB_SETITEMHEIGHT
// LB_GETITEMHEIGHT
// LB_DELETESTRING
//
BOOL FASTCALL WM32LBControl (LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
}
return (TRUE);
}
// This function thunks the list box control messages
//
// LB_GETTEXT
BOOL FASTCALL WM32LBGetText (LPWM32MSGPARAMEX lpwm32mpex)
{
PWW pww;
if ( lpwm32mpex->fThunk ) {
INT cb;
if (!(pww = lpwm32mpex->pww)) {
if (pww = FindPWW (lpwm32mpex->hwnd))
lpwm32mpex->pww = pww;
else
return FALSE;
}
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
//
// Determine if this listbox has string pointers or handles passed
// in with LB_ADDSTRING messages. Owner-draw listboxes that don't
// have the LBS_HASSTRINGS style bit set have handles passed in.
// These handles are simply passed back to the owner at paint time.
// If the LBS_HASSTRINGS style bit is set, strings are used instead of
// handles as the "cookie" which is passed back to the application
// at paint time.
//
// We treat lpwm32mpex->dwParam as a BOOL indicating this listbox
// takes handles instead of strings.
//
lpwm32mpex->dwParam =
(pww->style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) &&
!(pww->style & LBS_HASSTRINGS);
if (lpwm32mpex->dwParam) { // if this listbox takes handles
cb = 4;
}
else {
cb = SendMessage(lpwm32mpex->hwnd, LB_GETTEXTLEN, lpwm32mpex->uParam, 0);
// Check for LB_ERR (which is -1) on the above SendMessage().
// When cb is equal to LB_ERR make the size as SIZE_BOGUS (256 bytes),
// and allocate a buffer just in case if the app diddles the lParam.
// We will free the buffer while unthunking the message (LB_GETTEXT).
// This fix makes the app MCAD happy.
// ChandanC 4-21-93.
if (cb == LB_ERR) {
cb = SIZE_BOGUS;
}
else {
//
// Add one for NULL character.
//
cb = cb + 1;
}
}
if (lpwm32mpex->lParam) {
BYTE *lpT;
lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb);
if (!(lpwm32mpex->Parm16.WndProc.lParam))
return FALSE;
// The reason for this code to be here is that sometimes thunks
// are executed on a buffer that has not been initialized, e.g.
// if the hooks are installed by a wow app. That means we will
// alloc 16-bit buffer while thunking (boils down to uninitialized
// data buffer and will try to copy the buffer back while unthunking
// overwriting the stack sometimes (as user allocates temp bufs from
// the stack). This code initializes data so problem is avoided
// App: Grammatik/Windows v6.0 -- VadimB
GETVDMPTR((lpwm32mpex->Parm16.WndProc.lParam), sizeof(BYTE), lpT);
*lpT = 0;
FREEVDMPTR(lpT);
}
}
else {
if ((lpwm32mpex->lReturn != LB_ERR) && lpwm32mpex->lParam && lpwm32mpex->Parm16.WndProc.lParam) {
if (lpwm32mpex->dwParam) { // if this listbox takes handles
UNALIGNED DWORD *lpT;
GETVDMPTR((lpwm32mpex->Parm16.WndProc.lParam), sizeof(DWORD), lpT);
*(UNALIGNED DWORD *)lpwm32mpex->lParam = *lpT;
FREEVDMPTR(lpT);
}
else {
getstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, -1);
}
}
if (lpwm32mpex->Parm16.WndProc.lParam) {
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
}
}
return(TRUE);
}
// This function thunks the list box control messages
//
// LB_GETTEXTLEN
BOOL FASTCALL WM32LBGetTextLen (LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
// USER32 and so do we send the LB_GETTEXTLEN message whenever an
// LB_GETTEXT message is sent. This LB_GETTEXTLEN message is an
// additional message that an app normally wouldn't see in WIN31.
// lParam by definition is NULL.
//
// Super Project dies (at times) when it receives the LB_GETTEXTLEN
// message. It doesn't expect to see this message and as a result does
// strlen(lParam) and dies.
// - nanduri
if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_LB_NONNULLLPARAM) {
// be sure allocation size matches stackfree16() size below
LPBYTE lpT = (LPBYTE)stackalloc16(0x2); // just an even number
lpwm32mpex->Parm16.WndProc.lParam = (LONG)lpT;
GETVDMPTR(lpT, 0x2, lpT);
*lpT = '\0';
}
} else {
if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_LB_NONNULLLPARAM) {
if(lpwm32mpex->Parm16.WndProc.lParam) {
stackfree16((VPVOID)lpwm32mpex->Parm16.WndProc.lParam, 0x2);
}
}
}
return (TRUE);
}
// This function thunks the list box control messages
//
// LB_DIR
BOOL FASTCALL WM32LBDir (LPWM32MSGPARAMEX lpwm32mpex)
{
INT cb;
VPVOID vp;
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
if (lpwm32mpex->lParam) {
cb = strlen((LPSTR)lpwm32mpex->lParam)+1;
if (!(vp = malloc16(cb))) {
LOGDEBUG(0,(" WOW32.DLL : WM32LBDir() :: Could not allocate memory for string, ChandanC\n"));
WOW32ASSERT(vp);
return FALSE;
}
putstr16(vp, (LPSTR) lpwm32mpex->lParam, cb);
lpwm32mpex->Parm16.WndProc.lParam = vp;
}
}
else {
if (lpwm32mpex->Parm16.WndProc.lParam) {
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
}
}
return(TRUE);
}
// This function thunks the list box control messages
//
// LB_GETSELITEMS
BOOL FASTCALL WM32LBGetSelItems (LPWM32MSGPARAMEX lpwm32mpex)
{
if ( lpwm32mpex->fThunk ) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
if (lpwm32mpex->lParam) {
INT cb;
cb = lpwm32mpex->uParam * sizeof(WORD);
lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb);
if (!(lpwm32mpex->Parm16.WndProc.lParam))
return FALSE;
}
} else {
getintarray16((VPRECT16)lpwm32mpex->Parm16.WndProc.lParam, (INT)lpwm32mpex->uParam, (LPINT)lpwm32mpex->lParam);
if (lpwm32mpex->Parm16.WndProc.lParam)
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
}
return(TRUE);
}
// This function thunks the list box control messages
//
// LB_SETTABSTOPS
BOOL FASTCALL WM32LBSetTabStops (LPWM32MSGPARAMEX lpwm32mpex)
{
if ( lpwm32mpex->fThunk ) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
if (lpwm32mpex->uParam != 0) {
lpwm32mpex->Parm16.WndProc.lParam = malloc16(lpwm32mpex->uParam * sizeof(WORD));
if (!(lpwm32mpex->Parm16.WndProc.lParam))
return FALSE;
putintarray16((VPRECT16)lpwm32mpex->Parm16.WndProc.lParam, (INT)lpwm32mpex->uParam, (LPINT)lpwm32mpex->lParam);
}
} else {
if (lpwm32mpex->Parm16.WndProc.lParam)
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
}
return(TRUE);
}
// This function thunks the list box control messages
//
// LB_GETITEMRECT
BOOL FASTCALL WM32LBGetItemRect (LPWM32MSGPARAMEX lpwm32mpex)
{
if ( lpwm32mpex->fThunk ) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(RECT16));
if (!(lpwm32mpex->Parm16.WndProc.lParam))
return FALSE;
} else {
GETRECT16( lpwm32mpex->Parm16.WndProc.lParam, (LPRECT)lpwm32mpex->lParam );
if (lpwm32mpex->Parm16.WndProc.lParam)
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
}
LOGDEBUG(3,(" Window %08lX is receiving Control Message %s(%08x)\n", lpwm32mpex->hwnd, (LPSZ)GetWMMsgName(lpwm32mpex->uMsg), lpwm32mpex->uMsg));
return(TRUE);
}
// This function thunks the list box control messages
//
// LB_ADDSTRING
// LB_INSERTSTRING
// LB_FINDSTRING
// LB_SELECTSTRING
BOOL FASTCALL WM32LBAddString (LPWM32MSGPARAMEX lpwm32mpex)
{
PWW pww;
if ( lpwm32mpex->fThunk ) {
if (!(pww = lpwm32mpex->pww)) {
if (pww = FindPWW (lpwm32mpex->hwnd))
lpwm32mpex->pww = pww;
else
return FALSE;
}
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
//
// Determine if this listbox has string pointers or handles passed
// in with LB_ADDSTRING messages. Owner-draw listboxes that don't
// have the LBS_HASSTRINGS style bit set have handles passed in.
// These handles are simply passed back to the owner at paint time.
// If the LBS_HASSTRINGS style bit is set, strings are used instead of
// handles as the "cookie" which is passed back to the application
// at paint time.
//
// We treat lpwm32mpex->dwParam as a BOOL indicating this listbox
// takes handles instead of strings.
//
lpwm32mpex->dwParam =
(pww->style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) &&
!(pww->style & LBS_HASSTRINGS);
if ( !lpwm32mpex->dwParam ) { // if this listbox takes strings
if (lpwm32mpex->lParam) {
INT cb;
cb = strlen((LPSZ)lpwm32mpex->lParam)+1;
lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb);
if (!(lpwm32mpex->Parm16.WndProc.lParam))
return FALSE;
putstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, cb);
}
}
} else {
if ( !lpwm32mpex->dwParam ) { // if this listbox takes strings
if (lpwm32mpex->Parm16.WndProc.lParam) {
getstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, -1);
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
}
}
}
return(TRUE);
}
// This function thunks the scrollbar control messages,
//
// SBM_SETPOS
// SBM_GETPOS
// SBM_ENABLE_ARROWS
//
BOOL FASTCALL WM32SBMControl (LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = WM_USER + (lpwm32mpex->uMsg - SBM_SETPOS);
}
return (TRUE);
}
// SBM_GETRANGE
BOOL FASTCALL WM32SBMGetRange (LPWM32MSGPARAMEX lpwm32mpex)
{
//
// Changed semantics for this message to support 32-bit
// scroll bar ranges (vs. 16-bit).
//
// Win16:
// posMin = LOWORD(SendMessage(hwnd, SBM_GETRANGE, 0, 0));
// posMax = HIWORD(SendMessage(hwnd, SBM_GETRANGE, 0, 0));
//
// Win32:
// SendMessage(hwnd, SBM_GETRANGE,
// (WPARAM) &posMin, (LPARAM) &posMax);
//
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = OLDSBM_GETRANGE;
} else {
*(DWORD *)lpwm32mpex->uParam = INT32(LOWORD(lpwm32mpex->lReturn));
*(DWORD *)lpwm32mpex->lParam = INT32(HIWORD(lpwm32mpex->lReturn));
lpwm32mpex->lReturn = 0;
}
return (TRUE);
}
// SBM_SETRANGE
// SBM_SETRANGEREDRAW (new for Win32)
BOOL FASTCALL WM32SBMSetRange (LPWM32MSGPARAMEX lpwm32mpex)
{
//
// Changed semantics to support 32-bit scroll bar range:
//
// Win16:
// SendMessage(hwnd, SBM_SETRANGE, fRedraw, MAKELONG(posMin, posMax);
//
// Win32:
// SendMessage(hwnd, fRedraw ? SBM_SETRANGE : SBM_SETRANGEREDRAW,
// posMin, posMax);
//
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = OLDSBM_SETRANGE;
lpwm32mpex->Parm16.WndProc.wParam = (SBM_SETRANGEREDRAW == lpwm32mpex->uMsg);
lpwm32mpex->Parm16.WndProc.lParam = MAKELONG( (WORD)lpwm32mpex->uParam, (WORD)lpwm32mpex->lParam);
}
return (TRUE);
}
// LB_SETSEL
BOOL FASTCALL WM32LBSetSel (LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
lpwm32mpex->Parm16.WndProc.wParam = (WORD) lpwm32mpex->uParam;
lpwm32mpex->Parm16.WndProc.lParam = (WORD)lpwm32mpex->lParam; // loword = index, hiword = 0
}
return (TRUE);
}
// This function thunks the static control messages,
//
// STM_SETICON
// STM_GETICON
//
BOOL FASTCALL WM32STMControl (LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
switch (lpwm32mpex->uMsg) {
case STM_SETICON:
lpwm32mpex->Parm16.WndProc.wParam = (WORD)GETHICON16(lpwm32mpex->uParam);
break;
case STM_GETICON:
break;
}
lpwm32mpex->Parm16.WndProc.wMsg = WM_USER + (lpwm32mpex->uMsg - STM_SETICON);
}
else {
lpwm32mpex->lReturn = (LONG)HICON32(lpwm32mpex->lReturn);
}
return (TRUE);
}
// This function thunks the messages,
//
// MN_FINDMENUWINDOWFROMPOINT
//
// NT - wparam = (PUINT)pitem lParam = MAKELONG(pt.x, pt.y)
// returns flags or hwnd *pitem = index or -1
//
// win31 wParam = 0 lParam = same
// returns 0 or MAKELONG(-1, item) or MAKELONG(-2, item) or MAKELONG(hwnd, item)
BOOL FASTCALL WM32MNFindMenuWindow (LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
lpwm32mpex->Parm16.WndProc.wMsg = WIN30_MN_FINDMENUWINDOWFROMPOINT;
lpwm32mpex->Parm16.WndProc.wParam = 0;
} else {
USHORT n = LOWORD(lpwm32mpex->lReturn);
*(PLONG)lpwm32mpex->uParam = (SHORT)HIWORD(lpwm32mpex->lReturn);
lpwm32mpex->lReturn = (LONG)HWND32(n); // this sign-extends -1, -2 and leaves 0 as 0
}
return TRUE;
}