Alexandre Julliard : server: Class and global atoms should not be local to a window station.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Mar 23 13:50:08 CST 2006


Module: wine
Branch: refs/heads/master
Commit: 9873494ced8405113381266b4d99c2a9f3002cb1
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=9873494ced8405113381266b4d99c2a9f3002cb1

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Mar 22 22:13:40 2006 +0100

server: Class and global atoms should not be local to a window station.

---

 dlls/user/tests/winstation.c |   43 +++++++++++++++++++++++++++++++++++++++++-
 server/atom.c                |   27 ++++++++++++++++----------
 server/class.c               |   24 ++++-------------------
 3 files changed, 62 insertions(+), 32 deletions(-)

diff --git a/dlls/user/tests/winstation.c b/dlls/user/tests/winstation.c
index 4bc1941..a595718 100644
--- a/dlls/user/tests/winstation.c
+++ b/dlls/user/tests/winstation.c
@@ -42,12 +42,29 @@ static void print_object( HANDLE obj )
         trace( "obj %p type '%s'\n", obj, buffer );
 }
 
+static void register_class(void)
+{
+    WNDCLASSA cls;
+
+    cls.style = CS_DBLCLKS;
+    cls.lpfnWndProc = DefWindowProcA;
+    cls.cbClsExtra = 0;
+    cls.cbWndExtra = 0;
+    cls.hInstance = GetModuleHandleA(0);
+    cls.hIcon = 0;
+    cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
+    cls.hbrBackground = GetStockObject(WHITE_BRUSH);
+    cls.lpszMenuName = NULL;
+    cls.lpszClassName = "WinStationClass";
+    RegisterClassA(&cls);
+}
+
 static HDESK initial_desktop;
 
 static DWORD CALLBACK thread( LPVOID arg )
 {
     HDESK d1, d2;
-    HWND hwnd = CreateWindowExA(0,"BUTTON","test",WS_POPUP,0,0,100,100,GetDesktopWindow(),0,0,0);
+    HWND hwnd = CreateWindowExA(0,"WinStationClass","test",WS_POPUP,0,0,100,100,GetDesktopWindow(),0,0,0);
     ok( hwnd != 0, "CreateWindow failed\n" );
     d1 = GetThreadDesktop(GetCurrentThreadId());
     trace( "thread %p desktop: %p\n", arg, d1 );
@@ -89,6 +106,8 @@ static void test_handles(void)
     HDESK d1, d2, d3;
     HANDLE hthread;
     DWORD id, flags;
+    ATOM atom;
+    char buffer[20];
 
     /* win stations */
 
@@ -144,6 +163,28 @@ static void test_handles(void)
     w3 = OpenWindowStation("foobar", TRUE, WINSTA_ALL_ACCESS );
     ok( !w3, "open foobar station succeeded\n" );
 
+    w2 = CreateWindowStation("foobar1", 0, WINSTA_ALL_ACCESS, NULL );
+    ok( w2 != 0, "create foobar station failed\n" );
+    w3 = CreateWindowStation("foobar2", 0, WINSTA_ALL_ACCESS, NULL );
+    ok( w3 != 0, "create foobar station failed\n" );
+    ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" );
+    ok( GetHandleInformation( w3, &flags ), "GetHandleInformation failed\n" );
+
+    SetProcessWindowStation( w2 );
+    register_class();
+    atom = GlobalAddAtomA("foo");
+    ok( GlobalGetAtomNameA( atom, buffer, sizeof(buffer) ) == 3, "GlobalGetAtomName failed\n" );
+    ok( !lstrcmpiA( buffer, "foo" ), "bad atom value %s\n", buffer );
+
+    ok( !CloseWindowStation( w2 ), "CloseWindowStation succeeded\n" );
+    ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" );
+
+    SetProcessWindowStation( w3 );
+    ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" );
+    ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" );
+    ok( GlobalGetAtomNameA( atom, buffer, sizeof(buffer) ) == 3, "GlobalGetAtomName failed\n" );
+    ok( !lstrcmpiA( buffer, "foo" ), "bad atom value %s\n", buffer );
+
     /* desktops */
     d1 = GetThreadDesktop(GetCurrentThreadId());
     initial_desktop = d1;
diff --git a/server/atom.c b/server/atom.c
index 18a59db..f48078b 100644
--- a/server/atom.c
+++ b/server/atom.c
@@ -88,6 +88,7 @@ static const struct object_ops atom_tabl
     atom_table_destroy            /* destroy */
 };
 
