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