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