Rebase against upstream changes, partially removed patches for job objects (accepted upstream).

This commit is contained in:
Sebastian Lackner
2015-04-01 22:09:49 +02:00
parent 2aadb491e9
commit c6b84caa19
16 changed files with 608 additions and 992 deletions

View File

@ -0,0 +1,334 @@
From f116e9e73f00bd6c65ebd087a1f7b23ceb9064a9 Mon Sep 17 00:00:00 2001
From: Andrew Cook <ariscop@gmail.com>
Date: Thu, 26 Feb 2015 12:25:23 +1100
Subject: server: Implement remaining wineserver calls for job objects.
---
dlls/kernel32/tests/process.c | 6 +---
dlls/ntdll/sync.c | 76 +++++++++++++++++++++++++++++++++++++++----
include/winnt.h | 4 +++
server/process.c | 59 +++++++++++++++++++++++++++++++++
server/process.h | 1 +
server/protocol.def | 14 ++++++++
6 files changed, 149 insertions(+), 11 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 1add23d..8c9a6ef 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -2269,13 +2269,11 @@ static void test_TerminateJobObject(void)
ok(ret, "TerminateJobObject error %u\n", GetLastError());
dwret = WaitForSingleObject(pi.hProcess, 1000);
- todo_wine
ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
if (dwret == WAIT_TIMEOUT) TerminateProcess(pi.hProcess, 0);
ret = GetExitCodeProcess(pi.hProcess, &dwret);
ok(ret, "GetExitCodeProcess error %u\n", GetLastError());
- todo_wine
ok(dwret == 123 || broken(dwret == 0) /* randomly fails on Win 2000 / XP */,
"wrong exitcode %u\n", dwret);
@@ -2401,6 +2399,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);
@@ -2498,7 +2497,6 @@ static void test_jobInheritance(HANDLE job)
out = FALSE;
ret = pIsProcessInJob(pi.hProcess, job, &out);
ok(ret, "IsProcessInJob error %u\n", GetLastError());
- todo_wine
ok(out, "IsProcessInJob returned out=%u\n", out);
dwret = WaitForSingleObject(pi.hProcess, 1000);
@@ -2526,9 +2524,7 @@ static void test_BreakawayOk(HANDLE job)
snprintf(buffer, MAX_PATH, "\"%s\" tests/process.c %s", selfname, "exit");
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &si, &pi);
- todo_wine
ok(!ret, "CreateProcessA expected failure\n");
- todo_wine
expect_eq_d(ERROR_ACCESS_DENIED, GetLastError());
if (ret)
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index ce1a635..e001e28 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -56,6 +56,7 @@
#include "wine/server.h"
#include "wine/debug.h"
#include "ntdll_misc.h"
+#include "winnt.h"
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
@@ -613,8 +614,19 @@ NTSTATUS WINAPI NtOpenJobObject( PHANDLE handle, ACCESS_MASK access, const OBJEC
*/
NTSTATUS WINAPI NtTerminateJobObject( HANDLE handle, NTSTATUS status )
{
- FIXME( "stub: %p %x\n", handle, status );
- return STATUS_SUCCESS;
+ NTSTATUS ret;
+
+ TRACE( "(%p, %d)\n", handle, status );
+
+ SERVER_START_REQ( terminate_job )
+ {
+ req->handle = wine_server_obj_handle( handle );
+ req->status = status;
+ ret = wine_server_call( req );
+ }
+ SERVER_END_REQ;
+
+ return ret;
}
/******************************************************************************
@@ -624,8 +636,17 @@ NTSTATUS WINAPI NtTerminateJobObject( HANDLE handle, NTSTATUS status )
NTSTATUS WINAPI NtQueryInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS class, PVOID info,
ULONG len, PULONG ret_len )
{
- FIXME( "stub: %p %u %p %u %p\n", handle, class, info, len, ret_len );
- return STATUS_NOT_IMPLEMENTED;
+ TRACE( "%p %u %p %u %p\n", handle, class, info, len, ret_len );
+
+ if (class >= MaxJobObjectInfoClass)
+ return STATUS_INVALID_PARAMETER;
+
+ switch (class)
+ {
+ default:
+ FIXME( "stub: %p %u %p %u %p\n", handle, class, info, len, ret_len );
+ return STATUS_NOT_IMPLEMENTED;
+ }
}
/******************************************************************************
@@ -634,8 +655,51 @@ 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;
+ JOBOBJECT_BASIC_LIMIT_INFORMATION *basic_limit;
+ NTSTATUS status = STATUS_SUCCESS;
+
+ TRACE( "(%p, %u, %p, %u)\n", handle, class, info, len );
+
+ if (class >= MaxJobObjectInfoClass)
+ return STATUS_INVALID_PARAMETER;
+
+ switch (class)
+ {
+
+ case JobObjectExtendedLimitInformation:
+ if (len != sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION))
+ return STATUS_INVALID_PARAMETER;
+
+ basic_limit = &(((JOBOBJECT_EXTENDED_LIMIT_INFORMATION *)info)->BasicLimitInformation);
+ if (basic_limit->LimitFlags & ~JOB_OBJECT_EXTENDED_LIMIT_VALID_FLAGS)
+ return STATUS_INVALID_PARAMETER;
+
+ goto set_basic_limits;
+
+ case JobObjectBasicLimitInformation:
+ if (len != sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION))
+ return STATUS_INVALID_PARAMETER;
+
+ basic_limit = info;
+ if (basic_limit->LimitFlags & ~JOB_OBJECT_BASIC_LIMIT_VALID_FLAGS)
+ return STATUS_INVALID_PARAMETER;
+
+ set_basic_limits:
+ 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/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 f9738c0..a1ab8c7 100644
--- a/server/process.c
+++ b/server/process.c
@@ -65,6 +65,7 @@ static unsigned int process_map_access( struct object *obj, unsigned int access
static struct security_descriptor *process_get_sd( struct object *obj );
static void process_poll_event( struct fd *fd, int event );
static void process_destroy( struct object *obj );
+static void terminate_process( struct process *process, struct thread *skip, int exit_code );
static const struct object_ops process_ops =
{
@@ -147,6 +148,7 @@ struct job
struct object obj; /* object header */
struct list process_list; /* list of all processes */
int num_processes; /* count of running processes */
+ int limit_flags; /* limit flags */
};
static const struct object_ops job_ops =
@@ -185,6 +187,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;
@@ -223,6 +226,7 @@ static void add_job_process( struct job *job, struct process *process )
set_error( STATUS_ACCESS_DENIED );
return;
}
+
process->job = (struct job *)grab_object( job );
list_add_tail( &job->process_list, &process->job_entry );
job->num_processes++;
@@ -239,6 +243,23 @@ static void release_job_process( struct process *process )
job->num_processes--;
}
+static void terminate_job( struct job *job, int exit_code )
+{
+ for (;;) /* restart from the beginning of the list every time */
+ {
+ struct process *process;
+
+ /* find the first process associcated with this job and still running */
+ LIST_FOR_EACH_ENTRY( process, &job->process_list, struct process, job_entry )
+ {
+ if (process->running_threads) break;
+ }
+ if (&process->job_entry == &job->process_list) break; /* no process found */
+ assert( process->job == job );
+ terminate_process( process, NULL, exit_code );
+ }
+}
+
static void job_destroy( struct object *obj )
{
struct job *job = (struct job *)obj;
@@ -1087,6 +1108,14 @@ DECL_HANDLER(new_process)
return;
}
+ if (parent->job && (req->create_flags & CREATE_BREAKAWAY_FROM_JOB) &&
+ !(parent->job->limit_flags & (JOB_OBJECT_LIMIT_BREAKAWAY_OK | JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK)))
+ {
+ set_error( STATUS_ACCESS_DENIED );
+ close( socket_fd );
+ return;
+ }
+
if (!req->info_size) /* create an orphaned process */
{
create_process( socket_fd, NULL, 0 );
@@ -1157,6 +1186,12 @@ DECL_HANDLER(new_process)
&& !(req->create_flags & DEBUG_ONLY_THIS_PROCESS);
process->startup_info = (struct startup_info *)grab_object( info );
+ if (parent->job && !((req->create_flags & CREATE_BREAKAWAY_FROM_JOB) ||
+ (parent->job->limit_flags & JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK)))
+ {
+ add_job_process( parent->job, process );
+ }
+
/* connect to the window station */
connect_process_winstation( process, current );
@@ -1559,3 +1594,27 @@ DECL_HANDLER(process_in_job)
}
release_object( process );
}
+
+/* terminate all processes associated with the job */
+DECL_HANDLER(terminate_job)
+{
+ struct job *job = get_job_obj( current->process, req->handle, JOB_OBJECT_TERMINATE );
+
+ if (job)
+ {
+ terminate_job( job, req->status );
+ release_object( job );
+ }
+}
+
+/* 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)
+ {
+ job->limit_flags = req->limit_flags;
+ release_object( job );
+ }
+}
diff --git a/server/process.h b/server/process.h
index 0cf9514..ae83b0e 100644
--- a/server/process.h
+++ b/server/process.h
@@ -26,6 +26,7 @@
struct atom_table;
struct handle_table;
struct startup_info;
+struct job;
/* process startup state */
enum startup_state { STARTUP_IN_PROGRESS, STARTUP_DONE, STARTUP_ABORTED };
diff --git a/server/protocol.def b/server/protocol.def
index b85adca..0077aa4 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3528,3 +3528,17 @@ enum coords_relative
obj_handle_t job; /* handle to the job */
obj_handle_t process; /* handle to the process */
@END
+
+
+/* Terminate all processes associated with the job */
+@REQ(terminate_job)
+ obj_handle_t handle; /* handle to the job */
+ int status; /* exitcode of the process */
+@END
+
+
+/* Update limits of the job object */
+@REQ(set_job_limits)
+ obj_handle_t handle; /* handle to the job */
+ unsigned int limit_flags; /* limit flags */
+@END
--
2.3.3

