|
|
/****************************** Module Header ******************************\
* Module Name: wow.c * * Copyright (c) 1985 - 1999, Microsoft Corporation * * This module contains shared code between USER32 and USER16 * No New CODE should be added to this file, unless its shared * with USER16. * * History: * 29-DEC-93 NanduriR shared user32/user16 code. \***************************************************************************/
#include "precomp.h"
#pragma hdrstop
/***************************************************************************\
* ValidateHwnd * * Verify that the handle is valid. If the handle is invalid or access * cannot be granted fail. * * History: * 03-18-92 DarrinM Created from pieces of misc server-side funcs. \***************************************************************************/ PWND FASTCALL ValidateHwnd( HWND hwnd) { PCLIENTINFO pci = GetClientInfo();
/*
* Attempt fast window validation. */ if (hwnd != NULL && hwnd == pci->CallbackWnd.hwnd) { return pci->CallbackWnd.pwnd; }
/*
* Validate that the handle is of the proper type. */ return HMValidateHandle(hwnd, TYPE_WINDOW); }
PWND FASTCALL ValidateHwndNoRip( HWND hwnd) { PCLIENTINFO pci = GetClientInfo();
/*
* Attempt fast window validation. */ if (hwnd != NULL && hwnd == pci->CallbackWnd.hwnd) { return pci->CallbackWnd.pwnd; }
/*
* Validate the handle is of the proper type. */ return HMValidateHandleNoRip(hwnd, TYPE_WINDOW); }
FUNCLOG3(LOG_GENERAL, int, WINAPI, GetClassNameA, HWND, hwnd, LPSTR, lpClassName, int, nMaxCount) int WINAPI GetClassNameA( HWND hwnd, LPSTR lpClassName, int nMaxCount) { PCLS pcls; LPSTR lpszClassNameSrc; PWND pwnd; int cchSrc;
pwnd = ValidateHwnd(hwnd);
if (pwnd == NULL) return FALSE;
try { if (nMaxCount != 0) { pcls = (PCLS)REBASEALWAYS(pwnd, pcls); lpszClassNameSrc = REBASEPTR(pwnd, pcls->lpszAnsiClassName); cchSrc = lstrlenA(lpszClassNameSrc); nMaxCount = min(cchSrc, nMaxCount - 1); RtlCopyMemory(lpClassName, lpszClassNameSrc, nMaxCount); lpClassName[nMaxCount] = '\0'; } } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { nMaxCount = 0; }
return nMaxCount; }
/***************************************************************************\
* _GetDesktopWindow (API) * * History: * 11-07-90 darrinm Implemented. \***************************************************************************/ PWND _GetDesktopWindow( VOID) { PCLIENTINFO pci;
ConnectIfNecessary(0);
pci = GetClientInfo(); return (PWND)((KERNEL_ULONG_PTR)pci->pDeskInfo->spwnd - pci->ulClientDelta); }
HWND GetDesktopWindow( VOID) { PWND pwnd = _GetDesktopWindow(); PCLIENTINFO pci = GetClientInfo();
/*
* Validate the parent window's handle if a restricted process. */ if (pci && (pci->dwTIFlags & TIF_RESTRICTED)) { if (ValidateHwnd(HW(pwnd)) == NULL) { return NULL; } }
return HW(pwnd); }
PWND _GetDlgItem( PWND pwnd, int id) { if (pwnd != NULL) { pwnd = REBASEPWND(pwnd, spwndChild); while (pwnd != NULL) { if (PtrToLong(pwnd->spmenu) == id) { break; } pwnd = REBASEPWND(pwnd, spwndNext); } }
return pwnd; }
FUNCLOG2(LOG_GENERAL, HWND, DUMMYCALLINGTYPE, GetDlgItem, HWND, hwnd, int, id) HWND GetDlgItem( HWND hwnd, int id) { PWND pwnd; HWND hwndRet;
pwnd = ValidateHwnd(hwnd); if (pwnd == NULL) { return NULL; }
pwnd = _GetDlgItem(pwnd, id);
hwndRet = HW(pwnd);
if (hwndRet == (HWND)0) { RIPERR0(ERROR_CONTROL_ID_NOT_FOUND, RIP_VERBOSE, ""); }
return hwndRet; }
FUNCLOG1(LOG_GENERAL, HMENU, DUMMYCALLINGTYPE, GetMenu, HWND, hwnd) HMENU GetMenu( HWND hwnd) { PWND pwnd; PMENU pmenu;
pwnd = ValidateHwnd(hwnd); if (pwnd == NULL) { return 0; }
/*
* Some ill-behaved apps use GetMenu to get the child id, so * only map to the handle for non-child windows. */ if (!TestwndChild(pwnd)) { pmenu = REBASE(pwnd, spmenu); return (HMENU)PtoH(pmenu); } else { return (HMENU)KPVOID_TO_PVOID(pwnd->spmenu); } }
/***************************************************************************\
* GetMenuItemCount * * Returns a count of the number of items in the menu. Returns -1 if * invalid menu. * * History: \***************************************************************************/ FUNCLOG1(LOG_GENERAL, int, DUMMYCALLINGTYPE, GetMenuItemCount, HMENU, hMenu) int GetMenuItemCount( HMENU hMenu) { PMENU pMenu;
pMenu = VALIDATEHMENU(hMenu); if (pMenu == NULL) { return -1; }
return pMenu->cItems; }
/***************************************************************************\
* GetMenuItemID * * Return the ID of a menu item at the specified position. * * History: \***************************************************************************/ FUNCLOG2(LOG_GENERAL, UINT, DUMMYCALLINGTYPE, GetMenuItemID, HMENU, hMenu, int, nPos) UINT GetMenuItemID( HMENU hMenu, int nPos) { PMENU pMenu; PITEM pItem;
pMenu = VALIDATEHMENU(hMenu); if (pMenu == NULL) { return (UINT)-1; }
/*
* If the position is valid and the item is not a popup, get the ID * Don't allow negative indexes, because that'll cause an access violation. */ if (nPos < (int)pMenu->cItems && nPos >= 0) { pItem = &((PITEM)REBASEALWAYS(pMenu, rgItems))[nPos]; if (pItem->spSubMenu == NULL) { return pItem->wID; } }
return (UINT)-1; }
FUNCLOG3(LOG_GENERAL, UINT, DUMMYCALLINGTYPE, GetMenuState, HMENU, hMenu, UINT, uId, UINT, uFlags) UINT GetMenuState( HMENU hMenu, UINT uId, UINT uFlags) { PMENU pMenu;
pMenu = VALIDATEHMENU(hMenu); if (pMenu == NULL || (uFlags & ~MF_VALID) != 0) { return (UINT)-1; }
return _GetMenuState(pMenu, uId, uFlags); }
FUNCLOG1(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, IsWindow, HWND, hwnd) BOOL IsWindow( HWND hwnd) { PWND pwnd;
/*
* Validate the handle is of type window */ pwnd = ValidateHwndNoRip(hwnd);
/*
* And validate this handle is valid for this desktop by trying to read it */ if (pwnd != NULL) { try { if (pwnd->fnid & FNID_DELETED_BIT) { pwnd = 0; } } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { RIPMSG1(RIP_WARNING, "IsWindow: Window %#p not of this desktop", pwnd); pwnd = 0; } }
return !!pwnd; }
FUNCLOG2(LOG_GENERAL, HWND, DUMMYCALLINGTYPE, GetWindow, HWND, hwnd, UINT, wCmd) HWND GetWindow( HWND hwnd, UINT wCmd) { PWND pwnd;
pwnd = ValidateHwnd(hwnd); if (pwnd == NULL) { return NULL; }
pwnd = _GetWindow(pwnd, wCmd); return HW(pwnd); }
FUNCLOG1(LOG_GENERAL, HWND, DUMMYCALLINGTYPE, GetParent, HWND, hwnd) HWND GetParent( HWND hwnd) { PWND pwnd; PCLIENTINFO pci;
pwnd = ValidateHwnd(hwnd); if (pwnd == NULL) { return NULL; }
try { pwnd = _GetParent(pwnd); hwnd = HW(pwnd); } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { hwnd = NULL; }
pci = GetClientInfo();
/*
* validate the parent window's handle if a restricted process */ if (pci && (pci->dwTIFlags & TIF_RESTRICTED)) { if (ValidateHwnd(hwnd) == NULL) { return NULL; } }
return hwnd; }
FUNCLOG2(LOG_GENERAL, HMENU, DUMMYCALLINGTYPE, GetSubMenu, HMENU, hMenu, int, nPos) HMENU GetSubMenu( HMENU hMenu, int nPos) { PMENU pMenu;
pMenu = VALIDATEHMENU(hMenu); if (pMenu == NULL) { return 0; }
pMenu = _GetSubMenu(pMenu, nPos); return (HMENU)PtoH(pMenu); }
FUNCLOG1(LOG_GENERAL, DWORD, DUMMYCALLINGTYPE, GetSysColor, int, nIndex) DWORD GetSysColor( int nIndex) { /*
* Return 0 if the index is out of range. */ if (nIndex < 0 || nIndex >= COLOR_MAX) { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid parameter \"nIndex\" (%ld) to GetSysColor", nIndex);
return 0; }
return gpsi->argbSystem[nIndex]; }
FUNCLOG1(LOG_GENERAL, int, DUMMYCALLINGTYPE, GetSystemMetrics, int, index) int GetSystemMetrics( int index) { int ret;
BEGIN_USERAPIHOOK() ret = guah.pfnGetSystemMetrics(index); END_USERAPIHOOK()
return ret; }
int RealGetSystemMetrics( int index) { ConnectIfNecessary(0);
/*
* First check for values that aren't in the aiSysMet array. */ switch (index) { case SM_REMOTESESSION: return ISREMOTESESSION(); }
/*
* If it's in the BOOLEAN system metric range then do our magic. */ if (index >= SM_STARTBOOLRANGE && index <= SM_ENDBOOLRANGE) { return SYSMETBOOL2(index); }
if (index < 0 || index >= SM_CMETRICS) { return 0; }
switch (index) { case SM_DBCSENABLED: #ifdef FE_SB
return TEST_SRVIF(SRVIF_DBCS); #else
return FALSE; #endif
case SM_IMMENABLED: #ifdef FE_IME
return TEST_SRVIF(SRVIF_IME); #else
return FALSE; #endif
case SM_MIDEASTENABLED: return TEST_SRVIF(SRVIF_MIDEAST); }
if (!Is400Compat(GetClientInfo()->dwExpWinVer)) { /*
* SCROLL BAR * before 4.0, the scroll bars and the border overlapped by a pixel. Many apps * rely on this overlap when they compute dimensions. Now, in 4.0, this pixel * overlap is no longer there. So for old apps, we lie and pretend the overlap * is there by making the scroll bar widths one bigger. * * DLGFRAME * In Win3.1, SM_CXDLGFRAME & SM_CYDLGFRAME were border space MINUS 1 * In Win4.0, they are border space * * CAPTION * In Win3.1, SM_CYCAPTION was the caption height PLUS 1 * In Win4.0, SM_CYCAPTION is the caption height * * MENU * In Win3.1, SM_CYMENU was the menu height MINUS 1 * In Win4.0, SM_CYMENU is the menu height */
switch (index) {
case SM_CXDLGFRAME: case SM_CYDLGFRAME: case SM_CYMENU: case SM_CYFULLSCREEN: return gpsi->aiSysMet[index] - 1;
case SM_CYCAPTION: case SM_CXVSCROLL: case SM_CYHSCROLL: return gpsi->aiSysMet[index] + 1; } }
return gpsi->aiSysMet[index]; }
/***************************************************************************\
* GetTopWindow (API) * * This poorly named API should really be called 'GetFirstChild', which is * what it does. * * History: * 11-12-90 darrinm Ported. * 02-19-91 JimA Added enum access check * 05-04-02 DarrinM Removed enum access check and moved to USERRTL.DLL \***************************************************************************/ FUNCLOG1(LOG_GENERAL, HWND, DUMMYCALLINGTYPE, GetTopWindow, HWND, hwnd) HWND GetTopWindow( HWND hwnd) { PWND pwnd;
/*
* Allow a NULL hwnd to go through here. */ if (hwnd == NULL) { pwnd = _GetDesktopWindow(); } else { pwnd = ValidateHwnd(hwnd); }
if (pwnd == NULL) { return NULL; }
pwnd = REBASEPWND(pwnd, spwndChild); return HW(pwnd); }
FUNCLOG2(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, IsChild, HWND, hwndParent, HWND, hwnd) BOOL IsChild( HWND hwndParent, HWND hwnd) { PWND pwnd, pwndParent;
pwnd = ValidateHwnd(hwnd); if (pwnd == NULL) { return FALSE; }
pwndParent = ValidateHwnd(hwndParent); if (pwndParent == NULL) { return FALSE; }
return _IsChild(pwndParent, pwnd); }
FUNCLOG1(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, IsIconic, HWND, hwnd) BOOL IsIconic( HWND hwnd) { PWND pwnd;
pwnd = ValidateHwnd(hwnd); if (pwnd == NULL) { return FALSE; }
return _IsIconic(pwnd); }
FUNCLOG1(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, IsWindowEnabled, HWND, hwnd) BOOL IsWindowEnabled( HWND hwnd) { PWND pwnd;
pwnd = ValidateHwnd(hwnd); if (pwnd == NULL) { return FALSE; }
return _IsWindowEnabled(pwnd); }
FUNCLOG1(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, IsWindowVisible, HWND, hwnd) BOOL IsWindowVisible( HWND hwnd) { PWND pwnd; BOOL bRet;
pwnd = ValidateHwnd(hwnd); if (pwnd == NULL) { bRet = FALSE; } else { try { bRet = _IsWindowVisible(pwnd); } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { bRet = FALSE; } }
return bRet; }
FUNCLOG1(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, IsZoomed, HWND, hwnd) BOOL IsZoomed( HWND hwnd) { PWND pwnd;
pwnd = ValidateHwnd(hwnd); if (pwnd == NULL) { return FALSE; }
return _IsZoomed(pwnd); }
FUNCLOG2(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, ClientToScreen, HWND, hwnd, LPPOINT, ppoint) BOOL ClientToScreen( HWND hwnd, LPPOINT ppoint) { PWND pwnd;
pwnd = ValidateHwnd(hwnd); if (pwnd == NULL) { return FALSE; }
_ClientToScreen(pwnd, ppoint); return TRUE; }
FUNCLOG2(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, GetClientRect, HWND, hwnd, LPRECT, prect) BOOL GetClientRect( HWND hwnd, LPRECT prect) { PWND pwnd;
pwnd = ValidateHwnd(hwnd); if (pwnd == NULL) { return FALSE; }
_GetClientRect(pwnd, prect); return TRUE; }
FUNCLOG1(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, GetCursorPos, LPPOINT, lpPoint) BOOL GetCursorPos( LPPOINT lpPoint) { return (BOOL)NtUserCallOneParam((ULONG_PTR)lpPoint, SFI_XXXGETCURSORPOS); }
FUNCLOG2(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, GetWindowRect, HWND, hwnd, LPRECT, prect) BOOL GetWindowRect( HWND hwnd, LPRECT prect) { PWND pwnd;
pwnd = ValidateHwnd(hwnd); if (pwnd == NULL) { return FALSE; }
_GetWindowRect(pwnd, prect); return TRUE; }
FUNCLOG2(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, ScreenToClient, HWND, hwnd, LPPOINT, ppoint) BOOL ScreenToClient( HWND hwnd, LPPOINT ppoint) { PWND pwnd;
pwnd = ValidateHwnd(hwnd); if (pwnd == NULL) { return FALSE; }
_ScreenToClient(pwnd, ppoint); return TRUE; }
FUNCLOG3(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, EnableMenuItem, HMENU, hMenu, UINT, uIDEnableItem, UINT, uEnable) BOOL EnableMenuItem( HMENU hMenu, UINT uIDEnableItem, UINT uEnable) { PMENU pMenu; PITEM pItem;
pMenu = VALIDATEHMENU(hMenu); if (pMenu == NULL) { return (BOOL)-1; }
/*
* Get a pointer the the menu item. */ if ((pItem = MNLookUpItem(pMenu, uIDEnableItem, (BOOL) (uEnable & MF_BYPOSITION), NULL)) == NULL) { return (DWORD)-1; }
/*
* If the item is already in the state we're * trying to set, just return. */ if ((pItem->fState & MFS_GRAYED) == (uEnable & MFS_GRAYED)) { return pItem->fState & MFS_GRAYED; }
return NtUserEnableMenuItem(hMenu, uIDEnableItem, uEnable); }
/***************************************************************************\
* CallNextHookEx * * This routine is called to call the next hook in the hook chain. * * 05-09-91 ScottLu Created. \***************************************************************************/ FUNCLOG4(LOG_GENERAL, LRESULT, WINAPI, CallNextHookEx, HHOOK, hhk, int, nCode, WPARAM, wParam, LPARAM, lParam) LRESULT WINAPI CallNextHookEx( HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam) { LRESULT nRet; BOOL bAnsi; DWORD dwHookCurrent; PCLIENTINFO pci; ULONG_PTR dwHookData; ULONG_PTR dwFlags;
UNREFERENCED_PARAMETER(hhk);
ConnectIfNecessary(0);
pci = GetClientInfo(); dwHookCurrent = pci->dwHookCurrent; bAnsi = LOWORD(dwHookCurrent);
/*
* If this is the last hook in the hook chain then return 0; we're done. */ if (PhkNextValid((PHOOK)((KERNEL_ULONG_PTR)pci->phkCurrent - pci->ulClientDelta)) == NULL) { return 0; }
switch ((INT)(SHORT)HIWORD(dwHookCurrent)) { case WH_CALLWNDPROC: case WH_CALLWNDPROCRET: /*
* This is the hardest of the hooks because we need to thunk through * the message hooks in order to deal with synchronously sent messages * that point to structures - to get the structures passed across * alright, etc. * * This will call a special kernel-side routine that'll rebundle the * arguments and call the hook in the right format. * * Currently, the message thunk callbacks to the client-side don't take * enough parameters to pass wParam (which == fInterThread send msg). * To do this, save the state of wParam in the CLIENTINFO structure. */ dwFlags = KERNEL_ULONG_PTR_TO_ULONG_PTR(pci->CI_flags) & CI_INTERTHREAD_HOOK; dwHookData = KERNEL_ULONG_PTR_TO_ULONG_PTR(pci->dwHookData); if (wParam) { pci->CI_flags |= CI_INTERTHREAD_HOOK; } else { pci->CI_flags &= ~CI_INTERTHREAD_HOOK; }
if ((INT)(SHORT)HIWORD(dwHookCurrent) == WH_CALLWNDPROC) { nRet = CsSendMessage( ((LPCWPSTRUCT)lParam)->hwnd, ((LPCWPSTRUCT)lParam)->message, ((LPCWPSTRUCT)lParam)->wParam, ((LPCWPSTRUCT)lParam)->lParam, 0, FNID_HKINLPCWPEXSTRUCT, bAnsi); } else { pci->dwHookData = ((LPCWPRETSTRUCT)lParam)->lResult; nRet = CsSendMessage( ((LPCWPRETSTRUCT)lParam)->hwnd, ((LPCWPRETSTRUCT)lParam)->message, ((LPCWPRETSTRUCT)lParam)->wParam, ((LPCWPRETSTRUCT)lParam)->lParam, 0, FNID_HKINLPCWPRETEXSTRUCT, bAnsi); }
/*
* Restore previous hook state. */ pci->CI_flags ^= ((pci->CI_flags ^ dwFlags) & CI_INTERTHREAD_HOOK); pci->dwHookData = dwHookData; break;
default: nRet = NtUserCallNextHookEx(nCode, wParam, lParam, bAnsi); }
return nRet; }
|