Make sure that functions returning an HWND always return a full 32-bit
handle.
diff --git a/windows/clipboard.c b/windows/clipboard.c
index 9a2d1e3..422d71f0 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 <stdlib.h>
@@ -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 @@
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 @@
hClipLock = GetCurrentTask();
/* Save current user of the clipboard */
- hWndClipWindow = hWnd;
+ hWndClipWindow = WIN_GetFullHandle( hWnd );
bCBHasChanged = FALSE;
bRet = TRUE;
}
@@ -1320,7 +1318,7 @@
TRACE("(%04x): returning %04x\n", hWnd, hwndPrev);
- hWndViewer = hWnd;
+ hWndViewer = WIN_GetFullHandle( hWnd );
return hwndPrev;
}
@@ -1368,7 +1366,7 @@
else
WARN("hWndViewer is lost\n");
- if( hWnd == hWndViewer ) hWndViewer = hWndNext;
+ if( hWnd == hWndViewer ) hWndViewer = WIN_GetFullHandle( hWndNext );
return bRet;
}
@@ -1474,4 +1472,3 @@
/* FIXME: Use serial numbers */
return 0;
}
-
diff --git a/windows/dce.c b/windows/dce.c
index d206458..2065cb3 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -70,7 +70,6 @@
{
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 @@
}
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_FreeDCE( DCE *dce )
{
- DCE **ppDCE;
+ DCE **ppDCE, *ret;
if (!dce) return NULL;
@@ -125,6 +123,8 @@
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 @@
DeleteObject(dce->hClipRgn);
HeapFree( GetProcessHeap(), 0, dce );
- USER_Unlock();
-
- return *ppDCE;
+ return ret;
}
/***********************************************************************
@@ -146,22 +144,21 @@
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 @@
* 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 @@
pDCE->DCXflags |= DCX_DCEEMPTY;
pDCE->hwndCurrent = 0;
}
- WIN_ReleaseWndPtr( pWnd );
}
pDCE = pDCE->next;
}
- USER_Unlock();
+ WIN_ReleaseWndPtr( pWnd );
}
@@ -403,6 +398,7 @@
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 ca15e7f..b950172 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -1953,6 +1953,9 @@
{
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 @@
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 57582d5..175d39d 100644
--- a/windows/focus.c
+++ b/windows/focus.c
@@ -74,6 +74,7 @@
/* 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 f371e61..018e669 100644
--- a/windows/input.c
+++ b/windows/input.c
@@ -493,7 +493,7 @@
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 6869cda..aa6162f 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -147,17 +147,50 @@
/***********************************************************************
- * 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 @@
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 @@
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 @@
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 8a9be5e..843864a 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -374,6 +374,7 @@
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 @@
HWND WINAPI SetShellWindow(HWND hwndshell)
{ WARN("(hWnd=%08x) semi stub\n",hwndshell );
- hGlobalShellWindow = hwndshell;
+ hGlobalShellWindow = WIN_GetFullHandle( hwndshell );
return hGlobalShellWindow;
}
@@ -1423,6 +1424,9 @@
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 @@
/* if (wndPtr && (GetFastQueue16() != wndPtr->hmemTaskQ))
* return 0;
*/
- wndPtr = WIN_FindWndPtr(hWnd);
hOldActiveQueue = hActiveQueue;
if( (wndTemp = WIN_FindWndPtr(hwndActive)) )