View File

@ -1,4 +1,4 @@
From 2dc3e01bbb999ff93918375bdc5071eb9439a011 Mon Sep 17 00:00:00 2001
From 3babb8a2681bd530008b0d268cde0b5788177097 Mon Sep 17 00:00:00 2001
From: Andrew Cook <ariscop@gmail.com>
Date: Thu, 26 Feb 2015 13:02:36 +1100
Subject: server: Implement completion messages for job objects.
@ -10,15 +10,15 @@ coding style by Sebastian Lackner <sebastian@fds-team.de>.
---
dlls/kernel32/tests/process.c | 4 ----
dlls/ntdll/sync.c | 15 +++++++++++++++
server/process.c | 44 +++++++++++++++++++++++++++++++++++++++++++
server/protocol.def | 6 ++++++
4 files changed, 65 insertions(+), 4 deletions(-)
server/process.c | 45 +++++++++++++++++++++++++++++++++++++++++++
server/protocol.def | 8 ++++++++
4 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 6c2f86d..911fad7 100644
index 8c9a6ef..a86e331 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -2375,7 +2375,6 @@ static void test_CompletionPort(void)
@@ -2399,7 +2399,6 @@ static void test_CompletionPort(void)
port_info.CompletionKey = job;
port_info.CompletionPort = port;
ret = pSetInformationJobObject(job, JobObjectAssociateCompletionPortInformation, &port_info, sizeof(port_info));
@ -26,7 +26,7 @@ index 6c2f86d..911fad7 100644
ok(ret, "SetInformationJobObject error %u\n", GetLastError());
create_process("wait", &pi);
@@ -2383,16 +2382,13 @@ static void test_CompletionPort(void)
@@ -2407,16 +2406,13 @@ static void test_CompletionPort(void)
ret = pAssignProcessToJobObject(job, pi.hProcess);
ok(ret, "AssignProcessToJobObject error %u\n", GetLastError());
@ -44,7 +44,7 @@ index 6c2f86d..911fad7 100644
CloseHandle(pi.hProcess);
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index a0b8c15..c754df6 100644
index e001e28..87ff3e0 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -694,6 +694,21 @@ NTSTATUS WINAPI NtSetInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS cla
@ -55,12 +55,12 @@ index a0b8c15..c754df6 100644
+ if (len != sizeof(JOBOBJECT_ASSOCIATE_COMPLETION_PORT))
+ return STATUS_INVALID_PARAMETER;
+
+ SERVER_START_REQ( job_set_completion )
+ SERVER_START_REQ( set_job_completion )
+ {
+ JOBOBJECT_ASSOCIATE_COMPLETION_PORT *port_info = info;
+ req->handle = wine_server_obj_handle( handle );
+ req->port = wine_server_obj_handle( port_info->CompletionPort );
+ req->key = wine_server_client_ptr( port_info->CompletionKey );
+ req->port = wine_server_obj_handle( port_info->CompletionPort );
+ req->key = wine_server_client_ptr( port_info->CompletionKey );
+ status = wine_server_call(req);
+ }
+ SERVER_END_REQ;
@ -70,7 +70,7 @@ index a0b8c15..c754df6 100644
FIXME( "stub: %p %u %p %u\n", handle, class, info, len );
return STATUS_NOT_IMPLEMENTED;
diff --git a/server/process.c b/server/process.c
index 6384203..e02b7af 100644
index a1ab8c7..10193ef 100644
--- a/server/process.c
+++ b/server/process.c
@@ -149,6 +149,9 @@ struct job
@ -103,19 +103,20 @@ index 6384203..e02b7af 100644
+ add_completion(job->completion_port, job->completion_key, pid, STATUS_SUCCESS, msg);
+}
+
static int add_job_process( struct job *job, struct process *process )
static void add_job_process( struct job *job, struct process *process )
{
assert( job->obj.ops == &job_ops );
@@ -233,6 +245,7 @@ static int add_job_process( struct job *job, struct process *process )
if (!process->running_threads)
@@ -230,6 +242,8 @@ static void add_job_process( struct job *job, struct process *process )
process->job = (struct job *)grab_object( job );
list_add_tail( &job->process_list, &process->job_entry );
job->num_processes++;
+
+ add_job_completion( job, JOB_OBJECT_MSG_NEW_PROCESS, get_process_id(process) );
return 1;
}
@@ -247,10 +260,20 @@ static void release_job_process( struct process *process )
assert( job->obj.ops == &job_ops );
/* called when a process has terminated, allow one additional process */
@@ -241,10 +255,20 @@ static void release_job_process( struct process *process )
assert( job->num_processes );
job->num_processes--;
+
@ -135,7 +136,7 @@ index 6384203..e02b7af 100644
for (;;) /* restart from the beginning of the list every time */
{
struct process *process;
@@ -264,6 +287,8 @@ static void terminate_job( struct job *job, int exit_code )
@@ -258,6 +282,8 @@ static void terminate_job( struct job *job, int exit_code )
assert( process->job == job );
terminate_process( process, NULL, exit_code );
}
@ -144,7 +145,7 @@ index 6384203..e02b7af 100644
}
static void job_destroy( struct object *obj )
@@ -273,6 +298,9 @@ static void job_destroy( struct object *obj )
@@ -267,6 +293,9 @@ static void job_destroy( struct object *obj )
assert( !job->num_processes );
assert( list_empty(&job->process_list) );
@ -154,12 +155,12 @@ index 6384203..e02b7af 100644
}
static void job_dump( struct object *obj, int verbose )
@@ -1620,3 +1648,19 @@ DECL_HANDLER(job_set_limits)
@@ -1618,3 +1647,19 @@ DECL_HANDLER(set_job_limits)
release_object( job );
}
}
+
+DECL_HANDLER(job_set_completion)
+DECL_HANDLER(set_job_completion)
+{
+ struct job *job = get_job_obj( current->process, req->handle, JOB_OBJECT_SET_ATTRIBUTES );
+
@ -175,22 +176,21 @@ index 6384203..e02b7af 100644
+ }
+}
diff --git a/server/protocol.def b/server/protocol.def
index 655a9ac..deaaa7b 100644
index 0077aa4..c88c970 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -710,6 +710,12 @@ struct rawinput_device
unsigned int limit_flags;
@@ -3542,3 +3542,11 @@ enum coords_relative
obj_handle_t handle; /* handle to the job */
unsigned int limit_flags; /* limit flags */
@END
+@REQ(job_set_completion)
+ obj_handle_t handle;
+ obj_handle_t port;
+ client_ptr_t key;
+@END
+
/* Retrieve information about a newly started process */
@REQ(get_new_process_info)
obj_handle_t info; /* info handle returned from new_process_request */
+
+/* Set a job completion port/key */
+@REQ(set_job_completion)
+ obj_handle_t handle; /* handle to the job */
+ obj_handle_t port; /* completion port */
+ client_ptr_t key; /* completion key */
+@END
--
2.3.3

