Alexandre Julliard : user32: Don' t send cross-process message for GetWindowTextLength().
Alexandre Julliard
julliard at winehq.org
Tue May 22 15:37:14 CDT 2018
Module: wine
Branch: master
Commit: 51e8d579bb643859385edcf53b263eeeb13dd9ac
URL: https://source.winehq.org/git/wine.git/?a=commit;h=51e8d579bb643859385edcf53b263eeeb13dd9ac
Author: Alexandre Julliard <julliard at 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 at 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() ));
}
}
More information about the wine-cvs
mailing list