Maarten Lankhorst : user32: Fix enumeration for EnumWindowStations and EnumDesktops.

Alexandre Julliard julliard at winehq.org
Sat Mar 15 05:53:52 CDT 2008


Module: wine
Branch: master
Commit: fd69ababec3b26e76837ed0d3cd82509c619a38e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=fd69ababec3b26e76837ed0d3cd82509c619a38e

Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date:   Wed Mar  5 13:41:41 2008 -0800

user32: Fix enumeration for EnumWindowStations and EnumDesktops.

---

 dlls/user32/tests/winstation.c |  102 ++++++++++++++++++++++++++++++++++++++++
 dlls/user32/winstation.c       |   36 ++++++++++++--
 2 files changed, 132 insertions(+), 6 deletions(-)

diff --git a/dlls/user32/tests/winstation.c b/dlls/user32/tests/winstation.c
index 16a1c93..d69faa4 100644
--- a/dlls/user32/tests/winstation.c
+++ b/dlls/user32/tests/winstation.c
@@ -22,6 +22,7 @@
 #include "winbase.h"
 #include "wingdi.h"
 #include "winuser.h"
+#include "winnls.h"
 
 #define DESKTOP_ALL_ACCESS 0x01ff
 
@@ -248,6 +249,105 @@ static void test_handles(void)
     CloseHandle( hthread );
 }
 
+/* Enumeration tests */
+
+static BOOL CALLBACK window_station_callbackA(LPSTR winsta, LPARAM lp)
+{
+    trace("window_station_callbackA called with argument %s\n", winsta);
+    return lp;
+}
+
+static BOOL CALLBACK open_window_station_callbackA(LPSTR winsta, LPARAM lp)
+{
+    HWINSTA hwinsta;
+
+    trace("open_window_station_callbackA called with argument %s\n", winsta);
+    hwinsta = OpenWindowStationA(winsta, FALSE, WINSTA_ENUMERATE);
+    ok(hwinsta != NULL, "Could not open desktop %s!\n", winsta);
+    if (hwinsta)
+        CloseWindowStation(hwinsta);
+    return lp;
+}
+
+static void test_enumstations(void)
+{
+    BOOL ret;
+
+    if (0) /* Crashes instead */
+    {
+        SetLastError(0xbabefeed);
+        ret = EnumWindowStationsA(NULL, 0);
+        ok(!ret, "EnumWindowStationsA returned succesfully!\n");
+        ok(GetLastError() == ERROR_INVALID_PARAMETER, "LastError is set to %08x\n", GetLastError());
+    }
+
+    SetLastError(0xdeadbeef);
+    ret = EnumWindowStationsA(open_window_station_callbackA, 0x12345);
+    ok(ret == 0x12345, "EnumWindowStationsA returned %x\n", ret);
+    ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = EnumWindowStationsA(window_station_callbackA, 0);
+    ok(!ret, "EnumWindowStationsA returned %x\n", ret);
+    ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
+}
+
+static BOOL CALLBACK desktop_callbackA(LPSTR desktop, LPARAM lp)
+{
+    trace("desktop_callbackA called with argument %s\n", desktop);
+    return lp;
+}
+
+static BOOL CALLBACK open_desktop_callbackA(LPSTR desktop, LPARAM lp)
+{
+    HDESK hdesk;
+    static int once;
+
+    trace("open_desktop_callbackA called with argument %s\n", desktop);
+    /* Only try to open one desktop */
+    if (once++)
+        return lp;
+
+    hdesk = OpenDesktopA(desktop, 0, FALSE, DESKTOP_ENUMERATE);
+    ok(hdesk != NULL, "Could not open desktop %s!\n", desktop);
+    if (hdesk)
+        CloseDesktop(hdesk);
+    return lp;
+}
+
+static void test_enumdesktops(void)
+{
+    BOOL ret;
+
+    if (0)  /* Crashes instead */
+    {
+        SetLastError(0xbabefeed);
+        ret = EnumDesktopsA(GetProcessWindowStation(), NULL, 0);
+        ok(!ret, "EnumDesktopsA returned succesfully!\n");
+        ok(GetLastError() == ERROR_INVALID_PARAMETER, "LastError is set to %08x\n", GetLastError());
+    }
+
+    SetLastError(0xdeadbeef);
+    ret = EnumDesktopsA(NULL, desktop_callbackA, 0x12345);
+    ok(ret == 0x12345, "EnumDesktopsA returned %x\n", ret);
+    ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = EnumDesktopsA(GetProcessWindowStation(), open_desktop_callbackA, 0x12345);
+    ok(ret == 0x12345, "EnumDesktopsA returned %x\n", ret);
+    ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = EnumDesktopsA(INVALID_HANDLE_VALUE, desktop_callbackA, 0x12345);
+    ok(!ret, "EnumDesktopsA returned %x\n", ret);
+    ok(GetLastError() == ERROR_INVALID_HANDLE, "LastError is set to %08x\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = EnumDesktopsA(GetProcessWindowStation(), desktop_callbackA, 0);
+    ok(!ret, "EnumDesktopsA returned %x\n", ret);
+    ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
+}
+
 START_TEST(winstation)
 {
     /* Check whether this platform supports WindowStation calls */
@@ -260,5 +360,7 @@ START_TEST(winstation)
         return;
     }
 
+    test_enumstations();
+    test_enumdesktops();
     test_handles();
 }