View File

@ -1,4 +1,4 @@
From 126ffd832a29072552150c335b4f3c945bce5bbe Mon Sep 17 00:00:00 2001
From 7d8fc002a6adf69f64f635d37b19ddc892283f03 Mon Sep 17 00:00:00 2001
From: Andrew Cook <ariscop@gmail.com>
Date: Thu, 26 Feb 2015 10:51:16 +1100
Subject: server: Properly track handle count of objects.
@ -12,10 +12,10 @@ Subject: server: Properly track handle count of objects.
5 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c
index 47a2614..05f18c0 100644
index f5f75c6..b337444 100644
--- a/dlls/ntdll/om.c
+++ b/dlls/ntdll/om.c
@@ -78,7 +78,7 @@ NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
@@ -77,7 +77,7 @@ NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
memset( p, 0, sizeof(*p) );
p->GrantedAccess = reply->access;
p->PointerCount = reply->ref_count;
@ -128,10 +128,10 @@ index 3817c75..978baeb 100644
struct list wait_queue;
struct object_name *name;
diff --git a/server/protocol.def b/server/protocol.def
index 126c2a7..2c5af48 100644
index c88c970..fdebf29 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3292,6 +3292,7 @@ enum coords_relative
@@ -3269,6 +3269,7 @@ enum coords_relative
@REPLY
unsigned int access; /* granted access mask */
unsigned int ref_count; /* object ref count */
@ -140,5 +140,5 @@ index 126c2a7..2c5af48 100644
VARARG(name,unicode_str); /* object name */
@END
--
2.3.0
2.3.3

