mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Added patch to fix possible leak of explorer.exe processes and implement proper desktop refcounting.
This commit is contained in:
parent
78ed3fc7e9
commit
78db8b7950
@ -34,6 +34,11 @@ Wine. All those differences are also documented on the
|
||||
Included bug fixes and improvements
|
||||
-----------------------------------
|
||||
|
||||
**Bug fixes and features included in the next upcoming release [1]:**
|
||||
|
||||
* Fix possible leak of explorer.exe processes and implement proper desktop refcounting
|
||||
|
||||
|
||||
**Bug fixes and features in Wine Staging 1.8-rc2 [270]:**
|
||||
|
||||
*Note: The following list only contains features and bug fixes which are not
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 686c258580f515c706074970599fb5a081bdf06a Mon Sep 17 00:00:00 2001
|
||||
From ffd7b942761e5010bdc234f10e5e9721c8d8159b Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 6 Jun 2015 01:21:05 +0200
|
||||
Subject: server: Return correct error codes for NtWriteFile when pipes are
|
||||
@ -39,10 +39,10 @@ index 42d1fae..3bb2905 100644
|
||||
}
|
||||
}
|
||||
diff --git a/server/named_pipe.c b/server/named_pipe.c
|
||||
index 4bdb4d7..c9c08e5 100644
|
||||
index 37f97ed..28816a2 100644
|
||||
--- a/server/named_pipe.c
|
||||
+++ b/server/named_pipe.c
|
||||
@@ -144,6 +144,7 @@ static const struct object_ops named_pipe_ops =
|
||||
@@ -145,6 +145,7 @@ static const struct object_ops named_pipe_ops =
|
||||
/* server end functions */
|
||||
static void pipe_server_dump( struct object *obj, int verbose );
|
||||
static struct fd *pipe_server_get_fd( struct object *obj );
|
||||
@ -50,16 +50,16 @@ index 4bdb4d7..c9c08e5 100644
|
||||
static void pipe_server_destroy( struct object *obj);
|
||||
static obj_handle_t pipe_server_flush( struct fd *fd, const async_data_t *async, int blocking );
|
||||
static enum server_fd_type pipe_server_get_fd_type( struct fd *fd );
|
||||
@@ -166,7 +167,7 @@ static const struct object_ops pipe_server_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
@@ -168,7 +169,7 @@ static const struct object_ops pipe_server_ops =
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
no_alloc_handle, /* alloc_handle */
|
||||
- fd_close_handle, /* close_handle */
|
||||
+ pipe_server_close_handle, /* close_handle */
|
||||
pipe_server_destroy /* destroy */
|
||||
};
|
||||
|
||||
@@ -188,6 +189,7 @@ static const struct fd_ops pipe_server_fd_ops =
|
||||
@@ -190,6 +191,7 @@ static const struct fd_ops pipe_server_fd_ops =
|
||||
static void pipe_client_dump( struct object *obj, int verbose );
|
||||
static int pipe_client_signaled( struct object *obj, struct wait_queue_entry *entry );
|
||||
static struct fd *pipe_client_get_fd( struct object *obj );
|
||||
@ -67,16 +67,16 @@ index 4bdb4d7..c9c08e5 100644
|
||||
static void pipe_client_destroy( struct object *obj );
|
||||
static obj_handle_t pipe_client_flush( struct fd *fd, const async_data_t *async, int blocking );
|
||||
static enum server_fd_type pipe_client_get_fd_type( struct fd *fd );
|
||||
@@ -208,7 +210,7 @@ static const struct object_ops pipe_client_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
@@ -211,7 +213,7 @@ static const struct object_ops pipe_client_ops =
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
no_alloc_handle, /* alloc_handle */
|
||||
- fd_close_handle, /* close_handle */
|
||||
+ pipe_client_close_handle, /* close_handle */
|
||||
pipe_client_destroy /* destroy */
|
||||
};
|
||||
|
||||
@@ -272,6 +274,8 @@ static const struct fd_ops named_pipe_device_fd_ops =
|
||||
@@ -276,6 +278,8 @@ static const struct fd_ops named_pipe_device_fd_ops =
|
||||
default_fd_cancel_async /* cancel_async */
|
||||
};
|
||||
|
||||
@ -85,7 +85,7 @@ index 4bdb4d7..c9c08e5 100644
|
||||
static void named_pipe_dump( struct object *obj, int verbose )
|
||||
{
|
||||
struct named_pipe *pipe = (struct named_pipe *) obj;
|
||||
@@ -386,6 +390,23 @@ static void do_disconnect( struct pipe_server *server )
|
||||
@@ -390,6 +394,23 @@ static void do_disconnect( struct pipe_server *server )
|
||||
server->fd = NULL;
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ index 4bdb4d7..c9c08e5 100644
|
||||
static void pipe_server_destroy( struct object *obj)
|
||||
{
|
||||
struct pipe_server *server = (struct pipe_server *)obj;
|
||||
@@ -412,6 +433,24 @@ static void pipe_server_destroy( struct object *obj)
|
||||
@@ -416,6 +437,24 @@ static void pipe_server_destroy( struct object *obj)
|
||||
release_object( server->pipe );
|
||||
}
|
||||
|
||||
@ -135,7 +135,7 @@ index 4bdb4d7..c9c08e5 100644
|
||||
{
|
||||
struct pipe_client *client = (struct pipe_client *)obj;
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index d0a949f..91ab8cc 100644
|
||||
index 6b2030b..390c09a 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -2389,6 +2389,7 @@ enum message_type
|
||||
|
@ -4,4 +4,5 @@ Fixes: Improve ReadDataAvailable handling in FilePipeLocalInformation class
|
||||
Fixes: Set NamedPipeState to FILE_PIPE_CLOSING_STATE on broken pipe in NtQueryInformationFile
|
||||
FIxes: Return proper status codes when NtReadFile/NtWriteFile is called on closed (but not disconnected) pipe
|
||||
Depends: rpcrt4-Pipe_Transport
|
||||
Depends: server-Desktop_Refcount
|
||||
Category: stable
|
||||
|
@ -236,6 +236,7 @@ patch_enable_all ()
|
||||
enable_secur32_ANSI_NTLM_Credentials="$1"
|
||||
enable_server_ClipCursor="$1"
|
||||
enable_server_CreateProcess_ACLs="$1"
|
||||
enable_server_Desktop_Refcount="$1"
|
||||
enable_server_FileEndOfFileInformation="$1"
|
||||
enable_server_File_Permissions="$1"
|
||||
enable_server_Inherited_ACLs="$1"
|
||||
@ -818,6 +819,9 @@ patch_enable ()
|
||||
server-CreateProcess_ACLs)
|
||||
enable_server_CreateProcess_ACLs="$2"
|
||||
;;
|
||||
server-Desktop_Refcount)
|
||||
enable_server_Desktop_Refcount="$2"
|
||||
;;
|
||||
server-FileEndOfFileInformation)
|
||||
enable_server_FileEndOfFileInformation="$2"
|
||||
;;
|
||||
@ -1755,6 +1759,13 @@ if test "$enable_category_stable" -eq 1; then
|
||||
enable_ws2_32_WriteWatches=1
|
||||
fi
|
||||
|
||||
if test "$enable_ws2_32_TransmitFile" -eq 1; then
|
||||
if test "$enable_server_Desktop_Refcount" -gt 1; then
|
||||
abort "Patchset server-Desktop_Refcount disabled, but ws2_32-TransmitFile depends on that."
|
||||
fi
|
||||
enable_server_Desktop_Refcount=1
|
||||
fi
|
||||
|
||||
if test "$enable_wined3d_CSMT_Main" -eq 1; then
|
||||
if test "$enable_wined3d_CSMT_Helper" -gt 1; then
|
||||
abort "Patchset wined3d-CSMT_Helper disabled, but wined3d-CSMT_Main depends on that."
|
||||
@ -1961,7 +1972,11 @@ if test "$enable_kernel32_Named_Pipe" -eq 1; then
|
||||
if test "$enable_rpcrt4_Pipe_Transport" -gt 1; then
|
||||
abort "Patchset rpcrt4-Pipe_Transport disabled, but kernel32-Named_Pipe depends on that."
|
||||
fi
|
||||
if test "$enable_server_Desktop_Refcount" -gt 1; then
|
||||
abort "Patchset server-Desktop_Refcount disabled, but kernel32-Named_Pipe depends on that."
|
||||
fi
|
||||
enable_rpcrt4_Pipe_Transport=1
|
||||
enable_server_Desktop_Refcount=1
|
||||
fi
|
||||
|
||||
if test "$enable_kernel32_CopyFileEx" -eq 1; then
|
||||
@ -3518,10 +3533,29 @@ if test "$enable_rpcrt4_Pipe_Transport" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset server-Desktop_Refcount
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * programs/explorer/desktop.c, server/async.c, server/atom.c, server/change.c, server/clipboard.c, server/completion.c,
|
||||
# | server/console.c, server/debugger.c, server/device.c, server/directory.c, server/event.c, server/fd.c, server/file.c,
|
||||
# | server/handle.c, server/handle.h, server/hook.c, server/mailslot.c, server/mapping.c, server/mutex.c,
|
||||
# | server/named_pipe.c, server/object.c, server/object.h, server/process.c, server/queue.c, server/registry.c,
|
||||
# | server/request.c, server/semaphore.c, server/serial.c, server/signal.c, server/snapshot.c, server/sock.c,
|
||||
# | server/symlink.c, server/thread.c, server/timer.c, server/token.c, server/winstation.c
|
||||
# |
|
||||
if test "$enable_server_Desktop_Refcount" -eq 1; then
|
||||
patch_apply server-Desktop_Refcount/0001-server-Introduce-a-new-alloc_handle-object-callback..patch
|
||||
patch_apply server-Desktop_Refcount/0002-server-Track-desktop-handle-count-more-correctly.patch
|
||||
(
|
||||
echo '+ { "Sebastian Lackner", "server: Introduce a new alloc_handle object callback.", 2 },';
|
||||
echo '+ { "Sebastian Lackner", "server: Track desktop handle count more correctly.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset kernel32-Named_Pipe
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * rpcrt4-Pipe_Transport
|
||||
# | * rpcrt4-Pipe_Transport, server-Desktop_Refcount
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#16550] Fix for ConnectNamedPort return value in overlapped mode
|
||||
@ -4438,7 +4472,7 @@ fi
|
||||
# Patchset ntdll-WriteWatches
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * rpcrt4-Pipe_Transport, kernel32-Named_Pipe, ws2_32-WriteWatches
|
||||
# | * rpcrt4-Pipe_Transport, server-Desktop_Refcount, kernel32-Named_Pipe, ws2_32-WriteWatches
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/kernel32/tests/virtual.c, dlls/ntdll/file.c
|
||||
@ -4937,7 +4971,7 @@ fi
|
||||
# Patchset server-Pipe_ObjectName
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * rpcrt4-Pipe_Transport, kernel32-Named_Pipe
|
||||
# | * rpcrt4-Pipe_Transport, server-Desktop_Refcount, kernel32-Named_Pipe
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * server/named_pipe.c, server/object.c, server/object.h
|
||||
@ -6625,6 +6659,9 @@ fi
|
||||
|
||||
# Patchset ws2_32-TransmitFile
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * server-Desktop_Refcount
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/ws2_32/socket.c, dlls/ws2_32/tests/sock.c, include/winsock.h, server/protocol.def, server/sock.c
|
||||
# |
|
||||
|
@ -0,0 +1,686 @@
|
||||
From a04ff4bba9832fd787972911fb391558f129870c Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Fri, 4 Dec 2015 10:36:47 +0100
|
||||
Subject: server: Introduce a new alloc_handle object callback. (v2)
|
||||
|
||||
Signed-off-by: Sebastian Lackner <sebastian@fds-team.de>
|
||||
---
|
||||
server/async.c | 2 ++
|
||||
server/atom.c | 1 +
|
||||
server/change.c | 1 +
|
||||
server/clipboard.c | 1 +
|
||||
server/completion.c | 1 +
|
||||
server/console.c | 3 +++
|
||||
server/debugger.c | 2 ++
|
||||
server/device.c | 4 ++++
|
||||
server/directory.c | 2 ++
|
||||
server/event.c | 2 ++
|
||||
server/fd.c | 4 ++++
|
||||
server/file.c | 1 +
|
||||
server/handle.c | 13 +++++++++++--
|
||||
server/hook.c | 1 +
|
||||
server/mailslot.c | 3 +++
|
||||
server/mapping.c | 1 +
|
||||
server/mutex.c | 1 +
|
||||
server/named_pipe.c | 4 ++++
|
||||
server/object.c | 4 ++++
|
||||
server/object.h | 5 ++++-
|
||||
server/process.c | 3 +++
|
||||
server/queue.c | 2 ++
|
||||
server/registry.c | 1 +
|
||||
server/request.c | 1 +
|
||||
server/semaphore.c | 1 +
|
||||
server/serial.c | 1 +
|
||||
server/signal.c | 1 +
|
||||
server/snapshot.c | 1 +
|
||||
server/sock.c | 2 ++
|
||||
server/symlink.c | 1 +
|
||||
server/thread.c | 2 ++
|
||||
server/timer.c | 1 +
|
||||
server/token.c | 1 +
|
||||
server/winstation.c | 2 ++
|
||||
34 files changed, 73 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/server/async.c b/server/async.c
|
||||
index d2da976..b00d2cc 100644
|
||||
--- a/server/async.c
|
||||
+++ b/server/async.c
|
||||
@@ -66,6 +66,7 @@ static const struct object_ops async_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
async_destroy /* destroy */
|
||||
};
|
||||
@@ -99,6 +100,7 @@ static const struct object_ops async_queue_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
async_queue_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/atom.c b/server/atom.c
|
||||
index 0ed4ed5..1f694bc 100644
|
||||
--- a/server/atom.c
|
||||
+++ b/server/atom.c
|
||||
@@ -88,6 +88,7 @@ static const struct object_ops atom_table_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
atom_table_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/change.c b/server/change.c
|
||||
index 59d1819..4f36179 100644
|
||||
--- a/server/change.c
|
||||
+++ b/server/change.c
|
||||
@@ -167,6 +167,7 @@ static const struct object_ops dir_ops =
|
||||
dir_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
fd_close_handle, /* close_handle */
|
||||
dir_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/clipboard.c b/server/clipboard.c
|
||||
index 2f56c72..1f988bc 100644
|
||||
--- a/server/clipboard.c
|
||||
+++ b/server/clipboard.c
|
||||
@@ -66,6 +66,7 @@ static const struct object_ops clipboard_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
no_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/completion.c b/server/completion.c
|
||||
index 77c72cc..97d2102 100644
|
||||
--- a/server/completion.c
|
||||
+++ b/server/completion.c
|
||||
@@ -73,6 +73,7 @@ static const struct object_ops completion_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
completion_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/console.c b/server/console.c
|
||||
index a57b2fe..264b45f 100644
|
||||
--- a/server/console.c
|
||||
+++ b/server/console.c
|
||||
@@ -85,6 +85,7 @@ static const struct object_ops console_input_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
console_input_destroy /* destroy */
|
||||
};
|
||||
@@ -117,6 +118,7 @@ static const struct object_ops console_input_events_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
console_input_events_destroy /* destroy */
|
||||
};
|
||||
@@ -169,6 +171,7 @@ static const struct object_ops screen_buffer_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
screen_buffer_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/debugger.c b/server/debugger.c
|
||||
index 374f2ad..5e9e6bf 100644
|
||||
--- a/server/debugger.c
|
||||
+++ b/server/debugger.c
|
||||
@@ -82,6 +82,7 @@ static const struct object_ops debug_event_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
debug_event_destroy /* destroy */
|
||||
};
|
||||
@@ -106,6 +107,7 @@ static const struct object_ops debug_ctx_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
debug_ctx_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/device.c b/server/device.c
|
||||
index fb91c02..e207ba8 100644
|
||||
--- a/server/device.c
|
||||
+++ b/server/device.c
|
||||
@@ -79,6 +79,7 @@ static const struct object_ops irp_call_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
irp_call_destroy /* destroy */
|
||||
};
|
||||
@@ -113,6 +114,7 @@ static const struct object_ops device_manager_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
device_manager_destroy /* destroy */
|
||||
};
|
||||
@@ -152,6 +154,7 @@ static const struct object_ops device_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
device_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
device_destroy /* destroy */
|
||||
};
|
||||
@@ -198,6 +201,7 @@ static const struct object_ops device_file_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
device_file_close_handle, /* close_handle */
|
||||
device_file_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/directory.c b/server/directory.c
|
||||
index e0cf75e..da98fb0 100644
|
||||
--- a/server/directory.c
|
||||
+++ b/server/directory.c
|
||||
@@ -65,6 +65,7 @@ static const struct object_ops object_type_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
no_destroy /* destroy */
|
||||
};
|
||||
@@ -98,6 +99,7 @@ static const struct object_ops directory_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
directory_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
directory_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/event.c b/server/event.c
|
||||
index 4d3c562..9c09694 100644
|
||||
--- a/server/event.c
|
||||
+++ b/server/event.c
|
||||
@@ -66,6 +66,7 @@ static const struct object_ops event_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
no_destroy /* destroy */
|
||||
};
|
||||
@@ -97,6 +98,7 @@ static const struct object_ops keyed_event_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
no_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index e3fe292..3e6373a 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -210,6 +210,7 @@ static const struct object_ops fd_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
fd_destroy /* destroy */
|
||||
};
|
||||
@@ -247,6 +248,7 @@ static const struct object_ops device_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
device_destroy /* destroy */
|
||||
};
|
||||
@@ -283,6 +285,7 @@ static const struct object_ops inode_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
inode_destroy /* destroy */
|
||||
};
|
||||
@@ -321,6 +324,7 @@ static const struct object_ops file_lock_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
no_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index a07ca16..c9c47a4 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -92,6 +92,7 @@ static const struct object_ops file_ops =
|
||||
file_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
file_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
fd_close_handle, /* close_handle */
|
||||
file_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/handle.c b/server/handle.c
|
||||
index 5043ff7..64db8fc 100644
|
||||
--- a/server/handle.c
|
||||
+++ b/server/handle.c
|
||||
@@ -131,6 +131,7 @@ static const struct object_ops handle_table_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
handle_table_destroy /* destroy */
|
||||
};
|
||||
@@ -229,7 +230,7 @@ static int grow_handle_table( struct handle_table *table )
|
||||
}
|
||||
|
||||
/* allocate the first free entry in the handle table */
|
||||
-static obj_handle_t alloc_entry( struct handle_table *table, void *obj, unsigned int access )
|
||||
+static obj_handle_t alloc_entry( struct handle_table *table, struct object *obj, unsigned int access )
|
||||
{
|
||||
struct handle_entry *entry = table->entries + table->free;
|
||||
int i;
|
||||
@@ -245,6 +246,10 @@ static obj_handle_t alloc_entry( struct handle_table *table, void *obj, unsigned
|
||||
table->free = i + 1;
|
||||
entry->ptr = grab_object_for_handle( obj );
|
||||
entry->access = access;
|
||||
+
|
||||
+ if (table->process)
|
||||
+ obj->ops->alloc_handle( obj, table->process, index_to_handle(i) );
|
||||
+
|
||||
return index_to_handle(i);
|
||||
}
|
||||
|
||||
@@ -369,7 +374,11 @@ struct handle_table *copy_handle_table( struct process *process, struct process
|
||||
for (i = 0; i <= table->last; i++, ptr++)
|
||||
{
|
||||
if (!ptr->ptr) continue;
|
||||
- if (ptr->access & RESERVED_INHERIT) grab_object_for_handle( ptr->ptr );
|
||||
+ if (ptr->access & RESERVED_INHERIT)
|
||||
+ {
|
||||
+ ptr->ptr->ops->alloc_handle( ptr->ptr, process, index_to_handle(i) );
|
||||
+ grab_object_for_handle( ptr->ptr );
|
||||
+ }
|
||||
else ptr->ptr = NULL; /* don't inherit this entry */
|
||||
}
|
||||
}
|
||||
diff --git a/server/hook.c b/server/hook.c
|
||||
index a8e6ab9..c005cae 100644
|
||||
--- a/server/hook.c
|
||||
+++ b/server/hook.c
|
||||
@@ -89,6 +89,7 @@ static const struct object_ops hook_table_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
hook_table_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/mailslot.c b/server/mailslot.c
|
||||
index 97ea3f6..5075a1a 100644
|
||||
--- a/server/mailslot.c
|
||||
+++ b/server/mailslot.c
|
||||
@@ -86,6 +86,7 @@ static const struct object_ops mailslot_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
mailslot_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
fd_close_handle, /* close_handle */
|
||||
mailslot_destroy /* destroy */
|
||||
};
|
||||
@@ -139,6 +140,7 @@ static const struct object_ops mail_writer_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
fd_close_handle, /* close_handle */
|
||||
mail_writer_destroy /* destroy */
|
||||
};
|
||||
@@ -193,6 +195,7 @@ static const struct object_ops mailslot_device_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
mailslot_device_lookup_name, /* lookup_name */
|
||||
mailslot_device_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
fd_close_handle, /* close_handle */
|
||||
mailslot_device_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/mapping.c b/server/mapping.c
|
||||
index 16e7c1c..fd31df2 100644
|
||||
--- a/server/mapping.c
|
||||
+++ b/server/mapping.c
|
||||
@@ -92,6 +92,7 @@ static const struct object_ops mapping_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
fd_close_handle, /* close_handle */
|
||||
mapping_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/mutex.c b/server/mutex.c
|
||||
index 910fbca..6e23770 100644
|
||||
--- a/server/mutex.c
|
||||
+++ b/server/mutex.c
|
||||
@@ -69,6 +69,7 @@ static const struct object_ops mutex_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
mutex_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/named_pipe.c b/server/named_pipe.c
|
||||
index 8d5753a..f48ead9 100644
|
||||
--- a/server/named_pipe.c
|
||||
+++ b/server/named_pipe.c
|
||||
@@ -132,6 +132,7 @@ static const struct object_ops named_pipe_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
named_pipe_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
named_pipe_destroy /* destroy */
|
||||
};
|
||||
@@ -161,6 +162,7 @@ static const struct object_ops pipe_server_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
fd_close_handle, /* close_handle */
|
||||
pipe_server_destroy /* destroy */
|
||||
};
|
||||
@@ -203,6 +205,7 @@ static const struct object_ops pipe_client_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
fd_close_handle, /* close_handle */
|
||||
pipe_client_destroy /* destroy */
|
||||
};
|
||||
@@ -249,6 +252,7 @@ static const struct object_ops named_pipe_device_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
named_pipe_device_lookup_name, /* lookup_name */
|
||||
named_pipe_device_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
fd_close_handle, /* close_handle */
|
||||
named_pipe_device_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/object.c b/server/object.c
|
||||
index 31883bd..3ccaa4c 100644
|
||||
--- a/server/object.c
|
||||
+++ b/server/object.c
|
||||
@@ -548,6 +548,10 @@ struct object *no_open_file( struct object *obj, unsigned int access, unsigned i
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+void no_alloc_handle( struct object *obj, struct process *process, obj_handle_t handle )
|
||||
+{
|
||||
+}
|
||||
+
|
||||
int no_close_handle( struct object *obj, struct process *process, obj_handle_t handle )
|
||||
{
|
||||
return 1; /* ok to close */
|
||||
diff --git a/server/object.h b/server/object.h
|
||||
index b59811f..06ee321 100644
|
||||
--- a/server/object.h
|
||||
+++ b/server/object.h
|
||||
@@ -86,8 +86,10 @@ struct object_ops
|
||||
/* open a file object to access this object */
|
||||
struct object *(*open_file)(struct object *, unsigned int access, unsigned int sharing,
|
||||
unsigned int options);
|
||||
+ /* allocate a handle to this object */
|
||||
+ void (*alloc_handle)(struct object *, struct process *, obj_handle_t);
|
||||
/* close a handle to this object */
|
||||
- int (*close_handle)(struct object *,struct process *,obj_handle_t);
|
||||
+ int (*close_handle)(struct object *, struct process *, obj_handle_t);
|
||||
/* destroy on refcount == 0 */
|
||||
void (*destroy)(struct object *);
|
||||
};
|
||||
@@ -145,6 +147,7 @@ extern int set_sd_defaults_from_token( struct object *obj, const struct security
|
||||
extern struct object *no_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attributes );
|
||||
extern struct object *no_open_file( struct object *obj, unsigned int access, unsigned int sharing,
|
||||
unsigned int options );
|
||||
+extern void no_alloc_handle( struct object *obj, struct process *process, obj_handle_t handle );
|
||||
extern int no_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
|
||||
extern void no_destroy( struct object *obj );
|
||||
#ifdef DEBUG_OBJECTS
|
||||
diff --git a/server/process.c b/server/process.c
|
||||
index e00b429..bc86c24 100644
|
||||
--- a/server/process.c
|
||||
+++ b/server/process.c
|
||||
@@ -82,6 +82,7 @@ static const struct object_ops process_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
process_destroy /* destroy */
|
||||
};
|
||||
@@ -130,6 +131,7 @@ static const struct object_ops startup_info_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
startup_info_destroy /* destroy */
|
||||
};
|
||||
@@ -171,6 +173,7 @@ static const struct object_ops job_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
job_close_handle, /* close_handle */
|
||||
job_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index 3099e12..bdc740d 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -179,6 +179,7 @@ static const struct object_ops msg_queue_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
msg_queue_destroy /* destroy */
|
||||
};
|
||||
@@ -212,6 +213,7 @@ static const struct object_ops thread_input_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
thread_input_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/registry.c b/server/registry.c
|
||||
index a3c1390..2db56c3 100644
|
||||
--- a/server/registry.c
|
||||
+++ b/server/registry.c
|
||||
@@ -167,6 +167,7 @@ static const struct object_ops key_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
key_close_handle, /* close_handle */
|
||||
key_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/request.c b/server/request.c
|
||||
index f78026a..bd01179 100644
|
||||
--- a/server/request.c
|
||||
+++ b/server/request.c
|
||||
@@ -103,6 +103,7 @@ static const struct object_ops master_socket_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
master_socket_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/semaphore.c b/server/semaphore.c
|
||||
index d87325c..aaf2d65 100644
|
||||
--- a/server/semaphore.c
|
||||
+++ b/server/semaphore.c
|
||||
@@ -66,6 +66,7 @@ static const struct object_ops semaphore_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
no_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/serial.c b/server/serial.c
|
||||
index 164a4b1..cc9c3bc 100644
|
||||
--- a/server/serial.c
|
||||
+++ b/server/serial.c
|
||||
@@ -101,6 +101,7 @@ static const struct object_ops serial_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
fd_close_handle, /* close_handle */
|
||||
serial_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/signal.c b/server/signal.c
|
||||
index 5e4fe33..308f494 100644
|
||||
--- a/server/signal.c
|
||||
+++ b/server/signal.c
|
||||
@@ -75,6 +75,7 @@ static const struct object_ops handler_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
handler_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/snapshot.c b/server/snapshot.c
|
||||
index dd00bd1..b827c6f 100644
|
||||
--- a/server/snapshot.c
|
||||
+++ b/server/snapshot.c
|
||||
@@ -69,6 +69,7 @@ static const struct object_ops snapshot_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
snapshot_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/sock.c b/server/sock.c
|
||||
index 1767dea..57d3d93 100644
|
||||
--- a/server/sock.c
|
||||
+++ b/server/sock.c
|
||||
@@ -154,6 +154,7 @@ static const struct object_ops sock_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
fd_close_handle, /* close_handle */
|
||||
sock_destroy /* destroy */
|
||||
};
|
||||
@@ -996,6 +997,7 @@ static const struct object_ops ifchange_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
ifchange_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/symlink.c b/server/symlink.c
|
||||
index 2330fde..1107639 100644
|
||||
--- a/server/symlink.c
|
||||
+++ b/server/symlink.c
|
||||
@@ -68,6 +68,7 @@ static const struct object_ops symlink_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
symlink_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
symlink_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/thread.c b/server/thread.c
|
||||
index bad2231..9407938 100644
|
||||
--- a/server/thread.c
|
||||
+++ b/server/thread.c
|
||||
@@ -118,6 +118,7 @@ static const struct object_ops thread_apc_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
thread_apc_destroy /* destroy */
|
||||
};
|
||||
@@ -147,6 +148,7 @@ static const struct object_ops thread_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
destroy_thread /* destroy */
|
||||
};
|
||||
diff --git a/server/timer.c b/server/timer.c
|
||||
index 9c293f2..9957ee3 100644
|
||||
--- a/server/timer.c
|
||||
+++ b/server/timer.c
|
||||
@@ -73,6 +73,7 @@ static const struct object_ops timer_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
timer_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/token.c b/server/token.c
|
||||
index 42cfb3d..893d58f 100644
|
||||
--- a/server/token.c
|
||||
+++ b/server/token.c
|
||||
@@ -159,6 +159,7 @@ static const struct object_ops token_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
no_close_handle, /* close_handle */
|
||||
token_destroy /* destroy */
|
||||
};
|
||||
diff --git a/server/winstation.c b/server/winstation.c
|
||||
index 5016184..c4e55e3 100644
|
||||
--- a/server/winstation.c
|
||||
+++ b/server/winstation.c
|
||||
@@ -71,6 +71,7 @@ static const struct object_ops winstation_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
winstation_close_handle, /* close_handle */
|
||||
winstation_destroy /* destroy */
|
||||
};
|
||||
@@ -92,6 +93,7 @@ static const struct object_ops desktop_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
+ no_alloc_handle, /* alloc_handle */
|
||||
desktop_close_handle, /* close_handle */
|
||||
desktop_destroy /* destroy */
|
||||
};
|
||||
--
|
||||
2.6.2
|
||||
|
@ -0,0 +1,253 @@
|
||||
From dd59d5fa25b8a20842e565d656c2b0f7833dae6c Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Fri, 4 Dec 2015 01:22:29 +0100
|
||||
Subject: server: Track desktop handle count more correctly.
|
||||
|
||||
Desktop objects should stay valid, as long as there is a handle from a
|
||||
(non-system) process. Counting only process->desktop references is not
|
||||
sufficient in practice, and causes explorer.exe process leaks.
|
||||
|
||||
Signed-off-by: Sebastian Lackner <sebastian@fds-team.de>
|
||||
---
|
||||
programs/explorer/desktop.c | 18 +++++++++-
|
||||
server/handle.c | 3 +-
|
||||
server/handle.h | 2 +-
|
||||
server/process.c | 1 -
|
||||
server/winstation.c | 88 +++++++++++++++++++++++----------------------
|
||||
5 files changed, 65 insertions(+), 47 deletions(-)
|
||||
|
||||
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c
|
||||
index 2b8502b..b59ed4e 100644
|
||||
--- a/programs/explorer/desktop.c
|
||||
+++ b/programs/explorer/desktop.c
|
||||
@@ -37,6 +37,8 @@
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(explorer);
|
||||
|
||||
+extern HANDLE CDECL __wine_make_process_system(void);
|
||||
+
|
||||
#define DESKTOP_CLASS_ATOM ((LPCWSTR)MAKEINTATOM(32769))
|
||||
#define DESKTOP_ALL_ACCESS 0x01ff
|
||||
|
||||
@@ -1024,8 +1026,22 @@ void manage_desktop( WCHAR *arg )
|
||||
/* run the desktop message loop */
|
||||
if (hwnd)
|
||||
{
|
||||
+ HANDLE exit_event = __wine_make_process_system();
|
||||
WINE_TRACE( "desktop message loop starting on hwnd %p\n", hwnd );
|
||||
- while (GetMessageW( &msg, 0, 0, 0 )) DispatchMessageW( &msg );
|
||||
+ while (exit_event != NULL && MsgWaitForMultipleObjectsEx( 1,
|
||||
+ &exit_event, INFINITE, QS_ALLINPUT, 0 ) == WAIT_OBJECT_0 + 1)
|
||||
+ {
|
||||
+ while (PeekMessageW( &msg, NULL, 0, 0, PM_REMOVE ))
|
||||
+ {
|
||||
+ if (msg.message == WM_QUIT)
|
||||
+ {
|
||||
+ exit_event = NULL;
|
||||
+ break;
|
||||
+ }
|
||||
+ TranslateMessage( &msg );
|
||||
+ DispatchMessageW( &msg );
|
||||
+ }
|
||||
+ }
|
||||
WINE_TRACE( "desktop message loop exiting for hwnd %p\n", hwnd );
|
||||
}
|
||||
|
||||
diff --git a/server/handle.c b/server/handle.c
|
||||
index 64db8fc..63dbf4e 100644
|
||||
--- a/server/handle.c
|
||||
+++ b/server/handle.c
|
||||
@@ -487,7 +487,7 @@ obj_handle_t find_inherited_handle( struct process *process, const struct object
|
||||
/* enumerate handles of a given type */
|
||||
/* this is needed for window stations and desktops */
|
||||
obj_handle_t enumerate_handles( struct process *process, const struct object_ops *ops,
|
||||
- unsigned int *index )
|
||||
+ obj_handle_t *index, struct object **obj )
|
||||
{
|
||||
struct handle_table *table = process->handles;
|
||||
unsigned int i;
|
||||
@@ -500,6 +500,7 @@ obj_handle_t enumerate_handles( struct process *process, const struct object_ops
|
||||
if (!entry->ptr) continue;
|
||||
if (entry->ptr->ops != ops) continue;
|
||||
*index = i + 1;
|
||||
+ if (obj) *obj = grab_object( entry->ptr );
|
||||
return index_to_handle(i);
|
||||
}
|
||||
return 0;
|
||||
diff --git a/server/handle.h b/server/handle.h
|
||||
index 821c4ef..583a25a 100644
|
||||
--- a/server/handle.h
|
||||
+++ b/server/handle.h
|
||||
@@ -48,7 +48,7 @@ extern obj_handle_t open_object( const struct namespace *namespace, const struct
|
||||
const struct object_ops *ops, unsigned int access, unsigned int attr );
|
||||
extern obj_handle_t find_inherited_handle( struct process *process, const struct object_ops *ops );
|
||||
extern obj_handle_t enumerate_handles( struct process *process, const struct object_ops *ops,
|
||||
- unsigned int *index );
|
||||
+ unsigned int *index, struct object **obj );
|
||||
extern void close_process_handles( struct process *process );
|
||||
extern struct handle_table *alloc_handle_table( struct process *process, int count );
|
||||
extern struct handle_table *copy_handle_table( struct process *process, struct process *parent );
|
||||
diff --git a/server/process.c b/server/process.c
|
||||
index bc86c24..77771e5 100644
|
||||
--- a/server/process.c
|
||||
+++ b/server/process.c
|
||||
@@ -832,7 +832,6 @@ static void process_killed( struct process *process )
|
||||
|
||||
assert( list_empty( &process->thread_list ));
|
||||
process->end_time = current_time;
|
||||
- if (!process->is_system) close_process_desktop( process );
|
||||
process->winstation = 0;
|
||||
process->desktop = 0;
|
||||
close_process_handles( process );
|
||||
diff --git a/server/winstation.c b/server/winstation.c
|
||||
index c4e55e3..78bd24c 100644
|
||||
--- a/server/winstation.c
|
||||
+++ b/server/winstation.c
|
||||
@@ -51,6 +51,7 @@ static void winstation_destroy( struct object *obj );
|
||||
static unsigned int winstation_map_access( struct object *obj, unsigned int access );
|
||||
static void desktop_dump( struct object *obj, int verbose );
|
||||
static struct object_type *desktop_get_type( struct object *obj );
|
||||
+static void desktop_alloc_handle( struct object *obj, struct process *process, obj_handle_t handle );
|
||||
static int desktop_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
|
||||
static void desktop_destroy( struct object *obj );
|
||||
static unsigned int desktop_map_access( struct object *obj, unsigned int access );
|
||||
@@ -93,7 +94,7 @@ static const struct object_ops desktop_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
- no_alloc_handle, /* alloc_handle */
|
||||
+ desktop_alloc_handle, /* alloc_handle */
|
||||
desktop_close_handle, /* close_handle */
|
||||
desktop_destroy /* destroy */
|
||||
};
|
||||
@@ -261,14 +262,54 @@ static struct object_type *desktop_get_type( struct object *obj )
|
||||
return get_object_type( &str );
|
||||
}
|
||||
|
||||
+static void close_desktop_timeout( void *private )
|
||||
+{
|
||||
+ struct desktop *desktop = private;
|
||||
+
|
||||
+ desktop->close_timeout = NULL;
|
||||
+ unlink_named_object( &desktop->obj ); /* make sure no other process can open it */
|
||||
+ post_desktop_message( desktop, WM_CLOSE, 0, 0 ); /* and signal the owner to quit */
|
||||
+}
|
||||
+
|
||||
+/* remove a user of the desktop and start the close timeout if necessary */
|
||||
+static void remove_desktop_user( struct desktop *desktop )
|
||||
+{
|
||||
+ assert( desktop->users > 0 );
|
||||
+ desktop->users--;
|
||||
+
|
||||
+ if (!desktop->users && get_top_window_owner( desktop ))
|
||||
+ {
|
||||
+ assert( !desktop->close_timeout );
|
||||
+ desktop->close_timeout = add_timeout_user( -TICKS_PER_SEC, close_desktop_timeout, desktop );
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void desktop_alloc_handle( struct object *obj, struct process *process, obj_handle_t handle )
|
||||
+{
|
||||
+ struct desktop *desktop = (struct desktop *)obj;
|
||||
+ if (process->is_system) return;
|
||||
+
|
||||
+ desktop->users++;
|
||||
+ if (desktop->close_timeout)
|
||||
+ {
|
||||
+ remove_timeout_user( desktop->close_timeout );
|
||||
+ desktop->close_timeout = NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int desktop_close_handle( struct object *obj, struct process *process, obj_handle_t handle )
|
||||
{
|
||||
+ struct desktop *desktop = (struct desktop *)obj;
|
||||
struct thread *thread;
|
||||
|
||||
/* check if the handle is currently used by the process or one of its threads */
|
||||
if (process->desktop == handle) return 0;
|
||||
LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry )
|
||||
if (thread->desktop == handle) return 0;
|
||||
+
|
||||
+ if (!process->is_system)
|
||||
+ remove_desktop_user( desktop );
|
||||
+
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -276,6 +317,7 @@ static void desktop_destroy( struct object *obj )
|
||||
{
|
||||
struct desktop *desktop = (struct desktop *)obj;
|
||||
|
||||
+ assert( !desktop->users );
|
||||
free_hotkeys( desktop, 0 );
|
||||
if (desktop->top_window) destroy_window( desktop->top_window );
|
||||
if (desktop->msg_window) destroy_window( desktop->msg_window );
|
||||
@@ -302,40 +344,6 @@ struct desktop *get_thread_desktop( struct thread *thread, unsigned int access )
|
||||
return get_desktop_obj( thread->process, thread->desktop, access );
|
||||
}
|
||||
|
||||
-static void close_desktop_timeout( void *private )
|
||||
-{
|
||||
- struct desktop *desktop = private;
|
||||
-
|
||||
- desktop->close_timeout = NULL;
|
||||
- unlink_named_object( &desktop->obj ); /* make sure no other process can open it */
|
||||
- post_desktop_message( desktop, WM_CLOSE, 0, 0 ); /* and signal the owner to quit */
|
||||
-}
|
||||
-
|
||||
-/* add a user of the desktop and cancel the close timeout */
|
||||
-static void add_desktop_user( struct desktop *desktop )
|
||||
-{
|
||||
- desktop->users++;
|
||||
- if (desktop->close_timeout)
|
||||
- {
|
||||
- remove_timeout_user( desktop->close_timeout );
|
||||
- desktop->close_timeout = NULL;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-/* remove a user of the desktop and start the close timeout if necessary */
|
||||
-static void remove_desktop_user( struct desktop *desktop )
|
||||
-{
|
||||
- assert( desktop->users > 0 );
|
||||
- desktop->users--;
|
||||
-
|
||||
- /* if we have one remaining user, it has to be the manager of the desktop window */
|
||||
- if (desktop->users == 1 && get_top_window_owner( desktop ))
|
||||
- {
|
||||
- assert( !desktop->close_timeout );
|
||||
- desktop->close_timeout = add_timeout_user( -TICKS_PER_SEC, close_desktop_timeout, desktop );
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/* set the process default desktop handle */
|
||||
void set_process_default_desktop( struct process *process, struct desktop *desktop,
|
||||
obj_handle_t handle )
|
||||
@@ -352,12 +360,6 @@ void set_process_default_desktop( struct process *process, struct desktop *deskt
|
||||
LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry )
|
||||
if (!thread->desktop) thread->desktop = handle;
|
||||
|
||||
- if (!process->is_system && desktop != old_desktop)
|
||||
- {
|
||||
- add_desktop_user( desktop );
|
||||
- if (old_desktop) remove_desktop_user( old_desktop );
|
||||
- }
|
||||
-
|
||||
if (old_desktop) release_object( old_desktop );
|
||||
}
|
||||
|
||||
@@ -407,8 +409,8 @@ done:
|
||||
void close_process_desktop( struct process *process )
|
||||
{
|
||||
struct desktop *desktop;
|
||||
-
|
||||
- if (process->desktop && (desktop = get_desktop_obj( process, process->desktop, 0 )))
|
||||
+ unsigned int i = 0;
|
||||
+ while (enumerate_handles( process, &desktop_ops, &i, (struct object **)&desktop ))
|
||||
{
|
||||
remove_desktop_user( desktop );
|
||||
release_object( desktop );
|
||||
--
|
||||
2.6.2
|
||||
|
1
patches/server-Desktop_Refcount/definition
Normal file
1
patches/server-Desktop_Refcount/definition
Normal file
@ -0,0 +1 @@
|
||||
Fixes: Fix possible leak of explorer.exe processes and implement proper desktop refcounting
|
@ -1,4 +1,4 @@
|
||||
From 58723ec84900590ae95a7abd688540d963372993 Mon Sep 17 00:00:00 2001
|
||||
From 361a906c0026d132a08bc292450a098fd2fc072b Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 16 Jan 2014 19:08:30 -0700
|
||||
Subject: ws2_32: Add support for TF_REUSE_SOCKET to TransmitFile.
|
||||
@ -12,10 +12,10 @@ Subject: ws2_32: Add support for TF_REUSE_SOCKET to TransmitFile.
|
||||
5 files changed, 75 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
|
||||
index 7deaeda..258f121 100644
|
||||
index 9cff400..c2dbbf4 100644
|
||||
--- a/dlls/ws2_32/socket.c
|
||||
+++ b/dlls/ws2_32/socket.c
|
||||
@@ -2886,6 +2886,17 @@ static NTSTATUS WS2_transmitfile_base( int fd, struct ws2_transmitfile_async *ws
|
||||
@@ -2888,6 +2888,17 @@ static NTSTATUS WS2_transmitfile_base( int fd, struct ws2_transmitfile_async *ws
|
||||
if (status != STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
@ -33,7 +33,7 @@ index 7deaeda..258f121 100644
|
||||
if (wsa->flags & TF_DISCONNECT)
|
||||
{
|
||||
/* we can't use WS_closesocket because it modifies the last error */
|
||||
@@ -2929,7 +2940,7 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD
|
||||
@@ -2931,7 +2942,7 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD
|
||||
LPOVERLAPPED overlapped, LPTRANSMIT_FILE_BUFFERS buffers,
|
||||
DWORD flags )
|
||||
{
|
||||
@ -43,10 +43,10 @@ index 7deaeda..258f121 100644
|
||||
unsigned int uaddrlen = sizeof(uaddr);
|
||||
struct ws2_transmitfile_async *wsa;
|
||||
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
|
||||
index d5c206c..4e1a432 100644
|
||||
index 41554b4..9462628 100644
|
||||
--- a/dlls/ws2_32/tests/sock.c
|
||||
+++ b/dlls/ws2_32/tests/sock.c
|
||||
@@ -7675,7 +7675,6 @@ static void test_TransmitFile(void)
|
||||
@@ -8049,7 +8049,6 @@ static void test_TransmitFile(void)
|
||||
err, WSAENOTSOCK);
|
||||
|
||||
/* Test TransmitFile with a UDP datagram socket */
|
||||
@ -55,10 +55,10 @@ index d5c206c..4e1a432 100644
|
||||
bret = pTransmitFile(client, NULL, 0, 0, NULL, NULL, 0);
|
||||
err = WSAGetLastError();
|
||||
diff --git a/include/winsock.h b/include/winsock.h
|
||||
index 50237e8..e53aa1e 100644
|
||||
index cf9adf5..2feb224 100644
|
||||
--- a/include/winsock.h
|
||||
+++ b/include/winsock.h
|
||||
@@ -814,6 +814,7 @@ typedef struct WS(WSAData)
|
||||
@@ -816,6 +816,7 @@ typedef struct WS(WSAData)
|
||||
|
||||
/* internal per-socket flags */
|
||||
#ifdef __WINESRC__
|
||||
@ -67,7 +67,7 @@ index 50237e8..e53aa1e 100644
|
||||
#define FD_WINE_NONBLOCKING 0x20000000
|
||||
#define FD_WINE_CONNECTED 0x40000000
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index c313006..5588f6a 100644
|
||||
index 04814c9..8a2d395 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -1263,6 +1263,12 @@ enum server_fd_type
|
||||
@ -84,7 +84,7 @@ index c313006..5588f6a 100644
|
||||
@REQ(set_socket_event)
|
||||
obj_handle_t handle; /* handle to the socket */
|
||||
diff --git a/server/sock.c b/server/sock.c
|
||||
index 1767dea..0f029bf 100644
|
||||
index 57d3d93..37c78b1 100644
|
||||
--- a/server/sock.c
|
||||
+++ b/server/sock.c
|
||||
@@ -86,6 +86,7 @@
|
||||
@ -103,16 +103,16 @@ index 1767dea..0f029bf 100644
|
||||
|
||||
static int sock_get_ntstatus( int err );
|
||||
static int sock_get_error( int err );
|
||||
@@ -154,7 +156,7 @@ static const struct object_ops sock_ops =
|
||||
default_set_sd, /* set_sd */
|
||||
@@ -155,7 +157,7 @@ static const struct object_ops sock_ops =
|
||||
no_lookup_name, /* lookup_name */
|
||||
no_open_file, /* open_file */
|
||||
no_alloc_handle, /* alloc_handle */
|
||||
- fd_close_handle, /* close_handle */
|
||||
+ sock_close_handle, /* close_handle */
|
||||
sock_destroy /* destroy */
|
||||
};
|
||||
|
||||
@@ -626,6 +628,47 @@ static struct fd *sock_get_fd( struct object *obj )
|
||||
@@ -627,6 +629,47 @@ static struct fd *sock_get_fd( struct object *obj )
|
||||
return (struct fd *)grab_object( sock->fd );
|
||||
}
|
||||
|
||||
@ -160,7 +160,7 @@ index 1767dea..0f029bf 100644
|
||||
static void sock_destroy( struct object *obj )
|
||||
{
|
||||
struct sock *sock = (struct sock *)obj;
|
||||
@@ -677,15 +720,8 @@ static struct object *create_socket( int family, int type, int protocol, unsigne
|
||||
@@ -678,15 +721,8 @@ static struct object *create_socket( int family, int type, int protocol, unsigne
|
||||
struct sock *sock;
|
||||
int sockfd;
|
||||
|
||||
@ -177,7 +177,7 @@ index 1767dea..0f029bf 100644
|
||||
if (!(sock = alloc_object( &sock_ops )))
|
||||
{
|
||||
close( sockfd );
|
||||
@@ -1261,6 +1297,17 @@ DECL_HANDLER(accept_into_socket)
|
||||
@@ -1263,6 +1299,17 @@ DECL_HANDLER(accept_into_socket)
|
||||
release_object( sock );
|
||||
}
|
||||
|
||||
@ -196,5 +196,5 @@ index 1767dea..0f029bf 100644
|
||||
DECL_HANDLER(set_socket_event)
|
||||
{
|
||||
--
|
||||
2.6.1
|
||||
2.6.2
|
||||
|
||||
|
@ -1 +1,2 @@
|
||||
# Fixes: [5048] Support for TransmitFile
|
||||
Depends: server-Desktop_Refcount
|
||||
|
@ -8,6 +8,8 @@ wine-staging (1.8~rc3) UNRELEASED; urgency=low
|
||||
upstream).
|
||||
* Removed patch to show windows version when collecting system info in winedbg
|
||||
(accepted upstream).
|
||||
* Added patch to fix possible leak of explorer.exe processes and implement
|
||||
proper desktop refcounting.
|
||||
-- Sebastian Lackner <sebastian@fds-team.de> Tue, 01 Dec 2015 02:35:10 +0100
|
||||
|
||||
wine-staging (1.8~rc2) unstable; urgency=low
|
||||
|
Loading…
Reference in New Issue
Block a user