commit add782bc2eee075b5658b484795467a1e106ac5d
Author: Rico Sch��ller <kgbricola@web.de>
Date:   Thu Aug 30 22:39:31 2012 +0200

    winpos

diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index e84824d..2f86807 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -7104,6 +7104,190 @@ todo_wine
     ok(ret, "UnregisterClass(my_window) failed\n");
 }
 
+static void test_MapWindowPoints(void)
+{
+    BOOL ret;
+    POINT p;
+    HWND wnd, dwnd;
+    INT n;
+    DWORD err;
+
+    /* create test window */
+    wnd = CreateWindow("static", "test", 100, 200, 150, 150, 0, NULL, NULL, NULL, NULL);
+    ok(wnd != NULL, "Failed %p\n", wnd);
+    dwnd = CreateWindow("static", "test", 200, 300, 150, 150, 0, NULL, NULL, NULL, NULL);
+    DestroyWindow(dwnd);
+    ok(dwnd != NULL, "Failed %p\n", dwnd);
+
+    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);
+    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);
+    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);
+    n = MapWindowPoints(wnd, 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(NULL, 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, 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);
+
+    /*
+     * These crash on xp:
+     * MapWindowPoints(NULL, NULL, NULL, 1);
+     * MapWindowPoints(wnd, NULL, NULL, 1);
+     * ClientToScreen(wnd, NULL);
+     * MapWindowPoints(NULL, wnd, NULL, 1);
+     * ScreenToClient(wnd, NULL);
+     * MapWindowPoints(wnd, wnd, NULL, 1);
+     */
+
+    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;
+    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 = 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;
+    n = MapWindowPoints(NULL, 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;
+    ret = ScreenToClient(wnd, &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 == 0xdeadbeef, "Got %x, expected %x\n", err, 0xdeadbeef);
+
+    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;
+    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;
+    n = MapWindowPoints(wnd, 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;
+    ret = ClientToScreen(wnd, &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 == 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;
+    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;
+    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(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(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(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);
+
+    DestroyWindow(wnd);
+}
+
 START_TEST(win)
 {
     HMODULE user32 = GetModuleHandleA( "user32.dll" );
@@ -7213,6 +7397,8 @@ START_TEST(win)
     test_handles( hwndMain );
     test_winregion();
 
+    test_MapWindowPoints();
+
     /* add the tests above this line */
     if (hhook) UnhookWindowsHookEx(hhook);
 
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index 5a2f1f2..2251109 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -240,8 +240,12 @@ BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect )
  */
 BOOL WINAPI ClientToScreen( HWND hwnd, LPPOINT lppnt )
 {
-    MapWindowPoints( hwnd, 0, lppnt, 1 );
-    return TRUE;
+    if (!hwnd)
+    {
+        SetLastError( ERROR_INVALID_WINDOW_HANDLE );
+        return FALSE;
+    }
+    return MapWindowPoints( hwnd, 0, lppnt, 1 ) != 0;
 }
 
 
@@ -250,8 +254,12 @@ BOOL WINAPI ClientToScreen( HWND hwnd, LPPOINT lppnt )
  */
 BOOL WINAPI ScreenToClient( HWND hwnd, LPPOINT lppnt )
 {
-    MapWindowPoints( 0, hwnd, lppnt, 1 );
-    return TRUE;
+    if (!hwnd)
+    {
+        SetLastError( ERROR_INVALID_WINDOW_HANDLE );
+        return FALSE;
+    }
+    return MapWindowPoints( 0, hwnd, lppnt, 1 ) != 0;
 }
 
 
@@ -557,9 +565,17 @@ void map_window_region( HWND from, HWND to, HRGN hrgn )
 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;
