From cc9f3cfa0e279fc555ca24927585d443ac5896aa Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Tue, 31 Mar 2015 00:53:08 +0200 Subject: [PATCH] Rebase against upstream changes. --- debian/changelog | 1 + ...tests-Add-test-for-mapping-DACL-to-p.patch | 13 +- .../0001-d3dx9_36-Add-dxtn-support.patch | 8 +- ...-console-handles-for-new-processes-a.patch | 36 +-- patches/patchinstall.sh | 36 +-- ...llow-multiple-subprocess-commands-in.patch | 271 ------------------ ...mplementation-of-job-objects.-rev-2.patch} | 64 ++--- ...2-tests-Add-tests-for-IsProcessInJob.patch | 140 --------- ...completion-messages-for-job-objects.patch} | 26 +- ...sts-Add-tests-for-TerminateJobObject.patch | 80 ------ ...perly-track-handle-count-of-objects.patch} | 0 ...dd-tests-for-QueryInformationJobObje.patch | 141 --------- ...-JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.patch} | 10 +- ...dd-tests-for-job-object-completion-p.patch | 116 -------- ...-NULL-job-handles-in-IsProcessInJob.patch} | 12 +- ...dd-tests-for-JOB_OBJECT_LIMIT_KILL_O.patch | 66 ----- ...d-tests-for-waiting-on-an-job-objec.patch} | 18 +- ...dd-tests-for-JOB_OBJECT_LIMIT_ACTIVE.patch | 122 -------- ...r-Implement-waiting-for-job-objects.patch} | 0 ...dd-tests-for-JOB_OBJECT_LIMIT_BREAKA.patch | 123 -------- ...tQueryInformationJobObject-stub-fun.patch} | 0 ...-tests-Add-tests-for-job-inheritance.patch | 60 ---- ...dd-tests-for-adding-a-terminated-pro.patch | 41 --- ...-storage-of-security-attributes-for-.patch | 22 +- ...e-the-framebuffer-into-wined3d_state.patch | 36 +-- .../wined3d-CSMT_Main/9999-IfDefined.patch | 14 +- ...e-conditions-of-async-WSARecv-operat.patch | 10 +- 27 files changed, 144 insertions(+), 1322 deletions(-) delete mode 100644 patches/server-JobObjects/0001-kernel32-tests-Allow-multiple-subprocess-commands-in.patch rename patches/server-JobObjects/{0011-server-Basic-implementation-of-job-objects.-rev-2.patch => 0001-server-Basic-implementation-of-job-objects.-rev-2.patch} (94%) delete mode 100644 patches/server-JobObjects/0002-kernel32-tests-Add-tests-for-IsProcessInJob.patch rename patches/server-JobObjects/{0012-server-Implement-completion-messages-for-job-objects.patch => 0002-server-Implement-completion-messages-for-job-objects.patch} (92%) delete mode 100644 patches/server-JobObjects/0003-kernel32-tests-Add-tests-for-TerminateJobObject.patch rename patches/server-JobObjects/{0013-server-Properly-track-handle-count-of-objects.patch => 0003-server-Properly-track-handle-count-of-objects.patch} (100%) delete mode 100644 patches/server-JobObjects/0004-kernel32-tests-Add-tests-for-QueryInformationJobObje.patch rename patches/server-JobObjects/{0014-server-Implement-JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.patch => 0004-server-Implement-JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.patch} (91%) delete mode 100644 patches/server-JobObjects/0005-kernel32-tests-Add-tests-for-job-object-completion-p.patch rename patches/server-JobObjects/{0015-server-Support-NULL-job-handles-in-IsProcessInJob.patch => 0005-server-Support-NULL-job-handles-in-IsProcessInJob.patch} (89%) delete mode 100644 patches/server-JobObjects/0006-kernel32-tests-Add-tests-for-JOB_OBJECT_LIMIT_KILL_O.patch rename patches/server-JobObjects/{0016-kernel32-tests-Add-tests-for-waiting-on-an-job-objec.patch => 0006-kernel32-tests-Add-tests-for-waiting-on-an-job-objec.patch} (90%) delete mode 100644 patches/server-JobObjects/0007-kernel32-tests-Add-tests-for-JOB_OBJECT_LIMIT_ACTIVE.patch rename patches/server-JobObjects/{0017-server-Implement-waiting-for-job-objects.patch => 0007-server-Implement-waiting-for-job-objects.patch} (100%) delete mode 100644 patches/server-JobObjects/0008-kernel32-tests-Add-tests-for-JOB_OBJECT_LIMIT_BREAKA.patch rename patches/server-JobObjects/{0018-ntdll-Implement-NtQueryInformationJobObject-stub-fun.patch => 0008-ntdll-Implement-NtQueryInformationJobObject-stub-fun.patch} (100%) delete mode 100644 patches/server-JobObjects/0009-kernel32-tests-Add-tests-for-job-inheritance.patch delete mode 100644 patches/server-JobObjects/0010-kernel32-tests-Add-tests-for-adding-a-terminated-pro.patch diff --git a/debian/changelog b/debian/changelog index 2b697283..841d78d2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -19,6 +19,7 @@ wine-staging (1.7.40) UNRELEASED; urgency=low * Removed patch with tests for GetFinalPathNameByHandleA/W (accepted upstream). * Removed patch to emulate 'mov Eb, Gb' instruction on x86 processor architecture (accepted upstream). * Removed patches for Setup*Log() functions (accepted upstream). + * Removed tests for job objects (accepted upstream). -- Sebastian Lackner Mon, 23 Mar 2015 16:12:20 +0100 wine-staging (1.7.39) unstable; urgency=low diff --git a/patches/advapi32-Revert_DACL/0002-Revert-advapi32-tests-Add-test-for-mapping-DACL-to-p.patch b/patches/advapi32-Revert_DACL/0002-Revert-advapi32-tests-Add-test-for-mapping-DACL-to-p.patch index b108015b..31c8e680 100644 --- a/patches/advapi32-Revert_DACL/0002-Revert-advapi32-tests-Add-test-for-mapping-DACL-to-p.patch +++ b/patches/advapi32-Revert_DACL/0002-Revert-advapi32-tests-Add-test-for-mapping-DACL-to-p.patch @@ -1,15 +1,15 @@ -From 0a8954d7ed5e57340ab6b6234fb3bdfe498fb69e Mon Sep 17 00:00:00 2001 +From eb05c44d59763b99851106cac937107f4c101639 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Fri, 27 Mar 2015 15:32:17 +0100 Subject: Revert "advapi32/tests: Add test for mapping DACL to permission." This reverts commit a4b12eb9f937202848b229ed15f2c7d1823b41da. --- - dlls/advapi32/tests/security.c | 35 ++--------------------------------- - 1 file changed, 2 insertions(+), 33 deletions(-) + dlls/advapi32/tests/security.c | 36 ++---------------------------------- + 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c -index 6d3f9ac..dbe52b0 100644 +index a12fb7b..91d8600 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -3405,6 +3405,7 @@ static void test_GetNamedSecurityInfoA(void) @@ -29,7 +29,7 @@ index 6d3f9ac..dbe52b0 100644 bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION); ok(bret, "Failed to initialize ACL.\n"); bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); -@@ -3472,39 +3473,7 @@ static void test_GetNamedSecurityInfoA(void) +@@ -3472,40 +3473,7 @@ static void test_GetNamedSecurityInfoA(void) NULL, OPEN_EXISTING, 0, NULL); ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); CloseHandle(h); @@ -48,7 +48,8 @@ index 6d3f9ac..dbe52b0 100644 - - h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ, - NULL, OPEN_EXISTING, 0, NULL); -- todo_wine ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); +- ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); +- CloseHandle(h); - - bret = InitializeAcl(pDacl, 100, ACL_REVISION); - ok(bret, "Failed to initialize ACL.\n"); diff --git a/patches/d3dx9_36-DXTn/0001-d3dx9_36-Add-dxtn-support.patch b/patches/d3dx9_36-DXTn/0001-d3dx9_36-Add-dxtn-support.patch index 383ddde4..c97b07e9 100644 --- a/patches/d3dx9_36-DXTn/0001-d3dx9_36-Add-dxtn-support.patch +++ b/patches/d3dx9_36-DXTn/0001-d3dx9_36-Add-dxtn-support.patch @@ -1,4 +1,4 @@ -From 748930c574cb486b0eeb31bbce189c014a865a3b Mon Sep 17 00:00:00 2001 +From 2774478cc69a3305989724186a0b68ca99f1fe61 Mon Sep 17 00:00:00 2001 From: Christian Costa Date: Sat, 1 Nov 2014 13:08:05 +0100 Subject: d3dx9_36: Add dxtn support. @@ -22,7 +22,7 @@ index 5958c57..aa387b5 100644 C_SRCS = \ core.c \ diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c -index f187031..70dc0cd 100644 +index 295ef63..ed1caff 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -18,6 +18,7 @@ @@ -76,7 +76,7 @@ index f187031..70dc0cd 100644 struct volume src_size, dst_size; + HRESULT ret = D3D_OK; - TRACE("(%p, %p, %s, %p, %#x, %u, %p, %s %#x, 0x%08x)\n", + TRACE("(%p, %p, %s, %p, %#x, %u, %p, %s, %#x, 0x%08x)\n", dst_surface, dst_palette, wine_dbgstr_rect(dst_rect), src_memory, src_format, @@ -1838,8 +1863,15 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, } @@ -221,5 +221,5 @@ index 7a4dff8..87c3eb7 100644 check_release((IUnknown*)newsurf, 1); check_release((IUnknown*)tex, 0); -- -2.2.1 +2.3.3 diff --git a/patches/kernel32-Console_Handles/0002-kernel32-Invalid-console-handles-for-new-processes-a.patch b/patches/kernel32-Console_Handles/0002-kernel32-Invalid-console-handles-for-new-processes-a.patch index c26cd75e..2db47af6 100644 --- a/patches/kernel32-Console_Handles/0002-kernel32-Invalid-console-handles-for-new-processes-a.patch +++ b/patches/kernel32-Console_Handles/0002-kernel32-Invalid-console-handles-for-new-processes-a.patch @@ -1,4 +1,4 @@ -From 43d5b2c8aa48574bfdbbb3f76c6ad670f7627571 Mon Sep 17 00:00:00 2001 +From 6a8d343ee865ec6aab96d5325f4cb374a5049cdf Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Sat, 3 Jan 2015 23:37:42 -0700 Subject: kernel32: Invalid console handles for new processes are 0, not @@ -78,7 +78,7 @@ index 57b6a1f..99bf706 100644 RtlReleasePebLock(); } diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c -index d7d3148..787ebfa 100644 +index fd3ce7f..5ab8fa2 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c @@ -57,7 +57,7 @@ @@ -95,10 +95,10 @@ index d7d3148..787ebfa 100644 static BOOL (WINAPI *pQueryFullProcessImageNameW)(HANDLE hProcess, DWORD dwFlags, LPWSTR lpExeName, PDWORD lpdwSize); static DWORD (WINAPI *pK32GetProcessImageFileNameA)(HANDLE,LPSTR,DWORD); +static struct _TEB * (WINAPI *pNtCurrentTeb)(void); - - /* ############################### */ - static char base[MAX_PATH]; -@@ -201,6 +202,8 @@ static BOOL init(void) + static HANDLE (WINAPI *pCreateJobObjectW)(LPSECURITY_ATTRIBUTES sa, LPCWSTR name); + static BOOL (WINAPI *pAssignProcessToJobObject)(HANDLE job, HANDLE process); + static BOOL (WINAPI *pIsProcessInJob)(HANDLE process, HANDLE job, PBOOL result); +@@ -208,6 +209,8 @@ static BOOL init(void) if ((p = strrchr(exename, '/')) != NULL) exename = p + 1; hkernel32 = GetModuleHandleA("kernel32"); @@ -107,15 +107,15 @@ index d7d3148..787ebfa 100644 pGetNativeSystemInfo = (void *) GetProcAddress(hkernel32, "GetNativeSystemInfo"); pGetSystemRegistryQuota = (void *) GetProcAddress(hkernel32, "GetSystemRegistryQuota"); pIsWow64Process = (void *) GetProcAddress(hkernel32, "IsWow64Process"); -@@ -209,6 +212,7 @@ static BOOL init(void) +@@ -216,6 +219,7 @@ static BOOL init(void) pQueryFullProcessImageNameA = (void *) GetProcAddress(hkernel32, "QueryFullProcessImageNameA"); pQueryFullProcessImageNameW = (void *) GetProcAddress(hkernel32, "QueryFullProcessImageNameW"); pK32GetProcessImageFileNameA = (void *) GetProcAddress(hkernel32, "K32GetProcessImageFileNameA"); -+ pNtCurrentTeb = (void *)GetProcAddress( hntdll, "NtCurrentTeb" ); - return TRUE; - } - -@@ -277,6 +281,16 @@ static void doChild(const char* file, const char* option) ++ pNtCurrentTeb = (void *)GetProcAddress(hntdll, "NtCurrentTeb"); + pCreateJobObjectW = (void *)GetProcAddress(hkernel32, "CreateJobObjectW"); + pAssignProcessToJobObject = (void *)GetProcAddress(hkernel32, "AssignProcessToJobObject"); + pIsProcessInJob = (void *)GetProcAddress(hkernel32, "IsProcessInJob"); +@@ -291,6 +295,16 @@ static void doChild(const char* file, const char* option) siA.dwFlags, siA.wShowWindow, (DWORD_PTR)siA.hStdInput, (DWORD_PTR)siA.hStdOutput, (DWORD_PTR)siA.hStdError); @@ -132,8 +132,8 @@ index d7d3148..787ebfa 100644 /* since GetStartupInfoW is only implemented in win2k, * zero out before calling so we can notice the difference */ -@@ -2119,6 +2133,43 @@ static void test_DuplicateHandle(void) - CloseHandle(out); +@@ -2548,6 +2562,43 @@ static void test_BreakawayOk(HANDLE job) + ok(ret, "SetInformationJobObject error %u\n", GetLastError()); } +void test_StartupNoConsole(void) @@ -155,7 +155,7 @@ index d7d3148..787ebfa 100644 + startup.dwFlags = STARTF_USESHOWWINDOW; + startup.wShowWindow = SW_SHOWNORMAL; + get_file_name(resfile); -+ sprintf(buffer, "\"%s\" tests/process.c \"%s\"", selfname, resfile); ++ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\"", selfname, resfile); + ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &startup, + &info), "CreateProcess\n"); + ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); @@ -175,8 +175,8 @@ index d7d3148..787ebfa 100644 + START_TEST(process) { - BOOL b = init(); -@@ -2149,6 +2200,7 @@ START_TEST(process) + HANDLE job; +@@ -2596,6 +2647,7 @@ START_TEST(process) test_SystemInfo(); test_RegistryQuota(); test_DuplicateHandle(); @@ -185,5 +185,5 @@ index d7d3148..787ebfa 100644 * lookup: check the way program to be executed is searched * handles: check the handle inheritance stuff (+sec options) -- -1.9.1 +2.3.3 diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 70f0ef07..fa5d0286 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -3869,35 +3869,15 @@ fi # | server/object.h, server/process.c, server/process.h, server/protocol.def # | if test "$enable_server_JobObjects" -eq 1; then - patch_apply server-JobObjects/0001-kernel32-tests-Allow-multiple-subprocess-commands-in.patch - patch_apply server-JobObjects/0002-kernel32-tests-Add-tests-for-IsProcessInJob.patch - patch_apply server-JobObjects/0003-kernel32-tests-Add-tests-for-TerminateJobObject.patch - patch_apply server-JobObjects/0004-kernel32-tests-Add-tests-for-QueryInformationJobObje.patch - patch_apply server-JobObjects/0005-kernel32-tests-Add-tests-for-job-object-completion-p.patch - patch_apply server-JobObjects/0006-kernel32-tests-Add-tests-for-JOB_OBJECT_LIMIT_KILL_O.patch - patch_apply server-JobObjects/0007-kernel32-tests-Add-tests-for-JOB_OBJECT_LIMIT_ACTIVE.patch - patch_apply server-JobObjects/0008-kernel32-tests-Add-tests-for-JOB_OBJECT_LIMIT_BREAKA.patch - patch_apply server-JobObjects/0009-kernel32-tests-Add-tests-for-job-inheritance.patch - patch_apply server-JobObjects/0010-kernel32-tests-Add-tests-for-adding-a-terminated-pro.patch - patch_apply server-JobObjects/0011-server-Basic-implementation-of-job-objects.-rev-2.patch - patch_apply server-JobObjects/0012-server-Implement-completion-messages-for-job-objects.patch - patch_apply server-JobObjects/0013-server-Properly-track-handle-count-of-objects.patch - patch_apply server-JobObjects/0014-server-Implement-JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.patch - patch_apply server-JobObjects/0015-server-Support-NULL-job-handles-in-IsProcessInJob.patch - patch_apply server-JobObjects/0016-kernel32-tests-Add-tests-for-waiting-on-an-job-objec.patch - patch_apply server-JobObjects/0017-server-Implement-waiting-for-job-objects.patch - patch_apply server-JobObjects/0018-ntdll-Implement-NtQueryInformationJobObject-stub-fun.patch + patch_apply server-JobObjects/0001-server-Basic-implementation-of-job-objects.-rev-2.patch + patch_apply server-JobObjects/0002-server-Implement-completion-messages-for-job-objects.patch + patch_apply server-JobObjects/0003-server-Properly-track-handle-count-of-objects.patch + patch_apply server-JobObjects/0004-server-Implement-JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.patch + patch_apply server-JobObjects/0005-server-Support-NULL-job-handles-in-IsProcessInJob.patch + patch_apply server-JobObjects/0006-kernel32-tests-Add-tests-for-waiting-on-an-job-objec.patch + patch_apply server-JobObjects/0007-server-Implement-waiting-for-job-objects.patch + patch_apply server-JobObjects/0008-ntdll-Implement-NtQueryInformationJobObject-stub-fun.patch ( - echo '+ { "Sebastian Lackner", "kernel32/tests: Allow multiple subprocess commands in process tests.", 1 },'; - echo '+ { "Andrew Cook", "kernel32/tests: Add tests for IsProcessInJob.", 1 },'; - echo '+ { "Andrew Cook", "kernel32/tests: Add tests for TerminateJobObject.", 1 },'; - echo '+ { "Andrew Cook", "kernel32/tests: Add tests for QueryInformationJobObject.", 1 },'; - echo '+ { "Andrew Cook", "kernel32/tests: Add tests for job object completion ports.", 1 },'; - echo '+ { "Andrew Cook", "kernel32/tests: Add tests for JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.", 1 },'; - echo '+ { "Andrew Cook", "kernel32/tests: Add tests for JOB_OBJECT_LIMIT_ACTIVE_PROCESS.", 1 },'; - echo '+ { "Andrew Cook", "kernel32/tests: Add tests for JOB_OBJECT_LIMIT_BREAKAWAY_OK.", 1 },'; - echo '+ { "Andrew Cook", "kernel32/tests: Add tests for job inheritance.", 1 },'; - echo '+ { "Sebastian Lackner", "kernel32/tests: Add tests for adding a terminated process to a job object.", 1 },'; echo '+ { "Andrew Cook", "server: Basic implementation of job objects.", 2 },'; echo '+ { "Andrew Cook", "server: Implement completion messages for job objects.", 1 },'; echo '+ { "Andrew Cook", "server: Properly track handle count of objects.", 1 },'; diff --git a/patches/server-JobObjects/0001-kernel32-tests-Allow-multiple-subprocess-commands-in.patch b/patches/server-JobObjects/0001-kernel32-tests-Allow-multiple-subprocess-commands-in.patch deleted file mode 100644 index dceeac49..00000000 --- a/patches/server-JobObjects/0001-kernel32-tests-Allow-multiple-subprocess-commands-in.patch +++ /dev/null @@ -1,271 +0,0 @@ -From d11a4312c95af78a10bda811e91d5175eb63aae4 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Thu, 26 Feb 2015 05:18:09 +0100 -Subject: kernel32/tests: Allow multiple subprocess commands in process tests. - ---- - dlls/kernel32/tests/process.c | 74 +++++++++++++++++++++++-------------------- - 1 file changed, 40 insertions(+), 34 deletions(-) - -diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c -index 99185fb..32d57c2 100644 ---- a/dlls/kernel32/tests/process.c -+++ b/dlls/kernel32/tests/process.c -@@ -550,7 +550,7 @@ static void test_Startup(void) - startup.wShowWindow = SW_SHOWNORMAL; - - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\"", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\"", selfname, resfile); - ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n"); - /* wait for child to terminate */ - ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); -@@ -588,7 +588,7 @@ static void test_Startup(void) - startup.dwFillAttribute = 0xA55A; - - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\"", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\"", selfname, resfile); - ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n"); - /* wait for child to terminate */ - ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); -@@ -626,7 +626,7 @@ static void test_Startup(void) - startup.dwFillAttribute = 0xA55A; - - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\"", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\"", selfname, resfile); - ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n"); - /* wait for child to terminate */ - ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); -@@ -664,7 +664,7 @@ static void test_Startup(void) - startup.dwFillAttribute = 0xA55A; - - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\"", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\"", selfname, resfile); - ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n"); - /* wait for child to terminate */ - ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); -@@ -702,7 +702,7 @@ static void test_Startup(void) - startup.dwFillAttribute = 0xA55A; - - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\"", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\"", selfname, resfile); - ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n"); - /* wait for child to terminate */ - ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); -@@ -742,7 +742,7 @@ static void test_Startup(void) - startup.dwFillAttribute = 0xA55A; - - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\"", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\"", selfname, resfile); - ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n"); - /* wait for child to terminate */ - ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); -@@ -780,7 +780,7 @@ static void test_Startup(void) - startup.dwFillAttribute = 0xA55A; - - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\"", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\"", selfname, resfile); - ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n"); - /* wait for child to terminate */ - ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); -@@ -820,16 +820,16 @@ static void test_CommandLine(void) - - /* the basics */ - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\" \"C:\\Program Files\\my nice app.exe\"", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\" \"C:\\Program Files\\my nice app.exe\"", selfname, resfile); - ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n"); - /* wait for child to terminate */ - ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); - /* child process has changed result file, so let profile functions know about it */ - WritePrivateProfileStringA(NULL, NULL, NULL, resfile); - -- okChildInt("Arguments", "argcA", 4); -- okChildString("Arguments", "argvA3", "C:\\Program Files\\my nice app.exe"); -- okChildString("Arguments", "argvA4", NULL); -+ okChildInt("Arguments", "argcA", 5); -+ okChildString("Arguments", "argvA4", "C:\\Program Files\\my nice app.exe"); -+ okChildString("Arguments", "argvA5", NULL); - okChildString("Arguments", "CommandLineA", buffer); - release_memory(); - assert(DeleteFileA(resfile) != 0); -@@ -841,18 +841,18 @@ static void test_CommandLine(void) - - /* from François */ - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\" \"a\\\"b\\\\\" c\\\" d", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\" \"a\\\"b\\\\\" c\\\" d", selfname, resfile); - ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n"); - /* wait for child to terminate */ - ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); - /* child process has changed result file, so let profile functions know about it */ - WritePrivateProfileStringA(NULL, NULL, NULL, resfile); - -- okChildInt("Arguments", "argcA", 6); -- okChildString("Arguments", "argvA3", "a\"b\\"); -- okChildString("Arguments", "argvA4", "c\""); -- okChildString("Arguments", "argvA5", "d"); -- okChildString("Arguments", "argvA6", NULL); -+ okChildInt("Arguments", "argcA", 7); -+ okChildString("Arguments", "argvA4", "a\"b\\"); -+ okChildString("Arguments", "argvA5", "c\""); -+ okChildString("Arguments", "argvA6", "d"); -+ okChildString("Arguments", "argvA7", NULL); - okChildString("Arguments", "CommandLineA", buffer); - release_memory(); - assert(DeleteFileA(resfile) != 0); -@@ -860,7 +860,7 @@ static void test_CommandLine(void) - /* Test for Bug1330 to show that XP doesn't change '/' to '\\' in argv[0]*/ - get_file_name(resfile); - /* Use exename to avoid buffer containing things like 'C:' */ -- sprintf(buffer, "./%s tests/process.c \"%s\" \"a\\\"b\\\\\" c\\\" d", exename, resfile); -+ sprintf(buffer, "./%s tests/process.c dump \"%s\" \"a\\\"b\\\\\" c\\\" d", exename, resfile); - SetLastError(0xdeadbeef); - ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info); - ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError()); -@@ -875,7 +875,7 @@ static void test_CommandLine(void) - - get_file_name(resfile); - /* Use exename to avoid buffer containing things like 'C:' */ -- sprintf(buffer, ".\\%s tests/process.c \"%s\" \"a\\\"b\\\\\" c\\\" d", exename, resfile); -+ sprintf(buffer, ".\\%s tests/process.c dump \"%s\" \"a\\\"b\\\\\" c\\\" d", exename, resfile); - SetLastError(0xdeadbeef); - ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info); - ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError()); -@@ -894,8 +894,8 @@ static void test_CommandLine(void) - *(lpFilePart -1 ) = 0; - p = strrchr(fullpath, '\\'); - /* Use exename to avoid buffer containing things like 'C:' */ -- if (p) sprintf(buffer, "..%s/%s tests/process.c \"%s\" \"a\\\"b\\\\\" c\\\" d", p, exename, resfile); -- else sprintf(buffer, "./%s tests/process.c \"%s\" \"a\\\"b\\\\\" c\\\" d", exename, resfile); -+ if (p) sprintf(buffer, "..%s/%s tests/process.c dump \"%s\" \"a\\\"b\\\\\" c\\\" d", p, exename, resfile); -+ else sprintf(buffer, "./%s tests/process.c dump \"%s\" \"a\\\"b\\\\\" c\\\" d", exename, resfile); - SetLastError(0xdeadbeef); - ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info); - ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError()); -@@ -918,7 +918,7 @@ static void test_CommandLine(void) - /* Use exename to avoid buffer containing things like 'C:' */ - if (p) sprintf(buffer, "..%s/%s", p, exename); - else sprintf(buffer, "./%s", exename); -- sprintf(buffer2, "dummy tests/process.c \"%s\" \"a\\\"b\\\\\" c\\\" d", resfile); -+ sprintf(buffer2, "dummy tests/process.c dump \"%s\" \"a\\\"b\\\\\" c\\\" d", resfile); - SetLastError(0xdeadbeef); - ret = CreateProcessA(buffer, buffer2, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info); - ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError()); -@@ -926,7 +926,7 @@ static void test_CommandLine(void) - ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); - /* child process has changed result file, so let profile functions know about it */ - WritePrivateProfileStringA(NULL, NULL, NULL, resfile); -- sprintf(buffer, "tests/process.c %s", resfile); -+ sprintf(buffer, "tests/process.c dump %s", resfile); - okChildString("Arguments", "argvA0", "dummy"); - okChildString("Arguments", "CommandLineA", buffer2); - okChildStringWA("Arguments", "CommandLineW", buffer2); -@@ -1016,7 +1016,7 @@ static void test_Directory(void) - - /* the basics */ - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\"", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\"", selfname, resfile); - GetWindowsDirectoryA( windir, sizeof(windir) ); - ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, windir, &startup, &info), "CreateProcess\n"); - /* wait for child to terminate */ -@@ -1123,7 +1123,7 @@ static void test_Environment(void) - - /* the basics */ - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\"", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\"", selfname, resfile); - ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n"); - /* wait for child to terminate */ - ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); -@@ -1142,7 +1142,7 @@ static void test_Environment(void) - - /* the basics */ - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\"", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\"", selfname, resfile); - - child_env_len = 0; - ptr = env; -@@ -1210,7 +1210,7 @@ static void test_SuspendFlag(void) - startup.wShowWindow = SW_SHOWNORMAL; - - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\"", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\"", selfname, resfile); - ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startup, &info), "CreateProcess\n"); - - ok(GetExitCodeThread(info.hThread, &exit_status) && exit_status == STILL_ACTIVE, "thread still running\n"); -@@ -1260,7 +1260,7 @@ static void test_DebuggingFlag(void) - startup.wShowWindow = SW_SHOWNORMAL; - - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\"", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\"", selfname, resfile); - ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, &startup, &info), "CreateProcess\n"); - - /* get all startup events up to the entry point break exception */ -@@ -1358,7 +1358,7 @@ static void test_Console(void) - cpOut = GetConsoleOutputCP(); - - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\" console", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\" console", selfname, resfile); - ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, 0, NULL, NULL, &startup, &info), "CreateProcess\n"); - - /* wait for child to terminate */ -@@ -1472,7 +1472,7 @@ static void test_Console(void) - startup.hStdError = hChildOutInh; - - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\" stdhandle", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\" stdhandle", selfname, resfile); - ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &startup, &info), "CreateProcess\n"); - ok(CloseHandle(hChildInInh), "Closing handle\n"); - ok(CloseHandle(hChildOutInh), "Closing handle\n"); -@@ -1509,7 +1509,7 @@ static void test_ExitCode(void) - startup.wShowWindow = SW_SHOWNORMAL; - - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\" exit_code", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\" exit_code", selfname, resfile); - ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info), "CreateProcess\n"); - - /* wait for child to terminate */ -@@ -2151,7 +2151,7 @@ void test_StartupNoConsole(void) - startup.dwFlags = STARTF_USESHOWWINDOW; - startup.wShowWindow = SW_SHOWNORMAL; - get_file_name(resfile); -- sprintf(buffer, "\"%s\" tests/process.c \"%s\"", selfname, resfile); -+ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\"", selfname, resfile); - ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &startup, - &info), "CreateProcess\n"); - ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); -@@ -2174,9 +2174,15 @@ START_TEST(process) - ok(b, "Basic init of CreateProcess test\n"); - if (!b) return; - -- if (myARGC >= 3) -+ if (myARGC >= 4) - { -- doChild(myARGV[2], (myARGC == 3) ? NULL : myARGV[3]); -+ if (!strcmp(myARGV[2], "dump")) -+ { -+ doChild(myARGV[3], (myARGC >= 5) ? myARGV[4] : NULL); -+ return; -+ } -+ -+ ok(0, "Unexpected command %s\n", myARGV[2]); - return; - } - test_TerminateProcess(); --- -2.3.0 - diff --git a/patches/server-JobObjects/0011-server-Basic-implementation-of-job-objects.-rev-2.patch b/patches/server-JobObjects/0001-server-Basic-implementation-of-job-objects.-rev-2.patch similarity index 94% rename from patches/server-JobObjects/0011-server-Basic-implementation-of-job-objects.-rev-2.patch rename to patches/server-JobObjects/0001-server-Basic-implementation-of-job-objects.-rev-2.patch index 47de80e5..9865b600 100644 --- a/patches/server-JobObjects/0011-server-Basic-implementation-of-job-objects.-rev-2.patch +++ b/patches/server-JobObjects/0001-server-Basic-implementation-of-job-objects.-rev-2.patch @@ -1,4 +1,4 @@ -From 91a03090c8aafda8f47004734a04a0ac8d83a901 Mon Sep 17 00:00:00 2001 +From fdec43a9ec165284f52d8ecd734abd6e2fe93d90 Mon Sep 17 00:00:00 2001 From: Andrew Cook Date: Thu, 26 Feb 2015 12:25:23 +1100 Subject: server: Basic implementation of job objects. (rev 2) @@ -24,10 +24,10 @@ Changes in revision 2: 6 files changed, 420 insertions(+), 22 deletions(-) diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c -index a464db2..e23d046 100644 +index 15ebd6e..6c2f86d 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c -@@ -2244,7 +2244,6 @@ static void test_IsProcessInJob(void) +@@ -2209,7 +2209,6 @@ static void test_IsProcessInJob(void) out = FALSE; ret = pIsProcessInJob(pi.hProcess, job, &out); ok(ret, "IsProcessInJob error %u\n", GetLastError()); @@ -35,7 +35,7 @@ index a464db2..e23d046 100644 ok(out, "IsProcessInJob returned out=%u\n", out); TerminateProcess(pi.hProcess, 0); -@@ -2255,7 +2254,6 @@ static void test_IsProcessInJob(void) +@@ -2220,7 +2219,6 @@ static void test_IsProcessInJob(void) out = FALSE; ret = pIsProcessInJob(pi.hProcess, job, &out); ok(ret, "IsProcessInJob error %u\n", GetLastError()); @@ -43,20 +43,10 @@ index a464db2..e23d046 100644 ok(out, "IsProcessInJob returned out=%u\n", out); CloseHandle(pi.hProcess); -@@ -2269,9 +2267,7 @@ static void test_IsProcessInJob(void) - - SetLastError(0xdeadbeef); - ret = pAssignProcessToJobObject(job, pi.hProcess); -- todo_wine - ok(!ret, "AssignProcessToJobObject unexpectedly succeeded\n"); -- todo_wine - expect_eq_d(ERROR_ACCESS_DENIED, GetLastError()); - - CloseHandle(pi.hProcess); -@@ -2299,13 +2295,11 @@ static void test_TerminateJobObject(void) +@@ -2247,13 +2245,11 @@ static void test_TerminateJobObject(void) ok(ret, "TerminateJobObject error %u\n", GetLastError()); - dwret = WaitForSingleObject(pi.hProcess, 500); + 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); @@ -67,7 +57,17 @@ index a464db2..e23d046 100644 ok(dwret == 123 || broken(dwret == 0) /* randomly fails on Win 2000 / XP */, "wrong exitcode %u\n", dwret); -@@ -2414,6 +2408,7 @@ static void test_CompletionPort(void) +@@ -2268,9 +2264,7 @@ static void test_TerminateJobObject(void) + + SetLastError(0xdeadbeef); + ret = pAssignProcessToJobObject(job, pi.hProcess); +- todo_wine + ok(!ret, "AssignProcessToJobObject unexpectedly succeeded\n"); +- todo_wine + expect_eq_d(ERROR_ACCESS_DENIED, GetLastError()); + + CloseHandle(pi.hProcess); +@@ -2381,6 +2375,7 @@ static void test_CompletionPort(void) port_info.CompletionKey = job; port_info.CompletionPort = port; ret = pSetInformationJobObject(job, JobObjectAssociateCompletionPortInformation, &port_info, sizeof(port_info)); @@ -75,15 +75,15 @@ index a464db2..e23d046 100644 ok(ret, "SetInformationJobObject error %u\n", GetLastError()); create_process("wait", &pi); -@@ -2581,7 +2576,6 @@ static HANDLE test_LimitActiveProcesses(void) +@@ -2478,7 +2473,6 @@ static void test_jobInheritance(HANDLE job) out = FALSE; - ret = pIsProcessInJob(pi[0].hProcess, job, &out); + 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[0].hProcess, 500); -@@ -2612,9 +2606,7 @@ static void test_BreakawayOk(HANDLE job) + dwret = WaitForSingleObject(pi.hProcess, 1000); +@@ -2506,9 +2500,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); @@ -94,10 +94,10 @@ index a464db2..e23d046 100644 if (ret) diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c -index 08fab44..56714ef 100644 +index 7d44e60..a0b8c15 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c -@@ -58,6 +58,7 @@ +@@ -56,6 +56,7 @@ #include "wine/server.h" #include "wine/debug.h" #include "ntdll_misc.h" @@ -105,7 +105,7 @@ index 08fab44..56714ef 100644 WINE_DEFAULT_DEBUG_CHANNEL(ntdll); -@@ -567,9 +568,36 @@ NTSTATUS WINAPI NtQueryMutant(IN HANDLE handle, +@@ -565,9 +566,36 @@ NTSTATUS WINAPI NtQueryMutant(IN HANDLE handle, */ NTSTATUS WINAPI NtCreateJobObject( PHANDLE handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { @@ -145,7 +145,7 @@ index 08fab44..56714ef 100644 } /****************************************************************************** -@@ -588,8 +616,19 @@ NTSTATUS WINAPI NtOpenJobObject( PHANDLE handle, ACCESS_MASK access, const OBJEC +@@ -586,8 +614,19 @@ NTSTATUS WINAPI NtOpenJobObject( PHANDLE handle, ACCESS_MASK access, const OBJEC */ NTSTATUS WINAPI NtTerminateJobObject( HANDLE handle, NTSTATUS status ) { @@ -167,7 +167,7 @@ index 08fab44..56714ef 100644 } /****************************************************************************** -@@ -599,8 +638,17 @@ NTSTATUS WINAPI NtTerminateJobObject( HANDLE handle, NTSTATUS status ) +@@ -597,8 +636,17 @@ NTSTATUS WINAPI NtTerminateJobObject( HANDLE handle, NTSTATUS status ) NTSTATUS WINAPI NtQueryInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS class, PVOID info, ULONG len, PULONG ret_len ) { @@ -187,7 +187,7 @@ index 08fab44..56714ef 100644 } /****************************************************************************** -@@ -609,8 +657,51 @@ NTSTATUS WINAPI NtQueryInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS c +@@ -607,8 +655,51 @@ NTSTATUS WINAPI NtQueryInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS c */ NTSTATUS WINAPI NtSetInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS class, PVOID info, ULONG len ) { @@ -241,7 +241,7 @@ index 08fab44..56714ef 100644 } /****************************************************************************** -@@ -619,8 +710,19 @@ NTSTATUS WINAPI NtSetInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS cla +@@ -617,8 +708,19 @@ NTSTATUS WINAPI NtSetInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS cla */ NTSTATUS WINAPI NtIsProcessInJob( HANDLE process, HANDLE job ) { @@ -263,7 +263,7 @@ index 08fab44..56714ef 100644 } /****************************************************************************** -@@ -629,8 +731,19 @@ NTSTATUS WINAPI NtIsProcessInJob( HANDLE process, HANDLE job ) +@@ -627,8 +729,19 @@ NTSTATUS WINAPI NtIsProcessInJob( HANDLE process, HANDLE job ) */ NTSTATUS WINAPI NtAssignProcessToJobObject( HANDLE job, HANDLE process ) { @@ -638,10 +638,10 @@ index da6d3da..ae83b0e 100644 struct list classes; /* window classes owned by the process */ struct console_input*console; /* console input */ diff --git a/server/protocol.def b/server/protocol.def -index fc6bec5..cc39ef1 100644 +index a34dde9..655a9ac 100644 --- a/server/protocol.def +++ b/server/protocol.def -@@ -681,6 +681,33 @@ struct rawinput_device +@@ -682,6 +682,33 @@ struct rawinput_device obj_handle_t thandle; /* thread handle (in the current process) */ @END @@ -676,5 +676,5 @@ index fc6bec5..cc39ef1 100644 /* Retrieve information about a newly started process */ @REQ(get_new_process_info) -- -2.3.0 +2.3.3 diff --git a/patches/server-JobObjects/0002-kernel32-tests-Add-tests-for-IsProcessInJob.patch b/patches/server-JobObjects/0002-kernel32-tests-Add-tests-for-IsProcessInJob.patch deleted file mode 100644 index 7e8e353c..00000000 --- a/patches/server-JobObjects/0002-kernel32-tests-Add-tests-for-IsProcessInJob.patch +++ /dev/null @@ -1,140 +0,0 @@ -From b9cd3dbe08f36f893911a4a0a7100e82bd92e606 Mon Sep 17 00:00:00 2001 -From: Andrew Cook -Date: Thu, 26 Feb 2015 11:15:03 +1100 -Subject: kernel32/tests: Add tests for IsProcessInJob. - -Cleanup and improvements by Sebastian Lackner . ---- - dlls/kernel32/tests/process.c | 86 ++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 84 insertions(+), 2 deletions(-) - -diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c -index 32d57c2..d0d5f46 100644 ---- a/dlls/kernel32/tests/process.c -+++ b/dlls/kernel32/tests/process.c -@@ -67,6 +67,9 @@ static BOOL (WINAPI *pQueryFullProcessImageNameA)(HANDLE hProcess, DWORD dwFla - static BOOL (WINAPI *pQueryFullProcessImageNameW)(HANDLE hProcess, DWORD dwFlags, LPWSTR lpExeName, PDWORD lpdwSize); - static DWORD (WINAPI *pK32GetProcessImageFileNameA)(HANDLE,LPSTR,DWORD); - static struct _TEB * (WINAPI *pNtCurrentTeb)(void); -+static HANDLE (WINAPI *pCreateJobObjectW)(LPSECURITY_ATTRIBUTES sa, LPCWSTR name); -+static BOOL (WINAPI *pAssignProcessToJobObject)(HANDLE job, HANDLE process); -+static BOOL (WINAPI *pIsProcessInJob)(HANDLE process, HANDLE job, PBOOL result); - - /* ############################### */ - static char base[MAX_PATH]; -@@ -213,6 +216,9 @@ static BOOL init(void) - pQueryFullProcessImageNameW = (void *) GetProcAddress(hkernel32, "QueryFullProcessImageNameW"); - pK32GetProcessImageFileNameA = (void *) GetProcAddress(hkernel32, "K32GetProcessImageFileNameA"); - pNtCurrentTeb = (void *)GetProcAddress( hntdll, "NtCurrentTeb" ); -+ pCreateJobObjectW = (void *)GetProcAddress(hkernel32, "CreateJobObjectW"); -+ pAssignProcessToJobObject = (void *)GetProcAddress(hkernel32, "AssignProcessToJobObject"); -+ pIsProcessInJob = (void *)GetProcAddress(hkernel32, "IsProcessInJob"); - return TRUE; - } - -@@ -2168,19 +2174,87 @@ void test_StartupNoConsole(void) - - } - -+#define create_process(cmd, pi) _create_process(__LINE__, cmd, pi) -+static void _create_process(int line, const char *command, LPPROCESS_INFORMATION pi) -+{ -+ BOOL ret; -+ char buffer[MAX_PATH] = ""; -+ STARTUPINFOA si = {0}; -+ -+ snprintf(buffer, MAX_PATH, "\"%s\" tests/process.c %s", selfname, command); -+ -+ ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, pi); -+ ok_(__FILE__, line)(ret, "CreateProcess error %u\n", GetLastError()); -+} -+ -+ -+static void test_IsProcessInJob(void) -+{ -+ HANDLE job; -+ PROCESS_INFORMATION pi; -+ BOOL ret, out; -+ DWORD dwret; -+ -+ if (!pIsProcessInJob) -+ { -+ win_skip("IsProcessInJob not available.\n"); -+ return; -+ } -+ -+ job = pCreateJobObjectW(NULL, NULL); -+ ok(job != NULL, "CreateJobObject error %u\n", GetLastError()); -+ -+ create_process("wait", &pi); -+ -+ out = TRUE; -+ ret = pIsProcessInJob(pi.hProcess, job, &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()); -+ -+ 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); -+ -+ TerminateProcess(pi.hProcess, 0); -+ -+ dwret = WaitForSingleObject(pi.hProcess, 500); -+ ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); -+ -+ 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); -+ -+ CloseHandle(pi.hProcess); -+ CloseHandle(pi.hThread); -+ CloseHandle(job); -+} -+ - START_TEST(process) - { - BOOL b = init(); - ok(b, "Basic init of CreateProcess test\n"); - if (!b) return; - -- if (myARGC >= 4) -+ if (myARGC >= 3) - { -- if (!strcmp(myARGV[2], "dump")) -+ if (!strcmp(myARGV[2], "dump") && myARGC >= 4) - { - doChild(myARGV[3], (myARGC >= 5) ? myARGV[4] : NULL); - return; - } -+ else if (!strcmp(myARGV[2], "wait")) -+ { -+ Sleep(30000); -+ ok(0, "Child process not killed\n"); -+ return; -+ } - - ok(0, "Unexpected command %s\n", myARGV[2]); - return; -@@ -2210,4 +2284,12 @@ START_TEST(process) - * handles: check the handle inheritance stuff (+sec options) - * console: check if console creation parameters work - */ -+ -+ if (!pCreateJobObjectW) -+ { -+ win_skip("No job object support\n"); -+ return; -+ } -+ -+ test_IsProcessInJob(); - } --- -2.3.0 - diff --git a/patches/server-JobObjects/0012-server-Implement-completion-messages-for-job-objects.patch b/patches/server-JobObjects/0002-server-Implement-completion-messages-for-job-objects.patch similarity index 92% rename from patches/server-JobObjects/0012-server-Implement-completion-messages-for-job-objects.patch rename to patches/server-JobObjects/0002-server-Implement-completion-messages-for-job-objects.patch index 2319823b..f1e2c8a4 100644 --- a/patches/server-JobObjects/0012-server-Implement-completion-messages-for-job-objects.patch +++ b/patches/server-JobObjects/0002-server-Implement-completion-messages-for-job-objects.patch @@ -1,4 +1,4 @@ -From f33f2fb03259b0218b83c1f6891b88cd5fe4336f Mon Sep 17 00:00:00 2001 +From 2dc3e01bbb999ff93918375bdc5071eb9439a011 Mon Sep 17 00:00:00 2001 From: Andrew Cook Date: Thu, 26 Feb 2015 13:02:36 +1100 Subject: server: Implement completion messages for job objects. @@ -15,10 +15,10 @@ coding style by Sebastian Lackner . 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c -index e23d046..97ad297 100644 +index 6c2f86d..911fad7 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c -@@ -2408,7 +2408,6 @@ static void test_CompletionPort(void) +@@ -2375,7 +2375,6 @@ static void test_CompletionPort(void) port_info.CompletionKey = job; port_info.CompletionPort = port; ret = pSetInformationJobObject(job, JobObjectAssociateCompletionPortInformation, &port_info, sizeof(port_info)); @@ -26,28 +26,28 @@ index e23d046..97ad297 100644 ok(ret, "SetInformationJobObject error %u\n", GetLastError()); create_process("wait", &pi); -@@ -2416,16 +2415,13 @@ static void test_CompletionPort(void) +@@ -2383,16 +2382,13 @@ static void test_CompletionPort(void) ret = pAssignProcessToJobObject(job, pi.hProcess); ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); - todo_wine - test_completion(port, JOB_OBJECT_MSG_NEW_PROCESS, (DWORD_PTR)job, (LPOVERLAPPED)pi.dwProcessId, 0); + test_completion(port, JOB_OBJECT_MSG_NEW_PROCESS, (DWORD_PTR)job, pi.dwProcessId, 0); TerminateProcess(pi.hProcess, 0); - dwret = WaitForSingleObject(pi.hProcess, 500); + dwret = WaitForSingleObject(pi.hProcess, 1000); ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); - todo_wine - test_completion(port, JOB_OBJECT_MSG_EXIT_PROCESS, (DWORD_PTR)job, (LPOVERLAPPED)pi.dwProcessId, 0); + test_completion(port, JOB_OBJECT_MSG_EXIT_PROCESS, (DWORD_PTR)job, pi.dwProcessId, 0); - todo_wine - test_completion(port, JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO, (DWORD_PTR)job, NULL, 100); + test_completion(port, JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO, (DWORD_PTR)job, 0, 100); CloseHandle(pi.hProcess); diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c -index 56714ef..ef4a4cb 100644 +index a0b8c15..c754df6 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c -@@ -696,6 +696,21 @@ NTSTATUS WINAPI NtSetInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS cla +@@ -694,6 +694,21 @@ NTSTATUS WINAPI NtSetInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS cla SERVER_END_REQ; break; @@ -175,10 +175,10 @@ index 6384203..e02b7af 100644 + } +} diff --git a/server/protocol.def b/server/protocol.def -index cc39ef1..126c2a7 100644 +index 655a9ac..deaaa7b 100644 --- a/server/protocol.def +++ b/server/protocol.def -@@ -709,6 +709,12 @@ struct rawinput_device +@@ -710,6 +710,12 @@ struct rawinput_device unsigned int limit_flags; @END @@ -192,5 +192,5 @@ index cc39ef1..126c2a7 100644 @REQ(get_new_process_info) obj_handle_t info; /* info handle returned from new_process_request */ -- -2.3.0 +2.3.3 diff --git a/patches/server-JobObjects/0003-kernel32-tests-Add-tests-for-TerminateJobObject.patch b/patches/server-JobObjects/0003-kernel32-tests-Add-tests-for-TerminateJobObject.patch deleted file mode 100644 index bcf28858..00000000 --- a/patches/server-JobObjects/0003-kernel32-tests-Add-tests-for-TerminateJobObject.patch +++ /dev/null @@ -1,80 +0,0 @@ -From b514c502559b1aa3bc4955b7ef2a9bc7be7ef430 Mon Sep 17 00:00:00 2001 -From: Andrew Cook -Date: Thu, 26 Feb 2015 08:13:08 +0100 -Subject: kernel32/tests: Add tests for TerminateJobObject. - -Cleanup and improvements by Sebastian Lackner . ---- - dlls/kernel32/tests/process.c | 37 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 37 insertions(+) - -diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c -index d0d5f46..bb9053a 100644 ---- a/dlls/kernel32/tests/process.c -+++ b/dlls/kernel32/tests/process.c -@@ -70,6 +70,7 @@ static struct _TEB * (WINAPI *pNtCurrentTeb)(void); - static HANDLE (WINAPI *pCreateJobObjectW)(LPSECURITY_ATTRIBUTES sa, LPCWSTR name); - static BOOL (WINAPI *pAssignProcessToJobObject)(HANDLE job, HANDLE process); - static BOOL (WINAPI *pIsProcessInJob)(HANDLE process, HANDLE job, PBOOL result); -+static BOOL (WINAPI *pTerminateJobObject)(HANDLE job, UINT exit_code); - - /* ############################### */ - static char base[MAX_PATH]; -@@ -219,6 +220,7 @@ static BOOL init(void) - pCreateJobObjectW = (void *)GetProcAddress(hkernel32, "CreateJobObjectW"); - pAssignProcessToJobObject = (void *)GetProcAddress(hkernel32, "AssignProcessToJobObject"); - pIsProcessInJob = (void *)GetProcAddress(hkernel32, "IsProcessInJob"); -+ pTerminateJobObject = (void *)GetProcAddress(hkernel32, "TerminateJobObject"); - return TRUE; - } - -@@ -2236,6 +2238,40 @@ static void test_IsProcessInJob(void) - CloseHandle(job); - } - -+static void test_TerminateJobObject(void) -+{ -+ HANDLE job; -+ PROCESS_INFORMATION pi; -+ BOOL ret; -+ DWORD dwret; -+ -+ job = pCreateJobObjectW(NULL, NULL); -+ ok(job != NULL, "CreateJobObject error %u\n", GetLastError()); -+ -+ create_process("wait", &pi); -+ -+ ret = pAssignProcessToJobObject(job, pi.hProcess); -+ ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); -+ -+ ret = pTerminateJobObject(job, 123); -+ ok(ret, "TerminateJobObject error %u\n", GetLastError()); -+ -+ dwret = WaitForSingleObject(pi.hProcess, 500); -+ 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); -+ -+ CloseHandle(pi.hProcess); -+ CloseHandle(pi.hThread); -+ CloseHandle(job); -+} -+ - START_TEST(process) - { - BOOL b = init(); -@@ -2292,4 +2328,5 @@ START_TEST(process) - } - - test_IsProcessInJob(); -+ test_TerminateJobObject(); - } --- -2.3.0 - diff --git a/patches/server-JobObjects/0013-server-Properly-track-handle-count-of-objects.patch b/patches/server-JobObjects/0003-server-Properly-track-handle-count-of-objects.patch similarity index 100% rename from patches/server-JobObjects/0013-server-Properly-track-handle-count-of-objects.patch rename to patches/server-JobObjects/0003-server-Properly-track-handle-count-of-objects.patch diff --git a/patches/server-JobObjects/0004-kernel32-tests-Add-tests-for-QueryInformationJobObje.patch b/patches/server-JobObjects/0004-kernel32-tests-Add-tests-for-QueryInformationJobObje.patch deleted file mode 100644 index 0254458b..00000000 --- a/patches/server-JobObjects/0004-kernel32-tests-Add-tests-for-QueryInformationJobObje.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 0882ebd11c9d8f52c3454ba715fc4cc3498edca4 Mon Sep 17 00:00:00 2001 -From: Andrew Cook -Date: Thu, 26 Feb 2015 08:19:59 +0100 -Subject: kernel32/tests: Add tests for QueryInformationJobObject - -Cleanup and improvements by Sebastian Lackner . ---- - dlls/kernel32/tests/process.c | 91 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 91 insertions(+) - -diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c -index bb9053a..9508d10 100644 ---- a/dlls/kernel32/tests/process.c -+++ b/dlls/kernel32/tests/process.c -@@ -71,6 +71,7 @@ static HANDLE (WINAPI *pCreateJobObjectW)(LPSECURITY_ATTRIBUTES sa, LPCWSTR name - static BOOL (WINAPI *pAssignProcessToJobObject)(HANDLE job, HANDLE process); - static BOOL (WINAPI *pIsProcessInJob)(HANDLE process, HANDLE job, PBOOL result); - static BOOL (WINAPI *pTerminateJobObject)(HANDLE job, UINT exit_code); -+static BOOL (WINAPI *pQueryInformationJobObject)(HANDLE job, JOBOBJECTINFOCLASS class, LPVOID info, DWORD len, LPDWORD ret_len); - - /* ############################### */ - static char base[MAX_PATH]; -@@ -221,6 +222,7 @@ static BOOL init(void) - pAssignProcessToJobObject = (void *)GetProcAddress(hkernel32, "AssignProcessToJobObject"); - pIsProcessInJob = (void *)GetProcAddress(hkernel32, "IsProcessInJob"); - pTerminateJobObject = (void *)GetProcAddress(hkernel32, "TerminateJobObject"); -+ pQueryInformationJobObject = (void *)GetProcAddress(hkernel32, "QueryInformationJobObject"); - return TRUE; - } - -@@ -2272,6 +2274,89 @@ static void test_TerminateJobObject(void) - CloseHandle(job); - } - -+static void test_QueryInformationJobObject(void) -+{ -+ char buf[FIELD_OFFSET(JOBOBJECT_BASIC_PROCESS_ID_LIST, ProcessIdList[5])]; -+ PJOBOBJECT_BASIC_PROCESS_ID_LIST pid_list = (JOBOBJECT_BASIC_PROCESS_ID_LIST *)buf; -+ DWORD dwret, ret_len; -+ PROCESS_INFORMATION pi[2]; -+ HANDLE job; -+ BOOL ret; -+ -+ job = pCreateJobObjectW(NULL, NULL); -+ ok(job != NULL, "CreateJobObject error %u\n", GetLastError()); -+ -+ /* Only active processes are returned */ -+ create_process("exit", &pi[0]); -+ ret = pAssignProcessToJobObject(job, pi[0].hProcess); -+ ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); -+ dwret = WaitForSingleObject(pi[0].hProcess, 1000); -+ ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); -+ -+ CloseHandle(pi[0].hProcess); -+ CloseHandle(pi[0].hThread); -+ -+ create_process("wait", &pi[0]); -+ ret = pAssignProcessToJobObject(job, pi[0].hProcess); -+ ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); -+ -+ create_process("wait", &pi[1]); -+ ret = pAssignProcessToJobObject(job, pi[1].hProcess); -+ ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); -+ -+ SetLastError(0xdeadbeef); -+ ret = QueryInformationJobObject(job, JobObjectBasicProcessIdList, pid_list, -+ FIELD_OFFSET(JOBOBJECT_BASIC_PROCESS_ID_LIST, ProcessIdList), &ret_len); -+ ok(!ret, "QueryInformationJobObject expected failure\n"); -+ todo_wine -+ expect_eq_d(ERROR_BAD_LENGTH, GetLastError()); -+ -+ SetLastError(0xdeadbeef); -+ memset(buf, 0, sizeof(buf)); -+ pid_list->NumberOfAssignedProcesses = 42; -+ pid_list->NumberOfProcessIdsInList = 42; -+ ret = QueryInformationJobObject(job, JobObjectBasicProcessIdList, pid_list, -+ FIELD_OFFSET(JOBOBJECT_BASIC_PROCESS_ID_LIST, ProcessIdList[1]), &ret_len); -+ ok(!ret, "QueryInformationJobObject expected failure\n"); -+ todo_wine -+ expect_eq_d(ERROR_MORE_DATA, GetLastError()); -+ if (ret) -+ { -+ expect_eq_d(42, pid_list->NumberOfAssignedProcesses); -+ expect_eq_d(42, pid_list->NumberOfProcessIdsInList); -+ } -+ -+ memset(buf, 0, sizeof(buf)); -+ ret = pQueryInformationJobObject(job, JobObjectBasicProcessIdList, pid_list, sizeof(buf), &ret_len); -+ todo_wine -+ ok(ret, "QueryInformationJobObject error %u\n", GetLastError()); -+ if(ret) -+ { -+ if (pid_list->NumberOfAssignedProcesses == 3) /* Win 8 */ -+ win_skip("Number of assigned processes broken on Win 8\n"); -+ else -+ { -+ ok(ret_len == FIELD_OFFSET(JOBOBJECT_BASIC_PROCESS_ID_LIST, ProcessIdList[2]), -+ "QueryInformationJobObject returned ret_len=%u\n", ret_len); -+ -+ expect_eq_d(2, pid_list->NumberOfAssignedProcesses); -+ expect_eq_d(2, pid_list->NumberOfProcessIdsInList); -+ expect_eq_d(pi[0].dwProcessId, pid_list->ProcessIdList[0]); -+ expect_eq_d(pi[1].dwProcessId, pid_list->ProcessIdList[1]); -+ } -+ } -+ -+ TerminateProcess(pi[0].hProcess, 0); -+ CloseHandle(pi[0].hProcess); -+ CloseHandle(pi[0].hThread); -+ -+ TerminateProcess(pi[1].hProcess, 0); -+ CloseHandle(pi[1].hProcess); -+ CloseHandle(pi[1].hThread); -+ -+ CloseHandle(job); -+} -+ - START_TEST(process) - { - BOOL b = init(); -@@ -2291,6 +2376,11 @@ START_TEST(process) - ok(0, "Child process not killed\n"); - return; - } -+ else if (!strcmp(myARGV[2], "exit")) -+ { -+ Sleep(100); -+ return; -+ } - - ok(0, "Unexpected command %s\n", myARGV[2]); - return; -@@ -2329,4 +2419,5 @@ START_TEST(process) - - test_IsProcessInJob(); - test_TerminateJobObject(); -+ test_QueryInformationJobObject(); - } --- -2.3.0 - diff --git a/patches/server-JobObjects/0014-server-Implement-JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.patch b/patches/server-JobObjects/0004-server-Implement-JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.patch similarity index 91% rename from patches/server-JobObjects/0014-server-Implement-JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.patch rename to patches/server-JobObjects/0004-server-Implement-JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.patch index 779509ff..e31d2f6f 100644 --- a/patches/server-JobObjects/0014-server-Implement-JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.patch +++ b/patches/server-JobObjects/0004-server-Implement-JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.patch @@ -1,4 +1,4 @@ -From 5762bfcf69275020150ca4c670cace134d0df80f Mon Sep 17 00:00:00 2001 +From dedf23f9a61a8ef5bcc23a229646d1244e859546 Mon Sep 17 00:00:00 2001 From: Andrew Cook Date: Thu, 26 Feb 2015 13:10:41 +1100 Subject: server: Implement JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE. @@ -9,13 +9,13 @@ 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 97ad297..5737d2e 100644 +index 911fad7..66e0863 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c -@@ -2458,7 +2458,6 @@ static void test_KillOnJobClose(void) +@@ -2425,7 +2425,6 @@ static void test_KillOnJobClose(void) CloseHandle(job); - dwret = WaitForSingleObject(pi.hProcess, 500); + 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); @@ -63,5 +63,5 @@ index e02b7af..f36548e 100644 { struct job *job = (struct job *)obj; -- -2.3.0 +2.3.3 diff --git a/patches/server-JobObjects/0005-kernel32-tests-Add-tests-for-job-object-completion-p.patch b/patches/server-JobObjects/0005-kernel32-tests-Add-tests-for-job-object-completion-p.patch deleted file mode 100644 index 09783d6c..00000000 --- a/patches/server-JobObjects/0005-kernel32-tests-Add-tests-for-job-object-completion-p.patch +++ /dev/null @@ -1,116 +0,0 @@ -From ea82086e5c229320cdd8dc187ce3935e67b193b8 Mon Sep 17 00:00:00 2001 -From: Andrew Cook -Date: Thu, 26 Feb 2015 13:23:35 +0100 -Subject: kernel32/tests: Add tests for job object completion ports. - -Cleanup and improvements by Sebastian Lackner . ---- - dlls/kernel32/tests/process.c | 66 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 66 insertions(+) - -diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c -index 9508d10..9d39268 100644 ---- a/dlls/kernel32/tests/process.c -+++ b/dlls/kernel32/tests/process.c -@@ -72,6 +72,8 @@ static BOOL (WINAPI *pAssignProcessToJobObject)(HANDLE job, HANDLE process); - static BOOL (WINAPI *pIsProcessInJob)(HANDLE process, HANDLE job, PBOOL result); - static BOOL (WINAPI *pTerminateJobObject)(HANDLE job, UINT exit_code); - static BOOL (WINAPI *pQueryInformationJobObject)(HANDLE job, JOBOBJECTINFOCLASS class, LPVOID info, DWORD len, LPDWORD ret_len); -+static BOOL (WINAPI *pSetInformationJobObject)(HANDLE job, JOBOBJECTINFOCLASS class, LPVOID info, DWORD len); -+static HANDLE (WINAPI *pCreateIoCompletionPort)(HANDLE file, HANDLE existing_port, ULONG_PTR key, DWORD threads); - - /* ############################### */ - static char base[MAX_PATH]; -@@ -223,6 +225,8 @@ static BOOL init(void) - pIsProcessInJob = (void *)GetProcAddress(hkernel32, "IsProcessInJob"); - pTerminateJobObject = (void *)GetProcAddress(hkernel32, "TerminateJobObject"); - pQueryInformationJobObject = (void *)GetProcAddress(hkernel32, "QueryInformationJobObject"); -+ pSetInformationJobObject = (void *)GetProcAddress(hkernel32, "SetInformationJobObject"); -+ pCreateIoCompletionPort = (void *)GetProcAddress(hkernel32, "CreateIoCompletionPort"); - return TRUE; - } - -@@ -2178,6 +2182,25 @@ void test_StartupNoConsole(void) - - } - -+#define test_completion(a, b, c, d, e) _test_completion(__LINE__, a, b, c, d, e) -+static void _test_completion(int line, HANDLE port, DWORD ekey, ULONG_PTR evalue, LPOVERLAPPED eoverlapped, DWORD wait) -+{ -+ LPOVERLAPPED overlapped; -+ ULONG_PTR value; -+ DWORD key; -+ BOOL ret; -+ -+ ret = GetQueuedCompletionStatus(port, &key, &value, &overlapped, wait); -+ -+ ok_(__FILE__, line)(ret, "GetQueuedCompletionStatus: %x\n", GetLastError()); -+ if (ret) -+ { -+ ok_(__FILE__, line)(key == ekey, "unexpected key %x\n", key); -+ ok_(__FILE__, line)(value == evalue, "unexpected value %p\n", (void *)value); -+ ok_(__FILE__, line)(overlapped == eoverlapped, "unexpected overlapped %p\n", (void *)overlapped); -+ } -+} -+ - #define create_process(cmd, pi) _create_process(__LINE__, cmd, pi) - static void _create_process(int line, const char *command, LPPROCESS_INFORMATION pi) - { -@@ -2357,6 +2380,48 @@ static void test_QueryInformationJobObject(void) - CloseHandle(job); - } - -+static void test_CompletionPort(void) -+{ -+ JOBOBJECT_ASSOCIATE_COMPLETION_PORT port_info; -+ PROCESS_INFORMATION pi; -+ HANDLE job, port; -+ DWORD dwret; -+ BOOL ret; -+ -+ job = pCreateJobObjectW(NULL, NULL); -+ ok(job != NULL, "CreateJobObject error %u\n", GetLastError()); -+ -+ port = pCreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); -+ ok(port != NULL, "CreateIoCompletionPort error %u\n", GetLastError()); -+ -+ port_info.CompletionKey = job; -+ port_info.CompletionPort = port; -+ ret = pSetInformationJobObject(job, JobObjectAssociateCompletionPortInformation, &port_info, sizeof(port_info)); -+ ok(ret, "SetInformationJobObject error %u\n", GetLastError()); -+ -+ create_process("wait", &pi); -+ -+ ret = pAssignProcessToJobObject(job, pi.hProcess); -+ ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); -+ -+ todo_wine -+ test_completion(port, JOB_OBJECT_MSG_NEW_PROCESS, (DWORD_PTR)job, (LPOVERLAPPED)pi.dwProcessId, 0); -+ -+ TerminateProcess(pi.hProcess, 0); -+ dwret = WaitForSingleObject(pi.hProcess, 500); -+ ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); -+ -+ todo_wine -+ test_completion(port, JOB_OBJECT_MSG_EXIT_PROCESS, (DWORD_PTR)job, (LPOVERLAPPED)pi.dwProcessId, 0); -+ todo_wine -+ test_completion(port, JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO, (DWORD_PTR)job, NULL, 100); -+ -+ CloseHandle(pi.hProcess); -+ CloseHandle(pi.hThread); -+ CloseHandle(job); -+ CloseHandle(port); -+} -+ - START_TEST(process) - { - BOOL b = init(); -@@ -2420,4 +2485,5 @@ START_TEST(process) - test_IsProcessInJob(); - test_TerminateJobObject(); - test_QueryInformationJobObject(); -+ test_CompletionPort(); - } --- -2.3.0 - diff --git a/patches/server-JobObjects/0015-server-Support-NULL-job-handles-in-IsProcessInJob.patch b/patches/server-JobObjects/0005-server-Support-NULL-job-handles-in-IsProcessInJob.patch similarity index 89% rename from patches/server-JobObjects/0015-server-Support-NULL-job-handles-in-IsProcessInJob.patch rename to patches/server-JobObjects/0005-server-Support-NULL-job-handles-in-IsProcessInJob.patch index e0443ca5..afc34021 100644 --- a/patches/server-JobObjects/0015-server-Support-NULL-job-handles-in-IsProcessInJob.patch +++ b/patches/server-JobObjects/0005-server-Support-NULL-job-handles-in-IsProcessInJob.patch @@ -1,4 +1,4 @@ -From 8195735992f652614bc987e7537836703bcb1cdd Mon Sep 17 00:00:00 2001 +From b55b5ab63248360985a6ff01e1d2c98867e05a16 Mon Sep 17 00:00:00 2001 From: Andrew Cook Date: Sat, 28 Feb 2015 13:37:47 +1100 Subject: server: Support NULL job handles in IsProcessInJob. @@ -9,10 +9,10 @@ Subject: server: Support NULL job handles in IsProcessInJob. 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c -index 5737d2e..44d98f7 100644 +index 66e0863..e20fb92 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c -@@ -2238,6 +2238,11 @@ static void test_IsProcessInJob(void) +@@ -2203,6 +2203,11 @@ static void test_IsProcessInJob(void) ok(ret, "IsProcessInJob error %u\n", GetLastError()); ok(!out, "IsProcessInJob returned out=%u\n", out); @@ -24,7 +24,7 @@ index 5737d2e..44d98f7 100644 ret = pAssignProcessToJobObject(job, pi.hProcess); ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); -@@ -2246,6 +2251,11 @@ static void test_IsProcessInJob(void) +@@ -2211,6 +2216,11 @@ static void test_IsProcessInJob(void) ok(ret, "IsProcessInJob error %u\n", GetLastError()); ok(out, "IsProcessInJob returned out=%u\n", out); @@ -35,7 +35,7 @@ index 5737d2e..44d98f7 100644 + TerminateProcess(pi.hProcess, 0); - dwret = WaitForSingleObject(pi.hProcess, 500); + dwret = WaitForSingleObject(pi.hProcess, 1000); diff --git a/server/process.c b/server/process.c index f36548e..db5a3b5 100644 --- a/server/process.c @@ -67,5 +67,5 @@ index f36548e..db5a3b5 100644 } -- -2.3.0 +2.3.3 diff --git a/patches/server-JobObjects/0006-kernel32-tests-Add-tests-for-JOB_OBJECT_LIMIT_KILL_O.patch b/patches/server-JobObjects/0006-kernel32-tests-Add-tests-for-JOB_OBJECT_LIMIT_KILL_O.patch deleted file mode 100644 index f1f00921..00000000 --- a/patches/server-JobObjects/0006-kernel32-tests-Add-tests-for-JOB_OBJECT_LIMIT_KILL_O.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 2bf4061460f17a0986efa2025d7808e11a388136 Mon Sep 17 00:00:00 2001 -From: Andrew Cook -Date: Thu, 26 Feb 2015 18:06:59 +0100 -Subject: kernel32/tests: Add tests for JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE. - -Cleanup and improvements by Sebastian Lackner . ---- - dlls/kernel32/tests/process.c | 37 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 37 insertions(+) - -diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c -index 9d39268..c86be74 100644 ---- a/dlls/kernel32/tests/process.c -+++ b/dlls/kernel32/tests/process.c -@@ -2422,6 +2422,42 @@ static void test_CompletionPort(void) - CloseHandle(port); - } - -+static void test_KillOnJobClose(void) -+{ -+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info; -+ PROCESS_INFORMATION pi; -+ DWORD dwret; -+ HANDLE job; -+ BOOL ret; -+ -+ job = pCreateJobObjectW(NULL, NULL); -+ ok(job != NULL, "CreateJobObject error %u\n", GetLastError()); -+ -+ limit_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; -+ ret = pSetInformationJobObject(job, JobObjectExtendedLimitInformation, &limit_info, sizeof(limit_info)); -+ if (!ret && GetLastError() == ERROR_INVALID_PARAMETER) -+ { -+ win_skip("Kill on job close limit not available\n"); -+ return; -+ } -+ ok(ret, "SetInformationJobObject error %u\n", GetLastError()); -+ -+ create_process("wait", &pi); -+ -+ ret = pAssignProcessToJobObject(job, pi.hProcess); -+ ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); -+ -+ CloseHandle(job); -+ -+ dwret = WaitForSingleObject(pi.hProcess, 500); -+ todo_wine -+ ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); -+ if (dwret == WAIT_TIMEOUT) TerminateProcess(pi.hProcess, 0); -+ -+ CloseHandle(pi.hProcess); -+ CloseHandle(pi.hThread); -+} -+ - START_TEST(process) - { - BOOL b = init(); -@@ -2486,4 +2522,5 @@ START_TEST(process) - test_TerminateJobObject(); - test_QueryInformationJobObject(); - test_CompletionPort(); -+ test_KillOnJobClose(); - } --- -2.3.0 - diff --git a/patches/server-JobObjects/0016-kernel32-tests-Add-tests-for-waiting-on-an-job-objec.patch b/patches/server-JobObjects/0006-kernel32-tests-Add-tests-for-waiting-on-an-job-objec.patch similarity index 90% rename from patches/server-JobObjects/0016-kernel32-tests-Add-tests-for-waiting-on-an-job-objec.patch rename to patches/server-JobObjects/0006-kernel32-tests-Add-tests-for-waiting-on-an-job-objec.patch index 3c90527a..0dea1bc6 100644 --- a/patches/server-JobObjects/0016-kernel32-tests-Add-tests-for-waiting-on-an-job-objec.patch +++ b/patches/server-JobObjects/0006-kernel32-tests-Add-tests-for-waiting-on-an-job-objec.patch @@ -1,4 +1,4 @@ -From b495ef0dc754b1dcdda42e0f42a6a5305682e26c Mon Sep 17 00:00:00 2001 +From f55bd1380e177f8fd48003fc3b1efae0c16b4c42 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner 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 44d98f7..e0da270 100644 +index e20fb92..31a4c1d 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c -@@ -2475,6 +2475,90 @@ static void test_KillOnJobClose(void) +@@ -2442,6 +2442,90 @@ static void test_KillOnJobClose(void) CloseHandle(pi.hThread); } @@ -99,17 +99,17 @@ index 44d98f7..e0da270 100644 + CloseHandle(job); +} + - static HANDLE test_LimitActiveProcesses(void) + static HANDLE test_AddSelfToJob(void) { - JOBOBJECT_BASIC_LIMIT_INFORMATION limit_info; -@@ -2731,6 +2815,7 @@ START_TEST(process) + HANDLE job; +@@ -2662,6 +2746,7 @@ START_TEST(process) test_QueryInformationJobObject(); test_CompletionPort(); test_KillOnJobClose(); + test_WaitForJobObject(); - job = test_LimitActiveProcesses(); + job = test_AddSelfToJob(); + test_jobInheritance(job); test_BreakawayOk(job); - CloseHandle(job); -- -2.3.0 +2.3.3 diff --git a/patches/server-JobObjects/0007-kernel32-tests-Add-tests-for-JOB_OBJECT_LIMIT_ACTIVE.patch b/patches/server-JobObjects/0007-kernel32-tests-Add-tests-for-JOB_OBJECT_LIMIT_ACTIVE.patch deleted file mode 100644 index acd781c2..00000000 --- a/patches/server-JobObjects/0007-kernel32-tests-Add-tests-for-JOB_OBJECT_LIMIT_ACTIVE.patch +++ /dev/null @@ -1,122 +0,0 @@ -From de031368ea2def75f9eeb259caa17af7bc14a013 Mon Sep 17 00:00:00 2001 -From: Andrew Cook -Date: Thu, 26 Feb 2015 18:50:14 +0100 -Subject: kernel32/tests: Add tests for JOB_OBJECT_LIMIT_ACTIVE_PROCESS. - -Cleanup and improvements by Sebastian Lackner . ---- - dlls/kernel32/tests/process.c | 93 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 93 insertions(+) - -diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c -index c86be74..028053b 100644 ---- a/dlls/kernel32/tests/process.c -+++ b/dlls/kernel32/tests/process.c -@@ -2458,6 +2458,98 @@ static void test_KillOnJobClose(void) - CloseHandle(pi.hThread); - } - -+static void test_LimitActiveProcesses(void) -+{ -+ JOBOBJECT_BASIC_LIMIT_INFORMATION limit_info; -+ PROCESS_INFORMATION pi[2]; -+ STARTUPINFOA si = {0}; -+ char buffer[MAX_PATH] = ""; -+ DWORD dwret; -+ HANDLE job; -+ BOOL ret; -+ -+ job = pCreateJobObjectW(NULL, NULL); -+ ok(job != NULL, "CreateJobObject error %u\n", GetLastError()); -+ -+ limit_info.LimitFlags = JOB_OBJECT_LIMIT_ACTIVE_PROCESS; -+ limit_info.ActiveProcessLimit = 1; -+ ret = pSetInformationJobObject(job, JobObjectBasicLimitInformation, &limit_info, sizeof(limit_info)); -+ ok(ret, "SetInformationJobObject error %u\n", GetLastError()); -+ -+ /* Only active processes count toward the limit */ -+ create_process("exit", &pi[0]); -+ dwret = WaitForSingleObject(pi[0].hProcess, 1000); -+ ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); -+ CloseHandle(pi[0].hProcess); -+ CloseHandle(pi[0].hThread); -+ -+ create_process("wait", &pi[0]); -+ create_process("wait", &pi[1]); -+ -+ ret = pAssignProcessToJobObject(job, pi[0].hProcess); -+ ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); -+ -+ ret = pAssignProcessToJobObject(job, pi[1].hProcess); -+ todo_wine -+ ok(!ret, "AssignProcessToJobObject expected failure\n"); -+ todo_wine -+ expect_eq_d(ERROR_NOT_ENOUGH_QUOTA, GetLastError()); -+ -+ /* Fails randomly on 2000 and xp */ -+ dwret = WaitForSingleObject(pi[1].hProcess, 500); -+ todo_wine -+ ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); -+ if (dwret == WAIT_OBJECT_0) -+ { -+ dwret = 0xdeadbeef; -+ ret = GetExitCodeProcess(pi[1].hProcess, &dwret); -+ ok(ret, "GetExitCodeProcess error %u\n", GetLastError()); -+ ok(dwret == ERROR_NOT_ENOUGH_QUOTA || broken(dwret == 0) /* randomly fails on Win 2000 / XP */, -+ "wrong exitcode %u\n", dwret); -+ } -+ else -+ { -+ TerminateProcess(pi[1].hProcess, 0); -+ } -+ -+ CloseHandle(pi[1].hProcess); -+ CloseHandle(pi[1].hThread); -+ -+ limit_info.LimitFlags = JOB_OBJECT_LIMIT_ACTIVE_PROCESS; -+ limit_info.ActiveProcessLimit = 2; -+ ret = pSetInformationJobObject(job, JobObjectBasicLimitInformation, &limit_info, sizeof(limit_info)); -+ ok(ret, "SetInformationJobObject error %u\n", GetLastError()); -+ -+ ret = pAssignProcessToJobObject(job, GetCurrentProcess()); -+ ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); -+ -+ snprintf(buffer, MAX_PATH, "\"%s\" tests/process.c %s", selfname, "exit"); -+ -+ ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi[1]); -+ todo_wine -+ ok(!ret, "CreateProcessA expected failure\n"); -+ todo_wine -+ expect_eq_d(ERROR_NOT_ENOUGH_QUOTA, GetLastError()); -+ -+ if (ret) -+ { -+ TerminateProcess(pi[1].hProcess, 0); -+ -+ dwret = WaitForSingleObject(pi[1].hProcess, 500); -+ ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); -+ -+ CloseHandle(pi[1].hProcess); -+ CloseHandle(pi[1].hThread); -+ } -+ -+ TerminateProcess(pi[0].hProcess, 0); -+ -+ CloseHandle(pi[0].hProcess); -+ CloseHandle(pi[0].hThread); -+ -+ CloseHandle(job); -+} -+ - START_TEST(process) - { - BOOL b = init(); -@@ -2523,4 +2615,5 @@ START_TEST(process) - test_QueryInformationJobObject(); - test_CompletionPort(); - test_KillOnJobClose(); -+ test_LimitActiveProcesses(); - } --- -2.3.0 - diff --git a/patches/server-JobObjects/0017-server-Implement-waiting-for-job-objects.patch b/patches/server-JobObjects/0007-server-Implement-waiting-for-job-objects.patch similarity index 100% rename from patches/server-JobObjects/0017-server-Implement-waiting-for-job-objects.patch rename to patches/server-JobObjects/0007-server-Implement-waiting-for-job-objects.patch diff --git a/patches/server-JobObjects/0008-kernel32-tests-Add-tests-for-JOB_OBJECT_LIMIT_BREAKA.patch b/patches/server-JobObjects/0008-kernel32-tests-Add-tests-for-JOB_OBJECT_LIMIT_BREAKA.patch deleted file mode 100644 index f1e017fa..00000000 --- a/patches/server-JobObjects/0008-kernel32-tests-Add-tests-for-JOB_OBJECT_LIMIT_BREAKA.patch +++ /dev/null @@ -1,123 +0,0 @@ -From cccd5e98e933fd8141f7e6924ba2d69c0c3339b8 Mon Sep 17 00:00:00 2001 -From: Andrew Cook -Date: Thu, 26 Feb 2015 19:03:00 +0100 -Subject: kernel32/tests: Add tests for JOB_OBJECT_LIMIT_BREAKAWAY_OK. - -Cleanup and improvements by Sebastian Lackner . ---- - dlls/kernel32/tests/process.c | 83 +++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 80 insertions(+), 3 deletions(-) - -diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c -index 028053b..f3f9552 100644 ---- a/dlls/kernel32/tests/process.c -+++ b/dlls/kernel32/tests/process.c -@@ -2458,7 +2458,7 @@ static void test_KillOnJobClose(void) - CloseHandle(pi.hThread); - } - --static void test_LimitActiveProcesses(void) -+static HANDLE test_LimitActiveProcesses(void) - { - JOBOBJECT_BASIC_LIMIT_INFORMATION limit_info; - PROCESS_INFORMATION pi[2]; -@@ -2547,11 +2547,86 @@ static void test_LimitActiveProcesses(void) - CloseHandle(pi[0].hProcess); - CloseHandle(pi[0].hThread); - -- CloseHandle(job); -+ return job; -+} -+ -+static void test_BreakawayOk(HANDLE job) -+{ -+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info; -+ PROCESS_INFORMATION pi; -+ STARTUPINFOA si = {0}; -+ char buffer[MAX_PATH]; -+ BOOL ret, out; -+ DWORD dwret; -+ -+ if (!pIsProcessInJob) -+ { -+ win_skip("IsProcessInJob not available.\n"); -+ return; -+ } -+ -+ 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) -+ { -+ TerminateProcess(pi.hProcess, 0); -+ -+ dwret = WaitForSingleObject(pi.hProcess, 500); -+ ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); -+ -+ CloseHandle(pi.hProcess); -+ CloseHandle(pi.hThread); -+ } -+ -+ limit_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_BREAKAWAY_OK; -+ ret = pSetInformationJobObject(job, JobObjectExtendedLimitInformation, &limit_info, sizeof(limit_info)); -+ ok(ret, "SetInformationJobObject error %u\n", GetLastError()); -+ -+ ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &si, &pi); -+ ok(ret, "CreateProcessA error %u\n", GetLastError()); -+ -+ ret = pIsProcessInJob(pi.hProcess, job, &out); -+ ok(ret, "IsProcessInJob error %u\n", GetLastError()); -+ ok(!out, "IsProcessInJob returned out=%u\n", out); -+ -+ dwret = WaitForSingleObject(pi.hProcess, 500); -+ ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); -+ -+ CloseHandle(pi.hProcess); -+ CloseHandle(pi.hThread); -+ -+ limit_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK; -+ ret = pSetInformationJobObject(job, JobObjectExtendedLimitInformation, &limit_info, sizeof(limit_info)); -+ ok(ret, "SetInformationJobObject error %u\n", GetLastError()); -+ -+ ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); -+ ok(ret, "CreateProcess error %u\n", GetLastError()); -+ -+ ret = pIsProcessInJob(pi.hProcess, job, &out); -+ ok(ret, "IsProcessInJob error %u\n", GetLastError()); -+ ok(!out, "IsProcessInJob returned out=%u\n", out); -+ -+ dwret = WaitForSingleObject(pi.hProcess, 500); -+ ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); -+ -+ CloseHandle(pi.hProcess); -+ CloseHandle(pi.hThread); -+ -+ /* unset breakaway ok */ -+ limit_info.BasicLimitInformation.LimitFlags = 0; -+ ret = pSetInformationJobObject(job, JobObjectExtendedLimitInformation, &limit_info, sizeof(limit_info)); -+ ok(ret, "SetInformationJobObject error %u\n", GetLastError()); - } - - START_TEST(process) - { -+ HANDLE job; - BOOL b = init(); - ok(b, "Basic init of CreateProcess test\n"); - if (!b) return; -@@ -2615,5 +2690,7 @@ START_TEST(process) - test_QueryInformationJobObject(); - test_CompletionPort(); - test_KillOnJobClose(); -- test_LimitActiveProcesses(); -+ job = test_LimitActiveProcesses(); -+ test_BreakawayOk(job); -+ CloseHandle(job); - } --- -2.3.0 - diff --git a/patches/server-JobObjects/0018-ntdll-Implement-NtQueryInformationJobObject-stub-fun.patch b/patches/server-JobObjects/0008-ntdll-Implement-NtQueryInformationJobObject-stub-fun.patch similarity index 100% rename from patches/server-JobObjects/0018-ntdll-Implement-NtQueryInformationJobObject-stub-fun.patch rename to patches/server-JobObjects/0008-ntdll-Implement-NtQueryInformationJobObject-stub-fun.patch diff --git a/patches/server-JobObjects/0009-kernel32-tests-Add-tests-for-job-inheritance.patch b/patches/server-JobObjects/0009-kernel32-tests-Add-tests-for-job-inheritance.patch deleted file mode 100644 index 79235cb9..00000000 --- a/patches/server-JobObjects/0009-kernel32-tests-Add-tests-for-job-inheritance.patch +++ /dev/null @@ -1,60 +0,0 @@ -From b7f6fb29fec1d258bc1db2c110044e2ae2779f9f Mon Sep 17 00:00:00 2001 -From: Andrew Cook -Date: Thu, 26 Feb 2015 22:30:28 +0100 -Subject: kernel32/tests: Add tests for job inheritance. - -Cleanup and improvements by Sebastian Lackner . ---- - dlls/kernel32/tests/process.c | 29 ++++++++++++++++++++++++++++- - 1 file changed, 28 insertions(+), 1 deletion(-) - -diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c -index f3f9552..466c231 100644 ---- a/dlls/kernel32/tests/process.c -+++ b/dlls/kernel32/tests/process.c -@@ -2466,7 +2466,7 @@ static HANDLE test_LimitActiveProcesses(void) - char buffer[MAX_PATH] = ""; - DWORD dwret; - HANDLE job; -- BOOL ret; -+ BOOL ret, out; - - job = pCreateJobObjectW(NULL, NULL); - ok(job != NULL, "CreateJobObject error %u\n", GetLastError()); -@@ -2547,6 +2547,33 @@ static HANDLE test_LimitActiveProcesses(void) - CloseHandle(pi[0].hProcess); - CloseHandle(pi[0].hThread); - -+ /* remove quota again */ -+ limit_info.LimitFlags = 0; -+ ret = pSetInformationJobObject(job, JobObjectBasicLimitInformation, &limit_info, sizeof(limit_info)); -+ ok(ret, "SetInformationJobObject error %u\n", GetLastError()); -+ -+ if (!pIsProcessInJob) -+ { -+ win_skip("IsProcessInJob not available.\n"); -+ goto out; -+ } -+ -+ ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi[0]); -+ ok(ret, "CreateProcessA error %u\n", GetLastError()); -+ -+ out = FALSE; -+ ret = pIsProcessInJob(pi[0].hProcess, job, &out); -+ ok(ret, "IsProcessInJob error %u\n", GetLastError()); -+ todo_wine -+ ok(out, "IsProcessInJob returned out=%u\n", out); -+ -+ dwret = WaitForSingleObject(pi[0].hProcess, 500); -+ ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); -+ -+ CloseHandle(pi[0].hProcess); -+ CloseHandle(pi[0].hThread); -+ -+out: - return job; - } - --- -2.3.0 - diff --git a/patches/server-JobObjects/0010-kernel32-tests-Add-tests-for-adding-a-terminated-pro.patch b/patches/server-JobObjects/0010-kernel32-tests-Add-tests-for-adding-a-terminated-pro.patch deleted file mode 100644 index 1f8df279..00000000 --- a/patches/server-JobObjects/0010-kernel32-tests-Add-tests-for-adding-a-terminated-pro.patch +++ /dev/null @@ -1,41 +0,0 @@ -From c3de2aeaf6101fb30a99bc8e7eaea614d97c4049 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 28 Feb 2015 06:34:24 +0100 -Subject: kernel32/tests: Add tests for adding a terminated process to a job - object. - ---- - dlls/kernel32/tests/process.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c -index 466c231..a464db2 100644 ---- a/dlls/kernel32/tests/process.c -+++ b/dlls/kernel32/tests/process.c -@@ -2260,6 +2260,23 @@ static void test_IsProcessInJob(void) - - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); -+ -+ /* Test adding an already terminated process to a job object */ -+ create_process("exit", &pi); -+ -+ dwret = WaitForSingleObject(pi.hProcess, 500); -+ ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); -+ -+ SetLastError(0xdeadbeef); -+ ret = pAssignProcessToJobObject(job, pi.hProcess); -+ todo_wine -+ ok(!ret, "AssignProcessToJobObject unexpectedly succeeded\n"); -+ todo_wine -+ expect_eq_d(ERROR_ACCESS_DENIED, GetLastError()); -+ -+ CloseHandle(pi.hProcess); -+ CloseHandle(pi.hThread); -+ - CloseHandle(job); - } - --- -2.3.0 - diff --git a/patches/server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch b/patches/server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch index 16145b90..5e84e6a0 100644 --- a/patches/server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch +++ b/patches/server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch @@ -1,13 +1,13 @@ -From f2866f1d9f575eab3034f71128c9e68c81e0138a Mon Sep 17 00:00:00 2001 +From 0e4cf36464b0ec84af3baf7feea3813dae9475ba Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Thu, 17 Apr 2014 16:07:46 -0600 Subject: server: Unify the storage of security attributes for files and directories. (try 7) --- - server/change.c | 46 ++++++---------------------------------------- - server/file.c | 25 +++++++++++++++++-------- - server/file.h | 2 ++ + server/change.c | 46 ++++++---------------------------------------- + server/file.c | 25 +++++++++++++++++-------- + server/file.h | 2 ++ 3 files changed, 25 insertions(+), 48 deletions(-) diff --git a/server/change.c b/server/change.c @@ -71,11 +71,11 @@ index 3ac70a4..4f6ce81 100644 static struct change_record *get_first_change_record( struct dir *dir ) diff --git a/server/file.c b/server/file.c -index cceb8ad..fb89272 100644 +index c8c880b..9777af4 100644 --- a/server/file.c +++ b/server/file.c -@@ -534,18 +534,13 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ) - return new_mode & ~denied_mode; +@@ -544,18 +544,13 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ) + return new_mode; } -static int file_set_sd( struct object *obj, const struct security_descriptor *sd, @@ -96,7 +96,7 @@ index cceb8ad..fb89272 100644 if (unix_fd == -1 || fstat( unix_fd, &st ) == -1) return 1; -@@ -584,6 +579,20 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd +@@ -594,6 +589,20 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd return 1; } @@ -118,10 +118,10 @@ index cceb8ad..fb89272 100644 { struct file *file = (struct file *)obj; diff --git a/server/file.h b/server/file.h -index 493d30b..76cb383 100644 +index 85e4257..524a688 100644 --- a/server/file.h +++ b/server/file.h -@@ -122,6 +122,8 @@ extern struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, +@@ -124,6 +124,8 @@ extern struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, extern void file_set_error(void); extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID *group ); extern mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ); @@ -131,5 +131,5 @@ index 493d30b..76cb383 100644 /* file mapping functions */ -- -1.7.9.5 +2.3.3 diff --git a/patches/wined3d-CSMT_Main/0043-wined3d-Move-the-framebuffer-into-wined3d_state.patch b/patches/wined3d-CSMT_Main/0043-wined3d-Move-the-framebuffer-into-wined3d_state.patch index b46164a4..73d05d84 100644 --- a/patches/wined3d-CSMT_Main/0043-wined3d-Move-the-framebuffer-into-wined3d_state.patch +++ b/patches/wined3d-CSMT_Main/0043-wined3d-Move-the-framebuffer-into-wined3d_state.patch @@ -1,4 +1,4 @@ -From 3633fb5bf88a562326133b84ba9105aff2cbd3c4 Mon Sep 17 00:00:00 2001 +From 819f7f67ac69f32981342604f7aa0b011377a891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Thu, 20 Dec 2012 13:09:17 +0100 Subject: wined3d: Move the framebuffer into wined3d_state @@ -577,10 +577,10 @@ index f2c2f42..c6a72fc 100644 surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c -index 0fa8308..c7216de 100644 +index e4ddbe6..9d27b50 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c -@@ -964,7 +964,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont +@@ -1064,7 +1064,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont const struct wined3d_state *state = &shader->device->state; const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args; const struct wined3d_gl_info *gl_info = context->gl_info; @@ -603,7 +603,7 @@ index 31b391b..6dc1abd 100644 { static unsigned int warned = 0; diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c -index a949077..f81ab33 100644 +index 69623af..90aae0a 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -105,7 +105,7 @@ static void state_zenable(struct wined3d_context *context, const struct wined3d_ @@ -816,19 +816,19 @@ index dd7d2c7..ed2964e 100644 struct wined3d_context *context; struct wined3d_surface *front; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c -index a772af8..d2e7fdc 100644 +index 468aea9..948b793 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c -@@ -3183,7 +3183,7 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w - float y_offset = (float)(context->render_offscreen - ? (63.0 / 64.0 - (2.0 * y) - h) / h - : (63.0 / 64.0 - (2.0 * y) - h) / -h); +@@ -3190,7 +3190,7 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w + float y_offset = context->render_offscreen + ? (center_offset - (2.0f * y) - h) / h + : (center_offset - (2.0f * y) - h) / -h; - enum wined3d_depth_buffer_type zenable = state->fb->depth_stencil ? + enum wined3d_depth_buffer_type zenable = state->fb.depth_stencil ? state->render_states[WINED3D_RS_ZENABLE] : WINED3D_ZB_FALSE; float z_scale = zenable ? 2.0f : 0.0f; float z_offset = zenable ? -1.0f : 0.0f; -@@ -3613,7 +3613,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d +@@ -3620,7 +3620,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d unsigned int i; DWORD ttff; DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2; @@ -838,10 +838,10 @@ index a772af8..d2e7fdc 100644 const struct wined3d_d3d_info *d3d_info = context->d3d_info; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 0f1dfdd..6a5e4b8 100644 +index 03831b8..e922f86 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -1120,6 +1120,36 @@ struct wined3d_timestamp_query +@@ -1121,6 +1121,36 @@ struct wined3d_timestamp_query void context_alloc_timestamp_query(struct wined3d_context *context, struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; void context_free_timestamp_query(struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; @@ -878,7 +878,7 @@ index 0f1dfdd..6a5e4b8 100644 struct wined3d_context { const struct wined3d_gl_info *gl_info; -@@ -1134,6 +1164,7 @@ struct wined3d_context +@@ -1135,6 +1165,7 @@ struct wined3d_context DWORD dirtyArray[STATE_HIGHEST + 1]; /* Won't get bigger than that, a state is never marked dirty 2 times */ DWORD numDirtyEntries; DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */ @@ -886,7 +886,7 @@ index 0f1dfdd..6a5e4b8 100644 struct wined3d_swapchain *swapchain; struct wined3d_surface *current_rt; -@@ -1235,12 +1266,6 @@ struct wined3d_context +@@ -1236,12 +1267,6 @@ struct wined3d_context GLuint dummy_arbfp_prog; }; @@ -899,7 +899,7 @@ index 0f1dfdd..6a5e4b8 100644 typedef void (*APPLYSTATEFUNC)(struct wined3d_context *ctx, const struct wined3d_state *state, DWORD state_id); struct StateEntry -@@ -1917,7 +1942,7 @@ struct wined3d_stream_state +@@ -1918,7 +1943,7 @@ struct wined3d_stream_state struct wined3d_state { DWORD flags; @@ -908,7 +908,7 @@ index 0f1dfdd..6a5e4b8 100644 struct wined3d_vertex_declaration *vertex_declaration; struct wined3d_stream_output stream_output[MAX_STREAM_OUT]; -@@ -2023,7 +2048,6 @@ struct wined3d_device +@@ -2024,7 +2049,6 @@ struct wined3d_device struct wine_rb_tree samplers; /* Render Target Support */ @@ -916,7 +916,7 @@ index 0f1dfdd..6a5e4b8 100644 struct wined3d_surface *onscreen_depth_stencil; struct wined3d_rendertarget_view *auto_depth_stencil_view; -@@ -2527,9 +2551,8 @@ struct wined3d_stateblock +@@ -2528,9 +2552,8 @@ struct wined3d_stateblock void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN; void state_cleanup(struct wined3d_state *state) DECLSPEC_HIDDEN; @@ -928,7 +928,7 @@ index 0f1dfdd..6a5e4b8 100644 void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN; struct wined3d_cs_ops -@@ -2542,7 +2565,6 @@ struct wined3d_cs +@@ -2543,7 +2566,6 @@ struct wined3d_cs { const struct wined3d_cs_ops *ops; struct wined3d_device *device; diff --git a/patches/wined3d-CSMT_Main/9999-IfDefined.patch b/patches/wined3d-CSMT_Main/9999-IfDefined.patch index 5dd5c83b..fb250315 100644 --- a/patches/wined3d-CSMT_Main/9999-IfDefined.patch +++ b/patches/wined3d-CSMT_Main/9999-IfDefined.patch @@ -1092,10 +1092,10 @@ diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c -@@ -3183,7 +3183,11 @@ - float y_offset = (float)(context->render_offscreen - ? (63.0 / 64.0 - (2.0 * y) - h) / h - : (63.0 / 64.0 - (2.0 * y) - h) / -h); +@@ -3190,7 +3190,11 @@ + float y_offset = context->render_offscreen + ? (center_offset - (2.0f * y) - h) / h + : (center_offset - (2.0f * y) - h) / -h; +#if defined(STAGING_CSMT) enum wined3d_depth_buffer_type zenable = state->fb.depth_stencil ? +#else /* STAGING_CSMT */ @@ -1104,7 +1104,7 @@ diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c state->render_states[WINED3D_RS_ZENABLE] : WINED3D_ZB_FALSE; float z_scale = zenable ? 2.0f : 0.0f; float z_offset = zenable ? -1.0f : 0.0f; -@@ -3306,6 +3310,7 @@ +@@ -3313,6 +3317,7 @@ /* case WINED3D_TTFF_COUNT1: Won't ever get here. */ case WINED3D_TTFF_COUNT2: mat._13 = mat._23 = mat._33 = mat._43 = 0.0f; @@ -1112,7 +1112,7 @@ diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c /* OpenGL divides the first 3 vertex coord by the 4th by default, * which is essentially the same as D3DTTFF_PROJECTED. Make sure that * the 4th coord evaluates to 1.0 to eliminate that. -@@ -3318,6 +3323,20 @@ +@@ -3325,6 +3330,20 @@ * A more serious problem occurs if the app passes 4 coordinates in, and the * 4th is != 1.0(opengl default). This would have to be fixed in draw_strided_slow * or a replacement shader. */ @@ -1133,7 +1133,7 @@ diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c default: mat._14 = mat._24 = mat._34 = 0.0f; mat._44 = 1.0f; } -@@ -3613,7 +3632,11 @@ +@@ -3620,7 +3639,11 @@ unsigned int i; DWORD ttff; DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2; diff --git a/patches/ws2_32-WriteWatches/0002-ws2_32-Avoid-race-conditions-of-async-WSARecv-operat.patch b/patches/ws2_32-WriteWatches/0002-ws2_32-Avoid-race-conditions-of-async-WSARecv-operat.patch index bc80c215..f184e08f 100644 --- a/patches/ws2_32-WriteWatches/0002-ws2_32-Avoid-race-conditions-of-async-WSARecv-operat.patch +++ b/patches/ws2_32-WriteWatches/0002-ws2_32-Avoid-race-conditions-of-async-WSARecv-operat.patch @@ -1,4 +1,4 @@ -From ae757e6bb862919e3b5a59bdb590555c462258ee Mon Sep 17 00:00:00 2001 +From 1fa875d307b456f103fd9ab225fe4b5a6272e602 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Fri, 21 Nov 2014 12:22:46 +0100 Subject: ws2_32: Avoid race-conditions of async WSARecv() operations with @@ -41,12 +41,12 @@ that data is immediately available. 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c -index a9ab0a5..9d94893 100644 +index 4444011..e287c2b 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c -@@ -1930,7 +1930,17 @@ static int WS2_recv( int fd, struct ws2_async *wsa ) +@@ -2014,7 +2014,17 @@ static int WS2_recv( int fd, struct ws2_async *wsa, int flags ) - while ((n = recvmsg(fd, &hdr, wsa->flags)) == -1) + while ((n = recvmsg(fd, &hdr, flags)) == -1) { - if (errno != EINTR) + if (errno == EFAULT) @@ -64,5 +64,5 @@ index a9ab0a5..9d94893 100644 } -- -2.2.1 +2.3.3