mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Added patch to properly handle multiple registry notifications per key.
This commit is contained in:
parent
19d466a729
commit
dbce23ab3b
@ -34,11 +34,12 @@ Wine. All those differences are also documented on the
|
||||
Included bug fixes and improvements
|
||||
-----------------------------------
|
||||
|
||||
**Bug fixes and features included in the next upcoming release [4]:**
|
||||
**Bug fixes and features included in the next upcoming release [5]:**
|
||||
|
||||
* Add partial implementation of ITfThreadMgrEx_ActivateEx ([Wine Bug #39564](https://bugs.winehq.org/show_bug.cgi?id=39564))
|
||||
* Implement stub for hid.HidP_TranslateUsagesToI8042ScanCodes ([Wine Bug #39447](https://bugs.winehq.org/show_bug.cgi?id=39447))
|
||||
* Implement support for "Purist Mode" (override for all dlls)
|
||||
* Properly handle multiple registry notifications per key
|
||||
* Revert patch to prepare GL resources before calling context_apply_fbo_state ([Wine Bug #39536](https://bugs.winehq.org/show_bug.cgi?id=39536))
|
||||
|
||||
|
||||
|
1
debian/changelog
vendored
1
debian/changelog
vendored
@ -4,6 +4,7 @@ wine-staging (1.7.55) UNRELEASED; urgency=low
|
||||
* Added patch to implement support for "Purist Mode" (override for all dlls).
|
||||
* Added patch for partial implementation of ITfThreadMgrEx_ActivateEx.
|
||||
* Added patch for stub of hid.HidP_TranslateUsagesToI8042ScanCodes.
|
||||
* Added patch to properly handle multiple registry notifications per key.
|
||||
* Remove disabled shell32-Quoted_ShellExecute patchset (bug already fixed and
|
||||
all tests pass).
|
||||
* Remove disabled reg-Cleanup patchset (only cleanup and not actively
|
||||
|
@ -243,6 +243,7 @@ patch_enable_all ()
|
||||
enable_server_PeekMessage="$1"
|
||||
enable_server_Pipe_ObjectName="$1"
|
||||
enable_server_Realtime_Priority="$1"
|
||||
enable_server_Registry_Notifications="$1"
|
||||
enable_server_Shared_Memory="$1"
|
||||
enable_server_Signal_Thread="$1"
|
||||
enable_server_Stored_ACLs="$1"
|
||||
@ -829,6 +830,9 @@ patch_enable ()
|
||||
server-Realtime_Priority)
|
||||
enable_server_Realtime_Priority="$2"
|
||||
;;
|
||||
server-Registry_Notifications)
|
||||
enable_server_Registry_Notifications="$2"
|
||||
;;
|
||||
server-Shared_Memory)
|
||||
enable_server_Shared_Memory="$2"
|
||||
;;
|
||||
@ -4887,6 +4891,20 @@ if test "$enable_server_Realtime_Priority" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset server-Registry_Notifications
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/ntdll/tests/reg.c, server/registry.c
|
||||
# |
|
||||
if test "$enable_server_Registry_Notifications" -eq 1; then
|
||||
patch_apply server-Registry_Notifications/0001-server-Allow-multiple-registry-notifications-for-the.patch
|
||||
patch_apply server-Registry_Notifications/0002-server-Introduce-refcounting-for-registry-notificati.patch
|
||||
(
|
||||
echo '+ { "Sebastian Lackner", "server: Allow multiple registry notifications for the same key.", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "server: Introduce refcounting for registry notifications.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset server-Signal_Thread
|
||||
# |
|
||||
# | Modified files:
|
||||
|
@ -0,0 +1,137 @@
|
||||
From b556ce4de01cf5e98a486aa13c26d5d5f651d33d Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Fri, 13 Nov 2015 22:39:00 +0100
|
||||
Subject: server: Allow multiple registry notifications for the same key.
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/reg.c | 6 +++---
|
||||
server/registry.c | 53 ++++++++++++++++++++++++++------------------------
|
||||
2 files changed, 31 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c
|
||||
index 96f190b..e0a58f2 100644
|
||||
--- a/dlls/ntdll/tests/reg.c
|
||||
+++ b/dlls/ntdll/tests/reg.c
|
||||
@@ -1611,7 +1611,7 @@ static void test_notify(void)
|
||||
ok(status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08x\n", status);
|
||||
|
||||
status = pNtWaitForSingleObject(events[0], FALSE, &timeout);
|
||||
- todo_wine ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %x\n", status);
|
||||
+ ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %x\n", status);
|
||||
status = pNtWaitForSingleObject(events[1], FALSE, &timeout);
|
||||
ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %x\n", status);
|
||||
|
||||
@@ -1624,7 +1624,7 @@ static void test_notify(void)
|
||||
ok(status == STATUS_SUCCESS, "NtDeleteSubkey failed: %x\n", status);
|
||||
|
||||
status = pNtWaitForSingleObject(events[0], FALSE, &timeout);
|
||||
- todo_wine ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %x\n", status);
|
||||
+ ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %x\n", status);
|
||||
status = pNtWaitForSingleObject(events[1], FALSE, &timeout);
|
||||
ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %x\n", status);
|
||||
|
||||
@@ -1638,7 +1638,7 @@ static void test_notify(void)
|
||||
pNtClose(key);
|
||||
|
||||
status = pNtWaitForSingleObject(events[0], FALSE, &timeout);
|
||||
- todo_wine ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %x\n", status);
|
||||
+ ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %x\n", status);
|
||||
status = pNtWaitForSingleObject(events[1], FALSE, &timeout);
|
||||
ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %x\n", status);
|
||||
|
||||
diff --git a/server/registry.c b/server/registry.c
|
||||
index c95e103..ead9749 100644
|
||||
--- a/server/registry.c
|
||||
+++ b/server/registry.c
|
||||
@@ -50,10 +50,16 @@
|
||||
#include "winternl.h"
|
||||
#include "wine/library.h"
|
||||
|
||||
+struct notify_event
|
||||
+{
|
||||
+ struct list entry; /* entry in list of events */
|
||||
+ struct event *event; /* event to set */
|
||||
+};
|
||||
+
|
||||
struct notify
|
||||
{
|
||||
struct list entry; /* entry in list of notifications */
|
||||
- struct event *event; /* event to set when changing this key */
|
||||
+ struct list events; /* list of events to set when changing this key */
|
||||
int subtree; /* true if subtree notification */
|
||||
unsigned int filter; /* which events to notify on */
|
||||
obj_handle_t hkey; /* hkey associated with this notification */
|
||||
@@ -303,12 +309,17 @@ static void key_dump( struct object *obj, int verbose )
|
||||
/* notify waiter and maybe delete the notification */
|
||||
static void do_notification( struct key *key, struct notify *notify, int del )
|
||||
{
|
||||
- if (notify->event)
|
||||
+ void *ptr;
|
||||
+
|
||||
+ while ((ptr = list_head( ¬ify->events )))
|
||||
{
|
||||
- set_event( notify->event );
|
||||
- release_object( notify->event );
|
||||
- notify->event = NULL;
|
||||
+ struct notify_event *notify_event = LIST_ENTRY( ptr, struct notify_event, entry );
|
||||
+ list_remove( ¬ify_event->entry );
|
||||
+ set_event( notify_event->event );
|
||||
+ release_object( notify_event->event );
|
||||
+ free( notify_event );
|
||||
}
|
||||
+
|
||||
if (del)
|
||||
{
|
||||
list_remove( ¬ify->entry );
|
||||
@@ -2260,6 +2271,7 @@ DECL_HANDLER(set_registry_notification)
|
||||
struct key *key;
|
||||
struct event *event;
|
||||
struct notify *notify;
|
||||
+ struct notify_event *notify_event;
|
||||
|
||||
key = get_hkey_obj( req->hkey, KEY_NOTIFY );
|
||||
if (key)
|
||||
@@ -2268,29 +2280,20 @@ DECL_HANDLER(set_registry_notification)
|
||||
if (event)
|
||||
{
|
||||
notify = find_notify( key, current->process, req->hkey );
|
||||
- if (notify)
|
||||
- {
|
||||
- if (notify->event)
|
||||
- release_object( notify->event );
|
||||
- grab_object( event );
|
||||
- notify->event = event;
|
||||
- }
|
||||
- else
|
||||
+ if (!notify && (notify = mem_alloc( sizeof(*notify) )))
|
||||
{
|
||||
- notify = mem_alloc( sizeof(*notify) );
|
||||
- if (notify)
|
||||
- {
|
||||
- grab_object( event );
|
||||
- notify->event = event;
|
||||
- notify->subtree = req->subtree;
|
||||
- notify->filter = req->filter;
|
||||
- notify->hkey = req->hkey;
|
||||
- notify->process = current->process;
|
||||
- list_add_head( &key->notify_list, ¬ify->entry );
|
||||
- }
|
||||
+ list_init( ¬ify->events );
|
||||
+ notify->subtree = req->subtree;
|
||||
+ notify->filter = req->filter;
|
||||
+ notify->hkey = req->hkey;
|
||||
+ notify->process = current->process;
|
||||
+ list_add_head( &key->notify_list, ¬ify->entry );
|
||||
}
|
||||
- if (notify)
|
||||
+ if (notify && (notify_event = mem_alloc( sizeof(*notify_event) )))
|
||||
{
|
||||
+ grab_object(event);
|
||||
+ notify_event->event = event;
|
||||
+ list_add_tail( ¬ify->events, ¬ify_event->entry );
|
||||
reset_event( event );
|
||||
set_error( STATUS_PENDING );
|
||||
}
|
||||
--
|
||||
2.6.2
|
||||
|
@ -0,0 +1,61 @@
|
||||
From aedc8d40763b059b996bdfc95d4974ac2f793b63 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Fri, 13 Nov 2015 23:30:27 +0100
|
||||
Subject: server: Introduce refcounting for registry notifications.
|
||||
|
||||
---
|
||||
server/registry.c | 16 ++++++++++++----
|
||||
1 file changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/server/registry.c b/server/registry.c
|
||||
index ead9749..5c70b8d 100644
|
||||
--- a/server/registry.c
|
||||
+++ b/server/registry.c
|
||||
@@ -58,6 +58,7 @@ struct notify_event
|
||||
|
||||
struct notify
|
||||
{
|
||||
+ unsigned int refcount; /* number of references */
|
||||
struct list entry; /* entry in list of notifications */
|
||||
struct list events; /* list of events to set when changing this key */
|
||||
int subtree; /* true if subtree notification */
|
||||
@@ -311,6 +312,14 @@ static void do_notification( struct key *key, struct notify *notify, int del )
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
+ if (del)
|
||||
+ list_remove( ¬ify->entry );
|
||||
+ else
|
||||
+ {
|
||||
+ assert( notify->refcount < INT_MAX );
|
||||
+ notify->refcount++;
|
||||
+ }
|
||||
+
|
||||
while ((ptr = list_head( ¬ify->events )))
|
||||
{
|
||||
struct notify_event *notify_event = LIST_ENTRY( ptr, struct notify_event, entry );
|
||||
@@ -320,11 +329,9 @@ static void do_notification( struct key *key, struct notify *notify, int del )
|
||||
free( notify_event );
|
||||
}
|
||||
|
||||
- if (del)
|
||||
- {
|
||||
- list_remove( ¬ify->entry );
|
||||
+ assert( notify->refcount );
|
||||
+ if (!--notify->refcount)
|
||||
free( notify );
|
||||
- }
|
||||
}
|
||||
|
||||
static inline struct notify *find_notify( struct key *key, struct process *process, obj_handle_t hkey )
|
||||
@@ -2282,6 +2289,7 @@ DECL_HANDLER(set_registry_notification)
|
||||
notify = find_notify( key, current->process, req->hkey );
|
||||
if (!notify && (notify = mem_alloc( sizeof(*notify) )))
|
||||
{
|
||||
+ notify->refcount = 1;
|
||||
list_init( ¬ify->events );
|
||||
notify->subtree = req->subtree;
|
||||
notify->filter = req->filter;
|
||||
--
|
||||
2.6.2
|
||||
|
1
patches/server-Registry_Notifications/definition
Normal file
1
patches/server-Registry_Notifications/definition
Normal file
@ -0,0 +1 @@
|
||||
Fixes: Properly handle multiple registry notifications per key
|
Loading…
Reference in New Issue
Block a user