[PATCH] user32: Add an exception handler to GetWindowText.

Rémi Bernon rbernon at codeweavers.com
Wed Oct 13 05:14:02 CDT 2021


On 10/13/21 11:41 AM, Dmitry Timoshkov wrote:
> Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
> ---
>   dlls/user32/tests/win.c | 29 ++++++++++++++++----
>   dlls/user32/win.c       | 59 ++++++++++++++++++++++++++++++-----------
>   2 files changed, 67 insertions(+), 21 deletions(-)
> 
> diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
> index 6b13d93be14..2679ea0813f 100644
> --- a/dlls/user32/tests/win.c
> +++ b/dlls/user32/tests/win.c
> @@ -7923,17 +7923,36 @@ static void test_gettext(void)
>       if (0)
>       {
>       r = SendMessageA( hwnd, WM_GETTEXT, 0x10, 0x1000);
> -    ok( r == 0, "settext should return zero\n");
> +    ok(r == 0, "WM_GETTEXT should return zero (%ld)\n", r);
>   
>       r = SendMessageA( hwnd, WM_GETTEXT, 0x10000, 0);
> -    ok( r == 0, "settext should return zero (%ld)\n", r);
> +    ok(r == 0, "WM_GETTEXT should return zero (%ld)\n", r);
>   
>       r = SendMessageA( hwnd, WM_GETTEXT, 0xff000000, 0x1000);
> -    ok( r == 0, "settext should return zero (%ld)\n", r);
> +    ok(r == 0, "WM_GETTEXT should return zero (%ld)\n", r);
>   
>       r = SendMessageA( hwnd, WM_GETTEXT, 0x1000, 0xff000000);
> -    ok( r == 0, "settext should return zero (%ld)\n", r);
> -    }
> +    ok(r == 0, "WM_GETTEXT should return zero (%ld)\n", r);
> +    }
> +
> +    /* GetWindowText doesn't crash */
> +    r = GetWindowTextA(hwnd, (LPSTR)0x10, 0x1000);
> +    ok(r == 0, "GetWindowText should return zero (%ld)\n", r);
> +    r = GetWindowTextA(hwnd, (LPSTR)0x10000, 0);
> +    ok(r == 0, "GetWindowText should return zero (%ld)\n", r);
> +    r = GetWindowTextA(hwnd, (LPSTR)0xff000000, 0x1000);
> +    ok(r == 0, "GetWindowText should return zero (%ld)\n", r);
> +    r = GetWindowTextA(hwnd, (LPSTR)0x1000, 0xff000000);
> +    ok(r == 0, "GetWindowText should return zero (%ld)\n", r);
> +
> +    r = GetWindowTextW(hwnd, (LPWSTR)0x10, 0x1000);
> +    ok(r == 0, "GetWindowText should return zero (%ld)\n", r);
> +    r = GetWindowTextW(hwnd, (LPWSTR)0x10000, 0);
> +    ok(r == 0, "GetWindowText should return zero (%ld)\n", r);
> +    r = GetWindowTextW(hwnd, (LPWSTR)0xff000000, 0x1000);
> +    ok(r == 0, "GetWindowText should return zero (%ld)\n", r);
> +    r = GetWindowTextW(hwnd, (LPWSTR)0x1000, 0xff000000);
> +    ok(r == 0, "GetWindowText should return zero (%ld)\n", r);
>   
>       DestroyWindow(hwnd);
>   }
> diff --git a/dlls/user32/win.c b/dlls/user32/win.c
> index 5e89f4c2c97..e57f291be35 100644
> --- a/dlls/user32/win.c
> +++ b/dlls/user32/win.c
> @@ -35,6 +35,7 @@
>   #include "controls.h"
>   #include "winerror.h"
>   #include "wine/gdi_driver.h"
> +#include "wine/exception.h"
>   #include "wine/debug.h"
>   
>   WINE_DEFAULT_DEBUG_CHANNEL(win);
> @@ -3001,22 +3002,34 @@ LONG WINAPI DECLSPEC_HOTPATCH SetWindowLongW(
>   INT WINAPI GetWindowTextA( HWND hwnd, LPSTR lpString, INT nMaxCount )
>   {
>       WCHAR *buffer;
> +    int ret = 0;
>   
>       if (!lpString || nMaxCount <= 0) return 0;
>   
> -    if (WIN_IsCurrentProcess( hwnd ))
> +    __TRY
>       {
> -        lpString[0] = 0;
> -        return (INT)SendMessageA( hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString );
> +        if (WIN_IsCurrentProcess( hwnd ))
> +        {
> +            lpString[0] = 0;
> +            ret = (INT)SendMessageA( hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString );
> +        }
> +        else if ((buffer = HeapAlloc( GetProcessHeap(), 0, nMaxCount * sizeof(WCHAR) )))
> +        {
> +            /* when window belongs to other process, don't send a message */
> +            get_server_window_text( hwnd, buffer, nMaxCount );
> +            if (!WideCharToMultiByte( CP_ACP, 0, buffer, -1, lpString, nMaxCount, NULL, NULL ))
> +                lpString[nMaxCount-1] = 0;
> +            HeapFree( GetProcessHeap(), 0, buffer );
> +            ret = strlen(lpString);
> +        }
> +    }
> +    __EXCEPT_ALL
> +    {
> +        ret = 0;
>       }
> +    __ENDTRY
>   
> -    /* when window belongs to other process, don't send a message */
> -    if (!(buffer = HeapAlloc( GetProcessHeap(), 0, nMaxCount * sizeof(WCHAR) ))) return 0;
> -    get_server_window_text( hwnd, buffer, nMaxCount );
> -    if (!WideCharToMultiByte( CP_ACP, 0, buffer, -1, lpString, nMaxCount, NULL, NULL ))
> -        lpString[nMaxCount-1] = 0;
> -    HeapFree( GetProcessHeap(), 0, buffer );
> -    return strlen(lpString);
> +    return ret;
>   }
>   
>   
> @@ -3049,17 +3062,31 @@ INT WINAPI InternalGetWindowText(HWND hwnd,LPWSTR lpString,INT nMaxCount )
>    */
>   INT WINAPI GetWindowTextW( HWND hwnd, LPWSTR lpString, INT nMaxCount )
>   {
> +    int ret;
> +
>       if (!lpString || nMaxCount <= 0) return 0;
>   
> -    if (WIN_IsCurrentProcess( hwnd ))
> +    __TRY
>       {
> -        lpString[0] = 0;
> -        return (INT)SendMessageW( hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString );
> +        if (WIN_IsCurrentProcess( hwnd ))
> +        {
> +            lpString[0] = 0;
> +            ret = (INT)SendMessageW( hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString );
> +        }
> +        else
> +        {
> +            /* when window belongs to other process, don't send a message */
> +            get_server_window_text( hwnd, lpString, nMaxCount );
> +            ret = lstrlenW(lpString);
> +        }
>       }
> +    __EXCEPT_ALL
> +    {
> +        ret = 0;
> +    }
> +    __ENDTRY
>   
> -    /* when window belongs to other process, don't send a message */
> -    get_server_window_text( hwnd, lpString, nMaxCount );
> -    return lstrlenW(lpString);
> +    return ret;
>   }
>   
>   
> 

Then I'm not sure if it's good to catch all exceptions. It will swallow 
any error coming from the heap or send message. Is it really what it 
should do?
-- 
Rémi Bernon <rbernon at codeweavers.com>



More information about the wine-devel mailing list