View File

@ -1,4 +1,4 @@
From dedf23f9a61a8ef5bcc23a229646d1244e859546 Mon Sep 17 00:00:00 2001
From e70c80c4f78ac6306629d79f86d8c1c5439aaa17 Mon Sep 17 00:00:00 2001
From: Andrew Cook <ariscop@gmail.com>
Date: Thu, 26 Feb 2015 13:10:41 +1100
Subject: server: Implement JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.
@ -9,10 +9,10 @@ Subject: server: Implement JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 911fad7..66e0863 100644
index a86e331..4f51cea 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -2425,7 +2425,6 @@ static void test_KillOnJobClose(void)
@@ -2449,7 +2449,6 @@ static void test_KillOnJobClose(void)
CloseHandle(job);
dwret = WaitForSingleObject(pi.hProcess, 1000);
@ -21,7 +21,7 @@ index 911fad7..66e0863 100644
if (dwret == WAIT_TIMEOUT) TerminateProcess(pi.hProcess, 0);
diff --git a/server/process.c b/server/process.c
index e02b7af..f36548e 100644
index 10193ef..89c029e 100644
--- a/server/process.c
+++ b/server/process.c
@@ -141,6 +141,7 @@ static void job_dump( struct object *obj, int verbose );
@ -41,7 +41,7 @@ index e02b7af..f36548e 100644
job_destroy /* destroy */
};
@@ -291,6 +292,20 @@ static void terminate_job( struct job *job, int exit_code )
@@ -286,6 +287,20 @@ static void terminate_job( struct job *job, int exit_code )
job->terminating = 0;
}

