[PATCH] ntdll: Add NtSuspendProcess()/NtResumeProcess() implementation.

Nikolay Sivov nsivov at codeweavers.com
Thu Apr 11 08:25:00 CDT 2019


Signed-off-by: Nikolay Sivov <nsivov at 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 */
+ at REQ(suspend_process)
+    obj_handle_t handle;          /* process handle */
+ at END
+
+
+/* Resume a process */
+ at REQ(resume_process)
+    obj_handle_t handle;          /* process handle */
+ at 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
-- 
2.20.1




More information about the wine-devel mailing list