Andrew Cook : server: Implement job limit flags.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Apr 2 11:09:20 CDT 2015


Module: wine
Branch: master
Commit: ecd41d1de7461b9601e61ee387b24a9610e22b96
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ecd41d1de7461b9601e61ee387b24a9610e22b96

Author: Andrew Cook <ariscop at gmail.com>
Date:   Thu Apr  2 20:40:15 2015 +1100

server: Implement job limit flags.

---

 dlls/kernel32/tests/process.c  |  1 +
 dlls/ntdll/sync.c              | 42 ++++++++++++++++++++++++++++++++++++++++--
 include/wine/server_protocol.h | 19 ++++++++++++++++++-
 include/winnt.h                |  4 ++++
 server/process.c               | 13 +++++++++++++
 server/protocol.def            |  7 +++++++
 server/request.h               |  5 +++++
 server/trace.c                 |  9 +++++++++
 8 files changed, 97 insertions(+), 3 deletions(-)

diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index fd47951..c991108 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -2387,6 +2387,7 @@ static void test_CompletionPort(void)
     port_info.CompletionKey = job;
     port_info.CompletionPort = port;
     ret = pSetInformationJobObject(job, JobObjectAssociateCompletionPortInformation, &port_info, sizeof(port_info));
+    todo_wine
     ok(ret, "SetInformationJobObject error %u\n", GetLastError());
 
     create_process("wait", &pi);
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index ce1a635..fff38c9 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -634,8 +634,46 @@ NTSTATUS WINAPI NtQueryInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS c
  */
 NTSTATUS WINAPI NtSetInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS class, PVOID info, ULONG len )
 {
-    FIXME( "stub: %p %u %p %u\n", handle, class, info, len );
-    return STATUS_SUCCESS;
+    NTSTATUS status = STATUS_SUCCESS;
+    JOBOBJECT_BASIC_LIMIT_INFORMATION *basic_limit;
+    ULONG info_size = sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION);
+    DWORD limit_flags = JOB_OBJECT_BASIC_LIMIT_VALID_FLAGS;
+
+    TRACE( "(%p, %u, %p, %u)\n", handle, class, info, len );
+
+    if (class >= MaxJobObjectInfoClass)
+        return STATUS_INVALID_PARAMETER;
+
+    switch (class)
+    {
+
+    case JobObjectExtendedLimitInformation:
+        info_size = sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION);
+        limit_flags = JOB_OBJECT_EXTENDED_LIMIT_VALID_FLAGS;
+        /* fallthrough */
+    case JobObjectBasicLimitInformation:
+        if (len != info_size)
+            return STATUS_INVALID_PARAMETER;
+
+        basic_limit = info;
+        if (basic_limit->LimitFlags & ~limit_flags)
+            return STATUS_INVALID_PARAMETER;
+
+        SERVER_START_REQ( set_job_limits )
+        {
+            req->handle = wine_server_obj_handle( handle );
+            req->limit_flags = basic_limit->LimitFlags;
+            status = wine_server_call( req );
+        }
+        SERVER_END_REQ;
+        break;
+
+    default:
+        FIXME( "stub: %p %u %p %u\n", handle, class, info, len );
+        return STATUS_NOT_IMPLEMENTED;
+    }
+
+    return status;
 }
 
 /******************************************************************************
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 5a9f3ab..6e113e7 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -5127,6 +5127,20 @@ struct process_in_job_reply
 };
 
 
+
+struct set_job_limits_request
+{
+    struct request_header __header;
+    obj_handle_t handle;
+    unsigned int limit_flags;
+    char __pad_20[4];
+};
+struct set_job_limits_reply
+{
+    struct reply_header __header;
+};
+
+
 enum request
 {
     REQ_new_process,
@@ -5388,6 +5402,7 @@ enum request
     REQ_create_job,
     REQ_assign_job,
     REQ_process_in_job,
+    REQ_set_job_limits,
     REQ_NB_REQUESTS
 };
 
@@ -5654,6 +5669,7 @@ union generic_request
     struct create_job_request create_job_request;
     struct assign_job_request assign_job_request;
     struct process_in_job_request process_in_job_request;
+    struct set_job_limits_request set_job_limits_request;
 };
 union generic_reply
 {
@@ -5918,8 +5934,9 @@ union generic_reply
     struct create_job_reply create_job_reply;
     struct assign_job_reply assign_job_reply;
     struct process_in_job_reply process_in_job_reply;
+    struct set_job_limits_reply set_job_limits_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 463
+#define SERVER_PROTOCOL_VERSION 464
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/include/winnt.h b/include/winnt.h
index 4b06b2c..c2aa50e 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -5610,6 +5610,10 @@ typedef struct _JOBOBJECT_EXTENDED_LIMIT_INFORMATION {
 #define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE          0x00002000
 #define JOB_OBJECT_LIMIT_SUBSET_AFFINITY            0x00004000
 
+#define JOB_OBJECT_LIMIT_VALID_FLAGS                0x0007ffff
+#define JOB_OBJECT_BASIC_LIMIT_VALID_FLAGS          0x000000ff
+#define JOB_OBJECT_EXTENDED_LIMIT_VALID_FLAGS       0x00007fff
+
 typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP
 {
     RelationProcessorCore    = 0,
diff --git a/server/process.c b/server/process.c
index 9534f90..84c6c82 100644
--- a/server/process.c
+++ b/server/process.c
@@ -146,6 +146,7 @@ struct job
     struct object obj;             /* object header */
     struct list process_list;      /* list of all processes */
     int num_processes;             /* count of running processes */
