[PATCH v4] server: Release of related atoms when destroying a, window class

Ralf Habacker ralf.habacker at freenet.de
Tue Nov 27 07:55:04 CST 2018


From 6f7e95559701c05ac12c88cf9114b777c5517056 Mon Sep 17 00:00:00 2001
From: Ralf Habacker <ralf.habacker at freenet.de>
Date: Mon, 26 Nov 2018 13:14:01 +0100
Subject: [PATCH v4] server: Release of related atoms when destroying a
 window class

According to the Windows API, UnregisterClass() releases the
corresponding atom, which has not been implemented in wine yet.

This commit adds a test to check if the corresponding atom is
released after calling UnregisterClass(). It cannot be submitted
as separate commit because it would fail without the base patch.

The test uses GetClipboardFormatName() to check the class atom
presence, because on native Windows class atoms are located in an
internal atom table and are not accessable by GlobalGetAtomName(),
which the wine implementation provides.

Many thanks to daniel.wendt at linux.com for doing some analysis work.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46180
Signed-off-by: Ralf Habacker <ralf.habacker at freenet.de>
---
 v4: add check for atom presence after registering class as mentioned by Alexandre Julliard
 dlls/user32/tests/class.c | 7 +++++++
 server/class.c            | 2 ++
 2 files changed, 9 insertions(+)

diff --git a/dlls/user32/tests/class.c b/dlls/user32/tests/class.c
index d6910d982d..3940390472 100644
--- a/dlls/user32/tests/class.c
+++ b/dlls/user32/tests/class.c
@@ -115,6 +115,10 @@ static void ClassTest(HINSTANCE hInstance, BOOL global)
         return;
     ok(classatom, "failed to register class\n");
 
+    // check presence of the atom in internal atom table
+    ok(GetClipboardFormatNameW(classatom, str, ARRAY_SIZE(str)) != 0,
+        "RegisterClass() failed - unable to register atom\n");
+
     ok(!RegisterClassW (&cls),
         "RegisterClass of the same class should fail for the second time\n");
 
@@ -230,6 +234,9 @@ static void ClassTest(HINSTANCE hInstance, BOOL global)
     ok(UnregisterClassW(className, hInstance),
         "UnregisterClass() failed\n");
 
+    // check that atom has been removed from the internal atom table
+    ok(GetClipboardFormatNameW(classatom, str, ARRAY_SIZE(str)) == 0,
+        "UnregisterClass() failed - unable to unregister atom\n");
     return;
 }
 
diff --git a/server/class.c b/server/class.c
index 403180db79..b8240bd568 100644
--- a/server/class.c
+++ b/server/class.c
@@ -76,6 +76,8 @@ static struct window_class *create_class( struct process *process, int extra_byt
 
 static void destroy_class( struct window_class *class )
 {
+    release_global_atom( NULL, class->atom );
+    release_global_atom( NULL, class->base_atom );
     list_remove( &class->entry );
     release_object( class->process );
     free( class );
-- 
2.13.7



More information about the wine-devel mailing list