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