Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ntdll/process.c | 24 ++++++++++++++++++++---- include/wine/server_protocol.h | 32 +++++++++++++++++++++++++++++++- server/process.c | 24 ++++++++++++++++++++++++ server/protocol.def | 12 ++++++++++++ server/request.h | 8 ++++++++ server/trace.c | 16 ++++++++++++++++ 6 files changed, 111 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c index 6c6c427372..573a7a771d 100644 --- a/dlls/ntdll/process.c +++ b/dlls/ntdll/process.c @@ -763,8 +763,16 @@ NTSTATUS WINAPI NtOpenProcess(PHANDLE handle, ACCESS_MASK access, */ NTSTATUS WINAPI NtResumeProcess( HANDLE handle ) { - FIXME("stub: %p\n", handle); - return STATUS_NOT_IMPLEMENTED; + NTSTATUS ret; + + SERVER_START_REQ( resume_process ) + { + req->handle = wine_server_obj_handle( handle ); + ret = wine_server_call( req ); + } + SERVER_END_REQ; + + return ret; }
/****************************************************************************** @@ -773,8 +781,16 @@ NTSTATUS WINAPI NtResumeProcess( HANDLE handle ) */ NTSTATUS WINAPI NtSuspendProcess( HANDLE handle ) { - FIXME("stub: %p\n", handle); - return STATUS_NOT_IMPLEMENTED; + NTSTATUS ret; + + SERVER_START_REQ( suspend_process ) + { + req->handle = wine_server_obj_handle( handle ); + ret = wine_server_call( req ); + } + SERVER_END_REQ; + + return ret; }
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 88b933cc14..c3d1bb6a59 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -5742,6 +5742,30 @@ struct terminate_job_reply };
+ +struct suspend_process_request +{ + struct request_header __header; + obj_handle_t handle; +}; +struct suspend_process_reply +{ + struct reply_header __header; +}; + + + +struct resume_process_request +{ + struct request_header __header; + obj_handle_t handle; +}; +struct resume_process_reply +{ + struct reply_header __header; +}; + + enum request { REQ_new_process, @@ -6040,6 +6064,8 @@ enum request REQ_set_job_limits, REQ_set_job_completion_port, REQ_terminate_job, + REQ_suspend_process, + REQ_resume_process, REQ_NB_REQUESTS };
@@ -6343,6 +6369,8 @@ union generic_request struct set_job_limits_request set_job_limits_request; struct set_job_completion_port_request set_job_completion_port_request; struct terminate_job_request terminate_job_request; + struct suspend_process_request suspend_process_request; + struct resume_process_request resume_process_request; }; union generic_reply { @@ -6644,8 +6672,10 @@ union generic_reply struct set_job_limits_reply set_job_limits_reply; struct set_job_completion_port_reply set_job_completion_port_reply; struct terminate_job_reply terminate_job_reply; + struct suspend_process_reply suspend_process_reply; + struct resume_process_reply resume_process_reply; };
-#define SERVER_PROTOCOL_VERSION 578 +#define SERVER_PROTOCOL_VERSION 579
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/process.c b/server/process.c index 473d3b1a27..01555b37a9 100644 --- a/server/process.c +++ b/server/process.c @@ -1705,3 +1705,27 @@ DECL_HANDLER(set_job_completion_port)
release_object( job ); } + +/* suspend a process */ +DECL_HANDLER(suspend_process) +{ + struct process *process; + + if ((process = get_process_from_handle( req->handle, PROCESS_SUSPEND_RESUME ))) + { + suspend_process( process ); + release_object( process ); + } +} + +/* resume a process */ +DECL_HANDLER(resume_process) +{ + struct process *process; + + if ((process = get_process_from_handle( req->handle, PROCESS_SUSPEND_RESUME ))) + { + resume_process( process ); + release_object( process ); + } +} diff --git a/server/protocol.def b/server/protocol.def index b6ad514463..8a3ca0a28f 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3909,3 +3909,15 @@ struct handle_info obj_handle_t handle; /* handle to the job */ int status; /* process exit code */ @END + + +/* Suspend a process */ +@REQ(suspend_process) + obj_handle_t handle; /* process handle */ +@END + + +/* Resume a process */ +@REQ(resume_process) + obj_handle_t handle; /* process handle */ +@END diff --git a/server/request.h b/server/request.h index a3e95137e1..a21252c7a6 100644 --- a/server/request.h +++ b/server/request.h @@ -408,6 +408,8 @@ DECL_HANDLER(process_in_job); DECL_HANDLER(set_job_limits); DECL_HANDLER(set_job_completion_port); DECL_HANDLER(terminate_job); +DECL_HANDLER(suspend_process); +DECL_HANDLER(resume_process);
#ifdef WANT_REQUEST_HANDLERS
@@ -710,6 +712,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_set_job_limits, (req_handler)req_set_job_completion_port, (req_handler)req_terminate_job, + (req_handler)req_suspend_process, + (req_handler)req_resume_process, };
C_ASSERT( sizeof(affinity_t) == 8 ); @@ -2436,6 +2440,10 @@ C_ASSERT( sizeof(struct set_job_completion_port_request) == 32 ); C_ASSERT( FIELD_OFFSET(struct terminate_job_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct terminate_job_request, status) == 16 ); C_ASSERT( sizeof(struct terminate_job_request) == 24 ); +C_ASSERT( FIELD_OFFSET(struct suspend_process_request, handle) == 12 ); +C_ASSERT( sizeof(struct suspend_process_request) == 16 ); +C_ASSERT( FIELD_OFFSET(struct resume_process_request, handle) == 12 ); +C_ASSERT( sizeof(struct resume_process_request) == 16 );
#endif /* WANT_REQUEST_HANDLERS */
diff --git a/server/trace.c b/server/trace.c index d4d0c3eb8d..5c6325a257 100644 --- a/server/trace.c +++ b/server/trace.c @@ -4582,6 +4582,16 @@ static void dump_terminate_job_request( const struct terminate_job_request *req fprintf( stderr, ", status=%d", req->status ); }
+static void dump_suspend_process_request( const struct suspend_process_request *req ) +{ + fprintf( stderr, " handle=%04x", req->handle ); +} + +static void dump_resume_process_request( const struct resume_process_request *req ) +{ + fprintf( stderr, " handle=%04x", req->handle ); +} + static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_new_process_request, (dump_func)dump_exec_process_request, @@ -4879,6 +4889,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_set_job_limits_request, (dump_func)dump_set_job_completion_port_request, (dump_func)dump_terminate_job_request, + (dump_func)dump_suspend_process_request, + (dump_func)dump_resume_process_request, };
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { @@ -5178,6 +5190,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { NULL, NULL, NULL, + NULL, + NULL, };
static const char * const req_names[REQ_NB_REQUESTS] = { @@ -5477,6 +5491,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "set_job_limits", "set_job_completion_port", "terminate_job", + "suspend_process", + "resume_process", };
static const struct