[PATCH] user32: Fix error handling in MapWindowPoints, ClientToScreen and ScreenToClient and add tests for them.
Christian Costa
titan.costa at gmail.com
Fri Oct 19 15:09:17 CDT 2012
Based ont a patch of Rico Schuller.
---
dlls/user32/tests/win.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++
dlls/user32/winpos.c | 52 ++++++++++-
2 files changed, 257 insertions(+), 8 deletions(-)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index e84824d..8c5dcc2 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -7104,6 +7104,217 @@ todo_wine
ok(ret, "UnregisterClass(my_window) failed\n");
}
+static void test_map_points(void)
+{
+ BOOL ret;
+ POINT p;
+ HWND wnd, dwnd;
+ INT n;
+ DWORD err;
+ POINT pos = { 100, 200 };
+ int width = 150;
+ int height = 150;
+ RECT window_rect;
+ RECT client_rect;
+
+ /* Create test windows */
+ wnd = CreateWindow("static", "test1", WS_POPUP, pos.x, pos.y, width, height, NULL, NULL, NULL, NULL);
+ ok(wnd != NULL, "Failed %p\n", wnd);
+ dwnd = CreateWindow("static", "test2", 0, 200, 300, 150, 150, NULL, NULL, NULL, NULL);
+ DestroyWindow(dwnd);
+ ok(dwnd != NULL, "Failed %p\n", dwnd);
+
+ /* Verify window rect and client rect (they should have the same width and height) */
+ GetWindowRect(wnd, &window_rect);
+ ok(window_rect.left == pos.x, "left is %d instead of %d\n", window_rect.left, pos.x);
+ ok(window_rect.top == pos.y, "top is %d instead of %d\n", window_rect.top, pos.y);
+ ok(window_rect.right == pos.x + width, "right is %d instead of %d\n", window_rect.right, pos.x + width);
+ ok(window_rect.bottom == pos.y + height, "bottom is %d instead of %d\n", window_rect.bottom, pos.y + height);
+ GetClientRect(wnd, &client_rect);
+ ok(client_rect.left == 0, "left is %d instead of 0\n", client_rect.left);
+ ok(client_rect.top == 0, "top is %d instead of 0\n", client_rect.top);
+ ok(client_rect.right == width, "right is %d instead of %d\n", client_rect.right, width);
+ ok(client_rect.bottom == height, "bottom is %d instead of %d\n", client_rect.bottom, height);
+
+ /* Test MapWindowPoints */
+
+ /* MapWindowPoints(NULL or wnd, NULL or wnd, NULL, 1); crashes on XP */
+
+ SetLastError(0xdeadbeef);
+ n = MapWindowPoints(NULL, NULL, NULL, 0);
+ err = GetLastError();
+ ok(n == 0, "Got %d, expected %d\n", n, 0);
+ ok(err == 0xdeadbeef, "Got %x, expected %x\n", err, 0xdeadbeef);
+
+ SetLastError(0xdeadbeef);
+ n = MapWindowPoints(wnd, wnd, NULL, 0);
+ err = GetLastError();
+ ok(n == 0, "Got %d, expected %d\n", n, 0);
+ ok(err == 0xdeadbeef, "Got %x, expected %x\n", err, 0xdeadbeef);
+
+ SetLastError(0xdeadbeef);
+ n = MapWindowPoints(wnd, NULL, NULL, 0);
+ err = GetLastError();
+ ok(n == ((window_rect.top << 16) | window_rect.left), "Got %x (%d, %d), expected %x (%d, %d)\n",
+ n, (n << 16) >> 16, n >> 16, window_rect.left, window_rect.top, (window_rect.top << 16) | window_rect.left);
+ ok(err == 0xdeadbeef, "Got %x, expected %x\n", err, 0xdeadbeef);
+
+ SetLastError(0xdeadbeef);
+ n = MapWindowPoints(NULL, wnd, NULL, 0);
+ err = GetLastError();
+ ok(n == ((-window_rect.top << 16) | (-window_rect.left & 0xffff)), "Got %x (%d, %d), expected %x (%d, %d)\n",
+ n, (n << 16) >> 16, n >> 16, (-window_rect.top << 16) | (-window_rect.left & 0xffff), -window_rect.left, -window_rect.top);
+ ok(err == 0xdeadbeef, "Got %x, expected %x\n", err, 0xdeadbeef);
+
+ SetLastError(0xdeadbeef);
+ p.x = p.y = 100;
+ n = MapWindowPoints(dwnd, NULL, &p, 1);
+ err = GetLastError();
+ ok(n == 0, "Got %d, expected %d\n", n, 0);
+ ok(p.x == 100 && p.y == 100, "Failed got(%d, %d), expected (%d, %d)\n", p.x, p.y, 100, 100);
+ ok(err == ERROR_INVALID_WINDOW_HANDLE, "Got %x, expected %x\n", err, ERROR_INVALID_WINDOW_HANDLE);
+
+ SetLastError(0xdeadbeef);
+ p.x = p.y = 100;
+ n = MapWindowPoints(dwnd, wnd, &p, 1);
+ err = GetLastError();
+ ok(n == 0, "Got %d, expected %d\n", n, 0);
+ ok(p.x == 100 && p.y == 100, "Failed got(%d, %d), expected (%d, %d)\n", p.x, p.y, 100, 100);
+ ok(err == ERROR_INVALID_WINDOW_HANDLE, "Got %x, expected %x\n", err, ERROR_INVALID_WINDOW_HANDLE);
+
+ SetLastError(0xdeadbeef);
+ p.x = p.y = 100;
+ n = MapWindowPoints(NULL, dwnd, &p, 1);
+ err = GetLastError();
+ ok(n == 0, "Got %d, expected %d\n", n, 0);
+ ok(p.x == 100 && p.y == 100, "Failed got(%d, %d), expected (%d, %d)\n", p.x, p.y, 100, 100);
+ ok(err == ERROR_INVALID_WINDOW_HANDLE, "Got %x, expected %x\n", err, ERROR_INVALID_WINDOW_HANDLE);
+
+ SetLastError(0xdeadbeef);
+ p.x = p.y = 100;
+ n = MapWindowPoints(wnd, dwnd, &p, 1);
+ err = GetLastError();
+ ok(n == 0, "Got %d, expected %d\n", n, 0);
+ ok(p.x == 100 && p.y == 100, "Failed got(%d, %d), expected (%d, %d)\n", p.x, p.y, 100, 100);
+ ok(err == ERROR_INVALID_WINDOW_HANDLE, "Got %x, expected %x\n", err, ERROR_INVALID_WINDOW_HANDLE);
+
+ SetLastError(0xdeadbeef);
+ p.x = p.y = 100;
+ n = MapWindowPoints(dwnd, dwnd, &p, 1);
+ err = GetLastError();
+ ok(n == 0, "Got %d, expected %d\n", n, 0);
+ ok(p.x == 100 && p.y == 100, "Failed got(%d, %d), expected (%d, %d)\n", p.x, p.y, 100, 100);
+ ok(err == ERROR_INVALID_WINDOW_HANDLE, "Got %x, expected %x\n", err, ERROR_INVALID_WINDOW_HANDLE);
+
+ SetLastError(0xdeadbeef);
+ p.x = p.y = 100;
+ n = MapWindowPoints(NULL, NULL, &p, 1);
+ err = GetLastError();
+ ok(n == 0, "Got %d, expected %d\n", n, 0);
+ ok(p.x == 100 && p.y == 100, "Failed got(%d, %d), expected (%d, %d)\n", p.x, p.y, 100, 100);
+ ok(err == 0xdeadbeef, "Got %x, expected %x\n", err, 0xdeadbeef);
+
+ SetLastError(0xdeadbeef);
+ p.x = p.y = 100;
+ n = MapWindowPoints(wnd, wnd, &p, 1);
+ err = GetLastError();
+ ok(n == 0, "Got %d, expected %d\n", n, 0);
+ ok(p.x == 100 && p.y == 100, "Failed got(%d, %d), expected (%d, %d)\n", p.x, p.y, 100, 100);
+ ok(err == 0xdeadbeef, "Got %x, expected %x\n", err, 0xdeadbeef);
+
+ SetLastError(0xdeadbeef);
+ p.x = p.y = 100;
+ n = MapWindowPoints(wnd, NULL, &p, 1);
+ err = GetLastError();
+ ok(n == ((window_rect.top << 16) | window_rect.left), "Got %x (%d, %d), expected %x (%d, %d)\n",
+ n, (n << 16) >> 16, n >> 16, window_rect.left, window_rect.top, (window_rect.top << 16) | window_rect.left);
+ ok((p.x == (window_rect.left + 100)) && (p.y == (window_rect.top + 100)), "Failed got (%d, %d), expected (%d, %d)\n",
+ p.x, p.y, window_rect.left + 100, window_rect.top + 100);
+ ok(err == 0xdeadbeef, "Got %x, expected %x\n", err, 0xdeadbeef);
+
+ SetLastError(0xdeadbeef);
+ p.x = p.y = 100;
+ n = MapWindowPoints(NULL, wnd, &p, 1);
+ err = GetLastError();
+ ok(n == ((-window_rect.top << 16) | (-window_rect.left & 0xffff)), "Got %x (%d, %d), expected %x (%d, %d)\n",
+ n, (n << 16) >> 16, n >> 16, (-window_rect.top << 16) | (-window_rect.left & 0xffff), -window_rect.left, -window_rect.top);
+ ok((p.x == (-window_rect.left + 100)) && (p.y == (-window_rect.top + 100)), "Failed got (%d, %d), expected (%d, %d)\n",
+ p.x, p.y, -window_rect.left + 100, -window_rect.top + 100);
+ ok(err == 0xdeadbeef, "Got %x, expected %x\n", err, 0xdeadbeef);
+
+ /* Test ClientToScreen */
+
+ /* ClientToScreen(wnd, NULL); crashes on XP */
+
+ SetLastError(0xdeadbeef);
+ ret = ClientToScreen(NULL, NULL);
+ err = GetLastError();
+ ok(!ret, "Failed\n");
+ ok(err == ERROR_INVALID_WINDOW_HANDLE, "Got %x, expected %x\n", err, ERROR_INVALID_WINDOW_HANDLE);
+
+ SetLastError(0xdeadbeef);
+ p.x = p.y = 100;
+ ret = ClientToScreen(NULL, &p);
+ err = GetLastError();
+ ok(!ret, "Failed\n");
+ ok(p.x == 100 && p.y == 100, "Failed got(%d, %d), expected (%d, %d)\n", p.x, p.y, 100, 100);
+ ok(err == ERROR_INVALID_WINDOW_HANDLE, "Got %x, expected %x\n", err, ERROR_INVALID_WINDOW_HANDLE);
+
+ SetLastError(0xdeadbeef);
+ p.x = p.y = 100;
+ ret = ClientToScreen(dwnd, &p);
+ err = GetLastError();
+ ok(!ret, "Failed\n");
+ ok(p.x == 100 && p.y == 100, "Failed got(%d, %d), expected (%d, %d)\n", p.x, p.y, 100, 100);
+ ok(err == ERROR_INVALID_WINDOW_HANDLE, "Got %x, expected %x\n", err, ERROR_INVALID_WINDOW_HANDLE);
+
+ SetLastError(0xdeadbeef);
+ p.x = p.y = 100;
+ ret = ClientToScreen(wnd, &p);
+ err = GetLastError();
+ ok(ret, "Failed\n");
+ ok((p.x == (window_rect.left + 100)) && (p.y == (window_rect.top + 100)), "Failed got (%d, %d), expected (%d, %d)\n",
+ p.x, p.y, window_rect.left + 100, window_rect.top + 100);
+ ok(err == 0xdeadbeef, "Got %x, expected %x\n", err, 0xdeadbeef);
+
+ /* Test ScreenToClient */
+
+ /* ScreenToClient(wnd, NULL); crashes on XP */
+
+ SetLastError(0xdeadbeef);
+ ret = ScreenToClient(NULL, NULL);
+ err = GetLastError();
+ ok(!ret, "Failed\n");
+ ok(err == ERROR_INVALID_WINDOW_HANDLE, "Got %x, expected %x\n", err, ERROR_INVALID_WINDOW_HANDLE);
+
+ SetLastError(0xdeadbeef);
+ p.x = p.y = 100;
+ ret = ScreenToClient(NULL, &p);
+ err = GetLastError();
+ ok(!ret, "Failed\n");
+ ok(p.x == 100 && p.y == 100, "Failed got(%d, %d), expected (%d, %d)\n", p.x, p.y, 100, 100);
+ ok(err == ERROR_INVALID_WINDOW_HANDLE, "Got %x, expected %x\n", err, ERROR_INVALID_WINDOW_HANDLE);
+
+ SetLastError(0xdeadbeef);
+ p.x = p.y = 100;
+ ret = ScreenToClient(dwnd, &p);
+ err = GetLastError();
+ ok(ret == FALSE, "Failed\n");
+ ok(p.x == 100 && p.y == 100, "Failed got(%d, %d), expected (%d, %d)\n", p.x, p.y, 100, 100);
+ ok(err == ERROR_INVALID_WINDOW_HANDLE, "Got %x, expected %x\n", err, ERROR_INVALID_WINDOW_HANDLE);
+
+ SetLastError(0xdeadbeef);
+ p.x = p.y = 100;
+ ret = ScreenToClient(wnd, &p);
+ err = GetLastError();
+ ok(ret, "Failed\n");
+ ok((p.x == (-window_rect.left + 100)) && (p.y == (-window_rect.top + 100)), "Failed got(%d, %d), expected (%d, %d)\n",
+ p.x, p.y, -window_rect.left + 100, -window_rect.top + 100);
+ ok(err == 0xdeadbeef, "Got %x, expected %x\n", err, 0xdeadbeef);
+
+ DestroyWindow(wnd);
+}
+
START_TEST(win)
{
HMODULE user32 = GetModuleHandleA( "user32.dll" );
@@ -7213,6 +7424,8 @@ START_TEST(win)
test_handles( hwndMain );
test_winregion();
+ test_map_points();
+
/* add the tests above this line */
if (hhook) UnhookWindowsHookEx(hhook);
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index 5a2f1f2..7f21687 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -236,21 +236,49 @@ BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect )
/*******************************************************************
- * ClientToScreen (USER32.@)
+ * ClientToScreen (USER32.@)
*/
-BOOL WINAPI ClientToScreen( HWND hwnd, LPPOINT lppnt )
+BOOL WINAPI ClientToScreen( HWND wnd, LPPOINT point )
{
- MapWindowPoints( hwnd, 0, lppnt, 1 );
+ DWORD error = GetLastError();
+
+ if (!wnd)
+ {
+ SetLastError( ERROR_INVALID_WINDOW_HANDLE );
+ return FALSE;
+ }
+
+ SetLastError( 0xdeadbeef );
+ MapWindowPoints( wnd, 0, point, 1 );
+
+ if (GetLastError() != 0xdeadbeef)
+ return FALSE;
+
+ SetLastError(error);
return TRUE;
}
/*******************************************************************
- * ScreenToClient (USER32.@)
+ * ScreenToClient (USER32.@)
*/
-BOOL WINAPI ScreenToClient( HWND hwnd, LPPOINT lppnt )
+BOOL WINAPI ScreenToClient( HWND wnd, LPPOINT point )
{
- MapWindowPoints( 0, hwnd, lppnt, 1 );
+ DWORD error = GetLastError();
+
+ if (!wnd)
+ {
+ SetLastError( ERROR_INVALID_WINDOW_HANDLE );
+ return FALSE;
+ }
+
+ SetLastError( 0xdeadbeef );
+ MapWindowPoints( 0, wnd, point, 1 );
+
+ if (GetLastError() != 0xdeadbeef)
+ return FALSE;
+
+ SetLastError(error);
return TRUE;
}
@@ -552,14 +580,22 @@ void map_window_region( HWND from, HWND to, HRGN hrgn )
/*******************************************************************
- * MapWindowPoints (USER32.@)
+ * MapWindowPoints (USER32.@)
*/
INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, UINT count )
{
BOOL mirrored;
- POINT offset = WINPOS_GetWinOffset( hwndFrom, hwndTo, &mirrored );
+ POINT offset;
UINT i;
+ if ((hwndFrom && !IsWindow( hwndFrom )) || (hwndTo && !IsWindow( hwndTo )))
+ {
+ SetLastError( ERROR_INVALID_WINDOW_HANDLE );
+ return 0;
+ }
+
+ offset = WINPOS_GetWinOffset( hwndFrom, hwndTo, &mirrored );
+
for (i = 0; i < count; i++)
{
lppt[i].x += offset.x;
More information about the wine-patches
mailing list