+static struct atom_table *global_table;
 
 /* create an atom table */
 static struct atom_table *create_table(int entries_count)
@@ -292,12 +293,22 @@ static atom_t find_atom( struct atom_tab
 
 static struct atom_table *get_global_table( struct winstation *winstation, int create )
 {
-    if (!winstation->atom_table)
+    struct atom_table *table = winstation ? winstation->atom_table : global_table;
+    if (!table)
     {
-        if (create) winstation->atom_table = create_table( HASH_SIZE );
+        if (create)
+        {
+            table = create_table( HASH_SIZE );
+            if (winstation) winstation->atom_table = table;
+            else
+            {
+                global_table = table;
+                make_object_static( &global_table->obj );
+            }
+        }
         else set_error( STATUS_OBJECT_NAME_NOT_FOUND );
     }
-    return winstation->atom_table;
+    return table;
 }
 
 static struct atom_table *get_table( obj_handle_t h, int create )
@@ -310,14 +321,8 @@ static struct atom_table *get_table( obj
     }
     else
     {
-        struct winstation *winstation = get_process_winstation( current->process,
-                                                                WINSTA_ACCESSGLOBALATOMS );
-        if (winstation)
-        {
-            table = get_global_table( winstation, 1 );
-            if (table) grab_object( table );
-            release_object( winstation );
-        }
+        table = get_global_table( NULL, 1 );
+        if (table) grab_object( table );
     }
     return table;
 }
diff --git a/server/class.c b/server/class.c
index 0019e25..5fcd267 100644
--- a/server/class.c
+++ b/server/class.c
@@ -142,7 +142,6 @@ void *get_class_client_ptr( struct windo
 DECL_HANDLER(create_class)
 {
     struct window_class *class;
-    struct winstation *winstation;
 
     class = find_class( current->process, req->atom, req->instance );
     if (class && !class->local == !req->local)
@@ -157,18 +156,11 @@ DECL_HANDLER(create_class)
         return;
     }
 
-    if (!(winstation = get_process_winstation( current->process, WINSTA_ACCESSGLOBALATOMS )))
-        return;
+    if (!grab_global_atom( NULL, req->atom )) return;
 
-    if (!grab_global_atom( winstation, req->atom ))
-    {
-        release_object( winstation );
-        return;
-    }
     if (!(class = create_class( current->process, req->extra, req->local )))
     {
-        release_global_atom( winstation, req->atom );
-        release_object( winstation );
+        release_global_atom( NULL, req->atom );
         return;
     }
     class->atom       = req->atom;
@@ -176,7 +168,6 @@ DECL_HANDLER(create_class)
     class->style      = req->style;
     class->win_extra  = req->win_extra;
     class->client_ptr = req->client_ptr;
-    release_object( winstation );
 }
 
 /* destroy a window class */
@@ -239,16 +230,9 @@ DECL_HANDLER(set_class_info)
 
     if (req->flags & SET_CLASS_ATOM)
     {
-        struct winstation *winstation = get_process_winstation( current->process,
-                                                                WINSTA_ACCESSGLOBALATOMS );
-        if (!grab_global_atom( winstation, req->atom ))
-        {
-            release_object( winstation );
-            return;
-        }
-        release_global_atom( winstation, class->atom );
+        if (!grab_global_atom( NULL, req->atom )) return;
+        release_global_atom( NULL, class->atom );
         class->atom = req->atom;
-        release_object( winstation );
     }
     if (req->flags & SET_CLASS_STYLE) class->style = req->style;
     if (req->flags & SET_CLASS_WINEXTRA) class->win_extra = req->win_extra;




More information about the wine-cvs mailing list