windows-nt/Source/XPSP1/NT/base/mvdm/wow32/wusercli.c

664 lines
17 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
//**************************************************************************
// wusercli.c :
// Contains all functions that execute USER32 client code on 16bitside.
// Most of these functions don't exist on x86 builds. So any changes
// to these files must be reflected in wow16\user\usercli.asm
//
// - nanduri
//**************************************************************************
#include "precomp.h"
#pragma hdrstop
MODNAME(wusercli.c);
//**************************************************************************
// WU32ClientToScreen -
//
//**************************************************************************
ULONG FASTCALL WU32ClientToScreen(PVDMFRAME pFrame)
{
POINT t2;
register PCLIENTTOSCREEN16 parg16;
GETARGPTR(pFrame, sizeof(CLIENTTOSCREEN16), parg16);
GETPOINT16(parg16->f2, &t2);
ClientToScreen( HWND32(parg16->f1), &t2 );
PUTPOINT16(parg16->f2, &t2);
FREEARGPTR(parg16);
RETURN(0);
}
//**************************************************************************
// WU32GetClientRect -
//
//**************************************************************************
ULONG FASTCALL WU32GetClientRect(PVDMFRAME pFrame)
{
RECT t2;
register PGETCLIENTRECT16 parg16;
GETARGPTR(pFrame, sizeof(GETCLIENTRECT16), parg16);
/*
* Home Design Gold 2.0
*
* If the call fails, don't overwrite the passed-in
* rect.
*/
if (GetClientRect(HWND32(parg16->hwnd), &t2)) {
PUTRECT16(parg16->vpRect, &t2);
}
FREEARGPTR(parg16);
RETURN(0);
}
//**************************************************************************
// WU32GetCursorPos -
//
//**************************************************************************
ULONG FASTCALL WU32GetCursorPos(PVDMFRAME pFrame)
{
POINT t1;
register PGETCURSORPOS16 parg16;
GETARGPTR(pFrame, sizeof(GETCURSORPOS16), parg16);
GetCursorPos( &t1 );
PUTPOINT16(parg16->f1, &t1);
FREEARGPTR(parg16);
RETURN(0);
}
//**************************************************************************
// WU32GetDesktopWindow -
//
//**************************************************************************
ULONG FASTCALL WU32GetDesktopWindow(PVDMFRAME pFrame)
{
ULONG ul;
UNREFERENCED_PARAMETER(pFrame);
ul = GETHWND16(GetDesktopWindow());
RETURN(ul);
}
//**************************************************************************
// WU32GetDlgItem -
//
//**************************************************************************
ULONG FASTCALL WU32GetDlgItem(PVDMFRAME pFrame)
{
ULONG ul;
register PGETDLGITEM16 parg16;
//
// pass the child ID zero-extended. this ID is the hMenu param to
// CreateWindow, so USER gets this ID with hiword = 0.
// Visual Basic relies on this.
//
GETARGPTR(pFrame, sizeof(GETDLGITEM16), parg16);
ul = GETHWND16(GetDlgItem(HWND32(parg16->f1),WORD32(parg16->f2)));
if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_DBASEHANDLEBUG) {
((PTDB)SEGPTR(pFrame->wTDB,0))->TDB_CompatHandle = (USHORT) ul;
}
FREEARGPTR(parg16);
RETURN(ul);
}
//**************************************************************************
// WU32GetMenu -
//
//**************************************************************************
ULONG FASTCALL WU32GetMenu(PVDMFRAME pFrame)
{
ULONG ul;
register PGETMENU16 parg16;
GETARGPTR(pFrame, sizeof(GETMENU16), parg16);
ul = GETHMENU16(GetMenu(HWND32(parg16->f1)));
FREEARGPTR(parg16);
RETURN(ul);
}
//**************************************************************************
// WU32GetMenuItemCount -
//
//**************************************************************************
ULONG FASTCALL WU32GetMenuItemCount(PVDMFRAME pFrame)
{
ULONG ul;
register PGETMENUITEMCOUNT16 parg16;
GETARGPTR(pFrame, sizeof(GETMENUITEMCOUNT16), parg16);
ul = GETWORD16(GetMenuItemCount( HMENU32(parg16->f1) ));
FREEARGPTR(parg16);
RETURN(ul);
}
//**************************************************************************
// WU32GetSysColor -
//
//**************************************************************************
ULONG FASTCALL WU32GetSysColor(PVDMFRAME pFrame)
{
ULONG ul;
register PGETSYSCOLOR16 parg16;
GETARGPTR(pFrame, sizeof(GETSYSCOLOR16), parg16);
ul = GETDWORD16(GetSysColor( INT32(parg16->f1) ));
FREEARGPTR(parg16);
RETURN(ul);
}
//**************************************************************************
// WU32GetSystemMetrics -
//
//**************************************************************************
ULONG FASTCALL WU32GetSystemMetrics(PVDMFRAME pFrame)
{
ULONG ul;
register PGETSYSTEMMETRICS16 parg16;
int sm;
GETARGPTR(pFrame, sizeof(GETSYSTEMMETRICS16), parg16);
sm = INT32(parg16->f1);
ul = GETINT16(GetSystemMetrics(sm) );
FREEARGPTR(parg16);
RETURN(ul);
}
//**************************************************************************
// WU32GetTopWindow -
//
//**************************************************************************
ULONG FASTCALL WU32GetTopWindow(PVDMFRAME pFrame)
{
ULONG ul;
register PGETTOPWINDOW16 parg16;
GETARGPTR(pFrame, sizeof(GETTOPWINDOW16), parg16);
ul = GETHWND16(GetTopWindow(HWND32(parg16->f1)));
FREEARGPTR(parg16);
RETURN(ul);
}
char szTrayWnd[] = "Shell_TrayWnd";
//**************************************************************************
// WU32GetWindowRect -
//
//**************************************************************************
ULONG FASTCALL WU32GetWindowRect(PVDMFRAME pFrame)
{
RECT t2;
register PGETWINDOWRECT16 parg16;
GETARGPTR(pFrame, sizeof(GETWINDOWRECT16), parg16);
/*
* Home Design Gold 2.0
*
* If the call fails, don't overwrite the passed-in
* rect.
*/
if (GetWindowRect(HWND32(parg16->f1), &t2)) {
// Sierra on-line setup hack (expects tray rect to be Classic style)
// See bug #425058
// Unfortunately we can't cache the tray hwnd because if explorer dies
// while the VDM is still running, explorer will get a new hwnd when it
// is restarted that won't match our cached one.
// IMHO this could be a general fix and not under an app compat flag
// in BlackComb.
if(CURRENTPTD()->dwWOWCompatFlags2 & WOWCF2_FIXLUNATRAYRECT) {
char szClassName[20];
if(GetClassName((HWND)parg16->f1,
szClassName,
sizeof(szClassName))) {
if(!lstrcmp(szClassName, szTrayWnd)) {
// these will only be 0 for the Luna theme
if((t2.left == 0) || (t2.top == 0)) {
// Find tray position on desktop. Leave the border that
// is actually in the desktop alone so that the apps can
// calculate their windows accurately.
/*******************************************************
* Note: IMHO the code that is commented out below could
* be uncommented for BlackComb as it more acurr-
* ately resembles what would be returned in
* Classic view. Instead, since we are late in the
* cycle for Whistler (RC2), we adjust the bare
* minimum required to fix the known Sierra cases.
*
* // if tray is at the BOTTOM of the desktop window
* if(t2.top > 0) {
* t2.left--;
* t2.right++;
* t2.bottom++;
*
* // else if the tray is at the RIGHT of desktop window
* } else if(t2.left > 0) {
* t2.top--;
* t2.right++;
* t2.bottom++;
*
* // else if the tray is at the TOP of desktop window
* } else if(t2.right > t2.bottom) {
* t2.top--;
* t2.left--;
* t2.right++;
*
* // else the tray must be at the LEFT of desktop window
* } else {
* t2.top--;
* t2.left--;
* t2.bottom++;
* }
*******************************************************/
// if tray is at the BOTTOM of the desktop window
if(t2.top > 0)
t2.bottom++;
// else if the tray is at the TOP of the desktop window
else if(t2.right > t2.bottom)
t2.top--;
}
}
}
}
PUTRECT16(parg16->f2, &t2);
}
FREEARGPTR(parg16);
RETURN(0);
}
//**************************************************************************
// WU32IsWindow -
//
//**************************************************************************
ULONG FASTCALL WU32IsWindow(PVDMFRAME pFrame)
{
ULONG ul;
HWND hWnd;
register PISWINDOW16 parg16;
GETARGPTR(pFrame, sizeof(ISWINDOW16), parg16);
hWnd = HWND32(parg16->f1);
ul = GETBOOL16(IsWindow(hWnd));
// For apps that get burned by recycled handles -- ie. the old handle they
// had has been destroyed & realloc'd to a different window -- not the one
// they were expecting. This needs to be handled on an app by app basis.
if(ul && (CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_FAKENOTAWINDOW)) {
// NetScape 4.0x install (the bug is in InstallShield)
// Test the offset portion of the 16:16 return address to this call.
// Bug #132616 et al
switch(pFrame->vpCSIP & 0x0000FFFF) {
case 0x4880: // (InstallShield 3.00.104.0)
case 0x44E4: // (InstallShield 3.00.091.0)
{
ULONG result;
LPVOID lp;
// we only want this to fail for calls during Int.Shld cleanup
// we probably shouldn't fail it if was created by a WOW process
result = GetWindowLong(hWnd, GWL_WNDPROC);
if(!IsWOWProc(result)) {
goto IW_HACK;
}
// extra sanity check: InstallSheild calls GetWindowLong & uses
// the returned value as a 16:16 ptr
result = GetWindowLong(hWnd, DWL_MSGRESULT);
GETVDMPTR(result, sizeof(VPVOID), lp);
if(!lp) {
goto IW_HACK;
}
break;
}
}
}
FREEARGPTR(parg16);
RETURN(ul);
IW_HACK:
WOW32WARNMSG((0),"WOW32::IsWindow hack hit!\n");
RETURN(0);
}
//**************************************************************************
// WU32ScreenToClient -
//
//**************************************************************************
ULONG FASTCALL WU32ScreenToClient(PVDMFRAME pFrame)
{
POINT t2;
register PSCREENTOCLIENT16 parg16;
GETARGPTR(pFrame, sizeof(SCREENTOCLIENT16), parg16);
GETPOINT16(parg16->f2, &t2);
ScreenToClient( HWND32(parg16->f1), &t2 );
PUTPOINT16(parg16->f2, &t2);
FREEARGPTR(parg16);
RETURN(0);
}
//**************************************************************************
// WU32IsChild -
//
//**************************************************************************
ULONG FASTCALL WU32IsChild(PVDMFRAME pFrame)
{
ULONG ul;
register PISCHILD16 parg16;
GETARGPTR(pFrame, sizeof(ISCHILD16), parg16);
ul = GETBOOL16(IsChild( HWND32(parg16->f1), HWND32(parg16->f2) ));
FREEARGPTR(parg16);
RETURN(ul);
}
//**************************************************************************
// WU32IsIconic -
//
//**************************************************************************
ULONG FASTCALL WU32IsIconic(PVDMFRAME pFrame)
{
ULONG ul;
register PISICONIC16 parg16;
GETARGPTR(pFrame, sizeof(ISICONIC16), parg16);
ul = GETBOOL16(IsIconic( HWND32(parg16->f1) ));
FREEARGPTR(parg16);
RETURN(ul);
}
//**************************************************************************
// WU32IsWindowEnabled -
//
//**************************************************************************
ULONG FASTCALL WU32IsWindowEnabled(PVDMFRAME pFrame)
{
ULONG ul;
register PISWINDOWENABLED16 parg16;
GETARGPTR(pFrame, sizeof(ISWINDOWENABLED16), parg16);
ul = GETBOOL16(IsWindowEnabled( HWND32(parg16->f1) ));
FREEARGPTR(parg16);
RETURN(ul);
}
//**************************************************************************
// WU32IsWindowVisible -
//
//**************************************************************************
ULONG FASTCALL WU32IsWindowVisible(PVDMFRAME pFrame)
{
ULONG ul;
register PISWINDOWVISIBLE16 parg16;
GETARGPTR(pFrame, sizeof(ISWINDOWVISIBLE16), parg16);
ul = GETBOOL16(IsWindowVisible( HWND32(parg16->f1) ));
FREEARGPTR(parg16);
RETURN(ul);
}
//**************************************************************************
// WU32IsZoomed -
//
//**************************************************************************
ULONG FASTCALL WU32IsZoomed(PVDMFRAME pFrame)
{
ULONG ul;
register PISZOOMED16 parg16;
GETARGPTR(pFrame, sizeof(ISZOOMED16), parg16);
ul = GETBOOL16(IsZoomed( HWND32(parg16->f1) ));
FREEARGPTR(parg16);
RETURN(ul);
}
//**************************************************************************
// WU32GetTickCount -
//
//**************************************************************************
ULONG FASTCALL WU32GetTickCount(PVDMFRAME pFrame)
{
ULONG ul;
UNREFERENCED_PARAMETER(pFrame);
ul = (ULONG)GetTickCount();
if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_GRAINYTICS) {
//
// round down to the nearest 55ms this is for RelayGold, which
// spins calling this API until consecutive calls return a delta
// greater than 52.
//
ul = ul - (ul % 55);
}
RETURN(ul);
}
//**************************************************************************
// On I386 all these functions her handled on clientside. But conditionally
// they may endup doing the actual work via these thunks.
//
// So any changes here like 'win31 compatiblity code' may have to be added
// in mvdm\wow16\user\usercli.asm too.
//
// - nanduri
//**************************************************************************
//**************************************************************************
// WU32DefHookProc -
//
//**************************************************************************
ULONG FASTCALL WU32DefHookProc(PVDMFRAME pFrame)
{
ULONG ul = 0;
register PDEFHOOKPROC16 parg16;
HOOKSTATEDATA HkData;
ULONG hHook16;
INT iHookCode;
INT nCode;
LONG wParam;
LONG lParam;
LPINT lpiFunc;
GETARGPTR(pFrame, sizeof(DEFHOOKPROC16), parg16);
nCode = INT32(parg16->f1);
wParam = WORD32(parg16->f2);
lParam = DWORD32(parg16->f3);
GETMISCPTR(parg16->f4, lpiFunc);
hHook16 = FETCHDWORD(*lpiFunc);
FREEVDMPTR(lpiFunc);
if (ISVALIDHHOOK(hHook16)) {
iHookCode = GETHHOOKINDEX(hHook16);
HkData.iIndex = (BYTE)iHookCode;
if ( W32GetHookStateData( &HkData ) ) {
ul = (ULONG)WU32StdDefHookProc(nCode, wParam, lParam, iHookCode);
}
}
FREEARGPTR(parg16);
RETURN(ul);
}
//**************************************************************************
// WU32GetKeyState -
//
//**************************************************************************
ULONG FASTCALL WU32GetKeyState(PVDMFRAME pFrame)
{
ULONG ul;
SHORT sTmp;
register PGETKEYSTATE16 parg16;
GETARGPTR(pFrame, sizeof(GETKEYSTATE16), parg16);
sTmp = GetKeyState(INT32(parg16->f1));
// compatiblity:
// MSTEST (testdrvr.exe) tests the bit 0x80 for checking the
// shift key state. This works in win31 because the keystate in win31 is
// one byte long and because of similar code below
//
// win31 code is similar to:
// mov al, byte ptr keystate
// cbw
// ret
//
// if 'al' is 0x80, cbw will make ax = 0xff80 and thus in win31
// (state & 0x8000) and (state & 0x0080) will work and mean the same.
//
ul = (ULONG)((sTmp & 0x8000) ? (sTmp | 0x80) : sTmp);
FREEARGPTR(parg16);
RETURN(ul);
}
//**************************************************************************
// WU32GetKeyboardState -
//
//**************************************************************************
ULONG FASTCALL WU32GetKeyboardState(PVDMFRAME pFrame)
{
PBYTE pb1;
register PGETKEYBOARDSTATE16 parg16;
GETARGPTR(pFrame, sizeof(GETKEYBOARDSTATE16), parg16);
ALLOCVDMPTR(parg16->f1, 256, pb1);
#ifdef HACK32 // bug 5704
if (pb1) {
GetKeyboardState( pb1 );
}
#else
GetKeyboardState( pb1 );
#endif
FLUSHVDMPTR(parg16->f1, 256, pb1);
FREEVDMPTR(pb1);
FREEARGPTR(parg16);
RETURN(0);
}