Source code of Windows XP (NT5)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*++
* intthunk.c * * WOW v5.0 * * Copyright 1996, Microsoft Corporation. All Rights Reserved. * * WOW32.C * WOW32 16-bit API support * * History: * Created 7-Dec-96 DaveHart * --*/
#include "precomp.h"
#pragma hdrstop
#include "wowit.h"
MODNAME(intthunk.c);
extern DWORD WK32ICallProc32MakeCall(DWORD pfn, DWORD cbArgs, VOID *pArgs);
//
// On x86 we don't bother aligning pointers to DWORDs
// passed to APIs. Perhaps we shouldn't for Alpha?
//
#ifdef _X86_
#define ALIGNDWORDS 0
#else
#define ALIGNDWORDS 1
#endif
ULONG FASTCALL InterpretThunk(PVDMFRAME pFrame, DWORD dwIntThunkID) { PINT_THUNK_TABLEENTRY pit = &IntThunkTable[ dwIntThunkID ]; CONST BYTE * pbInstr = pit->pbInstr; DWORD dwArgs32[MAX_IT_ARGS]; PDWORD pdwArg32 = dwArgs32; #if ALIGNDWORDS
BOOL fAlignedUsed = FALSE; DWORD adwAligned[MAX_IT_ARGS]; PDWORD pdwAligned = adwAligned; DWORD avpAligned[MAX_IT_ARGS]; PDWORD pvpAligned = avpAligned; #endif
WORD UNALIGNED *pwArg16 = (WORD UNALIGNED *) ((PBYTE)&pFrame->bArgs + pFrame->cbArgs - 2); DWORD dwReturn; DWORD dw;
WOW32ASSERTMSGF(dwIntThunkID <= ITID_MAX, ("WOW32 InterpretThunk error ID %d out of range (%d max).\n", dwIntThunkID, ITID_MAX));
while ( ! (*pbInstr & IT_RETMASK)) { switch (*pbInstr) {
case IT_WORD: *pdwArg32 = *pwArg16; break;
case IT_INT: *pdwArg32 = INT32(*pwArg16); break;
case IT_DWORD: *pdwArg32 = *(DWORD UNALIGNED *) --pwArg16; break;
case IT_LPDWORD: #if ALIGNDWORDS
if (! fAlignedUsed) { fAlignedUsed = TRUE; RtlZeroMemory(avpAligned, sizeof avpAligned); } *pvpAligned = *(DWORD UNALIGNED *) --pwArg16; if (*pvpAligned) { *pdwArg32 = (DWORD) pdwAligned; *pdwAligned = *(DWORD UNALIGNED *) GetPModeVDMPointer(*pvpAligned, 4); } else { *pdwArg32 = 0; } break; #else
//
// If we aren't aligning DWORDs use the generic
// pointer code.
//
/* FALL THROUGH TO IT_PTR */ #endif
case IT_PTR: dw = *(DWORD UNALIGNED *) --pwArg16; do_IT_PTR_with_dw: *pdwArg32 = (DWORD) GetPModeVDMPointer(dw, 0); break;
case IT_PTRORATOM: dw = *(DWORD UNALIGNED *) --pwArg16; if (HIWORD(dw)) { goto do_IT_PTR_with_dw; } *pdwArg32 = dw; // atom
break;
case IT_HGDI: *pdwArg32 = (DWORD) GDI32( (HAND16) *pwArg16 ); break;
case IT_HUSER: *pdwArg32 = (DWORD) USER32( (HAND16) *pwArg16 ); break;
case IT_COLOR: dw = *(DWORD UNALIGNED *) --pwArg16; *pdwArg32 = COLOR32(dw); break;
case IT_HINST: *pdwArg32 = (DWORD) HINSTRES32( (HAND16) *pwArg16 ); break;
case IT_HICON: *pdwArg32 = (DWORD) HICON32( (HAND16) *pwArg16 ); break;
case IT_HCURS: *pdwArg32 = (DWORD) HCURSOR32( (HAND16) *pwArg16 ); break;
case IT_16ONLY: //
// This is for params that appear on 16-bit side but not 32-bit side,
// for example the hinstOwner passed to CopyImage in Win16 but not in Win32.
//
pdwArg32--; break;
case IT_32ONLY: //
// This is for params that appear on 32-bit side but not 16-bit side,
// we pass zero for the 32-bit argument.
//
*pdwArg32 = 0; pwArg16++; break;
default: WOW32ASSERTMSGF(FALSE, ("WOW32 InterpretThunk error unknown opcode 0x%x.\n", *pbInstr)); }
pwArg16--; pdwArg32++; pbInstr++; #if ALIGNDWORDS
pdwAligned++; pvpAligned++; #endif
WOW32ASSERT((pbInstr - pit->pbInstr) <= (MAX_IT_ARGS + 1)); }
//
// Call API
//
dwReturn = WK32ICallProc32MakeCall( (DWORD) pit->pfnAPI, (PBYTE) pdwArg32 - (PBYTE) dwArgs32, dwArgs32 );
#ifdef DEBUG
pFrame = NULL; // Memory movement may have occurred.
#endif
//
// If we passed aligned DWORD pointers, copy the values back.
//
#if ALIGNDWORDS
if (fAlignedUsed) { pdwAligned = adwAligned; pvpAligned = avpAligned;
while (pvpAligned < (PDWORD)((PBYTE)avpAligned + sizeof avpAligned)) { if (*pvpAligned) { *(DWORD UNALIGNED *) GetPModeVDMPointer(*pvpAligned, 4) = *pdwAligned; }
pdwAligned++; pvpAligned++; } } #endif
//
// Thunk return value using last instruction opcode
//
WOW32ASSERT(*pbInstr & IT_RETMASK);
switch (*pbInstr) {
case IT_DWORDRET: // dwReturn is correct
break;
case IT_WORDRET: dwReturn = GETWORD16(dwReturn); break;
case IT_INTRET: dwReturn = (DWORD) GETINT16(dwReturn); break;
case IT_HGDIRET: dwReturn = GDI16( (HAND32) dwReturn ); break;
case IT_HUSERRET: dwReturn = USER16( (HAND32) dwReturn ); break;
case IT_ZERORET: dwReturn = 0; break;
case IT_HICONRET: dwReturn = GETHICON16( (HAND32) dwReturn ); break;
case IT_HCURSRET: dwReturn = GETHCURSOR16( (HAND32) dwReturn ); break;
case IT_ONERET: dwReturn = 1; break;
case IT_HPRNDWPRET: dwReturn = GetPrn16( (HAND32) dwReturn ); break;
default: WOW32ASSERTMSGF(FALSE, ("WOW32 InterpretThunk error unknown return opcode 0x%x.\n", *pbInstr)); }
return dwReturn; }
|