diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 575c2a71b04..40ce9336ec2 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -2605,6 +2605,7 @@ struct set_window_info_request void* instance; void* user_data; int extra_offset; + size_t extra_size; unsigned int extra_value; }; struct set_window_info_reply @@ -2622,8 +2623,7 @@ struct set_window_info_reply #define SET_WIN_ID 0x04 #define SET_WIN_INSTANCE 0x08 #define SET_WIN_USERDATA 0x10 -#define SET_WIN_EXTRAWORD 0x20 -#define SET_WIN_EXTRALONG 0x40 +#define SET_WIN_EXTRA 0x20 @@ -3673,6 +3673,6 @@ union generic_reply struct set_global_windows_reply set_global_windows_reply; }; -#define SERVER_PROTOCOL_VERSION 127 +#define SERVER_PROTOCOL_VERSION 128 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index 69004f7369b..c9d4df9371b 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1834,6 +1834,7 @@ enum message_type void* instance; /* creator instance */ void* user_data; /* user-specific data */ int extra_offset; /* offset to set in extra bytes */ + size_t extra_size; /* size to set in extra bytes */ unsigned int extra_value; /* value to set in extra bytes */ @REPLY unsigned int old_style; /* old window style */ @@ -1848,8 +1849,7 @@ enum message_type #define SET_WIN_ID 0x04 #define SET_WIN_INSTANCE 0x08 #define SET_WIN_USERDATA 0x10 -#define SET_WIN_EXTRAWORD 0x20 -#define SET_WIN_EXTRALONG 0x40 +#define SET_WIN_EXTRA 0x20 /* Get a list of the window parents, up to the root of the tree */ diff --git a/server/trace.c b/server/trace.c index a73d34c3d12..9cd065047de 100644 --- a/server/trace.c +++ b/server/trace.c @@ -2157,6 +2157,7 @@ static void dump_set_window_info_request( const struct set_window_info_request * fprintf( stderr, " instance=%p,", req->instance ); fprintf( stderr, " user_data=%p,", req->user_data ); fprintf( stderr, " extra_offset=%d,", req->extra_offset ); + fprintf( stderr, " extra_size=%d,", req->extra_size ); fprintf( stderr, " extra_value=%08x", req->extra_value ); } diff --git a/server/window.c b/server/window.c index ff16793e209..63730686e69 100644 --- a/server/window.c +++ b/server/window.c @@ -586,20 +586,20 @@ DECL_HANDLER(set_window_info) set_error( STATUS_ACCESS_DENIED ); return; } - if (req->extra_offset < -1 || req->extra_offset >= win->nb_extra_bytes) + if (req->extra_size > sizeof(req->extra_value) || + req->extra_offset < -1 || + req->extra_offset > win->nb_extra_bytes - (int)req->extra_size) { - set_error( STATUS_INVALID_PARAMETER ); + set_win32_error( ERROR_INVALID_INDEX ); return; } if (req->extra_offset != -1) { - memcpy( &reply->old_extra_value, win->extra_bytes + req->extra_offset, - min( sizeof(reply->old_extra_value), - (size_t)(win->nb_extra_bytes - req->extra_offset) )); + memcpy( &reply->old_extra_value, win->extra_bytes + req->extra_offset, req->extra_size ); } - else if (req->flags & (SET_WIN_EXTRAWORD|SET_WIN_EXTRALONG)) + else if (req->flags & SET_WIN_EXTRA) { - set_error( STATUS_INVALID_PARAMETER ); + set_win32_error( ERROR_INVALID_INDEX ); return; } reply->old_style = win->style; @@ -612,12 +612,8 @@ DECL_HANDLER(set_window_info) if (req->flags & SET_WIN_ID) win->id = req->id; if (req->flags & SET_WIN_INSTANCE) win->instance = req->instance; if (req->flags & SET_WIN_USERDATA) win->user_data = req->user_data; - if (req->flags & (SET_WIN_EXTRAWORD|SET_WIN_EXTRALONG)) - { - const int len = (req->flags & SET_WIN_EXTRALONG) ? sizeof(int) : sizeof(short); - memcpy( win->extra_bytes + req->extra_offset, &req->extra_value, - min( len, win->nb_extra_bytes - req->extra_offset )); - } + if (req->flags & SET_WIN_EXTRA) memcpy( win->extra_bytes + req->extra_offset, + &req->extra_value, req->extra_size ); } diff --git a/windows/win.c b/windows/win.c index 0e9ce70f843..0c41bda35f4 100644 --- a/windows/win.c +++ b/windows/win.c @@ -1752,17 +1752,24 @@ WORD WINAPI GetWindowWord( HWND hwnd, INT offset ) } if (wndPtr == WND_OTHER_PROCESS) { - if (IsWindow( hwnd )) - FIXME( "(%d) not supported yet on other process window %p\n", offset, hwnd ); - SetLastError( ERROR_INVALID_WINDOW_HANDLE ); - return 0; + SERVER_START_REQ( set_window_info ) + { + req->handle = hwnd; + req->flags = 0; /* don't set anything, just retrieve */ + req->extra_offset = offset; + req->extra_size = sizeof(retvalue); + if (!wine_server_call_err( req )) + memcpy( &retvalue, &reply->old_extra_value, sizeof(retvalue) ); + } + SERVER_END_REQ; + return retvalue; } if (offset > (int)(wndPtr->cbWndExtra - sizeof(WORD))) { WARN("Invalid offset %d\n", offset ); SetLastError( ERROR_INVALID_INDEX ); } - else retvalue = *(WORD *)(((char *)wndPtr->wExtra) + offset); + else memcpy( &retvalue, (char *)wndPtr->wExtra + offset, sizeof(retvalue) ); WIN_ReleasePtr( wndPtr ); return retvalue; } @@ -1834,14 +1841,15 @@ WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval ) SERVER_START_REQ( set_window_info ) { req->handle = hwnd; - req->flags = SET_WIN_EXTRAWORD; + req->flags = SET_WIN_EXTRA; req->extra_offset = offset; - req->extra_value = newval; + req->extra_size = sizeof(newval); + memcpy( &req->extra_value, &newval, sizeof(newval) ); if (!wine_server_call_err( req )) { - WORD *ptr = (WORD *)(((char *)wndPtr->wExtra) + offset); - retval = *ptr; - *ptr = newval; + void *ptr = (char *)wndPtr->wExtra + offset; + memcpy( &retval, ptr, sizeof(retval) ); + memcpy( ptr, &newval, sizeof(newval) ); } } SERVER_END_REQ; @@ -1885,6 +1893,7 @@ static LONG WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type ) req->handle = hwnd; req->flags = 0; /* don't set anything, just retrieve */ req->extra_offset = (offset >= 0) ? offset : -1; + req->extra_size = (offset >= 0) ? sizeof(retvalue) : 0; if (!wine_server_call_err( req )) { switch(offset) @@ -1900,8 +1909,6 @@ static LONG WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type ) break; } } - else if (offset >= 0 && GetLastError() == ERROR_INVALID_PARAMETER) - SetLastError( ERROR_INVALID_INDEX ); } SERVER_END_REQ; return retvalue; @@ -2094,9 +2101,10 @@ static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval, req->user_data = (void *)newval; break; default: - req->flags = SET_WIN_EXTRALONG; + req->flags = SET_WIN_EXTRA; req->extra_offset = offset; - req->extra_value = newval; + req->extra_size = sizeof(newval); + memcpy( &req->extra_value, &newval, sizeof(newval) ); } if ((ok = !wine_server_call_err( req ))) { @@ -2124,9 +2132,9 @@ static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval, break; default: { - LONG *ptr = (LONG *)((char *)wndPtr->wExtra + offset); - retval = *ptr; - *ptr = newval; + void *ptr = (char *)wndPtr->wExtra + offset; + memcpy( &retval, ptr, sizeof(retval) ); + memcpy( ptr, &newval, sizeof(newval) ); } break; }