View File

@ -1,4 +1,4 @@
From f55bd1380e177f8fd48003fc3b1efae0c16b4c42 Mon Sep 17 00:00:00 2001
From c86188e18efaf5ece7b4d85ccee4089208e392fa Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 28 Feb 2015 06:09:16 +0100
Subject: kernel32/tests: Add tests for waiting on an job object.
@ -8,10 +8,10 @@ Subject: kernel32/tests: Add tests for waiting on an job object.
1 file changed, 85 insertions(+)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index e20fb92..31a4c1d 100644
index 4f51cea..aaa1a6e 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -2442,6 +2442,90 @@ static void test_KillOnJobClose(void)
@@ -2456,6 +2456,90 @@ static void test_KillOnJobClose(void)
CloseHandle(pi.hThread);
}
@ -102,7 +102,7 @@ index e20fb92..31a4c1d 100644
static HANDLE test_AddSelfToJob(void)
{
HANDLE job;
@@ -2662,6 +2746,7 @@ START_TEST(process)
@@ -2676,6 +2760,7 @@ START_TEST(process)
test_QueryInformationJobObject();
test_CompletionPort();
test_KillOnJobClose();

View File

@ -1,71 +0,0 @@
From b55b5ab63248360985a6ff01e1d2c98867e05a16 Mon Sep 17 00:00:00 2001
From: Andrew Cook <ariscop@gmail.com>
Date: Sat, 28 Feb 2015 13:37:47 +1100
Subject: server: Support NULL job handles in IsProcessInJob.
---
dlls/kernel32/tests/process.c | 10 ++++++++++
server/process.c | 14 +++++++++-----
2 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 66e0863..e20fb92 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -2203,6 +2203,11 @@ static void test_IsProcessInJob(void)
ok(ret, "IsProcessInJob error %u\n", GetLastError());
ok(!out, "IsProcessInJob returned out=%u\n", out);
+ out = TRUE;
+ ret = pIsProcessInJob(pi.hProcess, NULL, &out);
+ ok(ret, "IsProcessInJob error %u\n", GetLastError());
+ ok(!out, "IsProcessInJob returned out=%u\n", out);
+
ret = pAssignProcessToJobObject(job, pi.hProcess);
ok(ret, "AssignProcessToJobObject error %u\n", GetLastError());
@@ -2211,6 +2216,11 @@ static void test_IsProcessInJob(void)
ok(ret, "IsProcessInJob error %u\n", GetLastError());
ok(out, "IsProcessInJob returned out=%u\n", out);
+ out = FALSE;
+ ret = pIsProcessInJob(pi.hProcess, NULL, &out);
+ ok(ret, "IsProcessInJob error %u\n", GetLastError());
+ ok(out, "IsProcessInJob returned out=%u\n", out);
+
TerminateProcess(pi.hProcess, 0);
dwret = WaitForSingleObject(pi.hProcess, 1000);
diff --git a/server/process.c b/server/process.c
index f36548e..db5a3b5 100644
--- a/server/process.c
+++ b/server/process.c
@@ -1627,16 +1627,20 @@ DECL_HANDLER(job_assign)
DECL_HANDLER(process_in_job)
{
struct process *process;
- struct job *job = get_job_obj( current->process, req->job_handle, JOB_OBJECT_ASSIGN_PROCESS );
+ struct job *job;
- if (job)
+ if ((process = get_process_from_handle( req->process_handle, PROCESS_QUERY_INFORMATION )))
{
- if ((process = get_process_from_handle( req->process_handle, PROCESS_QUERY_INFORMATION )))
+ if (!req->job_handle)
+ {
+ set_error( (process->job) ? STATUS_PROCESS_IN_JOB : STATUS_PROCESS_NOT_IN_JOB );
+ }
+ else if ((job = get_job_obj( current->process, req->job_handle, JOB_OBJECT_QUERY )))
{
set_error( (process->job == job) ? STATUS_PROCESS_IN_JOB : STATUS_PROCESS_NOT_IN_JOB );
- release_object( process );
+ release_object( job );
}
- release_object(job);
+ release_object( process );
}
}
--
2.3.3

View File

@ -1,4 +1,4 @@
From 0bd977f5878df0fbe053847aecf9ae0ed7cd110d Mon Sep 17 00:00:00 2001
From 2885683ee26ca39acc9158c804b5287da43585ac Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 28 Feb 2015 06:58:48 +0100
Subject: server: Implement waiting for job objects.
@ -9,10 +9,10 @@ Subject: server: Implement waiting for job objects.
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index e0da270..cf2c1df 100644
index aaa1a6e..c325d32 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -2501,7 +2501,6 @@ static void test_WaitForJobObject(void)
@@ -2482,7 +2482,6 @@ static void test_WaitForJobObject(void)
ok(ret, "TerminateJobObject error %u\n", GetLastError());
dwret = WaitForSingleObject(job, 500);
@ -20,7 +20,7 @@ index e0da270..cf2c1df 100644
ok(dwret == WAIT_OBJECT_0 || broken(dwret == WAIT_TIMEOUT),
"WaitForSingleObject returned %u\n", dwret);
@@ -2510,7 +2509,6 @@ static void test_WaitForJobObject(void)
@@ -2491,7 +2490,6 @@ static void test_WaitForJobObject(void)
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(job);
@ -29,7 +29,7 @@ index e0da270..cf2c1df 100644
return;
}
diff --git a/server/process.c b/server/process.c
index db5a3b5..673ce20 100644
index 89c029e..8c654b4 100644
--- a/server/process.c
+++ b/server/process.c
@@ -151,6 +151,7 @@ struct job
@ -48,7 +48,7 @@ index db5a3b5..673ce20 100644
job->completion_port = NULL;
job->completion_key = 0;
}
@@ -290,6 +292,8 @@ static void terminate_job( struct job *job, int exit_code )
@@ -285,6 +287,8 @@ static void terminate_job( struct job *job, int exit_code )
}
job->terminating = 0;
@ -57,7 +57,7 @@ index db5a3b5..673ce20 100644
}
static int job_close_handle( struct object *obj, struct process *process, obj_handle_t handle )
@@ -327,7 +331,8 @@ static void job_dump( struct object *obj, int verbose )
@@ -322,7 +326,8 @@ static void job_dump( struct object *obj, int verbose )
static int job_signaled( struct object *obj, struct wait_queue_entry *entry )
{
@ -68,5 +68,5 @@ index db5a3b5..673ce20 100644
struct ptid_entry
--
2.3.0
2.3.3

View File

@ -1,4 +1,4 @@
From 5aaa9bb4d39cfd92b4c913aa961854657dbf944d Mon Sep 17 00:00:00 2001
From 55894316559d36c433e8aa8ae6e6957fa651d09a Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Thu, 12 Mar 2015 22:19:50 +0100
Subject: ntdll: Implement NtQueryInformationJobObject stub function.
@ -8,10 +8,10 @@ Subject: ntdll: Implement NtQueryInformationJobObject stub function.
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index ef4a4cb..6f09b83 100644
index 87ff3e0..9a7a6d0 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -638,15 +638,37 @@ NTSTATUS WINAPI NtTerminateJobObject( HANDLE handle, NTSTATUS status )
@@ -636,15 +636,37 @@ NTSTATUS WINAPI NtTerminateJobObject( HANDLE handle, NTSTATUS status )
NTSTATUS WINAPI NtQueryInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS class, PVOID info,
ULONG len, PULONG ret_len )
{
@ -51,5 +51,5 @@ index ef4a4cb..6f09b83 100644
}
}
--
2.3.1
2.3.3