mirror of https://github.com/tongzx/nt5src
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.
663 lines
17 KiB
663 lines
17 KiB
//**************************************************************************
|
|
// 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);
|
|
}
|