mirror of https://github.com/lianthony/NT4.0
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.
583 lines
21 KiB
583 lines
21 KiB
/*++
|
|
*
|
|
* WOW v1.0
|
|
*
|
|
* Copyright (c) 1992, Microsoft Corporation
|
|
*
|
|
* wkgthunk.C
|
|
* WOW32 Generic Thunk Mechanism (for OLE 2.0 and others)
|
|
*
|
|
* History:
|
|
* Created 11-MARCH-1993 by Matt Felton (mattfe)
|
|
*
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
MODNAME(wkgthunk.c);
|
|
|
|
|
|
HINSTANCE FASTCALL WK32LoadLibraryEx32(PVDMFRAME pFrame)
|
|
{
|
|
PSZ psz1;
|
|
HINSTANCE hinstance;
|
|
PLOADLIBRARYEX32 parg16;
|
|
|
|
#ifdef i386
|
|
BYTE FpuState[108];
|
|
|
|
// Save the 487 state
|
|
_asm {
|
|
lea ecx, [FpuState]
|
|
fsave [ecx]
|
|
}
|
|
#endif
|
|
|
|
GETARGPTR(pFrame, sizeof(LOADLIBRARYEX32), parg16);
|
|
GETVDMPTR(parg16->lpszLibFile,0,psz1);
|
|
|
|
//
|
|
// Make sure the Win32 current directory matches this task's.
|
|
//
|
|
|
|
UpdateDosCurrentDirectory(DIR_DOS_TO_NT);
|
|
|
|
hinstance = LoadLibraryEx(psz1, (HANDLE)parg16->hFile, parg16->dwFlags);
|
|
|
|
FREEARGPTR(parg16);
|
|
|
|
#ifdef i386
|
|
// Restore the 487 state
|
|
_asm {
|
|
lea ecx, [FpuState]
|
|
frstor [ecx]
|
|
}
|
|
#endif
|
|
|
|
return (hinstance);
|
|
}
|
|
|
|
|
|
BOOL FASTCALL WK32FreeLibrary32(PVDMFRAME pFrame)
|
|
{
|
|
BOOL fResult;
|
|
PFREELIBRARY32 parg16;
|
|
|
|
GETARGPTR(pFrame, sizeof(FREELIBRARY32), parg16);
|
|
|
|
fResult = FreeLibrary((HMODULE)parg16->hLibModule);
|
|
|
|
FREEARGPTR(parg16);
|
|
return (fResult);
|
|
}
|
|
|
|
|
|
FARPROC FASTCALL WK32GetProcAddress32(PVDMFRAME pFrame)
|
|
{
|
|
FARPROC lpAddress;
|
|
PSZ psz1;
|
|
PGETPROCADDRESS32 parg16;
|
|
|
|
GETARGPTR(pFrame, sizeof(GETPROCADDRESS32), parg16);
|
|
GETPSZIDPTR(parg16->lpszProc, psz1);
|
|
|
|
lpAddress = GetProcAddress((HMODULE)parg16->hModule, psz1);
|
|
|
|
FREEARGPTR(parg16);
|
|
return (lpAddress);
|
|
}
|
|
|
|
|
|
LPVOID FASTCALL WK32GetVDMPointer32(PVDMFRAME pFrame)
|
|
{
|
|
LPVOID lpAddress;
|
|
PGETVDMPOINTER32 parg16;
|
|
|
|
GETARGPTR(pFrame, sizeof(GETVDMPOITNER32), parg16);
|
|
|
|
lpAddress = WOWGetVDMPointer(parg16->lpAddress, 0, parg16->fMode);
|
|
|
|
FREEARGPTR(parg16);
|
|
return(lpAddress);
|
|
}
|
|
|
|
|
|
DWORD FASTCALL WK32ICallProc32(PVDMFRAME pFrame)
|
|
{
|
|
register DWORD dwReturn;
|
|
PICALLPROC32 parg16;
|
|
UNALIGNED DWORD *pArg;
|
|
DWORD fAddress;
|
|
BOOL fSourceCDECL;
|
|
BOOL fDestCDECL;
|
|
UINT cParams;
|
|
UINT nParam;
|
|
UNALIGNED DWORD *lpArgs;
|
|
DWORD dwTemp[32];
|
|
|
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
|
|
|
fSourceCDECL = HIWORD(parg16->cParams) & CPEX32_SOURCE_CDECL;
|
|
fDestCDECL = HIWORD(parg16->cParams) & CPEX32_DEST_CDECL;
|
|
|
|
// We only support up to 32 parameters
|
|
|
|
cParams = LOWORD(parg16->cParams);
|
|
|
|
if (cParams > 32)
|
|
return(0);
|
|
|
|
// Don't call to Zero
|
|
|
|
if (parg16->lpProcAddress == 0) {
|
|
LOGDEBUG(LOG_ALWAYS,("WK32ICallProc32 - Error calling to 0 not allowed"));
|
|
return(0);
|
|
}
|
|
|
|
lpArgs = &parg16->p1;
|
|
|
|
// Convert Any 16:16 Addresses to 32 bit
|
|
// flat as required by fAddressConvert
|
|
|
|
pArg = lpArgs;
|
|
|
|
fAddress = parg16->fAddressConvert;
|
|
|
|
while (fAddress != 0) {
|
|
if (fAddress & 0x1) {
|
|
*pArg = (DWORD) GetPModeVDMPointer(*pArg, 0);
|
|
}
|
|
pArg++;
|
|
fAddress = fAddress >> 1;
|
|
}
|
|
|
|
//
|
|
// The above code is funny. It means that parameter translation will
|
|
// occur before accounting for the calling convention. This means that
|
|
// they will be specifying the bit position for pascal by counting the
|
|
// parameters from the end, whereas with cdecl, they count from the
|
|
// beginning. Weird for pascal, but that is compatible with what we've
|
|
// already shipped. cdecl should be more understandable.
|
|
//
|
|
// The above comment applies to CallProc32W, for CallProc32ExW,
|
|
// the lowest bit position always refers to the leftmost parameter.
|
|
//
|
|
|
|
//
|
|
// Make sure the Win32 current directory matches this task's.
|
|
//
|
|
|
|
UpdateDosCurrentDirectory(DIR_DOS_TO_NT);
|
|
|
|
|
|
#ifdef i386
|
|
|
|
{
|
|
extern DWORD WK32ICallProc32MakeCall(DWORD pfn, DWORD cArgs, VOID *pArgs);
|
|
|
|
//
|
|
// On x86 we call an assembly routine to actually make the call to
|
|
// the client's Win32 routine. The code is much more compact
|
|
// this way, and it's the only way we can be compatible with
|
|
// Win95's implementation, which cleans up the stack if the
|
|
// routine doesn't.
|
|
//
|
|
// This assembly routine "pushes" the arguments by copying
|
|
// them as a block, so they must be in the proper order for
|
|
// the destination calling convention.
|
|
//
|
|
|
|
if ( ! fSourceCDECL) {
|
|
//
|
|
// Invert the parameters
|
|
//
|
|
pArg = lpArgs;
|
|
lpArgs = dwTemp;
|
|
|
|
nParam = cParams;
|
|
while ( nParam != 0 ) {
|
|
--nParam;
|
|
lpArgs[nParam] = *pArg;
|
|
pArg++;
|
|
}
|
|
}
|
|
|
|
dwReturn = WK32ICallProc32MakeCall(parg16->lpProcAddress, cParams, lpArgs);
|
|
}
|
|
|
|
#else
|
|
|
|
if ( fSourceCDECL != fDestCDECL ) {
|
|
//
|
|
// Invert the parameters
|
|
//
|
|
pArg = lpArgs;
|
|
lpArgs = dwTemp;
|
|
|
|
nParam = cParams;
|
|
while ( nParam != 0 ) {
|
|
--nParam;
|
|
lpArgs[nParam] = *pArg;
|
|
pArg++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// lpArgs now points to the very first parameter in any calling convention
|
|
// And all of the parameters have been appropriately converted to flat ptrs
|
|
//
|
|
|
|
if ( fDestCDECL ) {
|
|
typedef int (FAR WINAPIV *FARFUNC)();
|
|
|
|
dwReturn = ((FARFUNC)parg16->lpProcAddress)(
|
|
lpArgs[ 0], lpArgs[ 1], lpArgs[ 2], lpArgs[ 3],
|
|
lpArgs[ 4], lpArgs[ 5], lpArgs[ 6], lpArgs[ 7],
|
|
lpArgs[ 8], lpArgs[ 9], lpArgs[10], lpArgs[11],
|
|
lpArgs[12], lpArgs[13], lpArgs[14], lpArgs[15],
|
|
lpArgs[16], lpArgs[17], lpArgs[18], lpArgs[19],
|
|
lpArgs[20], lpArgs[21], lpArgs[22], lpArgs[23],
|
|
lpArgs[24], lpArgs[25], lpArgs[26], lpArgs[27],
|
|
lpArgs[28], lpArgs[29], lpArgs[30], lpArgs[31] );
|
|
} else {
|
|
//
|
|
// There HAS to be a better way for portable variable number of
|
|
// Arguments
|
|
//
|
|
switch(cParams) {
|
|
|
|
case 0:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)();
|
|
break;
|
|
case 1:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[ 0] );
|
|
break;
|
|
case 2:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
case 3:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
case 4:
|
|
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
case 5:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
case 6:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
case 7:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
case 8:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 9:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 10:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 11:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 12:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 13:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 14:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 15:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
|
|
case 16:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 17:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[16],
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 18:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[17], lpArgs[16],
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 19:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[18], lpArgs[17], lpArgs[16],
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 20:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[19], lpArgs[18], lpArgs[17], lpArgs[16],
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 21:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[20],
|
|
lpArgs[19], lpArgs[18], lpArgs[17], lpArgs[16],
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 22:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[21], lpArgs[20],
|
|
lpArgs[19], lpArgs[18], lpArgs[17], lpArgs[16],
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 23:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[22], lpArgs[21], lpArgs[20],
|
|
lpArgs[19], lpArgs[18], lpArgs[17], lpArgs[16],
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 24:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[23], lpArgs[22], lpArgs[21], lpArgs[20],
|
|
lpArgs[19], lpArgs[18], lpArgs[17], lpArgs[16],
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 25:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[24],
|
|
lpArgs[23], lpArgs[22], lpArgs[21], lpArgs[20],
|
|
lpArgs[19], lpArgs[18], lpArgs[17], lpArgs[16],
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 26:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[25], lpArgs[24],
|
|
lpArgs[23], lpArgs[22], lpArgs[21], lpArgs[20],
|
|
lpArgs[19], lpArgs[18], lpArgs[17], lpArgs[16],
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 27:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[26], lpArgs[25], lpArgs[24],
|
|
lpArgs[23], lpArgs[22], lpArgs[21], lpArgs[20],
|
|
lpArgs[19], lpArgs[18], lpArgs[17], lpArgs[16],
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 28:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[27], lpArgs[26], lpArgs[25], lpArgs[24],
|
|
lpArgs[23], lpArgs[22], lpArgs[21], lpArgs[20],
|
|
lpArgs[19], lpArgs[18], lpArgs[17], lpArgs[16],
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 29:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[28],
|
|
lpArgs[27], lpArgs[26], lpArgs[25], lpArgs[24],
|
|
lpArgs[23], lpArgs[22], lpArgs[21], lpArgs[20],
|
|
lpArgs[19], lpArgs[18], lpArgs[17], lpArgs[16],
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 30:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[29], lpArgs[28],
|
|
lpArgs[27], lpArgs[26], lpArgs[25], lpArgs[24],
|
|
lpArgs[23], lpArgs[22], lpArgs[21], lpArgs[20],
|
|
lpArgs[19], lpArgs[18], lpArgs[17], lpArgs[16],
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 31:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[30], lpArgs[29], lpArgs[28],
|
|
lpArgs[27], lpArgs[26], lpArgs[25], lpArgs[24],
|
|
lpArgs[23], lpArgs[22], lpArgs[21], lpArgs[20],
|
|
lpArgs[19], lpArgs[18], lpArgs[17], lpArgs[16],
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
case 32:
|
|
dwReturn = ((FARPROC)parg16->lpProcAddress)(
|
|
lpArgs[31], lpArgs[30], lpArgs[29], lpArgs[28],
|
|
lpArgs[27], lpArgs[26], lpArgs[25], lpArgs[24],
|
|
lpArgs[23], lpArgs[22], lpArgs[21], lpArgs[20],
|
|
lpArgs[19], lpArgs[18], lpArgs[17], lpArgs[16],
|
|
lpArgs[15], lpArgs[14], lpArgs[13], lpArgs[12],
|
|
lpArgs[11], lpArgs[10], lpArgs[ 9], lpArgs[ 8],
|
|
lpArgs[ 7], lpArgs[ 6], lpArgs[ 5], lpArgs[ 4],
|
|
lpArgs[ 3], lpArgs[ 2], lpArgs[ 1], lpArgs[ 0] );
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
FREEARGPTR(parg16);
|
|
return(dwReturn);
|
|
}
|
|
|
|
|
|
//
|
|
// Chicago has WOWGetVDMPointerFix, which is just like WOWGetVDMPointer
|
|
// but also calls GlobalFix to keep the 16-bit memory from moving. It
|
|
// has a companion WOWGetVDMPointerUnfix, which is basically a Win32-callable
|
|
// GlobalUnfix.
|
|
//
|
|
// Chicago found the need for these functions because their global heaps
|
|
// can be rearranged while Win32 code called from a generic thunk is
|
|
// executing. In Windows NT, global memory cannot move while in a thunk
|
|
// unless the thunk calls back to the 16-bit side.
|
|
//
|
|
// Our exported WOWGetVDMPointerFix is simply an alias to WOWGetVDMPointer --
|
|
// it does *not* call GlobalFix because it is not needed in 99% of the
|
|
// cases. WOWGetVDMPointerUnfix is implemented below as NOP.
|
|
//
|
|
|
|
VOID WOWGetVDMPointerUnfix(VPVOID vp)
|
|
{
|
|
UNREFERENCED_PARAMETER(vp);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//
|
|
// Yielding functions allow 32-bit thunks to avoid 4 16<-->32 transitions
|
|
// involved in calling back to 16-bit side to call Yield or DirectedYield,
|
|
// which are thunked back to user32.
|
|
//
|
|
|
|
VOID WOWYield16(VOID)
|
|
{
|
|
//
|
|
// Since WK32Yield (the thunk for Yield) doesn't use pStack16,
|
|
// just call it rather than duplicate the code.
|
|
//
|
|
|
|
WK32Yield(NULL);
|
|
}
|
|
|
|
VOID WOWDirectedYield16(WORD hTask16)
|
|
{
|
|
//
|
|
// This is duplicating the code of WK32DirectedYield, the
|
|
// two must be kept synchronized.
|
|
//
|
|
|
|
BlockWOWIdle(TRUE);
|
|
|
|
(pfnOut.pfnDirectedYield)(THREADID32(hTask16));
|
|
|
|
BlockWOWIdle(FALSE);
|
|
}
|