+    unsigned int limit_flags;      /* limit flags */
 };
 
 static const struct object_ops job_ops =
@@ -184,6 +185,7 @@ static struct job *create_job_object( struct directory *root, const struct unico
                                                    SACL_SECURITY_INFORMATION );
             list_init( &job->process_list );
             job->num_processes = 0;
+            job->limit_flags = 0;
         }
     }
     return job;
@@ -1506,3 +1508,14 @@ DECL_HANDLER(process_in_job)
     }
     release_object( process );
 }
+
+/* update limits of the job object */
+DECL_HANDLER(set_job_limits)
+{
+    struct job *job = get_job_obj( current->process, req->handle, JOB_OBJECT_SET_ATTRIBUTES );
+
+    if (!job) return;
+
+    job->limit_flags = req->limit_flags;
+    release_object( job );
+}
diff --git a/server/protocol.def b/server/protocol.def
index b85adca..35de6ff 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3528,3 +3528,10 @@ enum coords_relative
     obj_handle_t job;             /* handle to the job */
     obj_handle_t process;         /* handle to the process */
 @END
+
+
+/* Set limit flags on a job */
+ at REQ(set_job_limits)
+    obj_handle_t handle;          /* handle to the job */
+    unsigned int limit_flags;     /* new limit flags */
+ at END
diff --git a/server/request.h b/server/request.h
index aef316a..d76ddea 100644
--- a/server/request.h
+++ b/server/request.h
@@ -365,6 +365,7 @@ DECL_HANDLER(set_suspend_context);
 DECL_HANDLER(create_job);
 DECL_HANDLER(assign_job);
 DECL_HANDLER(process_in_job);
+DECL_HANDLER(set_job_limits);
 
 #ifdef WANT_REQUEST_HANDLERS
 
@@ -630,6 +631,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
     (req_handler)req_create_job,
     (req_handler)req_assign_job,
     (req_handler)req_process_in_job,
+    (req_handler)req_set_job_limits,
 };
 
 C_ASSERT( sizeof(affinity_t) == 8 );
@@ -2221,6 +2223,9 @@ C_ASSERT( sizeof(struct assign_job_request) == 24 );
 C_ASSERT( FIELD_OFFSET(struct process_in_job_request, job) == 12 );
 C_ASSERT( FIELD_OFFSET(struct process_in_job_request, process) == 16 );
 C_ASSERT( sizeof(struct process_in_job_request) == 24 );
+C_ASSERT( FIELD_OFFSET(struct set_job_limits_request, handle) == 12 );
+C_ASSERT( FIELD_OFFSET(struct set_job_limits_request, limit_flags) == 16 );
+C_ASSERT( sizeof(struct set_job_limits_request) == 24 );
 
 #endif  /* WANT_REQUEST_HANDLERS */
 
diff --git a/server/trace.c b/server/trace.c
index cba15a3..3d8e349 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -4119,6 +4119,12 @@ static void dump_process_in_job_request( const struct process_in_job_request *re
     fprintf( stderr, ", process=%04x", req->process );
 }
 
+static void dump_set_job_limits_request( const struct set_job_limits_request *req )
+{
+    fprintf( stderr, " handle=%04x", req->handle );
+    fprintf( stderr, ", limit_flags=%08x", req->limit_flags );
+}
+
 static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_new_process_request,
     (dump_func)dump_get_new_process_info_request,
@@ -4379,6 +4385,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_create_job_request,
     (dump_func)dump_assign_job_request,
     (dump_func)dump_process_in_job_request,
+    (dump_func)dump_set_job_limits_request,
 };
 
 static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@@ -4641,6 +4648,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_create_job_reply,
     NULL,
     NULL,
+    NULL,
 };
 
 static const char * const req_names[REQ_NB_REQUESTS] = {
@@ -4903,6 +4911,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
     "create_job",
     "assign_job",
     "process_in_job",
+    "set_job_limits",
 };
 
 static const struct




More information about the wine-cvs mailing list