|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Copyright (c) 1998-1999 Microsoft Corporation
;;
;; Module Name:
;;
;; msgthnk.tpl
;;
;; Abstract:
;;
;; This template files defines the thunks for outbound 32bit to 64bit messages.
;;
;; Author:
;;
;; 6-Oct-98 mzoran
;;
;; Revision History:
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[Macros]
; Generate an api call, passing the name of the variable to use for the return
; value and the name of the API to call.
; eg. @CallApi(ApiName, RetVal)
TemplateName=CallApi
NumArgs=2
Begin=
@IfApiRet(@MArg(2)=)MSG_THUNK_CALLPROC(@ArgList(@ArgName@ArgMore(,))); @NL
End=
; Expand all parameters into local variables
TemplateName=ApiLocals
NumArgs=0
Begin=
@IfArgs(@ListCol@ArgList(@ArgLocal;))
End=
MacroName=CallNameFromApiName
NumArgs=1
Begin=
@ApiName
End=
TemplateName=MsgProlog
NumArgs=0
Begin=
// @NL
// @ApiName - @ApiNum @NL
MSG_THUNK_BEGIN(@ApiName,@ArgList(@ArgNameHost@ArgMore(,))) @NL
End=
TemplateName=ApiExit
NumArgs=0
Begin=
MSG_THUNK_END(@ApiName, wParamHost, lParamHost) @NL
End=
; Generate the epilog for a thunked API.
MacroName=ApiEpilog
NumArgs=0
Begin=
return @IfApiRet(RetVal); @NL
End=
MacroName=GenMsgThunk
NumArgs=1
Begin=
@IfApiCode(Header)
@MsgProlog
// Begin: IfApiCode(ApiEntry) @NL
@IfApiCode(ApiEntry)
@NL
@Indent(
@IfApiRet(@ApiFnRet RetVal;) @NL
@NL
// Begin: ApiLocals @NL
@ApiLocals
@NL
// Begin: Types(Locals) @NL
@Types(Locals)
@NL
// Begin: IfApiCode(Locals) @NL
@IfApiCode(Locals)
@NL
//Begin: Types(PreCall) @NL
@Types(PreCall)
@NL
// Begin: IfApiCode(PreCall) @NL
@IfApiCode(PreCall)
@NL
// Begin: CallApi(MArg(1), RetVal) @NL
@CallApi(@MArg(1), RetVal)
@NL
// Begin: Types(PostCall) @NL
@Types(PostCall)
@NL
// Begin: ApiCode(PostCall) @NL
@IfApiCode(PostCall)
@NL
// @NL
// Begin: ApiEpilog @NL
@ApiEpilog
@NL
)
// Begin: IfApiCode(ApiExit) @NL
@IfApiCode(ApiExit)
@NL
// Begin: ApiExit @NL
@ApiExit
@NL
End=
[IFunc]
TemplateName=Thunks
Header=
End=
ApiEntry=
End=
Begin=
@GenMsgThunk(@CallNameFromApiName(@ApiName))
End=
ApiExit=
End=
[Types]
TemplateName=LPHELPINFO
IndLevel=0
Direction=IN
Locals=
// @ArgName(@ArgType) is an IN LPHELPINFO. @NL
End=
PreCall=
// @ArgName(@ArgType) is an IN LPHELPINFO. @NL
@ArgName = Wow64ShallowAllocThunkHELPINFO32TO64((NT32HELPINFO *)@ArgHostName); @NL
End=
TemplateName=LPHLP
IndLevel=0
Direction=IN
Locals=
// @ArgName(@ArgType) is an IN LPHLP
End=
PreCall=
// @ArgName(@ArgType) is an IN LPHLP. @NL
@ArgName = Wow64ShallowAllocThunkHLP32TO64((NT32HLP *)@ArgHostName); @NL
End=
TemplateName=HKL
IndLevel=0
Direction=IN OUT
PreCall=
@ArgName=(HKL)(LongToPtr(@ArgHostName)); @NL
End=
PostCall=
@ArgHostName=(NT32HKL)(@ArgName); @NL
End=
TemplateName=HKL
IndLevel=0
Direction=IN
PreCall=
@ArgName=(HKL)(LongToPtr(@ArgHostName)); @NL
End=
[EFunc]
TemplateName=Wow64MsgFncWM_GETDLGCODE
Begin=
@NoFormat(
//
// This message is special in that it contains a pointer to another message.
// It turns out that the kernel does not work correctly if this message points
// to another structure. The kernel will not deep copy the message and thus
// it wont work correctly cross process.
// Here the inter message will be stuffed back through the message thunks.
// If the message points to a structure, it will be converted to 64bit.
// Unfortunatly, this can break an app that depends on the kernel not deep
// copying the message. This can be fixed later if the messsage table
// were augmented to say which parameters are pointers to structures and this
// thunk could set them to NULL before passing in through and reset them in the
// unpack stage.
// Note: The message pointed to is an IN MSG.
typedef struct _WM_GETDLGCODE_PARAMS {
WPARAM wParamOld;
PMSG_THUNKCB_FUNC wrapfuncOld;
PVOID pContextOld;
MSG *pMsg;
} WM_GETDLGCODE_PARAMS, *PWM_GETDLGCODE_PARAMS;
LONG_PTR whNT32Wow64MsgFncWM_GETDLGCODECB(WPARAM wParam, LPARAM lParam, PVOID pContext) {
PWM_GETDLGCODE_PARAMS params;
params = (PWM_GETDLGCODE_PARAMS)pContext;
// Put the wParam and lParam back in the message that they came from.
params->pMsg->wParam = wParam;
params->pMsg->lParam = lParam;
return (*(params->wrapfuncOld))(params->wParamOld, (LPARAM)params->pMsg, params->pContextOld);
}
MSG_THUNK_BEGIN(MSGFN(WM_GETDLGCODE),wParamHost, lParamHost)
WM_GETDLGCODE_PARAMS params;
WPARAM wParam;
LPARAM lParam;
MSG msg;
NT32MSG *pmsg32;
if ((PVOID)lParamHost == NULL) {
wParam = (WPARAM)wParamHost;
lParam = (LPARAM)lParamHost;
return MSG_THUNK_CALLPROC(wParam, lParam);
}
// not used, but pass it for safety.
params.wParamOld = (WPARAM)wParamHost;
pmsg32 = (NT32MSG *)lParamHost;
msg.hwnd = (HWND)pmsg32->hwnd;
msg.message = pmsg32->message;
msg.wParam = (WPARAM)pmsg32->wParam;
msg.lParam = (LPARAM)pmsg32->lParam;
msg.time = pmsg32->time;
msg.pt.x = pmsg32->pt.x;
msg.pt.y = pmsg32->pt.y;
params.pMsg = &msg;
params.wrapfuncOld = wrapfunc;
params.pContextOld = pContext;
return Wow64DoMessageThunk(whNT32Wow64MsgFncWM_GETDLGCODECB, msg.message, msg.wParam, msg.lParam, ¶ms);
MSG_THUNK_END(WM_NULL, wParamHost, lParamHost)
)
End=
TemplateName=Wow64MsgFncWM_NCCALCSIZE
NoType=lpncsp
Locals=
@ForceType(Locals,lpncsp,lpncspHost,LPNCCALCSIZE_PARAMS,IN OUT)
End=
PreCall=
if (fCalcValidRectsHost) { @NL @ForceType(PreCall,lpncsp,lpncspHost,LPNCCALCSIZE_PARAMS,IN)
} else { @NL // lpncsp is really a LPRECT @NL
lpncsp=(LPNCCALCSIZE_PARAMS)lpncspHost; @NL
} @NL
End=
PostCall=
if (fCalcValidRectsHost) { @NL @ForceType(PostCall,lpncsp,lpncspHost,LPNCCALCSIZE_PARAMS,OUT)
} else { @NL // lpncsp is really a LPRECT @NL
} @NL
End=
TemplateName=Wow64MsgFncWM_SYSTIMER
PreCall=
if (tmprcHost != 0) { @NL WOWASSERT(gdwWM_SYSTIMERProcHiBits != 0); @NL
tmprc = (TIMERPROC)(tmprcHost | (((UINT64) gdwWM_SYSTIMERProcHiBits) << 32)); @NL
} @NL
End=
TemplateName=Wow64MsgFncLB_GETSELITEMS
Locals=
PINT lpiTemp;
End=
PreCall=
if ((ARGUMENT_PRESENT (lpiItems) != 0) && @NL
(((ULONG_PTR)lpiItems & (sizeof(INT) -1)) != 0)) { @NL @NL
lpiTemp = Wow64AllocateTemp (sizeof (INT) * MaxSel); @NL
if (lpiTemp != NULL) { @NL lpiItems = lpiTemp; @NL
} @NL
} @NL
End=
PostCall=
if (PtrToUlong(lpiItems) != lpiItemsHost) { @NL try { @NL if (RetVal != -1) { @NL RtlCopyMemory (UlongToPtr(lpiItemsHost), lpiItems, RetVal * sizeof (INT)); @NL
} @NL
} except (EXCEPTION_EXECUTE_HANDLER) { @NL LOGPRINT((ERRORLOG, "Wow64MsgFncLB_GETSELITEMS Exception- %lx\n", GetExceptionCode ())); @NL
RetVal = -1; @NL
} @NL
} @NL
End=
TemplateName=Wow64MsgFncLB_GETTEXT
Locals=
NTUSERMESSAGECALL_PARMS *MsgParams = (NTUSERMESSAGECALL_PARMS *)pContext;
ULONG_PTR lParam64; @NL
PWND pwnd; @NL
BOOL bNotString = FALSE; @NL
DWORD dw; @NL
End=
PreCall=
try { @NL pwnd = Wow64ValidateHwnd(MsgParams->hwnd); @NL
@NL
dw = pwnd->style; @NL
@NL
/* @NL
* See if the control is ownerdraw and does not have the LBS_HASSTRINGS @NL
* style. If so, treat lParam as a DWORD. @NL
*/ @NL
bNotString = (!(dw & LBS_HASSTRINGS) && @NL
(dw & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)));@NL
@NL
if (bNotString != FALSE) { @NL lpszBuffer = (LPCSTR) &lParam64; @NL
} @NL
} except (EXCEPTION_EXECUTE_HANDLER) { @NL return -1; @NL
} @NL
End=
PostCall=
if ((RetVal != -1) && @NL
(bNotString != FALSE)) { @NL try { @NL *((PULONG)lpszBufferHost) = (ULONG)lParam64;@NL
RetVal >>= 1; @NL
} except (EXCEPTION_EXECUTE_HANDLER) { @NL RetVal = -1; @NL
} @NL
} @NL
End=
[Code]
TemplateName=msgthnk
CGenBegin=
@NoFormat(
/*
* genthunk generated code: Do Not Modify
* Thunks for messages.
*
*/
#include "whwin32p.h"
ASSERTNAME;
#pragma warning(disable : 4311) //Disable pointer truncation warning
#define MSGFN(id) Wow64MsgFnc##id
#define MSG_THUNK_BEGIN(name,wparamname, lparamname) \
LONG_PTR name(PMSG_THUNKCB_FUNC wrapfunc, WPARAM wParamArg, LPARAM lParamArg, PVOID pContext) { \ \
UINT wparamname; \
LONG lparamname; \
\
wparamname = (UINT)wParamArg; \
lparamname = (LONG)lParamArg; \
\
{ \
#define MSG_THUNK_CALLPROC(wParam, lParam) \
(*wrapfunc)((WPARAM)wParam, (LPARAM)lParam, pContext)
#define MSG_THUNK_END(name,wparamname, lparamname) \
\
} \
\
} \
)
@Template(Thunks)
@NoFormat(
typedef struct _MSG_ENTRY { PMSG_THUNK_FUNC ThunkFunc;
UINT Id;
LPSTR Name;
} MSG_ENTRY, *PMSG_ENTRY;
//
//
// This is the default thunk for messages. It sign extends lParam and zero extends wParam.
//
MSG_THUNK_BEGIN(MSGFN(WM_NULL),wParamHost, lParamHost)
WPARAM wParam;
LPARAM lParam;
wParam = (WPARAM)wParamHost;
lParam = (LPARAM)lParamHost;
return MSG_THUNK_CALLPROC(wParam, lParam);
MSG_THUNK_END(WM_NULL, wParamHost, lParamHost)
//
// Include messages.h to get the jump table.
#define MSG_ENTRY_NOPARAM(entrynumber, id) {Wow64MsgFncWM_NULL, id, #id},
#define MSG_ENTRY_WPARAM(entrynumber, id, wparam) {Wow64MsgFnc##id, id, #id},
#define MSG_ENTRY_LPARAM(entrynumber, id, lparam) {Wow64MsgFnc##id, id, #id},
#define MSG_ENTRY_STD(entrynumber, id, wparam, lparam) {Wow64MsgFnc##id, id, #id},
#define MSG_ENTRY_UNREFERENCED(entrynumber, id) {Wow64MsgFncWM_NULL, entrynumber, NULL},
#define MSG_ENTRY_KERNELONLY(entrynumber, id) {Wow64MsgFncWM_NULL, entrynumber, NULL},
#define MSG_ENTRY_EMPTY(entrynumber) {Wow64MsgFncWM_NULL, entrynumber, NULL},
#define MSG_ENTRY_RESERVED(entrynumber) {Wow64MsgFncWM_NULL, entrynumber, NULL},
#define MSG_ENTRY_TODO(entrynumber) {Wow64MsgFncWM_NULL, entrynumber, NULL},
#define MSG_TABLE_BEGIN CONST MSG_ENTRY MsgTable[] = { #define MSG_TABLE_END {0, 0, NULL} };
#include "messages.h"
//
// Include messages.h again to get the profile table.
#if defined(WOW64DOPROFILE)
#undef MSG_ENTRY_NOPARAM
#undef MSG_ENTRY_WPARAM
#undef MSG_ENTRY_LPARAM
#undef MSG_ENTRY_STD
#undef MSG_ENTRY_UNREFERENCED
#undef MSG_ENTRY_KERNELONLY
#undef MSG_ENTRY_EMPTY
#undef MSG_ENTRY_RESERVED
#undef MSG_ENTRY_TODO
#undef MSG_TABLE_BEGIN
#undef MSG_TABLE_END
#define MSG_ENTRY_NOPARAM(entrynumber, id) {L#id,0,NULL,TRUE},
#define MSG_ENTRY_WPARAM(entrynumber, id, wparam) {L#id,0,NULL,TRUE},
#define MSG_ENTRY_LPARAM(entrynumber, id, lparam) {L#id,0,NULL,TRUE},
#define MSG_ENTRY_STD(entrynumber, id, wparam, lparam) {L#id,0,NULL,TRUE},
#define MSG_ENTRY_UNREFERENCED(entrynumber, id) {L"Unreferenced",0,NULL,FALSE},
#define MSG_ENTRY_KERNELONLY(entrynumber, id) {L"KernelOnly",0,NULL,FALSE},
#define MSG_ENTRY_EMPTY(entrynumber) {L"Empty",0,NULL,FALSE},
#define MSG_ENTRY_RESERVED(entrynumber) {L"Reserved",0,NULL,FALSE},
#define MSG_ENTRY_TODO(entrynumber) {L"TODO",0,NULL,TRUE},
#define MSG_TABLE_BEGIN WOW64SERVICE_PROFILE_TABLE_ELEMENT ptemsgthnk[] = { #define MSG_TABLE_END {NULL, 0} };
#include "messages.h"
WOW64SERVICE_PROFILE_TABLE ptmsgthnk = {L"MSGTHNK", L"Outbound Message Thunks", ptemsgthnk, (sizeof(ptemsgthnk)/sizeof(WOW64SERVICE_PROFILE_TABLE_ELEMENT))-1}; @NL
#endif
LONG_PTR
Wow64DoMessageThunk(PMSG_THUNKCB_FUNC func,
UINT msg,
WPARAM wParam,
LPARAM lParam,
PVOID pContext)
/*++
Routine Description:
This function is called to dispatch a message through the message thunks.
Arguments:
func - supplies the callback function.
msg - supplies the id of the message.
wParam - supplies the wParam of the message.
lParam - supplies the lParam of the message.
pContext - supplies the context that is passed to the callback function.
Return Value:
Return value of the actual function call, called by the callback function.
--*/
{
LONG_PTR retval;
//
// For now, do not thunk messages greater then or equal to WM_USER.
if (WM_USER <= msg) {
LOGPRINT((TRACELOG, "Wow64DoMessageThunk: skipping thunking of outbound %x since it is >= WM_USER\n", msg));
return (*func)(wParam, lParam, pContext);
}
LOGPRINT((TRACELOG, "Wow64DoMessageThunk: starting thunk of outbound %s(%x)\n",
MsgTable[msg].Name, MsgTable[msg].Id));
WOWASSERT(MsgTable[msg].Id == msg);
#if defined(WOW64DOPROFILE)
ptemsgthnk[msg].HitCount++;
#endif
retval = (*(MsgTable[msg].ThunkFunc))(func, wParam, lParam, pContext);
LOGPRINT((TRACELOG, "Wow64DoMessageThunk: finished thunk of outbound %s(%x), retval %I64x\n",
MsgTable[msg].Name, MsgTable[msg].Id, retval));
return retval;
}
)
End=
|