From 37a4639ee1f25440954ce350746fdbe366c38c85 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 12 Sep 2001 17:19:13 +0000 Subject: [PATCH] Make sure that functions returning an HWND always return a full 32-bit handle. --- dlls/user/message.c | 4 +- include/win.h | 13 ++++++- windows/clipboard.c | 19 ++++------ windows/dce.c | 38 +++++++++---------- windows/dialog.c | 5 +++ windows/focus.c | 1 + windows/input.c | 2 +- windows/win.c | 90 ++++++++++++++++++++++++++++----------------- windows/winpos.c | 7 +++- 9 files changed, 108 insertions(+), 71 deletions(-) diff --git a/dlls/user/message.c b/dlls/user/message.c index fe8e1b09dd..57c9c16ac4 100644 --- a/dlls/user/message.c +++ b/dlls/user/message.c @@ -1091,7 +1091,7 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar cwp.lParam = lparam; cwp.wParam = wparam; cwp.message = msg; - cwp.hwnd = hwnd; + cwp.hwnd = WIN_GetFullHandle( hwnd ); if (unicode) HOOK_CallHooksW( WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp ); else HOOK_CallHooksA( WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp ); lparam = cwp.lParam; @@ -1120,7 +1120,7 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar cwp.lParam = lparam; cwp.wParam = wparam; cwp.message = msg; - cwp.hwnd = hwnd; + cwp.hwnd = WIN_GetFullHandle( hwnd ); if (unicode) HOOK_CallHooksW( WH_CALLWNDPROCRET, HC_ACTION, 1, (LPARAM)&cwp ); else HOOK_CallHooksA( WH_CALLWNDPROCRET, HC_ACTION, 1, (LPARAM)&cwp ); } diff --git a/include/win.h b/include/win.h index 2f20cbce5c..cf56178110 100644 --- a/include/win.h +++ b/include/win.h @@ -85,7 +85,7 @@ extern WND* WIN_FindWndPtr( HWND hwnd ); extern WND* WIN_LockWndPtr(WND *wndPtr); extern void WIN_ReleaseWndPtr(WND *wndPtr); extern void WIN_UpdateWndPtr(WND **oldPtr,WND *newPtr); -extern HWND WIN_GetFullHandle( HWND hwnd ); +extern HWND WIN_Handle32( HWND16 hwnd16 ); extern void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter ); extern void WIN_UnlinkWindow( HWND hwnd ); extern HWND WIN_FindWinToRepaint( HWND hwnd ); @@ -96,6 +96,17 @@ extern HWND *WIN_ListParents( HWND hwnd ); extern HWND *WIN_ListChildren( HWND hwnd ); extern BOOL WIN_InternalShowOwnedPopups( HWND owner, BOOL fShow, BOOL unmanagedOnly ); +inline static HWND WIN_GetFullHandle( HWND hwnd ) +{ + if (!HIWORD(hwnd) && hwnd) hwnd = WIN_Handle32( LOWORD(hwnd) ); + return hwnd; +} + +inline static HWND16 WIN_Handle16( HWND hwnd ) +{ + return LOWORD(hwnd); +} + extern HWND CARET_GetHwnd(void); extern void CARET_GetRect(LPRECT lprc); /* windows/caret.c */ diff --git a/windows/clipboard.c b/windows/clipboard.c index 9a2d1e36d5..422d71f02d 100644 --- a/windows/clipboard.c +++ b/windows/clipboard.c @@ -12,9 +12,6 @@ * The internal implementation talks to a "clipboard driver" to fill or * expose the cache to the native device. (Currently only the X11 and * TTY clipboard driver are available) - * - * TODO: - * */ #include @@ -31,6 +28,7 @@ #include "wine/winbase16.h" #include "heap.h" #include "user.h" +#include "win.h" #include "clipboard.h" #include "debugtools.h" @@ -45,10 +43,10 @@ DEFAULT_DEBUG_CHANNEL(clipboard); static HANDLE hClipLock = 0; static BOOL bCBHasChanged = FALSE; -HWND hWndClipWindow = 0; /* window that last opened clipboard */ -HWND hWndClipOwner = 0; /* current clipboard owner */ -HANDLE16 hTaskClipOwner = 0; /* clipboard owner's task */ -static HWND hWndViewer = 0; /* start of viewers chain */ +static HWND hWndClipWindow; /* window that last opened clipboard */ +static HWND hWndClipOwner; /* current clipboard owner */ +static HANDLE16 hTaskClipOwner; /* clipboard owner's task */ +static HWND hWndViewer; /* start of viewers chain */ static WORD LastRegFormat = CF_REGFORMATBASE; @@ -737,7 +735,7 @@ BOOL WINAPI OpenClipboard( HWND hWnd ) hClipLock = GetCurrentTask(); /* Save current user of the clipboard */ - hWndClipWindow = hWnd; + hWndClipWindow = WIN_GetFullHandle( hWnd ); bCBHasChanged = FALSE; bRet = TRUE; } @@ -1320,7 +1318,7 @@ HWND WINAPI SetClipboardViewer( HWND hWnd ) TRACE("(%04x): returning %04x\n", hWnd, hwndPrev); - hWndViewer = hWnd; + hWndViewer = WIN_GetFullHandle( hWnd ); return hwndPrev; } @@ -1368,7 +1366,7 @@ BOOL WINAPI ChangeClipboardChain(HWND hWnd, HWND hWndNext) else WARN("hWndViewer is lost\n"); - if( hWnd == hWndViewer ) hWndViewer = hWndNext; + if( hWnd == hWndViewer ) hWndViewer = WIN_GetFullHandle( hWndNext ); return bRet; } @@ -1474,4 +1472,3 @@ DWORD WINAPI GetClipboardSequenceNumber(VOID) /* FIXME: Use serial numbers */ return 0; } - diff --git a/windows/dce.c b/windows/dce.c index d20645876c..2065cb3db9 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -70,7 +70,6 @@ DCE *DCE_AllocDCE( HWND hWnd, DCE_TYPE type ) { FARPROC16 hookProc; DCE * dce; - WND* wnd; if (!(dce = HeapAlloc( GetProcessHeap(), 0, sizeof(DCE) ))) return NULL; if (!(dce->hDC = CreateDCA( "DISPLAY", NULL, NULL, NULL ))) @@ -80,32 +79,31 @@ DCE *DCE_AllocDCE( HWND hWnd, DCE_TYPE type ) } if (!defaultDCstate) defaultDCstate = GetDCState16( dce->hDC ); - wnd = WIN_FindWndPtr(hWnd); - /* store DCE handle in DC hook data field */ hookProc = GetProcAddress16( GetModuleHandle16("USER"), (LPCSTR)362 ); SetDCHook( dce->hDC, hookProc, (DWORD)dce ); - dce->hwndCurrent = hWnd; + dce->hwndCurrent = WIN_GetFullHandle( hWnd ); dce->hClipRgn = 0; - dce->next = firstDCE; - firstDCE = dce; if( type != DCE_CACHE_DC ) /* owned or class DC */ { dce->DCXflags = DCX_DCEBUSY; if( hWnd ) { - if( wnd->dwStyle & WS_CLIPCHILDREN ) dce->DCXflags |= DCX_CLIPCHILDREN; - if( wnd->dwStyle & WS_CLIPSIBLINGS ) dce->DCXflags |= DCX_CLIPSIBLINGS; + LONG style = GetWindowLongW( hWnd, GWL_STYLE ); + if (style & WS_CLIPCHILDREN) dce->DCXflags |= DCX_CLIPCHILDREN; + if (style & WS_CLIPSIBLINGS) dce->DCXflags |= DCX_CLIPSIBLINGS; } SetHookFlags16(dce->hDC,DCHF_INVALIDATEVISRGN); } else dce->DCXflags = DCX_CACHE | DCX_DCEEMPTY; - - WIN_ReleaseWndPtr(wnd); + USER_Lock(); + dce->next = firstDCE; + firstDCE = dce; + USER_Unlock(); return dce; } @@ -115,7 +113,7 @@ DCE *DCE_AllocDCE( HWND hWnd, DCE_TYPE type ) */ DCE* DCE_FreeDCE( DCE *dce ) { - DCE **ppDCE; + DCE **ppDCE, *ret; if (!dce) return NULL; @@ -125,6 +123,8 @@ DCE* DCE_FreeDCE( DCE *dce ) while (*ppDCE && (*ppDCE != dce)) ppDCE = &(*ppDCE)->next; if (*ppDCE == dce) *ppDCE = dce->next; + ret = *ppDCE; + USER_Unlock(); SetDCHook(dce->hDC, NULL, 0L); @@ -133,9 +133,7 @@ DCE* DCE_FreeDCE( DCE *dce ) DeleteObject(dce->hClipRgn); HeapFree( GetProcessHeap(), 0, dce ); - USER_Unlock(); - - return *ppDCE; + return ret; } /*********************************************************************** @@ -146,22 +144,21 @@ DCE* DCE_FreeDCE( DCE *dce ) void DCE_FreeWindowDCE( HWND hwnd ) { DCE *pDCE; + WND *pWnd = WIN_FindWndPtr( hwnd ); - USER_Lock(); pDCE = firstDCE; + hwnd = pWnd->hwndSelf; /* make it a full handle */ while( pDCE ) { if( pDCE->hwndCurrent == hwnd ) { - WND *pWnd = WIN_FindWndPtr( hwnd ); if( pDCE == pWnd->dce ) /* owned or Class DCE*/ { if (pWnd->clsStyle & CS_OWNDC) /* owned DCE*/ { pDCE = DCE_FreeDCE( pDCE ); pWnd->dce = NULL; - WIN_ReleaseWndPtr( pWnd ); continue; } else if( pDCE->DCXflags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN) ) /* Class DCE*/ @@ -181,8 +178,7 @@ void DCE_FreeWindowDCE( HWND hwnd ) * We should change this to WARN when Wine is more stable * (for 1.0?). */ - ERR("[%04x] GetDC() without ReleaseDC()!\n", - pWnd->hwndSelf); + ERR("[%08x] GetDC() without ReleaseDC()!\n",hwnd); DCE_ReleaseDC( pDCE ); } @@ -190,12 +186,11 @@ void DCE_FreeWindowDCE( HWND hwnd ) pDCE->DCXflags |= DCX_DCEEMPTY; pDCE->hwndCurrent = 0; } - WIN_ReleaseWndPtr( pWnd ); } pDCE = pDCE->next; } - USER_Unlock(); + WIN_ReleaseWndPtr( pWnd ); } @@ -403,6 +398,7 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) if (!hwnd) hwnd = GetDesktopWindow(); if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; + hwnd = wndPtr->hwndSelf; /* make it a full handle */ /* fixup flags */ diff --git a/windows/dialog.c b/windows/dialog.c index ca15e7faca..b9501721e7 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -1953,6 +1953,9 @@ HWND WINAPI GetNextDlgGroupItem( HWND hwndDlg, HWND hwndCtrl, { HWND hwnd, retvalue; + hwndDlg = WIN_GetFullHandle( hwndDlg ); + hwndCtrl = WIN_GetFullHandle( hwndCtrl ); + if(hwndCtrl) { /* if the hwndCtrl is the child of the control in the hwndDlg, @@ -2108,6 +2111,8 @@ static HWND DIALOG_GetNextTabItem( HWND hwndMain, HWND hwndDlg, HWND hwndCtrl, B HWND WINAPI GetNextDlgTabItem( HWND hwndDlg, HWND hwndCtrl, BOOL fPrevious ) { + hwndDlg = WIN_GetFullHandle( hwndDlg ); + hwndCtrl = WIN_GetFullHandle( hwndCtrl ); return DIALOG_GetNextTabItem(hwndDlg,hwndDlg,hwndCtrl,fPrevious); } diff --git a/windows/focus.c b/windows/focus.c index 57582d5cd9..175d39da07 100644 --- a/windows/focus.c +++ b/windows/focus.c @@ -74,6 +74,7 @@ HWND WINAPI SetFocus( HWND hwnd ) /* Check if we can set the focus to this window */ WND *wndPtr; + hwnd = WIN_GetFullHandle( hwnd ); for (;;) { HWND parent; diff --git a/windows/input.c b/windows/input.c index f371e6161b..018e669a63 100644 --- a/windows/input.c +++ b/windows/input.c @@ -493,7 +493,7 @@ HWND EVENT_Capture(HWND hwnd, INT16 ht) if (wndPtr) { TRACE_(win)("(0x%04x)\n", hwnd ); - captureWnd = hwnd; + captureWnd = wndPtr->hwndSelf; captureHT = ht; } } diff --git a/windows/win.c b/windows/win.c index 6869cda074..aa6162f0c4 100644 --- a/windows/win.c +++ b/windows/win.c @@ -147,17 +147,50 @@ static WND *free_window_handle( HWND hwnd ) /*********************************************************************** - * WIN_GetFullHandle + * get_wnd_ptr * - * Get the full 32-bit window handle from a possibly truncated handle. + * Return a pointer to the WND structure if local to the process. + * If ret value is non-NULL, the user lock is held. */ -HWND WIN_GetFullHandle( HWND hwnd ) +static WND *get_wnd_ptr( HWND hwnd ) { - if (!HIWORD(hwnd)) + WND * ptr; + + if (!hwnd) return NULL; + + USER_Lock(); + if ((ptr = user_handles[LOWORD(hwnd)])) + { + if (ptr->dwMagic == WND_MAGIC && (!HIWORD(hwnd) || hwnd == ptr->hwndSelf)) + return ptr; + } + USER_Unlock(); + return NULL; +} + + +/*********************************************************************** + * WIN_Handle32 + * + * Convert a 16-bit window handle to a full 32-bit handle. + */ +HWND WIN_Handle32( HWND16 hwnd16 ) +{ + WND *ptr; + HWND hwnd = (HWND)hwnd16; + + if (!hwnd || hwnd == HWND_BROADCAST) return hwnd; + + if ((ptr = get_wnd_ptr( hwnd ))) + { + hwnd = ptr->hwndSelf; + USER_Unlock(); + } + else /* may belong to another process */ { SERVER_START_REQ( get_window_info ) { - req->handle = hwnd; + req->handle = (user_handle_t)hwnd16; if (!SERVER_CALL_ERR()) hwnd = req->full_handle; } SERVER_END_REQ; @@ -177,27 +210,19 @@ WND * WIN_FindWndPtr( HWND hwnd ) if (!hwnd) return NULL; - USER_Lock(); - if (!(ptr = user_handles[LOWORD(hwnd)])) + if ((ptr = get_wnd_ptr( hwnd ))) { - /* check other processes */ - if (IsWindow( hwnd )) - { - ERR( "window %04x belongs to other process\n", hwnd ); - /* DbgBreakPoint(); */ - } - goto error; + /* increment destruction monitoring */ + ptr->irefCount++; + return ptr; } - if (ptr->dwMagic != WND_MAGIC) goto error; - /* verify that handle highword (if any) matches the window */ - if (HIWORD(hwnd) && hwnd != ptr->hwndSelf) goto error; - /*and increment destruction monitoring*/ - ptr->irefCount++; - return ptr; - error: - /* Unlock all WND structures for thread safeness*/ - USER_Unlock(); + /* check other processes */ + if (IsWindow( hwnd )) + { + ERR( "window %04x belongs to other process\n", hwnd ); + /* DbgBreakPoint(); */ + } SetLastError( ERROR_INVALID_WINDOW_HANDLE ); return NULL; } @@ -2078,24 +2103,24 @@ BOOL16 WINAPI IsWindow16( HWND16 hwnd ) BOOL WINAPI IsWindow( HWND hwnd ) { WND *ptr; - BOOL ret = FALSE; + BOOL ret; USER_Lock(); if ((ptr = user_handles[LOWORD(hwnd)])) { ret = ((ptr->dwMagic == WND_MAGIC) && (!HIWORD(hwnd) || hwnd == ptr->hwndSelf)); + USER_Unlock(); + return ret; } USER_Unlock(); - if (!ret) /* check other processes */ + /* check other processes */ + SERVER_START_REQ( get_window_info ) { - SERVER_START_REQ( get_window_info ) - { - req->handle = hwnd; - ret = !SERVER_CALL_ERR(); - } - SERVER_END_REQ; + req->handle = hwnd; + ret = !SERVER_CALL_ERR(); } + SERVER_END_REQ; return ret; } @@ -2601,9 +2626,8 @@ HWND WINAPI GetLastActivePopup( HWND hwnd ) WND *wndPtr =WIN_FindWndPtr(hwnd); if (!wndPtr) return hwnd; retval = wndPtr->hwndLastActive; + if (!IsWindow( retval )) retval = wndPtr->hwndSelf; WIN_ReleaseWndPtr(wndPtr); - if ((retval != hwnd) && (!IsWindow(retval))) - retval = hwnd; return retval; } diff --git a/windows/winpos.c b/windows/winpos.c index 8a9be5e284..843864a587 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -374,6 +374,7 @@ HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest ) if (!hwndScope) hwndScope = GetDesktopWindow(); if (!(wndScope = WIN_FindWndPtr( hwndScope ))) return 0; + hwndScope = wndScope->hwndSelf; /* make it a full handle */ *hittest = HTERROR; wndPtr = WIN_LockWndPtr(wndScope->child); @@ -892,7 +893,7 @@ HWND16 WINAPI GetShellWindow16(void) HWND WINAPI SetShellWindow(HWND hwndshell) { WARN("(hWnd=%08x) semi stub\n",hwndshell ); - hGlobalShellWindow = hwndshell; + hGlobalShellWindow = WIN_GetFullHandle( hwndshell ); return hGlobalShellWindow; } @@ -1423,6 +1424,9 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus) hwndActive = PERQDATA_GetActiveWnd( pOldActiveQueue->pQData ); } + if ((wndPtr = WIN_FindWndPtr(hWnd))) + hWnd = wndPtr->hwndSelf; /* make it a full handle */ + /* paranoid checks */ if( hWnd == GetDesktopWindow() || (bRet = (hWnd == hwndActive)) ) goto CLEANUP_END; @@ -1430,7 +1434,6 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus) /* if (wndPtr && (GetFastQueue16() != wndPtr->hmemTaskQ)) * return 0; */ - wndPtr = WIN_FindWndPtr(hWnd); hOldActiveQueue = hActiveQueue; if( (wndTemp = WIN_FindWndPtr(hwndActive)) ) -- 2.32.0.93.g670b81a890