Added support for inter-process GetWindowLong on the window extra
bytes.
This commit is contained in:
parent
d78dfc8e44
commit
97903d260b
|
@ -2525,6 +2525,7 @@ struct create_window_request
|
|||
user_handle_t parent;
|
||||
user_handle_t owner;
|
||||
atom_t atom;
|
||||
int extra;
|
||||
};
|
||||
struct create_window_reply
|
||||
{
|
||||
|
@ -2603,6 +2604,8 @@ struct set_window_info_request
|
|||
unsigned int id;
|
||||
void* instance;
|
||||
void* user_data;
|
||||
int extra_offset;
|
||||
unsigned int extra_value;
|
||||
};
|
||||
struct set_window_info_reply
|
||||
{
|
||||
|
@ -2612,12 +2615,15 @@ struct set_window_info_reply
|
|||
unsigned int old_id;
|
||||
void* old_instance;
|
||||
void* old_user_data;
|
||||
unsigned int old_extra_value;
|
||||
};
|
||||
#define SET_WIN_STYLE 0x01
|
||||
#define SET_WIN_EXSTYLE 0x02
|
||||
#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
|
||||
|
||||
|
||||
|
||||
|
@ -3667,6 +3673,6 @@ union generic_reply
|
|||
struct set_global_windows_reply set_global_windows_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 126
|
||||
#define SERVER_PROTOCOL_VERSION 127
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -1780,6 +1780,7 @@ enum message_type
|
|||
user_handle_t parent; /* parent window */
|
||||
user_handle_t owner; /* owner window */
|
||||
atom_t atom; /* class atom */
|
||||
int extra; /* number of extra bytes */
|
||||
@REPLY
|
||||
user_handle_t handle; /* created window */
|
||||
@END
|
||||
|
@ -1832,18 +1833,23 @@ enum message_type
|
|||
unsigned int id; /* window id */
|
||||
void* instance; /* creator instance */
|
||||
void* user_data; /* user-specific data */
|
||||
int extra_offset; /* offset to set in extra bytes */
|
||||
unsigned int extra_value; /* value to set in extra bytes */
|
||||
@REPLY
|
||||
unsigned int old_style; /* old window style */
|
||||
unsigned int old_ex_style; /* old window extended style */
|
||||
unsigned int old_id; /* old window id */
|
||||
void* old_instance; /* old creator instance */
|
||||
void* old_user_data; /* old user-specific data */
|
||||
unsigned int old_extra_value; /* old value in extra bytes */
|
||||
@END
|
||||
#define SET_WIN_STYLE 0x01
|
||||
#define SET_WIN_EXSTYLE 0x02
|
||||
#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
|
||||
|
||||
|
||||
/* Get a list of the window parents, up to the root of the tree */
|
||||
|
|
|
@ -2095,7 +2095,8 @@ static void dump_create_window_request( const struct create_window_request *req
|
|||
{
|
||||
fprintf( stderr, " parent=%p,", req->parent );
|
||||
fprintf( stderr, " owner=%p,", req->owner );
|
||||
fprintf( stderr, " atom=%04x", req->atom );
|
||||
fprintf( stderr, " atom=%04x,", req->atom );
|
||||
fprintf( stderr, " extra=%d", req->extra );
|
||||
}
|
||||
|
||||
static void dump_create_window_reply( const struct create_window_reply *req )
|
||||
|
@ -2154,7 +2155,9 @@ static void dump_set_window_info_request( const struct set_window_info_request *
|
|||
fprintf( stderr, " ex_style=%08x,", req->ex_style );
|
||||
fprintf( stderr, " id=%08x,", req->id );
|
||||
fprintf( stderr, " instance=%p,", req->instance );
|
||||
fprintf( stderr, " user_data=%p", req->user_data );
|
||||
fprintf( stderr, " user_data=%p,", req->user_data );
|
||||
fprintf( stderr, " extra_offset=%d,", req->extra_offset );
|
||||
fprintf( stderr, " extra_value=%08x", req->extra_value );
|
||||
}
|
||||
|
||||
static void dump_set_window_info_reply( const struct set_window_info_reply *req )
|
||||
|
@ -2163,7 +2166,8 @@ static void dump_set_window_info_reply( const struct set_window_info_reply *req
|
|||
fprintf( stderr, " old_ex_style=%08x,", req->old_ex_style );
|
||||
fprintf( stderr, " old_id=%08x,", req->old_id );
|
||||
fprintf( stderr, " old_instance=%p,", req->old_instance );
|
||||
fprintf( stderr, " old_user_data=%p", req->old_user_data );
|
||||
fprintf( stderr, " old_user_data=%p,", req->old_user_data );
|
||||
fprintf( stderr, " old_extra_value=%08x", req->old_extra_value );
|
||||
}
|
||||
|
||||
static void dump_get_window_parents_request( const struct get_window_parents_request *req )
|
||||
|
|
|
@ -77,6 +77,8 @@ struct window
|
|||
int prop_inuse; /* number of in-use window properties */
|
||||
int prop_alloc; /* number of allocated window properties */
|
||||
struct property *properties; /* window properties array */
|
||||
int nb_extra_bytes; /* number of extra bytes */
|
||||
char extra_bytes[1]; /* extra bytes storage */
|
||||
};
|
||||
|
||||
static struct window *top_window; /* top-level (desktop) window */
|
||||
|
@ -264,9 +266,10 @@ static void destroy_window( struct window *win )
|
|||
}
|
||||
|
||||
/* create a new window structure (note: the window is not linked in the window tree) */
|
||||
static struct window *create_window( struct window *parent, struct window *owner, atom_t atom )
|
||||
static struct window *create_window( struct window *parent, struct window *owner, atom_t atom,
|
||||
int extra_bytes )
|
||||
{
|
||||
struct window *win = mem_alloc( sizeof(*win) );
|
||||
struct window *win = mem_alloc( sizeof(*win) + extra_bytes - 1 );
|
||||
if (!win) return NULL;
|
||||
|
||||
if (!(win->handle = alloc_user_handle( win, USER_WINDOW )))
|
||||
|
@ -292,6 +295,8 @@ static struct window *create_window( struct window *parent, struct window *owner
|
|||
win->prop_inuse = 0;
|
||||
win->prop_alloc = 0;
|
||||
win->properties = NULL;
|
||||
win->nb_extra_bytes = extra_bytes;
|
||||
memset( win->extra_bytes, 0, extra_bytes );
|
||||
|
||||
if (parent) /* put it on parent unlinked list */
|
||||
{
|
||||
|
@ -448,11 +453,16 @@ user_handle_t find_window_to_repaint( user_handle_t parent, struct thread *threa
|
|||
DECL_HANDLER(create_window)
|
||||
{
|
||||
reply->handle = 0;
|
||||
if (req->extra < 0 || req->extra > 4096) /* don't allow stupid values here */
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
if (!req->parent) /* return desktop window */
|
||||
{
|
||||
if (!top_window)
|
||||
{
|
||||
if (!(top_window = create_window( NULL, NULL, req->atom ))) return;
|
||||
if (!(top_window = create_window( NULL, NULL, req->atom, req->extra ))) return;
|
||||
top_window->thread = NULL; /* no thread owns the desktop */
|
||||
top_window->style = WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
|
||||
}
|
||||
|
@ -471,7 +481,7 @@ DECL_HANDLER(create_window)
|
|||
set_error( STATUS_ACCESS_DENIED );
|
||||
return;
|
||||
}
|
||||
if (!(win = create_window( parent, owner, req->atom ))) return;
|
||||
if (!(win = create_window( parent, owner, req->atom, req->extra ))) return;
|
||||
reply->handle = win->handle;
|
||||
}
|
||||
}
|
||||
|
@ -576,6 +586,22 @@ DECL_HANDLER(set_window_info)
|
|||
set_error( STATUS_ACCESS_DENIED );
|
||||
return;
|
||||
}
|
||||
if (req->extra_offset < -1 || req->extra_offset >= win->nb_extra_bytes)
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
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) ));
|
||||
}
|
||||
else if (req->flags & (SET_WIN_EXTRAWORD|SET_WIN_EXTRALONG))
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
reply->old_style = win->style;
|
||||
reply->old_ex_style = win->ex_style;
|
||||
reply->old_id = win->id;
|
||||
|
@ -586,6 +612,12 @@ 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 ));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
111
windows/win.c
111
windows/win.c
|
@ -62,12 +62,12 @@ static void *user_handles[NB_USER_HANDLES];
|
|||
*
|
||||
* Create a window handle with the server.
|
||||
*/
|
||||
static WND *create_window_handle( HWND parent, HWND owner, ATOM atom, INT size )
|
||||
static WND *create_window_handle( HWND parent, HWND owner, ATOM atom, unsigned int extra_bytes )
|
||||
{
|
||||
BOOL res;
|
||||
user_handle_t handle = 0;
|
||||
WORD index;
|
||||
WND *win = HeapAlloc( GetProcessHeap(), 0, size );
|
||||
WND *win = HeapAlloc( GetProcessHeap(), 0, sizeof(WND) + extra_bytes - sizeof(win->wExtra) );
|
||||
|
||||
if (!win) return NULL;
|
||||
|
||||
|
@ -78,6 +78,7 @@ static WND *create_window_handle( HWND parent, HWND owner, ATOM atom, INT size )
|
|||
req->parent = parent;
|
||||
req->owner = owner;
|
||||
req->atom = atom;
|
||||
req->extra = extra_bytes;
|
||||
if ((res = !wine_server_call_err( req ))) handle = reply->handle;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
@ -459,6 +460,7 @@ LONG WIN_SetStyle( HWND hwnd, LONG style )
|
|||
req->handle = hwnd;
|
||||
req->flags = SET_WIN_STYLE;
|
||||
req->style = style;
|
||||
req->extra_offset = -1;
|
||||
if ((ok = !wine_server_call( req )))
|
||||
{
|
||||
ret = reply->old_style;
|
||||
|
@ -499,6 +501,7 @@ LONG WIN_SetExStyle( HWND hwnd, LONG style )
|
|||
req->handle = hwnd;
|
||||
req->flags = SET_WIN_EXSTYLE;
|
||||
req->ex_style = style;
|
||||
req->extra_offset = -1;
|
||||
if (!wine_server_call( req ))
|
||||
{
|
||||
ret = reply->old_ex_style;
|
||||
|
@ -718,8 +721,7 @@ BOOL WIN_CreateDesktopWindow(void)
|
|||
&wndExtra, &winproc, &clsStyle, &dce )))
|
||||
return FALSE;
|
||||
|
||||
pWndDesktop = create_window_handle( 0, 0, LOWORD(DESKTOP_CLASS_ATOM),
|
||||
sizeof(WND) + wndExtra - sizeof(pWndDesktop->wExtra) );
|
||||
pWndDesktop = create_window_handle( 0, 0, LOWORD(DESKTOP_CLASS_ATOM), wndExtra );
|
||||
if (!pWndDesktop) return FALSE;
|
||||
hwndDesktop = pWndDesktop->hwndSelf;
|
||||
|
||||
|
@ -759,6 +761,7 @@ BOOL WIN_CreateDesktopWindow(void)
|
|||
{
|
||||
req->handle = hwndDesktop;
|
||||
req->flags = 0; /* don't set anything, just retrieve */
|
||||
req->extra_offset = -1;
|
||||
wine_server_call( req );
|
||||
pWndDesktop->dwStyle = reply->old_style;
|
||||
pWndDesktop->dwExStyle = reply->old_ex_style;
|
||||
|
@ -1049,8 +1052,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
|
|||
|
||||
/* Create the window structure */
|
||||
|
||||
if (!(wndPtr = create_window_handle( parent, owner, classAtom,
|
||||
sizeof(*wndPtr) + wndExtra - sizeof(wndPtr->wExtra) )))
|
||||
if (!(wndPtr = create_window_handle( parent, owner, classAtom, wndExtra )))
|
||||
{
|
||||
TRACE("out of memory\n" );
|
||||
return 0;
|
||||
|
@ -1100,6 +1102,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
|
|||
req->style = wndPtr->dwStyle;
|
||||
req->ex_style = wndPtr->dwExStyle;
|
||||
req->instance = (void *)wndPtr->hInstance;
|
||||
req->extra_offset = -1;
|
||||
wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
@ -1788,7 +1791,7 @@ WORD WINAPI GetWindowWord( HWND hwnd, INT offset )
|
|||
*/
|
||||
WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval )
|
||||
{
|
||||
WORD *ptr, retval;
|
||||
WORD retval = 0;
|
||||
WND * wndPtr;
|
||||
|
||||
switch(offset)
|
||||
|
@ -1827,9 +1830,21 @@ WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval )
|
|||
SetLastError( ERROR_INVALID_INDEX );
|
||||
return 0;
|
||||
}
|
||||
ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
|
||||
|
||||
SERVER_START_REQ( set_window_info )
|
||||
{
|
||||
req->handle = hwnd;
|
||||
req->flags = SET_WIN_EXTRAWORD;
|
||||
req->extra_offset = offset;
|
||||
req->extra_value = newval;
|
||||
if (!wine_server_call_err( req ))
|
||||
{
|
||||
WORD *ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
|
||||
retval = *ptr;
|
||||
*ptr = newval;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
WIN_ReleasePtr( wndPtr );
|
||||
return retval;
|
||||
}
|
||||
|
@ -1860,13 +1875,6 @@ static LONG WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type )
|
|||
|
||||
if (wndPtr == WND_OTHER_PROCESS)
|
||||
{
|
||||
if (offset >= 0)
|
||||
{
|
||||
if (IsWindow(hwnd))
|
||||
FIXME( "(%d) not supported on other process window %p\n", offset, hwnd );
|
||||
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
|
||||
return 0;
|
||||
}
|
||||
if (offset == GWL_WNDPROC)
|
||||
{
|
||||
SetLastError( ERROR_ACCESS_DENIED );
|
||||
|
@ -1876,6 +1884,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;
|
||||
if (!wine_server_call_err( req ))
|
||||
{
|
||||
switch(offset)
|
||||
|
@ -1886,10 +1895,13 @@ static LONG WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type )
|
|||
case GWL_HINSTANCE: retvalue = (ULONG_PTR)reply->old_instance; break;
|
||||
case GWL_USERDATA: retvalue = (ULONG_PTR)reply->old_user_data; break;
|
||||
default:
|
||||
SetLastError( ERROR_INVALID_INDEX );
|
||||
if (offset >= 0) retvalue = reply->old_extra_value;
|
||||
else SetLastError( ERROR_INVALID_INDEX );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (offset >= 0 && GetLastError() == ERROR_INVALID_PARAMETER)
|
||||
SetLastError( ERROR_INVALID_INDEX );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return retvalue;
|
||||
|
@ -1961,6 +1973,8 @@ static LONG WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type )
|
|||
static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval,
|
||||
WINDOWPROCTYPE type )
|
||||
{
|
||||
STYLESTRUCT style;
|
||||
BOOL ok;
|
||||
LONG retval = 0;
|
||||
WND *wndPtr;
|
||||
|
||||
|
@ -1990,33 +2004,6 @@ static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (offset >= 0)
|
||||
{
|
||||
LONG *ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
|
||||
if (offset > (int)(wndPtr->cbWndExtra - sizeof(LONG)))
|
||||
{
|
||||
WARN("Invalid offset %d\n", offset );
|
||||
WIN_ReleasePtr( wndPtr );
|
||||
SetLastError( ERROR_INVALID_INDEX );
|
||||
return 0;
|
||||
}
|
||||
/* Special case for dialog window procedure */
|
||||
if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
|
||||
{
|
||||
retval = (LONG)WINPROC_GetProc( (WNDPROC)*ptr, type );
|
||||
WINPROC_SetProc( (WNDPROC *)ptr, (WNDPROC)newval, type, WIN_PROC_WINDOW );
|
||||
WIN_ReleasePtr( wndPtr );
|
||||
return retval;
|
||||
}
|
||||
retval = *ptr;
|
||||
*ptr = newval;
|
||||
WIN_ReleasePtr( wndPtr );
|
||||
}
|
||||
else
|
||||
{
|
||||
STYLESTRUCT style;
|
||||
BOOL ok;
|
||||
|
||||
/* first some special cases */
|
||||
switch( offset )
|
||||
{
|
||||
|
@ -2050,16 +2037,40 @@ static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval,
|
|||
case GWL_HINSTANCE:
|
||||
case GWL_USERDATA:
|
||||
break;
|
||||
default:
|
||||
case DWL_DLGPROC:
|
||||
if ((wndPtr->cbWndExtra + sizeof(LONG) >= DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
|
||||
{
|
||||
WNDPROC *ptr = (WNDPROC *)((char *)wndPtr->wExtra + DWL_DLGPROC);
|
||||
retval = (LONG)WINPROC_GetProc( *ptr, type );
|
||||
WINPROC_SetProc( ptr, (WNDPROC)newval, type, WIN_PROC_WINDOW );
|
||||
WIN_ReleasePtr( wndPtr );
|
||||
return retval;
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
if (offset < 0 || offset > (int)(wndPtr->cbWndExtra - sizeof(LONG)))
|
||||
{
|
||||
WARN("Invalid offset %d\n", offset );
|
||||
WIN_ReleasePtr( wndPtr );
|
||||
SetLastError( ERROR_INVALID_INDEX );
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LONG *ptr = (LONG *)((char *)wndPtr->wExtra + offset);
|
||||
if (*ptr == newval) /* already set to the same value */
|
||||
{
|
||||
WIN_ReleasePtr( wndPtr );
|
||||
return newval;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
SERVER_START_REQ( set_window_info )
|
||||
{
|
||||
req->handle = hwnd;
|
||||
req->extra_offset = -1;
|
||||
switch(offset)
|
||||
{
|
||||
case GWL_STYLE:
|
||||
|
@ -2082,6 +2093,10 @@ static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval,
|
|||
req->flags = SET_WIN_USERDATA;
|
||||
req->user_data = (void *)newval;
|
||||
break;
|
||||
default:
|
||||
req->flags = SET_WIN_EXTRALONG;
|
||||
req->extra_offset = offset;
|
||||
req->extra_value = newval;
|
||||
}
|
||||
if ((ok = !wine_server_call_err( req )))
|
||||
{
|
||||
|
@ -2107,6 +2122,13 @@ static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval,
|
|||
wndPtr->userdata = newval;
|
||||
retval = (ULONG_PTR)reply->old_user_data;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
LONG *ptr = (LONG *)((char *)wndPtr->wExtra + offset);
|
||||
retval = *ptr;
|
||||
*ptr = newval;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2121,7 +2143,6 @@ static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval,
|
|||
if (offset == GWL_STYLE || offset == GWL_EXSTYLE)
|
||||
SendMessageW( hwnd, WM_STYLECHANGED, offset, (LPARAM)&style );
|
||||
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue