From a95c58b871e27ab2a4051b266f00ebbf41fa7e4d Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 9 May 2006 13:49:37 +0200 Subject: [PATCH] user: Separate Get/SetWindowLong16 implementation from the 32-bit one. --- dlls/user/win.c | 86 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/dlls/user/win.c b/dlls/user/win.c index 10a1a4fec2b..9fef05b2be7 100644 --- a/dlls/user/win.c +++ b/dlls/user/win.c @@ -1888,24 +1888,6 @@ static LONG_PTR WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type ) { if (offset > (int)(wndPtr->cbWndExtra - sizeof(LONG))) { - /* - * Some programs try to access last element from 16 bit - * code using illegal offset value. Hopefully this is - * what those programs really expect. - */ - if (type == WIN_PROC_16 && - wndPtr->cbWndExtra >= 4 && - offset == wndPtr->cbWndExtra - sizeof(WORD)) - { - INT offset2 = wndPtr->cbWndExtra - sizeof(LONG); - - ERR( "- replaced invalid offset %d with %d\n", - offset, offset2 ); - - retvalue = *(LONG_PTR *)(((char *)wndPtr->wExtra) + offset2); - WIN_ReleasePtr( wndPtr ); - return retvalue; - } WARN("Invalid offset %d\n", offset ); WIN_ReleasePtr( wndPtr ); SetLastError( ERROR_INVALID_INDEX ); @@ -2144,7 +2126,47 @@ static LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, LONG_PTR newval, */ LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset ) { - return WIN_GetWindowLong( WIN_Handle32(hwnd), offset, WIN_PROC_16 ); + WND *wndPtr; + LONG_PTR retvalue; + BOOL is_winproc = (offset == GWLP_WNDPROC); + + if (offset >= 0) + { + if (!(wndPtr = WIN_GetPtr( WIN_Handle32(hwnd) ))) + { + SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return 0; + } + if (wndPtr != WND_OTHER_PROCESS && wndPtr != WND_DESKTOP) + { + if (offset > (int)(wndPtr->cbWndExtra - sizeof(LONG))) + { + /* + * Some programs try to access last element from 16 bit + * code using illegal offset value. Hopefully this is + * what those programs really expect. + */ + if (wndPtr->cbWndExtra >= 4 && offset == wndPtr->cbWndExtra - sizeof(WORD)) + { + INT offset2 = wndPtr->cbWndExtra - sizeof(LONG); + ERR( "- replaced invalid offset %d with %d\n", offset, offset2 ); + offset = offset2; + } + else + { + WARN("Invalid offset %d\n", offset ); + WIN_ReleasePtr( wndPtr ); + SetLastError( ERROR_INVALID_INDEX ); + return 0; + } + } + is_winproc = ((offset == DWLP_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG)); + WIN_ReleasePtr( wndPtr ); + } + } + retvalue = GetWindowLongA( WIN_Handle32(hwnd), offset ); + if (is_winproc) retvalue = (LONG_PTR)WINPROC_GetProc( (WNDPROC)retvalue, WIN_PROC_16 ); + return retvalue; } @@ -2171,7 +2193,31 @@ LONG WINAPI GetWindowLongW( HWND hwnd, INT offset ) */ LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval ) { - return WIN_SetWindowLong( WIN_Handle32(hwnd), offset, newval, WIN_PROC_16 ); + WND *wndPtr; + BOOL is_winproc = (offset == GWLP_WNDPROC); + + if (offset == DWLP_DLGPROC) + { + if (!(wndPtr = WIN_GetPtr( WIN_Handle32(hwnd) ))) + { + SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return 0; + } + if (wndPtr != WND_OTHER_PROCESS && wndPtr != WND_DESKTOP) + { + is_winproc = ((wndPtr->cbWndExtra - sizeof(LONG_PTR) >= DWLP_DLGPROC) && + (wndPtr->flags & WIN_ISDIALOG)); + WIN_ReleasePtr( wndPtr ); + } + } + + if (is_winproc) + { + WNDPROC new_proc = WINPROC_AllocProc( (WNDPROC)newval, WIN_PROC_16 ); + WNDPROC old_proc = (WNDPROC)SetWindowLongA( WIN_Handle32(hwnd), offset, (LONG_PTR)new_proc ); + return (LONG)WINPROC_GetProc( (WNDPROC)old_proc, WIN_PROC_16 ); + } + else return SetWindowLongA( WIN_Handle32(hwnd), offset, newval ); }