Module: wine Branch: master Commit: 51e8d579bb643859385edcf53b263eeeb13dd9ac URL: https://source.winehq.org/git/wine.git/?a=commit;h=51e8d579bb643859385edcf53...
Author: Alexandre Julliard julliard@winehq.org Date: Tue May 22 13:00:34 2018 +0200
user32: Don't send cross-process message for GetWindowTextLength().
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/user32/win.c | 28 +++++++++++++++++++++------- include/wine/server_protocol.h | 4 +++- server/protocol.def | 1 + server/request.h | 3 ++- server/trace.c | 3 ++- server/window.c | 5 ++--- 6 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 850f0ba..7c12825 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -461,18 +461,23 @@ static void update_window_state( HWND hwnd ) * * Retrieve the window text from the server. */ -static void get_server_window_text( HWND hwnd, LPWSTR text, INT count ) +static data_size_t get_server_window_text( HWND hwnd, WCHAR *text, data_size_t count ) { - size_t len = 0; + data_size_t len = 0, needed = 0;
SERVER_START_REQ( get_window_text ) { req->handle = wine_server_user_handle( hwnd ); - wine_server_set_reply( req, text, (count - 1) * sizeof(WCHAR) ); - if (!wine_server_call_err( req )) len = wine_server_reply_size(reply); + if (count) wine_server_set_reply( req, text, (count - 1) * sizeof(WCHAR) ); + if (!wine_server_call_err( req )) + { + needed = reply->length; + len = wine_server_reply_size(reply); + } } SERVER_END_REQ; - text[len / sizeof(WCHAR)] = 0; + if (text) text[len / sizeof(WCHAR)] = 0; + return needed; }
@@ -2875,7 +2880,13 @@ BOOL WINAPI DECLSPEC_HOTPATCH SetWindowTextW( HWND hwnd, LPCWSTR lpString ) */ INT WINAPI GetWindowTextLengthA( HWND hwnd ) { - return SendMessageA( hwnd, WM_GETTEXTLENGTH, 0, 0 ); + CPINFO info; + + if (WIN_IsCurrentProcess( hwnd )) return SendMessageA( hwnd, WM_GETTEXTLENGTH, 0, 0 ); + + /* when window belongs to other process, don't send a message */ + GetCPInfo( CP_ACP, &info ); + return get_server_window_text( hwnd, NULL, 0 ) * info.MaxCharSize; }
/******************************************************************* @@ -2883,7 +2894,10 @@ INT WINAPI GetWindowTextLengthA( HWND hwnd ) */ INT WINAPI GetWindowTextLengthW( HWND hwnd ) { - return SendMessageW( hwnd, WM_GETTEXTLENGTH, 0, 0 ); + if (WIN_IsCurrentProcess( hwnd )) return SendMessageW( hwnd, WM_GETTEXTLENGTH, 0, 0 ); + + /* when window belongs to other process, don't send a message */ + return get_server_window_text( hwnd, NULL, 0 ); }
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 6aee918..564ae92 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -3703,7 +3703,9 @@ struct get_window_text_request struct get_window_text_reply { struct reply_header __header; + data_size_t length; /* VARARG(text,unicode_str); */ + char __pad_12[4]; };
@@ -6509,6 +6511,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; };
-#define SERVER_PROTOCOL_VERSION 551 +#define SERVER_PROTOCOL_VERSION 552
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index 1673ae3..9fb155b 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2659,6 +2659,7 @@ enum coords_relative @REQ(get_window_text) user_handle_t handle; /* handle to the window */ @REPLY + data_size_t length; /* total length in WCHARs */ VARARG(text,unicode_str); /* window text */ @END
diff --git a/server/request.h b/server/request.h index f69ff16..3e6183b 100644 --- a/server/request.h +++ b/server/request.h @@ -1772,7 +1772,8 @@ C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_reply, client) == 40 ); C_ASSERT( sizeof(struct get_window_rectangles_reply) == 56 ); C_ASSERT( FIELD_OFFSET(struct get_window_text_request, handle) == 12 ); C_ASSERT( sizeof(struct get_window_text_request) == 16 ); -C_ASSERT( sizeof(struct get_window_text_reply) == 8 ); +C_ASSERT( FIELD_OFFSET(struct get_window_text_reply, length) == 8 ); +C_ASSERT( sizeof(struct get_window_text_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct set_window_text_request, handle) == 12 ); C_ASSERT( sizeof(struct set_window_text_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_windows_offset_request, from) == 12 ); diff --git a/server/trace.c b/server/trace.c index ac15ba9..44004ad 100644 --- a/server/trace.c +++ b/server/trace.c @@ -3233,7 +3233,8 @@ static void dump_get_window_text_request( const struct get_window_text_request *
static void dump_get_window_text_reply( const struct get_window_text_reply *req ) { - dump_varargs_unicode_str( " text=", cur_size ); + fprintf( stderr, " length=%u", req->length ); + dump_varargs_unicode_str( ", text=", cur_size ); }
static void dump_set_window_text_request( const struct set_window_text_request *req ) diff --git a/server/window.c b/server/window.c index 9560f93..4a1a278 100644 --- a/server/window.c +++ b/server/window.c @@ -2398,9 +2398,8 @@ DECL_HANDLER(get_window_text)
if (win && win->text) { - data_size_t len = strlenW( win->text ) * sizeof(WCHAR); - if (len > get_reply_max_size()) len = get_reply_max_size(); - set_reply_data( win->text, len ); + reply->length = strlenW( win->text ); + set_reply_data( win->text, min( reply->length * sizeof(WCHAR), get_reply_max_size() )); } }