diff --git a/dlls/user32/winstation.c b/dlls/user32/winstation.c
index 75cb286..906f2ba 100644
--- a/dlls/user32/winstation.c
+++ b/dlls/user32/winstation.c
@@ -18,6 +18,9 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+
 #include <stdarg.h>
 #include "windef.h"
 #include "winbase.h"
@@ -211,18 +214,27 @@ BOOL WINAPI EnumWindowStationsW( WINSTAENUMPROCW func, LPARAM lparam )
     unsigned int index = 0;
     WCHAR name[MAX_PATH];
     BOOL ret = TRUE;
+    NTSTATUS status;
 
     while (ret)
     {
         SERVER_START_REQ( enum_winstation )
         {
             req->index = index;
-            wine_server_set_reply( req, name, sizeof(name) );
-            ret = !wine_server_call( req );
+            wine_server_set_reply( req, name, sizeof(name) - sizeof(WCHAR) );
+            status = wine_server_call( req );
+            name[wine_server_reply_size(reply)/sizeof(WCHAR)] = 0;
             index = reply->next;
         }
         SERVER_END_REQ;
-        if (ret) ret = func( name, lparam );
+        if (status == STATUS_NO_MORE_ENTRIES)
+            break;
+        if (status)
+        {
+            SetLastError( RtlNtStatusToDosError( status ) );
+            return FALSE;
+        }
+        ret = func( name, lparam );
     }
     return ret;
 }
@@ -401,6 +413,10 @@ BOOL WINAPI EnumDesktopsW( HWINSTA winsta, DESKTOPENUMPROCW func, LPARAM lparam
     unsigned int index = 0;
     WCHAR name[MAX_PATH];
     BOOL ret = TRUE;
+    NTSTATUS status;
+
+    if (!winsta)
+        winsta = GetProcessWindowStation();
 
     while (ret)
     {
@@ -408,12 +424,20 @@ BOOL WINAPI EnumDesktopsW( HWINSTA winsta, DESKTOPENUMPROCW func, LPARAM lparam
         {
             req->winstation = winsta;
             req->index      = index;
-            wine_server_set_reply( req, name, sizeof(name) );
-            ret = !wine_server_call( req );
+            wine_server_set_reply( req, name, sizeof(name) - sizeof(WCHAR) );
+            status = wine_server_call( req );
+            name[wine_server_reply_size(reply)/sizeof(WCHAR)] = 0;
             index = reply->next;
         }
         SERVER_END_REQ;
-        if (ret) ret = func( name, lparam );
+        if (status == STATUS_NO_MORE_ENTRIES)
+            break;
+        if (status)
+        {
+            SetLastError( RtlNtStatusToDosError( status ) );
+            return FALSE;
+        }
+        ret = func(name, lparam);
     }
     return ret;
 }




More information about the wine-cvs mailing list