Commit ecd41d1d authored by Andrew Cook's avatar Andrew Cook Committed by Alexandre Julliard

server: Implement job limit flags.

parent e8b9f813
......@@ -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);
......
......@@ -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;
}
/******************************************************************************
......
......@@ -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 */
......@@ -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,
......
......@@ -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 );
}
......@@ -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 */
@REQ(set_job_limits)
obj_handle_t handle; /* handle to the job */
unsigned int limit_flags; /* new limit flags */
@END
......@@ -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 */
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment