diff --git a/controls/icontitle.c b/controls/icontitle.c index 85bcd42cbf6..c0480928394 100644 --- a/controls/icontitle.c +++ b/controls/icontitle.c @@ -46,25 +46,22 @@ HWND ICONTITLE_Create( HWND owner ) WND* wndPtr; HWND hWnd; HINSTANCE instance = GetWindowLongA( owner, GWL_HINSTANCE ); + LONG style = WS_CLIPSIBLINGS; + if (!IsWindowEnabled(owner)) style |= WS_DISABLED; if( GetWindowLongA( owner, GWL_STYLE ) & WS_CHILD ) hWnd = CreateWindowExA( 0, ICONTITLE_CLASS_ATOM, NULL, - WS_CHILD | WS_CLIPSIBLINGS, 0, 0, 1, 1, - GetParent(owner), 0, instance, NULL ); + style | WS_CHILD, 0, 0, 1, 1, + GetParent(owner), 0, instance, NULL ); else hWnd = CreateWindowExA( 0, ICONTITLE_CLASS_ATOM, NULL, - WS_CLIPSIBLINGS, 0, 0, 1, 1, - owner, 0, instance, NULL ); - wndPtr = WIN_FindWndPtr( hWnd ); - if( wndPtr ) - { - wndPtr->owner = owner; /* MDI depends on this */ - wndPtr->dwStyle &= ~(WS_CAPTION | WS_BORDER); - if (!IsWindowEnabled(owner)) wndPtr->dwStyle |= WS_DISABLED; - WIN_ReleaseWndPtr(wndPtr); - return hWnd; - } - return 0; + style, 0, 0, 1, 1, + owner, 0, instance, NULL ); + if (!(wndPtr = WIN_GetPtr( hWnd ))) return 0; + wndPtr->owner = owner; /* MDI depends on this */ + wndPtr->dwStyle &= ~(WS_CAPTION | WS_BORDER); + WIN_ReleasePtr(wndPtr); + return hWnd; } /*********************************************************************** diff --git a/controls/scroll.c b/controls/scroll.c index 02720b52f5b..60d8ce6f23a 100644 --- a/controls/scroll.c +++ b/controls/scroll.c @@ -791,7 +791,7 @@ void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, INT nBar, if (!wndPtr || !infoPtr || ((nBar == SB_VERT) && !(wndPtr->dwStyle & WS_VSCROLL)) || ((nBar == SB_HORZ) && !(wndPtr->dwStyle & WS_HSCROLL))) goto END; - if (!WIN_IsWindowDrawable( wndPtr, FALSE )) goto END; + if (!WIN_IsWindowDrawable( hwnd, FALSE )) goto END; hwnd = wndPtr->hwndSelf; /* make it a full handle */ vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect, diff --git a/dlls/user/msg16.c b/dlls/user/msg16.c index 2ed9979b70b..29c19419a7d 100644 --- a/dlls/user/msg16.c +++ b/dlls/user/msg16.c @@ -5,6 +5,7 @@ */ #include "wine/winuser16.h" +#include "winerror.h" #include "heap.h" #include "hook.h" #include "message.h" @@ -263,35 +264,44 @@ LONG WINAPI DispatchMessage16( const MSG16* msg ) } } - if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; - if (!wndPtr->winproc) + if (!(wndPtr = WIN_GetPtr( msg->hwnd ))) { - WIN_ReleaseWndPtr( wndPtr ); + if (msg->hwnd) SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return 0; + } + if (wndPtr == WND_OTHER_PROCESS) + { + if (IsWindow( msg->hwnd )) + ERR( "cannot dispatch msg to other process window %x\n", msg->hwnd ); + SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return 0; + } + + if (!(winproc = (WNDPROC16)wndPtr->winproc)) + { + WIN_ReleasePtr( wndPtr ); return 0; } - winproc = (WNDPROC16)wndPtr->winproc; painting = (msg->message == WM_PAINT); if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT; - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); SPY_EnterMessage( SPY_DISPATCHMESSAGE16, hwnd, msg->message, msg->wParam, msg->lParam ); retval = CallWindowProc16( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam ); SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg->message, retval, msg->wParam, msg->lParam ); - if (!painting) return retval; - - if ((wndPtr = WIN_FindWndPtr( hwnd ))) + if (painting && (wndPtr = WIN_GetPtr( hwnd )) && (wndPtr != WND_OTHER_PROCESS)) { - if ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate) + BOOL validate = ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate); + wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT; + WIN_ReleasePtr( wndPtr ); + if (validate) { ERR( "BeginPaint not called on WM_PAINT for hwnd %04x!\n", msg->hwnd ); - wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT; - WIN_ReleaseWndPtr( wndPtr ); /* Validate the update region to avoid infinite WM_PAINT loop */ RedrawWindow( hwnd, NULL, 0, RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT ); } - else WIN_ReleaseWndPtr( wndPtr ); } return retval; } diff --git a/dlls/x11drv/desktop.c b/dlls/x11drv/desktop.c index b78da814835..5576f140529 100644 --- a/dlls/x11drv/desktop.c +++ b/dlls/x11drv/desktop.c @@ -54,11 +54,11 @@ static DWORD CALLBACK desktop_thread( LPVOID driver_data ) hwnd = GetDesktopWindow(); /* patch the desktop window queue to point to our queue */ - win = WIN_FindWndPtr( hwnd ); + win = WIN_GetPtr( hwnd ); win->tid = GetCurrentThreadId(); win->hmemTaskQ = InitThreadInput16( 0, 0 ); X11DRV_register_window( display, hwnd, win->pDriverData ); - WIN_ReleaseWndPtr( win ); + WIN_ReleasePtr( win ); SetWindowLongW( hwnd, GWL_WNDPROC, (LONG)desktop_winproc ); wine_tsx11_lock(); diff --git a/dlls/x11drv/scroll.c b/dlls/x11drv/scroll.c index ab506c4713d..443c6d2ce96 100644 --- a/dlls/x11drv/scroll.c +++ b/dlls/x11drv/scroll.c @@ -142,16 +142,9 @@ INT X11DRV_ScrollWindowEx( HWND hwnd, INT dx, INT dy, INT retVal = NULLREGION; BOOL bCaret = FALSE, bOwnRgn = TRUE; RECT rc, cliprc; - WND* wnd = WIN_FindWndPtr( hwnd ); - if (!wnd) return ERROR; - if (!WIN_IsWindowDrawable( wnd, TRUE )) - { - WIN_ReleaseWndPtr( wnd ); - return ERROR; - } - hwnd = wnd->hwndSelf; /* make it a full handle */ - WIN_ReleaseWndPtr( wnd ); + if (!WIN_IsWindowDrawable( hwnd, TRUE )) return ERROR; + hwnd = WIN_GetFullHandle( hwnd ); GetClientRect(hwnd, &rc); if (rect) IntersectRect(&rc, &rc, rect); diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c index b1a59059b94..b9023c734c7 100644 --- a/dlls/x11drv/window.c +++ b/dlls/x11drv/window.c @@ -45,6 +45,9 @@ Atom wmChangeState = None; Atom kwmDockWindow = None; Atom _kde_net_wm_system_tray_window_for = None; /* KDE 2 Final */ +static LPCSTR whole_window_atom; +static LPCSTR client_window_atom; +static LPCSTR icon_window_atom; /*********************************************************************** * is_window_managed @@ -197,7 +200,7 @@ static Window create_icon_window( Display *display, WND *win ) wine_tsx11_unlock(); TRACE( "created %lx\n", data->icon_window ); - SetPropA( win->hwndSelf, "__wine_x11_icon_window", (HANDLE)data->icon_window ); + SetPropA( win->hwndSelf, icon_window_atom, (HANDLE)data->icon_window ); return data->icon_window; } @@ -216,7 +219,7 @@ inline static void destroy_icon_window( Display *display, WND *win ) XDestroyWindow( display, data->icon_window ); data->icon_window = 0; wine_tsx11_unlock(); - RemovePropA( win->hwndSelf, "__wine_x11_icon_window" ); + RemovePropA( win->hwndSelf, icon_window_atom ); } @@ -600,11 +603,15 @@ static void create_desktop( Display *display, WND *wndPtr, CREATESTRUCTA *cs ) _kde_net_wm_system_tray_window_for = XInternAtom( display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False ); wine_tsx11_unlock(); + whole_window_atom = MAKEINTATOMA( GlobalAddAtomA( "__wine_x11_whole_window" )); + client_window_atom = MAKEINTATOMA( GlobalAddAtomA( "__wine_x11_client_window" )); + icon_window_atom = MAKEINTATOMA( GlobalAddAtomA( "__wine_x11_icon_window" )); + data->whole_window = data->client_window = root_window; data->whole_rect = data->client_rect = wndPtr->rectWindow; - SetPropA( wndPtr->hwndSelf, "__wine_x11_whole_window", (HANDLE)root_window ); - SetPropA( wndPtr->hwndSelf, "__wine_x11_client_window", (HANDLE)root_window ); + SetPropA( wndPtr->hwndSelf, whole_window_atom, (HANDLE)root_window ); + SetPropA( wndPtr->hwndSelf, client_window_atom, (HANDLE)root_window ); SetPropA( wndPtr->hwndSelf, "__wine_x11_visual_id", (HANDLE)XVisualIDFromVisual(visual) ); SendMessageW( wndPtr->hwndSelf, WM_NCCREATE, 0, (LPARAM)cs ); @@ -717,10 +724,8 @@ BOOL X11DRV_SetWindowText( HWND hwnd, LPCWSTR text ) char *utf8_buffer; static UINT text_cp = (UINT)-1; Window win; - WND *wndPtr = WIN_FindWndPtr( hwnd ); - if (!wndPtr) return FALSE; - if ((win = get_whole_window(wndPtr))) + if ((win = X11DRV_get_whole_window( hwnd ))) { if (text_cp == (UINT)-1) { @@ -743,7 +748,6 @@ BOOL X11DRV_SetWindowText( HWND hwnd, LPCWSTR text ) if (!(buffer = HeapAlloc( GetProcessHeap(), 0, count ))) { ERR("Not enough memory for window text\n"); - WIN_ReleaseWndPtr( wndPtr ); return FALSE; } WideCharToMultiByte(text_cp, 0, text, -1, buffer, count, NULL, NULL); @@ -752,7 +756,6 @@ BOOL X11DRV_SetWindowText( HWND hwnd, LPCWSTR text ) if (!(utf8_buffer = HeapAlloc( GetProcessHeap(), 0, count ))) { ERR("Not enough memory for window text in UTF-8\n"); - WIN_ReleaseWndPtr( wndPtr ); return FALSE; } WideCharToMultiByte(CP_UTF8, 0, text, strlenW(text), utf8_buffer, count, NULL, NULL); @@ -775,7 +778,6 @@ BOOL X11DRV_SetWindowText( HWND hwnd, LPCWSTR text ) HeapFree( GetProcessHeap(), 0, utf8_buffer ); HeapFree( GetProcessHeap(), 0, buffer ); } - WIN_ReleaseWndPtr( wndPtr ); return TRUE; } @@ -786,7 +788,7 @@ BOOL X11DRV_SetWindowText( HWND hwnd, LPCWSTR text ) BOOL X11DRV_DestroyWindow( HWND hwnd ) { Display *display = thread_display(); - WND *wndPtr = WIN_FindWndPtr( hwnd ); + WND *wndPtr = WIN_GetPtr( hwnd ); X11DRV_WND_DATA *data = wndPtr->pDriverData; if (!data) goto done; @@ -808,7 +810,7 @@ BOOL X11DRV_DestroyWindow( HWND hwnd ) HeapFree( GetProcessHeap(), 0, data ); wndPtr->pDriverData = NULL; done: - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); return TRUE; } @@ -847,8 +849,8 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode ) WIN_ReleaseWndPtr( wndPtr ); - SetPropA( hwnd, "__wine_x11_whole_window", (HANDLE)data->whole_window ); - SetPropA( hwnd, "__wine_x11_client_window", (HANDLE)data->client_window ); + SetPropA( hwnd, whole_window_atom, (HANDLE)data->whole_window ); + SetPropA( hwnd, client_window_atom, (HANDLE)data->client_window ); /* send WM_NCCREATE */ TRACE( "hwnd %x cs %d,%d %dx%d\n", hwnd, cs->x, cs->y, cs->cx, cs->cy ); @@ -958,12 +960,16 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode ) Window X11DRV_get_client_window( HWND hwnd ) { Window ret = 0; - WND *win = WIN_FindWndPtr( hwnd ); + WND *win = WIN_GetPtr( hwnd ); + + if (win == WND_OTHER_PROCESS) + return GetPropA( hwnd, client_window_atom ); + if (win) { struct x11drv_win_data *data = win->pDriverData; ret = data->client_window; - WIN_ReleaseWndPtr( win ); + WIN_ReleasePtr( win ); } return ret; } @@ -977,12 +983,16 @@ Window X11DRV_get_client_window( HWND hwnd ) Window X11DRV_get_whole_window( HWND hwnd ) { Window ret = 0; - WND *win = WIN_FindWndPtr( hwnd ); + WND *win = WIN_GetPtr( hwnd ); + + if (win == WND_OTHER_PROCESS) + return GetPropA( hwnd, whole_window_atom ); + if (win) { struct x11drv_win_data *data = win->pDriverData; ret = data->whole_window; - WIN_ReleaseWndPtr( win ); + WIN_ReleasePtr( win ); } return ret; } @@ -1176,19 +1186,15 @@ void X11DRV_SetFocus( HWND hwnd ) */ HICON X11DRV_SetWindowIcon( HWND hwnd, HICON icon, BOOL small ) { + WND *wndPtr; Display *display = thread_display(); - WND *wndPtr = WIN_FindWndPtr( hwnd ); - int index = small ? GCL_HICONSM : GCL_HICON; - HICON old; - - if (!wndPtr) return 0; - - old = GetClassLongW( hwnd, index ); - SetClassLongW( hwnd, index, icon ); + HICON old = SetClassLongW( hwnd, small ? GCL_HICONSM : GCL_HICON, icon ); SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER ); + if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return old; + if (wndPtr->dwExStyle & WS_EX_MANAGED) { Window win = get_whole_window(wndPtr); @@ -1202,7 +1208,6 @@ HICON X11DRV_SetWindowIcon( HWND hwnd, HICON icon, BOOL small ) TSXFree( wm_hints ); } } - - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); return old; } diff --git a/dlls/x11drv/winpos.c b/dlls/x11drv/winpos.c index 1852df11c01..ba7e4fa67bf 100644 --- a/dlls/x11drv/winpos.c +++ b/dlls/x11drv/winpos.c @@ -148,7 +148,7 @@ static HRGN get_visible_region( WND *win, HWND top, UINT flags, int mode ) if (top && top != win->hwndSelf) /* need to clip siblings of ancestors */ { - WND *parent, *ptr = WIN_LockWndPtr( win ); + WND *parent, *ptr = WIN_FindWndPtr( win->hwndSelf ); HRGN tmp = 0; OffsetRgn( rgn, xoffset, yoffset ); @@ -194,7 +194,7 @@ static int get_covered_region( WND *win, HRGN rgn ) { HRGN tmp; int ret; - WND *parent, *ptr = WIN_LockWndPtr( win ); + WND *parent, *ptr = WIN_FindWndPtr( win->hwndSelf ); int xoffset = 0, yoffset = 0; tmp = CreateRectRgn( 0, 0, 0, 0 ); @@ -384,7 +384,7 @@ void X11DRV_Expose( HWND hwnd, XExposeEvent *event ) rect.right = rect.left + event->width; rect.bottom = rect.top + event->height; - if (!(win = WIN_FindWndPtr(hwnd))) return; + if (!(win = WIN_GetPtr( hwnd ))) return; data = win->pDriverData; if (event->window != data->client_window) /* whole window or icon window */ @@ -393,7 +393,7 @@ void X11DRV_Expose( HWND hwnd, XExposeEvent *event ) /* make position relative to client area instead of window */ OffsetRect( &rect, -data->client_rect.left, -data->client_rect.top ); } - WIN_ReleaseWndPtr( win ); + WIN_ReleasePtr( win ); expose_window( hwnd, &rect, 0, flags ); } @@ -1434,7 +1434,7 @@ void X11DRV_ConfigureNotify( HWND hwnd, XConfigureEvent *event ) WINDOWPOS winpos; int x = event->x, y = event->y; - if (!(win = WIN_FindWndPtr( hwnd ))) return; + if (!(win = WIN_GetPtr( hwnd ))) return; data = win->pDriverData; /* Get geometry */ @@ -1455,7 +1455,7 @@ void X11DRV_ConfigureNotify( HWND hwnd, XConfigureEvent *event ) hwnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, event->x, event->y, event->width, event->height ); X11DRV_X_to_window_rect( win, &rect ); - WIN_ReleaseWndPtr( win ); + WIN_ReleasePtr( win ); winpos.hwnd = hwnd; winpos.x = rect.left; diff --git a/include/win.h b/include/win.h index f454d119b9e..dcd7ed0074b 100644 --- a/include/win.h +++ b/include/win.h @@ -14,6 +14,8 @@ #include "winuser.h" #include "wine/windef16.h" +#include "user.h" + #define WND_MAGIC 0x444e4957 /* 'WIND' */ struct tagCLASS; @@ -76,22 +78,20 @@ typedef struct #define WIN_NEEDS_INTERNALSOP 0x1000 /* Window was hidden by WIN_InternalShowOwnedPopups */ /* Window functions */ -extern WND *WIN_GetWndPtr( HWND hwnd ); +extern WND *WIN_GetPtr( HWND hwnd ); extern int WIN_SuspendWndsLock( void ); extern void WIN_RestoreWndsLock(int ipreviousLock); 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_Handle32( HWND16 hwnd16 ); -extern BOOL WIN_IsCurrentProcess( HWND hwnd ); -extern BOOL WIN_IsCurrentThread( HWND hwnd ); +extern HWND WIN_IsCurrentProcess( HWND hwnd ); +extern HWND WIN_IsCurrentThread( HWND hwnd ); extern void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter ); extern void WIN_UnlinkWindow( HWND hwnd ); extern HWND WIN_FindWinToRepaint( HWND hwnd ); extern void WIN_DestroyThreadWindows( HWND hwnd ); extern BOOL WIN_CreateDesktopWindow(void); -extern BOOL WIN_IsWindowDrawable(WND*, BOOL ); +extern BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL ); extern HWND *WIN_ListParents( HWND hwnd ); extern HWND *WIN_ListChildren( HWND hwnd ); extern BOOL WIN_InternalShowOwnedPopups( HWND owner, BOOL fShow, BOOL unmanagedOnly ); @@ -113,7 +113,13 @@ inline static WND *WIN_FindWndPtr16( HWND16 hwnd ) return WIN_FindWndPtr( (HWND)(ULONG_PTR)hwnd ); } -#define BAD_WND_PTR ((WND *)1) /* returned by WIN_GetWndPtr on bad window handles */ +/* to release pointers retrieved by WIN_GetPtr; do not confuse with WIN_ReleaseWndPtr!! */ +inline static void WIN_ReleasePtr( WND *ptr ) +{ + USER_Unlock(); +} + +#define WND_OTHER_PROCESS ((WND *)1) /* returned by WIN_GetPtr on unknown window handles */ extern HWND CARET_GetHwnd(void); extern void CARET_GetRect(LPRECT lprc); /* windows/caret.c */ diff --git a/windows/class.c b/windows/class.c index 1ec779759c1..9c5724ab468 100644 --- a/windows/class.c +++ b/windows/class.c @@ -58,25 +58,27 @@ static CLASS *firstClass; /*********************************************************************** * get_class_ptr */ -static CLASS *get_class_ptr( HWND hwnd ) +static CLASS *get_class_ptr( HWND hwnd, BOOL write_access ) { - CLASS *ret = NULL; - WND *ptr = WIN_GetWndPtr( hwnd ); + WND *ptr = WIN_GetPtr( hwnd ); - if (!ptr) + if (ptr) { + if (ptr != WND_OTHER_PROCESS) return ptr->class; if (IsWindow( hwnd )) /* check other processes */ { - ERR( "class of window %04x belongs to other process\n", hwnd ); + if (write_access) + { + /* modifying classes in other processes is not allowed */ + SetLastError( ERROR_ACCESS_DENIED ); + return NULL; + } + FIXME( "reading from class of other process window %04x\n", hwnd ); /* DbgBreakPoint(); */ } } - else - { - if (ptr != BAD_WND_PTR) ret = ptr->class; - else SetLastError( ERROR_INVALID_WINDOW_HANDLE ); - } - return ret; + SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return NULL; } @@ -741,7 +743,7 @@ WORD WINAPI GetClassWord( HWND hwnd, INT offset ) TRACE("%x %x\n",hwnd, offset); - if (!(class = get_class_ptr( hwnd ))) return 0; + if (!(class = get_class_ptr( hwnd, FALSE ))) return 0; if (offset <= class->cbClsExtra - sizeof(WORD)) retvalue = GET_WORD((char *)(class + 1) + offset); @@ -766,7 +768,7 @@ LONG WINAPI GetClassLong16( HWND16 hwnd16, INT16 offset ) switch( offset ) { case GCL_WNDPROC: - if (!(class = get_class_ptr( hwnd ))) return 0; + if (!(class = get_class_ptr( hwnd, FALSE ))) return 0; ret = (LONG)CLASS_GetProc( class, WIN_PROC_16 ); release_class_ptr( class ); return ret; @@ -789,7 +791,7 @@ LONG WINAPI GetClassLongA( HWND hwnd, INT offset ) TRACE("%x %d\n", hwnd, offset); - if (!(class = get_class_ptr( hwnd ))) return 0; + if (!(class = get_class_ptr( hwnd, FALSE ))) return 0; if (offset >= 0) { @@ -858,7 +860,7 @@ LONG WINAPI GetClassLongW( HWND hwnd, INT offset ) TRACE("%x %d\n", hwnd, offset); - if (!(class = get_class_ptr( hwnd ))) return 0; + if (!(class = get_class_ptr( hwnd, FALSE ))) return 0; if (offset == GCL_WNDPROC) retvalue = (LONG)CLASS_GetProc( class, WIN_PROC_32W ); @@ -882,7 +884,7 @@ WORD WINAPI SetClassWord( HWND hwnd, INT offset, WORD newval ) TRACE("%x %d %x\n", hwnd, offset, newval); - if (!(class = get_class_ptr( hwnd ))) return 0; + if (!(class = get_class_ptr( hwnd, TRUE ))) return 0; if (offset <= class->cbClsExtra - sizeof(WORD)) { @@ -911,7 +913,7 @@ LONG WINAPI SetClassLong16( HWND16 hwnd16, INT16 offset, LONG newval ) switch(offset) { case GCL_WNDPROC: - if (!(class = get_class_ptr( hwnd ))) return 0; + if (!(class = get_class_ptr( hwnd, TRUE ))) return 0; retval = (LONG)CLASS_SetProc( class, (WNDPROC)newval, WIN_PROC_16 ); release_class_ptr( class ); return retval; @@ -934,7 +936,7 @@ LONG WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval ) TRACE("%x %d %lx\n", hwnd, offset, newval); - if (!(class = get_class_ptr( hwnd ))) return 0; + if (!(class = get_class_ptr( hwnd, TRUE ))) return 0; if (offset >= 0) { @@ -979,10 +981,6 @@ LONG WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval ) retval = (LONG)class->cbWndExtra; class->cbWndExtra = newval; break; - case GCL_CBCLSEXTRA: - retval = (LONG)class->cbClsExtra; - class->cbClsExtra = newval; - break; case GCL_HMODULE: retval = (LONG)class->hInstance; class->hInstance = newval; @@ -991,6 +989,9 @@ LONG WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval ) retval = (DWORD)class->atomName; class->atomName = newval; break; + case GCL_CBCLSEXTRA: /* cannot change this one */ + SetLastError( ERROR_INVALID_PARAMETER ); + break; default: SetLastError( ERROR_INVALID_INDEX ); break; @@ -1013,7 +1014,7 @@ LONG WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval ) TRACE("%x %d %lx\n", hwnd, offset, newval); - if (!(class = get_class_ptr( hwnd ))) return 0; + if (!(class = get_class_ptr( hwnd, TRUE ))) return 0; if (offset == GCL_WNDPROC) retval = (LONG)CLASS_SetProc( class, (WNDPROC)newval, WIN_PROC_32W ); @@ -1032,12 +1033,7 @@ LONG WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval ) */ INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count ) { - INT ret; - CLASS *class; - - if (!(class = get_class_ptr( hwnd ))) return 0; - ret = GlobalGetAtomNameA( class->atomName, buffer, count ); - release_class_ptr( class ); + INT ret = GlobalGetAtomNameA( GetClassLongA( hwnd, GCW_ATOM ), buffer, count ); TRACE("%x %s %x\n",hwnd, debugstr_a(buffer), count); return ret; @@ -1049,12 +1045,7 @@ INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count ) */ INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count ) { - INT ret; - CLASS *class; - - if (!(class = get_class_ptr( hwnd ))) return 0; - ret = GlobalGetAtomNameW( class->atomName, buffer, count ); - release_class_ptr( class ); + INT ret = GlobalGetAtomNameW( GetClassLongW( hwnd, GCW_ATOM ), buffer, count ); TRACE("%x %s %x\n",hwnd, debugstr_w(buffer), count); return ret; diff --git a/windows/dce.c b/windows/dce.c index d9cf0d7cae2..c8e1688624c 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -274,65 +274,42 @@ BOOL DCE_InvalidateDCE(HWND hwnd, const RECT* pRectUpdate) for (dce = firstDCE; (dce); dce = dce->next) { - WND* wndCurrent; - HWND tmp; - INT xoffset = 0, yoffset = 0; - if (dce->DCXflags & DCX_DCEEMPTY) continue; if ((dce->hwndCurrent == hwndScope) && !(dce->DCXflags & DCX_CLIPCHILDREN)) continue; /* child window positions don't bother us */ - if (!(wndCurrent = WIN_FindWndPtr(dce->hwndCurrent))) continue; /* check if DCE window is within the z-order scope */ - for (tmp = dce->hwndCurrent; tmp; tmp = GetAncestor( tmp, GA_PARENT )) + if (hwndScope == dce->hwndCurrent || IsChild( hwndScope, dce->hwndCurrent )) { - if (tmp == hwndScope ) + if (hwnd != dce->hwndCurrent) { - RECT wndRect; + /* check if the window rectangle intersects this DCE window */ + RECT rect; + GetWindowRect( dce->hwndCurrent, &rect ); + MapWindowPoints( 0, hwndScope, (POINT *)&rect, 2 ); + if (!IntersectRect( &rect, &rect, pRectUpdate )) continue; - wndRect = wndCurrent->rectWindow; + } + if( !(dce->DCXflags & DCX_DCEBUSY) ) + { + /* Don't bother with visible regions of unused DCEs */ - OffsetRect( &wndRect, xoffset - wndCurrent->rectClient.left, - yoffset - wndCurrent->rectClient.top); - - if (hwnd == wndCurrent->hwndSelf || - IntersectRect( &wndRect, &wndRect, pRectUpdate )) - { - if( !(dce->DCXflags & DCX_DCEBUSY) ) - { - /* Don't bother with visible regions of unused DCEs */ - - TRACE("\tpurged %08x dce [%04x]\n", - (unsigned)dce, wndCurrent->hwndSelf); - - dce->hwndCurrent = 0; - dce->DCXflags &= DCX_CACHE; - dce->DCXflags |= DCX_DCEEMPTY; - } - else - { - /* Set dirty bits in the hDC and DCE structs */ - - TRACE("\tfixed up %08x dce [%04x]\n", - (unsigned)dce, wndCurrent->hwndSelf); - - dce->DCXflags |= DCX_DCEDIRTY; - SetHookFlags16(dce->hDC, DCHF_INVALIDATEVISRGN); - bRet = TRUE; - } - } - break; + TRACE("\tpurged %p dce [%04x]\n", dce, dce->hwndCurrent); + dce->hwndCurrent = 0; + dce->DCXflags &= DCX_CACHE; + dce->DCXflags |= DCX_DCEEMPTY; } else { - WND* wnd = WIN_FindWndPtr( tmp ); - xoffset += wnd->rectClient.left; - yoffset += wnd->rectClient.top; - WIN_ReleaseWndPtr( wnd ); + /* Set dirty bits in the hDC and DCE structs */ + + TRACE("\tfixed up %p dce [%04x]\n", dce, dce->hwndCurrent); + dce->DCXflags |= DCX_DCEDIRTY; + SetHookFlags16(dce->hDC, DCHF_INVALIDATEVISRGN); + bRet = TRUE; } } - WIN_ReleaseWndPtr(wndCurrent); } /* dce list */ } return bRet; diff --git a/windows/defdlg.c b/windows/defdlg.c index 3cc9b71b8b0..d63c9e33039 100644 --- a/windows/defdlg.c +++ b/windows/defdlg.c @@ -12,6 +12,9 @@ #include "controls.h" #include "win.h" #include "winproc.h" +#include "debugtools.h" + +DEFAULT_DEBUG_CHANNEL(dialog); /*********************************************************************** @@ -19,13 +22,17 @@ */ static WNDPROC DEFDLG_GetDlgProc( HWND hwnd ) { - WNDPROC ret = 0; - WND * wndPtr = WIN_FindWndPtr( hwnd ); - if (wndPtr) + WNDPROC ret; + WND *wndPtr = WIN_GetPtr( hwnd ); + + if (!wndPtr) return 0; + if (wndPtr == WND_OTHER_PROCESS) { - ret = *(WNDPROC *)((char *)wndPtr->wExtra + DWL_DLGPROC); - WIN_ReleaseWndPtr(wndPtr); + ERR( "cannot get dlg proc %x from other process\n", hwnd ); + return 0; } + ret = *(WNDPROC *)((char *)wndPtr->wExtra + DWL_DLGPROC); + WIN_ReleasePtr( wndPtr ); return ret; } diff --git a/windows/defwnd.c b/windows/defwnd.c index 8567523cb90..f7573d65d5f 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -38,10 +38,10 @@ static short iMenuSysKey = 0; static void DEFWND_HandleWindowPosChanged( HWND hwnd, UINT flags ) { RECT rect; - WND *wndPtr = WIN_FindWndPtr( hwnd ); + WND *wndPtr = WIN_GetPtr( hwnd ); rect = wndPtr->rectClient; - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); if (!(flags & SWP_NOCLIENTMOVE)) SendMessageW( hwnd, WM_MOVE, 0, MAKELONG(rect.left, rect.top)); @@ -96,14 +96,14 @@ static void DEFWND_SetTextW( HWND hwnd, LPCWSTR text ) if (!text) text = empty_string; count = strlenW(text) + 1; - if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return; + if (!(wndPtr = WIN_GetPtr( hwnd ))) return; if (wndPtr->text) HeapFree(GetProcessHeap(), 0, wndPtr->text); if ((wndPtr->text = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR)))) strcpyW( wndPtr->text, text ); else ERR("Not enough memory for window text\n"); text = wndPtr->text; - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); if (USER_Driver.pSetWindowText) USER_Driver.pSetWindowText( hwnd, text ); } @@ -357,9 +357,9 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa { LONG hitcode; POINT pt; - WND *wndPtr = WIN_FindWndPtr( hwnd ); + WND *wndPtr = WIN_GetPtr( hwnd ); HMENU hMenu = wndPtr->hSysMenu; - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); if (!hMenu) return 0; pt.x = SLOWORD(lParam); pt.y = SHIWORD(lParam); @@ -378,14 +378,14 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa case WM_NCDESTROY: { - WND *wndPtr = WIN_FindWndPtr( hwnd ); + WND *wndPtr = WIN_GetPtr( hwnd ); if (!wndPtr) return 0; if (wndPtr->text) HeapFree( GetProcessHeap(), 0, wndPtr->text ); wndPtr->text = NULL; if (wndPtr->pVScroll) HeapFree( GetProcessHeap(), 0, wndPtr->pVScroll ); if (wndPtr->pHScroll) HeapFree( GetProcessHeap(), 0, wndPtr->pHScroll ); wndPtr->pVScroll = wndPtr->pHScroll = NULL; - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); return 0; } @@ -607,9 +607,9 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa case WM_ISACTIVEICON: { - WND *wndPtr = WIN_FindWndPtr( hwnd ); + WND *wndPtr = WIN_GetPtr( hwnd ); BOOL ret = (wndPtr->flags & WIN_NCACTIVATED) != 0; - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); return ret; } @@ -626,21 +626,15 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa return USER_Driver.pSetWindowIcon( hwnd, lParam, (wParam != ICON_SMALL) ); else { - int index = (wParam != ICON_SMALL) ? GCL_HICON : GCL_HICONSM; - HICON hOldIcon = GetClassLongW(hwnd, index); - SetClassLongW(hwnd, index, lParam); - - SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED - | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE - | SWP_NOZORDER); - return hOldIcon; + HICON hOldIcon = SetClassLongW( hwnd, (wParam != ICON_SMALL) ? GCL_HICON : GCL_HICONSM, + lParam); + SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | + SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); + return hOldIcon; } case WM_GETICON: - { - int index = (wParam != ICON_SMALL) ? GCL_HICON : GCL_HICONSM; - return GetClassLongW(hwnd, index); - } + return GetClassLongW( hwnd, (wParam != ICON_SMALL) ? GCL_HICON : GCL_HICONSM ); case WM_HELP: SendMessageW( GetParent(hwnd), msg, wParam, lParam ); @@ -661,7 +655,12 @@ LRESULT WINAPI DefWindowProc16( HWND16 hwnd16, UINT16 msg, WPARAM16 wParam, LRESULT result = 0; HWND hwnd = WIN_Handle32( hwnd16 ); - if (!IsWindow( hwnd )) return 0; + if (!WIN_IsCurrentProcess( hwnd )) + { + if (!IsWindow( hwnd )) return 0; + ERR( "called for other process window %x\n", hwnd ); + return 0; + } SPY_EnterMessage( SPY_DEFWNDPROC16, hwnd, msg, wParam, lParam ); switch(msg) @@ -719,9 +718,16 @@ LRESULT WINAPI DefWindowProc16( HWND16 hwnd16, UINT16 msg, WPARAM16 wParam, LRESULT WINAPI DefWindowProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { LRESULT result = 0; + HWND full_handle; + + if (!(full_handle = WIN_IsCurrentProcess( hwnd ))) + { + if (!IsWindow( hwnd )) return 0; + ERR( "called for other process window %x\n", hwnd ); + return 0; + } + hwnd = full_handle; - if (!IsWindow( hwnd )) return 0; - hwnd = WIN_GetFullHandle( hwnd ); SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam ); switch(msg) @@ -754,17 +760,17 @@ LRESULT WINAPI DefWindowProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam case WM_GETTEXTLENGTH: { - WND *wndPtr = WIN_FindWndPtr( hwnd ); + WND *wndPtr = WIN_GetPtr( hwnd ); if (wndPtr && wndPtr->text) result = WideCharToMultiByte( CP_ACP, 0, wndPtr->text, strlenW(wndPtr->text), NULL, 0, NULL, NULL ); - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); } break; case WM_GETTEXT: { - WND *wndPtr = WIN_FindWndPtr( hwnd ); + WND *wndPtr = WIN_GetPtr( hwnd ); if (wParam && wndPtr && wndPtr->text) { LPSTR dest = (LPSTR)lParam; @@ -772,7 +778,7 @@ LRESULT WINAPI DefWindowProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam dest, wParam, NULL, NULL )) dest[wParam-1] = 0; result = strlen( dest ); } - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); } break; @@ -849,9 +855,15 @@ LRESULT WINAPI DefWindowProcW( LPARAM lParam ) /* [in] second message parameter */ { LRESULT result = 0; + HWND full_handle; - if (!IsWindow( hwnd )) return 0; - hwnd = WIN_GetFullHandle( hwnd ); + if (!(full_handle = WIN_IsCurrentProcess( hwnd ))) + { + if (!IsWindow( hwnd )) return 0; + ERR( "called for other process window %x\n", hwnd ); + return 0; + } + hwnd = full_handle; SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam ); switch(msg) @@ -884,22 +896,22 @@ LRESULT WINAPI DefWindowProcW( case WM_GETTEXTLENGTH: { - WND *wndPtr = WIN_FindWndPtr( hwnd ); + WND *wndPtr = WIN_GetPtr( hwnd ); if (wndPtr && wndPtr->text) result = (LRESULT)strlenW(wndPtr->text); - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); } break; case WM_GETTEXT: { - WND *wndPtr = WIN_FindWndPtr( hwnd ); + WND *wndPtr = WIN_GetPtr( hwnd ); if (wParam && wndPtr && wndPtr->text) { LPWSTR dest = (LPWSTR)lParam; lstrcpynW( dest, wndPtr->text, wParam ); result = strlenW( dest ); } - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); } break; diff --git a/windows/dialog.c b/windows/dialog.c index 76551eed0af..576a75ead0f 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -851,9 +851,9 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCSTR dlgTemplate, HeapFree( GetProcessHeap(), 0, dlgInfo ); return 0; } - wndPtr = WIN_FindWndPtr( hwnd ); + wndPtr = WIN_GetPtr( hwnd ); wndPtr->flags |= WIN_ISDIALOG; - WIN_ReleaseWndPtr(wndPtr); + WIN_ReleasePtr( wndPtr ); if (template.helpId) SetWindowContextHelpId( hwnd, template.helpId ); SetWindowLongW( hwnd, DWL_WINE_DIALOGINFO, (LONG)dlgInfo ); diff --git a/windows/mdi.c b/windows/mdi.c index 92a444933f8..c1ba9095729 100644 --- a/windows/mdi.c +++ b/windows/mdi.c @@ -180,9 +180,14 @@ const struct builtin_class_descr MDICLIENT_builtin_class = static MDICLIENTINFO *get_client_info( HWND client ) { MDICLIENTINFO *ret = NULL; - WND *win = WIN_FindWndPtr( client ); + WND *win = WIN_GetPtr( client ); if (win) { + if (win == WND_OTHER_PROCESS) + { + ERR( "client %x belongs to other process\n", client ); + return NULL; + } if (win->cbWndExtra < sizeof(MDICLIENTINFO)) WARN( "%x is not an MDI client\n", client ); else ret = (MDICLIENTINFO *)win->wExtra; WIN_ReleaseWndPtr( win ); @@ -1215,7 +1220,7 @@ static LRESULT MDIClientWndProc_common( HWND hwnd, UINT message, /* Since we are using only cs->lpCreateParams, we can safely * cast to LPCREATESTRUCTA here */ LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam; - WND *wndPtr = WIN_FindWndPtr( hwnd ); + WND *wndPtr = WIN_GetPtr( hwnd ); /* Translation layer doesn't know what's in the cs->lpCreateParams * so we have to keep track of what environment we're in. */ @@ -1233,7 +1238,7 @@ static LRESULT MDIClientWndProc_common( HWND hwnd, UINT message, ci->hWindowMenu = ccs->hWindowMenu; ci->idFirstChild = ccs->idFirstChild; } - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); ci->hwndChildMaximized = 0; ci->nActiveChildren = 0; @@ -1549,17 +1554,17 @@ LRESULT WINAPI DefFrameProcW( HWND hwnd, HWND hwndMDIClient, { /* control menu is between the frame system menu and * the first entry of menu bar */ - WND *wndPtr = WIN_FindWndPtr(hwnd); + WND *wndPtr = WIN_GetPtr(hwnd); if( (wParam == VK_LEFT && GetMenu(hwnd) == next_menu->hmenuIn) || (wParam == VK_RIGHT && GetSubMenu(wndPtr->hSysMenu, 0) == next_menu->hmenuIn) ) { - WIN_ReleaseWndPtr(wndPtr); - wndPtr = WIN_FindWndPtr(ci->hwndActiveChild); + WIN_ReleasePtr(wndPtr); + wndPtr = WIN_GetPtr(ci->hwndActiveChild); next_menu->hmenuNext = GetSubMenu(wndPtr->hSysMenu, 0); next_menu->hwndNext = ci->hwndActiveChild; - WIN_ReleaseWndPtr(wndPtr); } + WIN_ReleasePtr(wndPtr); } return 0; } @@ -1765,9 +1770,9 @@ LRESULT WINAPI DefMDIChildProcW( HWND hwnd, UINT message, if( wParam == VK_LEFT ) /* switch to frame system menu */ { - WND *wndPtr = WIN_FindWndPtr( parent ); + WND *wndPtr = WIN_GetPtr( parent ); next_menu->hmenuNext = GetSubMenu( wndPtr->hSysMenu, 0 ); - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); } if( wParam == VK_RIGHT ) /* to frame menu bar */ { diff --git a/windows/message.c b/windows/message.c index 8fd2f38e250..077af8619ba 100644 --- a/windows/message.c +++ b/windows/message.c @@ -1006,7 +1006,8 @@ LONG WINAPI DispatchMessageA( const MSG* msg ) WND * wndPtr; LONG retval; int painting; - + WNDPROC winproc; + /* Process timer messages */ if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER)) { @@ -1025,40 +1026,48 @@ LONG WINAPI DispatchMessageA( const MSG* msg ) } } - if (!msg->hwnd) return 0; - if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0; - if (!wndPtr->winproc) + if (!(wndPtr = WIN_GetPtr( msg->hwnd ))) { - retval = 0; - goto END; + if (msg->hwnd) SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return 0; + } + if (wndPtr == WND_OTHER_PROCESS) + { + if (IsWindow( msg->hwnd )) + ERR( "cannot dispatch msg to other process window %x\n", msg->hwnd ); + SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return 0; + } + if (!(winproc = wndPtr->winproc)) + { + WIN_ReleasePtr( wndPtr ); + return 0; } painting = (msg->message == WM_PAINT); if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT; -/* HOOK_CallHooks32A( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */ + WIN_ReleasePtr( wndPtr ); +/* hook_CallHooks32A( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */ SPY_EnterMessage( SPY_DISPATCHMESSAGE, msg->hwnd, msg->message, msg->wParam, msg->lParam ); - retval = CallWindowProcA( (WNDPROC)wndPtr->winproc, - msg->hwnd, msg->message, - msg->wParam, msg->lParam ); + retval = CallWindowProcA( winproc, msg->hwnd, msg->message, + msg->wParam, msg->lParam ); SPY_ExitMessage( SPY_RESULT_OK, msg->hwnd, msg->message, retval, - msg->wParam, msg->lParam ); + msg->wParam, msg->lParam ); - WIN_ReleaseWndPtr(wndPtr); - wndPtr = WIN_FindWndPtr(msg->hwnd); - - if (painting && wndPtr && - (wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate) + if (painting && (wndPtr = WIN_GetPtr( msg->hwnd )) && (wndPtr != WND_OTHER_PROCESS)) { - ERR("BeginPaint not called on WM_PAINT for hwnd %04x!\n", - msg->hwnd); - wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT; - /* Validate the update region to avoid infinite WM_PAINT loop */ - RedrawWindow( wndPtr->hwndSelf, NULL, 0, - RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT ); + BOOL validate = ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate); + wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT; + WIN_ReleasePtr( wndPtr ); + if (validate) + { + ERR( "BeginPaint not called on WM_PAINT for hwnd %04x!\n", msg->hwnd ); + /* Validate the update region to avoid infinite WM_PAINT loop */ + RedrawWindow( msg->hwnd, NULL, 0, + RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT ); + } } -END: - WIN_ReleaseWndPtr(wndPtr); return retval; } @@ -1089,7 +1098,8 @@ LONG WINAPI DispatchMessageW( const MSG* msg ) WND * wndPtr; LONG retval; int painting; - + WNDPROC winproc; + /* Process timer messages */ if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER)) { @@ -1108,40 +1118,48 @@ LONG WINAPI DispatchMessageW( const MSG* msg ) } } - if (!msg->hwnd) return 0; - if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0; - if (!wndPtr->winproc) + if (!(wndPtr = WIN_GetPtr( msg->hwnd ))) { - retval = 0; - goto END; + if (msg->hwnd) SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return 0; + } + if (wndPtr == WND_OTHER_PROCESS) + { + if (IsWindow( msg->hwnd )) + ERR( "cannot dispatch msg to other process window %x\n", msg->hwnd ); + SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return 0; + } + if (!(winproc = wndPtr->winproc)) + { + WIN_ReleasePtr( wndPtr ); + return 0; } painting = (msg->message == WM_PAINT); if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT; + WIN_ReleasePtr( wndPtr ); /* HOOK_CallHooks32W( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */ SPY_EnterMessage( SPY_DISPATCHMESSAGE, msg->hwnd, msg->message, msg->wParam, msg->lParam ); - retval = CallWindowProcW( (WNDPROC)wndPtr->winproc, - msg->hwnd, msg->message, - msg->wParam, msg->lParam ); + retval = CallWindowProcW( winproc, msg->hwnd, msg->message, + msg->wParam, msg->lParam ); SPY_ExitMessage( SPY_RESULT_OK, msg->hwnd, msg->message, retval, - msg->wParam, msg->lParam ); + msg->wParam, msg->lParam ); - WIN_ReleaseWndPtr(wndPtr); - wndPtr = WIN_FindWndPtr(msg->hwnd); - - if (painting && wndPtr && - (wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate) + if (painting && (wndPtr = WIN_GetPtr( msg->hwnd )) && (wndPtr != WND_OTHER_PROCESS)) { - ERR("BeginPaint not called on WM_PAINT for hwnd %04x!\n", - msg->hwnd); - wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT; - /* Validate the update region to avoid infinite WM_PAINT loop */ - RedrawWindow( wndPtr->hwndSelf, NULL, 0, - RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT ); + BOOL validate = ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate); + wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT; + WIN_ReleasePtr( wndPtr ); + if (validate) + { + ERR( "BeginPaint not called on WM_PAINT for hwnd %04x!\n", msg->hwnd ); + /* Validate the update region to avoid infinite WM_PAINT loop */ + RedrawWindow( msg->hwnd, NULL, 0, + RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT ); + } } -END: - WIN_ReleaseWndPtr(wndPtr); return retval; } diff --git a/windows/nonclient.c b/windows/nonclient.c index 1ed679f378e..111568db88a 100644 --- a/windows/nonclient.c +++ b/windows/nonclient.c @@ -1401,7 +1401,7 @@ static void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint ) HWND hwnd = wndPtr->hwndSelf; if ( wndPtr->dwStyle & WS_MINIMIZE || - !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */ + !WIN_IsWindowDrawable( hwnd, 0 )) return; /* Nothing to do */ active = wndPtr->flags & WIN_NCACTIVATED; @@ -1513,7 +1513,7 @@ static void NC_DoNCPaint95( HWND hwnd = wndPtr->hwndSelf; if ( wndPtr->dwStyle & WS_MINIMIZE || - !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */ + !WIN_IsWindowDrawable( hwnd, 0 )) return; /* Nothing to do */ active = wndPtr->flags & WIN_NCACTIVATED; diff --git a/windows/painting.c b/windows/painting.c index 3b8148584ae..6c854fec00c 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -787,16 +787,12 @@ BOOL WINAPI RedrawWindow( HWND hwnd, const RECT *rectUpdate, WND* wndPtr; if (!hwnd) hwnd = GetDesktopWindow(); - if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE; /* check if the window or its parents are visible/not minimized */ - if (!WIN_IsWindowDrawable( wndPtr, !(flags & RDW_FRAME) ) ) - { - WIN_ReleaseWndPtr(wndPtr); - return TRUE; - } + if (!WIN_IsWindowDrawable( hwnd, !(flags & RDW_FRAME) )) return TRUE; + if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE; if (TRACE_ON(win)) { if( hrgnUpdate ) diff --git a/windows/spy.c b/windows/spy.c index c3a0ede9192..3270b2132d2 100644 --- a/windows/spy.c +++ b/windows/spy.c @@ -1710,19 +1710,17 @@ static void SPY_GetMsgStuff( SPY_INSTANCE *sp_e ) */ void SPY_GetWndName( SPY_INSTANCE *sp_e ) { - WND* pWnd = WIN_FindWndPtr( sp_e->msg_hwnd ); - if( pWnd ) + WND* pWnd = WIN_GetPtr( sp_e->msg_hwnd ); + if (pWnd && pWnd != WND_OTHER_PROCESS) { - LPSTR p = (LPSTR)&sp_e->wnd_name; - LPSTR s = (LPSTR)&sp_e->wnd_name; + LPSTR p = sp_e->wnd_name; + LPSTR s = sp_e->wnd_name; char postfix; DWORD save_error; /* save and restore error code over the next call */ save_error = GetLastError(); - GlobalGetAtomNameA((ATOM) GetClassWord(pWnd->hwndSelf, GCW_ATOM), - (LPSTR)&sp_e->wnd_class, - sizeof(sp_e->wnd_class)-1); + GetClassNameA( sp_e->msg_hwnd, sp_e->wnd_class, sizeof(sp_e->wnd_class)-1); SetLastError(save_error); if( pWnd->text && pWnd->text[0] != '\0' ) @@ -1734,7 +1732,7 @@ void SPY_GetWndName( SPY_INSTANCE *sp_e ) } else /* get class name */ { - LPSTR src = (LPSTR)&sp_e->wnd_class; + LPSTR src = sp_e->wnd_class; int n=sizeof(sp_e->wnd_name)-2; *(p++) = '{'; while ((n-- > 0) && *src) *p++ = *src++; @@ -1749,10 +1747,14 @@ void SPY_GetWndName( SPY_INSTANCE *sp_e ) } *(p++) = postfix; *(p++) = '\0'; - WIN_ReleaseWndPtr(pWnd); + WIN_ReleasePtr(pWnd); } - else {strcpy( sp_e->wnd_name, "\"NULL\"" ); sp_e->wnd_class[0] = 0;} + else + { + strcpy( sp_e->wnd_name, "\"NULL\"" ); + sp_e->wnd_class[0] = 0; + } return; } diff --git a/windows/timer.c b/windows/timer.c index 0f760db7ae2..2168d61e4b0 100644 --- a/windows/timer.c +++ b/windows/timer.c @@ -104,7 +104,7 @@ static UINT TIMER_SetTimer( HWND hwnd, UINT id, UINT timeout, TIMER * pTimer; HWINDOWPROC winproc = 0; - if (hwnd && !WIN_IsCurrentThread( hwnd )) + if (hwnd && !(hwnd = WIN_IsCurrentThread( hwnd ))) { SetLastError( ERROR_INVALID_WINDOW_HANDLE ); return 0; @@ -243,8 +243,7 @@ UINT WINAPI SetTimer( HWND hwnd, UINT id, UINT timeout, { TRACE("%04x %d %d %08lx\n", hwnd, id, timeout, (LONG)proc ); - return TIMER_SetTimer( WIN_GetFullHandle(hwnd), id, timeout, (WNDPROC16)proc, - WIN_PROC_32A, FALSE ); + return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC16)proc, WIN_PROC_32A, FALSE ); } @@ -294,8 +293,7 @@ UINT WINAPI SetSystemTimer( HWND hwnd, UINT id, UINT timeout, { TRACE("%04x %d %d %08lx\n", hwnd, id, timeout, (LONG)proc ); - return TIMER_SetTimer( WIN_GetFullHandle(hwnd), id, timeout, (WNDPROC16)proc, - WIN_PROC_32A, TRUE ); + return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC16)proc, WIN_PROC_32A, TRUE ); } diff --git a/windows/win.c b/windows/win.c index c35e7c0d4b1..106a60c4e5d 100644 --- a/windows/win.c +++ b/windows/win.c @@ -176,26 +176,27 @@ static HWND *list_window_children( HWND hwnd, ATOM atom, DWORD tid ) /*********************************************************************** - * WIN_GetWndPtr + * WIN_GetPtr * * Return a pointer to the WND structure if local to the process, - * or BAD_WND_PTR is handle is local but not valid. - * If ret value is a valid pointer, the user lock is held. + * or WND_OTHER_PROCESS is handle may be valid in other process. + * If ret value is a valid pointer, it must be released with WIN_ReleasePtr. */ -WND *WIN_GetWndPtr( HWND hwnd ) +WND *WIN_GetPtr( HWND hwnd ) { WND * ptr; WORD index = LOWORD(hwnd) - FIRST_USER_HANDLE; - if (index >= NB_USER_HANDLES) return BAD_WND_PTR; + if (index >= NB_USER_HANDLES) return NULL; USER_Lock(); if ((ptr = user_handles[index])) { if (ptr->dwMagic == WND_MAGIC && (!HIWORD(hwnd) || hwnd == ptr->hwndSelf)) return ptr; - ptr = BAD_WND_PTR; + ptr = NULL; } + else ptr = WND_OTHER_PROCESS; USER_Unlock(); return ptr; } @@ -204,32 +205,34 @@ WND *WIN_GetWndPtr( HWND hwnd ) /*********************************************************************** * WIN_IsCurrentProcess * - * Check whether a given window belongs to the current process. + * Check whether a given window belongs to the current process (and return the full handle). */ -BOOL WIN_IsCurrentProcess( HWND hwnd ) +HWND WIN_IsCurrentProcess( HWND hwnd ) { WND *ptr; + HWND ret; - if (!(ptr = WIN_GetWndPtr( hwnd )) || ptr == BAD_WND_PTR) return FALSE; - USER_Unlock(); - return TRUE; + if (!(ptr = WIN_GetPtr( hwnd )) || ptr == WND_OTHER_PROCESS) return 0; + ret = ptr->hwndSelf; + WIN_ReleasePtr( ptr ); + return ret; } /*********************************************************************** * WIN_IsCurrentThread * - * Check whether a given window belongs to the current thread. + * Check whether a given window belongs to the current thread (and return the full handle). */ -BOOL WIN_IsCurrentThread( HWND hwnd ) +HWND WIN_IsCurrentThread( HWND hwnd ) { WND *ptr; - BOOL ret = FALSE; + HWND ret = 0; - if ((ptr = WIN_GetWndPtr( hwnd )) && ptr != BAD_WND_PTR) + if ((ptr = WIN_GetPtr( hwnd )) && ptr != WND_OTHER_PROCESS) { - ret = (ptr->tid == GetCurrentThreadId()); - USER_Unlock(); + if (ptr->tid == GetCurrentThreadId()) ret = ptr->hwndSelf; + WIN_ReleasePtr( ptr ); } return ret; } @@ -249,13 +252,12 @@ HWND WIN_Handle32( HWND16 hwnd16 ) /* do sign extension for -2 and -3 */ if (hwnd16 >= (HWND16)-3) return (HWND)(LONG_PTR)(INT16)hwnd16; - if ((ptr = WIN_GetWndPtr( hwnd ))) + if (!(ptr = WIN_GetPtr( hwnd ))) return hwnd; + + if (ptr != WND_OTHER_PROCESS) { - if (ptr != BAD_WND_PTR) - { - hwnd = ptr->hwndSelf; - USER_Unlock(); - } + hwnd = ptr->hwndSelf; + WIN_ReleasePtr( ptr ); } else /* may belong to another process */ { @@ -281,45 +283,25 @@ WND * WIN_FindWndPtr( HWND hwnd ) if (!hwnd) return NULL; - if ((ptr = WIN_GetWndPtr( hwnd ))) + if ((ptr = WIN_GetPtr( hwnd ))) { - if (ptr != BAD_WND_PTR) + if (ptr != WND_OTHER_PROCESS) { /* increment destruction monitoring */ ptr->irefCount++; return ptr; } - } - else if (IsWindow( hwnd )) /* check other processes */ - { - ERR( "window %04x belongs to other process\n", hwnd ); - /* DbgBreakPoint(); */ + if (IsWindow( hwnd )) /* check other processes */ + { + ERR( "window %04x belongs to other process\n", hwnd ); + /* DbgBreakPoint(); */ + } } SetLastError( ERROR_INVALID_WINDOW_HANDLE ); return NULL; } -/*********************************************************************** - * WIN_LockWndPtr - * - * Use in case the wnd ptr is not initialized with WIN_FindWndPtr - * but by initWndPtr; - * Returns the locked initialisation pointer - */ -WND *WIN_LockWndPtr(WND *initWndPtr) -{ - if(!initWndPtr) return 0; - - /* Lock all WND structures for thread safeness*/ - USER_Lock(); - /*and increment destruction monitoring*/ - initWndPtr->irefCount++; - - return initWndPtr; - -} - /*********************************************************************** * WIN_ReleaseWndPtr * @@ -346,21 +328,6 @@ void WIN_ReleaseWndPtr(WND *wndPtr) USER_Unlock(); } -/*********************************************************************** - * WIN_UpdateWndPtr - * - * Updates the value of oldPtr to newPtr. - */ -void WIN_UpdateWndPtr(WND **oldPtr, WND *newPtr) -{ - WND *tmpWnd = NULL; - - tmpWnd = WIN_LockWndPtr(newPtr); - WIN_ReleaseWndPtr(*oldPtr); - *oldPtr = tmpWnd; - -} - /*********************************************************************** * WIN_UnlinkWindow @@ -421,9 +388,9 @@ static HWND find_child_to_repaint( HWND parent ) for (i = 0; list[i] && !ret; i++) { - WND *win = WIN_GetWndPtr( list[i] ); - if (win == BAD_WND_PTR) continue; /* ignore it */ - if (!win) + WND *win = WIN_GetPtr( list[i] ); + if (!win) continue; /* ignore it */ + if (win == WND_OTHER_PROCESS) { /* doesn't belong to this process, but check children */ ret = find_child_to_repaint( list[i] ); @@ -431,14 +398,14 @@ static HWND find_child_to_repaint( HWND parent ) } if (!(win->dwStyle & WS_VISIBLE)) { - USER_Unlock(); + WIN_ReleasePtr( win ); continue; } if ((win->tid != GetCurrentThreadId()) || (!win->hrgnUpdate && !(win->flags & WIN_INTERNAL_PAINT))) { /* does not need repaint, check children */ - USER_Unlock(); + WIN_ReleasePtr( win ); ret = find_child_to_repaint( list[i] ); continue; } @@ -448,29 +415,29 @@ static HWND find_child_to_repaint( HWND parent ) if (!(win->dwExStyle & WS_EX_TRANSPARENT)) { /* not transparent, we can repaint it */ - USER_Unlock(); + WIN_ReleasePtr( win ); break; } - USER_Unlock(); + WIN_ReleasePtr( win ); /* transparent window, look for non-transparent sibling to paint first */ for (i++; list[i]; i++) { - if (!(win = WIN_GetWndPtr( list[i] ))) continue; - if (win == BAD_WND_PTR) continue; + if (!(win = WIN_GetPtr( list[i] ))) continue; + if (win == WND_OTHER_PROCESS) continue; if (!(win->dwStyle & WS_VISIBLE)) { - USER_Unlock(); + WIN_ReleasePtr( win ); continue; } if (!(win->dwExStyle & WS_EX_TRANSPARENT) && (win->hrgnUpdate || (win->flags & WIN_INTERNAL_PAINT))) { ret = list[i]; - USER_Unlock(); + WIN_ReleasePtr( win ); break; } - USER_Unlock(); + WIN_ReleasePtr( win ); } } HeapFree( GetProcessHeap(), 0, list ); @@ -587,7 +554,6 @@ void WIN_DestroyThreadWindows( HWND hwnd ) if (!(list = WIN_ListChildren( hwnd ))) return; for (i = 0; list[i]; i++) { - if (!IsWindow( list[i] )) continue; if (WIN_IsCurrentThread( list[i] )) DestroyWindow( list[i] ); else @@ -779,16 +745,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, WARN("Bad parent %04x\n", cs->hwndParent ); return 0; } - if (cs->style & WS_CHILD) - { - parent = WIN_GetFullHandle(cs->hwndParent); - if (!WIN_IsCurrentProcess(parent)) - { - FIXME( "creating child window of %x in other process not supported yet\n", - parent ); - return 0; - } - } + if (cs->style & WS_CHILD) parent = WIN_GetFullHandle(cs->hwndParent); else owner = GetAncestor( cs->hwndParent, GA_ROOT ); } else if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) @@ -2033,10 +1990,11 @@ BOOL WINAPI IsWindow( HWND hwnd ) WND *ptr; BOOL ret; - if ((ptr = WIN_GetWndPtr( hwnd ))) + if (!(ptr = WIN_GetPtr( hwnd ))) return FALSE; + + if (ptr != WND_OTHER_PROCESS) { - if (ptr == BAD_WND_PTR) return FALSE; - USER_Unlock(); + WIN_ReleasePtr( ptr ); return TRUE; } @@ -2059,16 +2017,18 @@ DWORD WINAPI GetWindowThreadProcessId( HWND hwnd, LPDWORD process ) WND *ptr; DWORD tid = 0; - if ((ptr = WIN_GetWndPtr( hwnd ))) + if (!(ptr = WIN_GetPtr( hwnd ))) { - if (ptr != BAD_WND_PTR) - { - /* got a valid window */ - tid = ptr->tid; - if (process) *process = GetCurrentProcessId(); - USER_Unlock(); - } - else SetLastError( ERROR_INVALID_WINDOW_HANDLE); + SetLastError( ERROR_INVALID_WINDOW_HANDLE); + return 0; + } + + if (ptr != WND_OTHER_PROCESS) + { + /* got a valid window */ + tid = ptr->tid; + if (process) *process = GetCurrentProcessId(); + WIN_ReleasePtr( ptr ); return tid; } @@ -2256,17 +2216,17 @@ BOOL WINAPI IsWindowVisible( HWND hwnd ) * minimized, and it is itself not minimized unless we are * trying to draw its default class icon. */ -BOOL WIN_IsWindowDrawable( WND* wnd, BOOL icon ) +BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL icon ) { HWND *list; BOOL retval; int i; + LONG style = GetWindowLongW( hwnd, GWL_STYLE ); - if (!(wnd->dwStyle & WS_VISIBLE)) return FALSE; - if ((wnd->dwStyle & WS_MINIMIZE) && - icon && GetClassLongA( wnd->hwndSelf, GCL_HICON )) return FALSE; + if (!(style & WS_VISIBLE)) return FALSE; + if ((style & WS_MINIMIZE) && icon && GetClassLongA( hwnd, GCL_HICON )) return FALSE; - if (!(list = WIN_ListParents( wnd->hwndSelf ))) return TRUE; + if (!(list = WIN_ListParents( hwnd ))) return TRUE; for (i = 0; list[i]; i++) if ((GetWindowLongW( list[i], GWL_STYLE ) & (WS_VISIBLE|WS_MINIMIZE)) != WS_VISIBLE) break;