user32: Avoid accessing the window structure directly in Get/SetWindowLong16.

This commit is contained in:
Alexandre Julliard 2009-12-22 15:25:15 +01:00
parent 4e343b6f3a
commit 388814dfa9
1 changed files with 24 additions and 45 deletions

View File

@ -821,44 +821,36 @@ WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
/********************************************************************** /**********************************************************************
* GetWindowLong (USER.135) * GetWindowLong (USER.135)
*/ */
LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset ) LONG WINAPI GetWindowLong16( HWND16 hwnd16, INT16 offset )
{ {
WND *wndPtr; HWND hwnd = WIN_Handle32( hwnd16 );
LONG_PTR retvalue; LONG_PTR retvalue;
BOOL is_winproc = (offset == GWLP_WNDPROC); BOOL is_winproc = (offset == GWLP_WNDPROC);
if (offset >= 0) if (offset >= 0)
{ {
if (!(wndPtr = WIN_GetPtr( WIN_Handle32(hwnd) ))) int cbWndExtra = GetClassLongA( hwnd, GCL_CBWNDEXTRA );
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE ); if (offset > (int)(cbWndExtra - sizeof(LONG)))
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 * Some programs try to access last element from 16 bit
* code using illegal offset value. Hopefully this is * code using illegal offset value. Hopefully this is
* what those programs really expect. * what those programs really expect.
*/ */
if (wndPtr->cbWndExtra >= 4 && offset == wndPtr->cbWndExtra - sizeof(WORD)) if (cbWndExtra >= 4 && offset == cbWndExtra - sizeof(WORD))
{ {
offset = wndPtr->cbWndExtra - sizeof(LONG); offset = cbWndExtra - sizeof(LONG);
} }
else else
{ {
WIN_ReleasePtr( wndPtr );
SetLastError( ERROR_INVALID_INDEX ); SetLastError( ERROR_INVALID_INDEX );
return 0; return 0;
} }
} }
is_winproc = ((offset == DWLP_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG)); else if (offset == DWLP_DLGPROC) is_winproc = (DIALOG_get_info( hwnd, FALSE ) != NULL);
WIN_ReleasePtr( wndPtr );
} }
} retvalue = GetWindowLongA( hwnd, offset );
retvalue = GetWindowLongA( WIN_Handle32(hwnd), offset );
if (is_winproc) retvalue = (LONG_PTR)WINPROC_GetProc16( (WNDPROC)retvalue, FALSE ); if (is_winproc) retvalue = (LONG_PTR)WINPROC_GetProc16( (WNDPROC)retvalue, FALSE );
return retvalue; return retvalue;
} }
@ -867,33 +859,20 @@ LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
/********************************************************************** /**********************************************************************
* SetWindowLong (USER.136) * SetWindowLong (USER.136)
*/ */
LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval ) LONG WINAPI SetWindowLong16( HWND16 hwnd16, INT16 offset, LONG newval )
{ {
WND *wndPtr; HWND hwnd = WIN_Handle32( hwnd16 );
BOOL is_winproc = (offset == GWLP_WNDPROC); BOOL is_winproc = (offset == GWLP_WNDPROC);
if (offset == DWLP_DLGPROC) if (offset == DWLP_DLGPROC) is_winproc = (DIALOG_get_info( hwnd, FALSE ) != NULL);
{
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) if (is_winproc)
{ {
WNDPROC new_proc = WINPROC_AllocProc16( (WNDPROC16)newval ); WNDPROC new_proc = WINPROC_AllocProc16( (WNDPROC16)newval );
WNDPROC old_proc = (WNDPROC)SetWindowLongPtrA( WIN_Handle32(hwnd), offset, (LONG_PTR)new_proc ); WNDPROC old_proc = (WNDPROC)SetWindowLongPtrA( hwnd, offset, (LONG_PTR)new_proc );
return (LONG)WINPROC_GetProc16( old_proc, FALSE ); return (LONG)WINPROC_GetProc16( old_proc, FALSE );
} }
else return SetWindowLongA( WIN_Handle32(hwnd), offset, newval ); else return SetWindowLongA( hwnd, offset, newval );
} }