ntdll: Avoid inter-process APCs when called for the process itself.
diff --git a/server/protocol.def b/server/protocol.def
index af9db7b..72157fd 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -635,6 +635,7 @@
apc_call_t call; /* call arguments */
@REPLY
obj_handle_t handle; /* APC handle */
+ int self; /* run APC in caller itself? */
@END
diff --git a/server/thread.c b/server/thread.c
index 7f8e229..b4a16cd 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -1172,7 +1172,7 @@
break;
case APC_MAP_VIEW:
process = get_process_from_handle( req->process, PROCESS_VM_OPERATION );
- if (process)
+ if (process && process != current->process)
{
/* duplicate the handle into the target process */
obj_handle_t handle = duplicate_handle( current->process, apc->call.map_view.handle,
@@ -1200,18 +1200,22 @@
}
else if (process)
{
- obj_handle_t handle = alloc_handle( current->process, apc, SYNCHRONIZE, 0 );
- if (handle)
+ reply->self = (process == current->process);
+ if (!reply->self)
{
- if (queue_apc( process, NULL, apc ))
+ obj_handle_t handle = alloc_handle( current->process, apc, SYNCHRONIZE, 0 );
+ if (handle)
{
- apc->caller = (struct thread *)grab_object( current );
- reply->handle = handle;
- }
- else
- {
- close_handle( current->process, handle );
- set_error( STATUS_PROCESS_IS_TERMINATING );
+ if (queue_apc( process, NULL, apc ))
+ {
+ apc->caller = (struct thread *)grab_object( current );
+ reply->handle = handle;
+ }
+ else
+ {
+ close_handle( current->process, handle );
+ set_error( STATUS_PROCESS_IS_TERMINATING );
+ }
}
}
release_object( process );
diff --git a/server/trace.c b/server/trace.c
index a70755c..0c0798e 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -995,7 +995,8 @@
static void dump_queue_apc_reply( const struct queue_apc_reply *req )
{
- fprintf( stderr, " handle=%p", req->handle );
+ fprintf( stderr, " handle=%p,", req->handle );
+ fprintf( stderr, " self=%d", req->self );
}
static void dump_get_apc_request( const struct get_apc_request *req )