From: Paul Gofman pgofman@codeweavers.com
--- dlls/kernel32/tests/process.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c index 8e168622c17..88c03066f2c 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c @@ -2933,18 +2933,38 @@ static void test_CompletionPort(void) job = pCreateJobObjectW(NULL, NULL); ok(job != NULL, "CreateJobObject error %lu\n", GetLastError());
- create_process("wait", &pi2); - ret = pAssignProcessToJobObject(job, pi2.hProcess); - ok(ret, "AssignProcessToJobObject error %lu\n", GetLastError()); + port_info.CompletionKey = job; + port_info.CompletionPort = NULL; + ret = pSetInformationJobObject(job, JobObjectAssociateCompletionPortInformation, &port_info, sizeof(port_info)); + todo_wine ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_PARAMETER) /* Before Win8 */, + "got ret %d, error %lu\n", ret, GetLastError());
port = pCreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); ok(port != NULL, "CreateIoCompletionPort error %lu\n", GetLastError());
- port_info.CompletionKey = job; port_info.CompletionPort = port; ret = pSetInformationJobObject(job, JobObjectAssociateCompletionPortInformation, &port_info, sizeof(port_info)); ok(ret, "SetInformationJobObject error %lu\n", GetLastError());
+ ret = pSetInformationJobObject(job, JobObjectAssociateCompletionPortInformation, &port_info, sizeof(port_info)); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got ret %d, error %lu\n", ret, GetLastError()); + + port_info.CompletionKey = NULL; + port_info.CompletionPort = NULL; + ret = pSetInformationJobObject(job, JobObjectAssociateCompletionPortInformation, &port_info, sizeof(port_info)); + todo_wine ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_PARAMETER) /* Before Win8 */, + "got ret %d, error %lu\n", ret, GetLastError()); + + create_process("wait", &pi2); + ret = pAssignProcessToJobObject(job, pi2.hProcess); + ok(ret, "AssignProcessToJobObject error %lu\n", GetLastError()); + + port_info.CompletionKey = job; + port_info.CompletionPort = port; + ret = pSetInformationJobObject(job, JobObjectAssociateCompletionPortInformation, &port_info, sizeof(port_info)); + todo_wine ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_PARAMETER), + "got ret %d, error %lu\n" /* Before Win8 */, ret, GetLastError()); + create_process("wait", &pi);
ret = pAssignProcessToJobObject(job, pi.hProcess);
From: Paul Gofman pgofman@codeweavers.com
--- dlls/kernel32/tests/process.c | 6 +++--- server/process.c | 10 +++++++++- 2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c index 88c03066f2c..7984f3d6fb4 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c @@ -2936,7 +2936,7 @@ static void test_CompletionPort(void) port_info.CompletionKey = job; port_info.CompletionPort = NULL; ret = pSetInformationJobObject(job, JobObjectAssociateCompletionPortInformation, &port_info, sizeof(port_info)); - todo_wine ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_PARAMETER) /* Before Win8 */, + ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_PARAMETER) /* Before Win8 */, "got ret %d, error %lu\n", ret, GetLastError());
port = pCreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); @@ -2952,7 +2952,7 @@ static void test_CompletionPort(void) port_info.CompletionKey = NULL; port_info.CompletionPort = NULL; ret = pSetInformationJobObject(job, JobObjectAssociateCompletionPortInformation, &port_info, sizeof(port_info)); - todo_wine ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_PARAMETER) /* Before Win8 */, + ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_PARAMETER) /* Before Win8 */, "got ret %d, error %lu\n", ret, GetLastError());
create_process("wait", &pi2); @@ -2962,7 +2962,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 || broken(!ret && GetLastError() == ERROR_INVALID_PARAMETER), + ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_PARAMETER), "got ret %d, error %lu\n" /* Before Win8 */, ret, GetLastError());
create_process("wait", &pi); diff --git a/server/process.c b/server/process.c index 139cadd0065..3b9f311e337 100644 --- a/server/process.c +++ b/server/process.c @@ -1947,7 +1947,15 @@ DECL_HANDLER(set_job_completion_port)
if (!job) return;
- if (!job->completion_port) + if (!req->port) + { + if (job->completion_port) + { + release_object( job->completion_port ); + job->completion_port = NULL; + } + } + else if (!job->completion_port) { job->completion_port = get_completion_obj( current->process, req->port, IO_COMPLETION_MODIFY_STATE ); job->completion_key = req->key;
Looks like it is possible starting from Win 8.
This helps Epic Online Services to start (with Dead Island 2).