diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 4a1de02b..ae763342 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -4998,13 +4998,18 @@ fi # | * [#37087] Do not hold reference on parent process in wineserver # | # | Modified files: -# | * server/console.c, server/process.c, server/process.h, server/snapshot.c, server/thread.c, server/token.c +# | * dlls/kernel32/tests/process.c, server/console.c, server/process.c, server/process.h, server/snapshot.c, server/thread.c, +# | server/token.c # | if test "$enable_server_Parent_Process" -eq 1; then - patch_apply server-Parent_Process/0001-server-token_duplicate-should-not-reference-the-orig.patch - patch_apply server-Parent_Process/0002-server-Increase-size-of-PID-table-to-512-to-reduce-r.patch - patch_apply server-Parent_Process/0003-server-Do-not-hold-reference-on-parent-process.patch + patch_apply server-Parent_Process/0001-kernel32-tests-Remove-unnecessary-call-to-GetExitCod.patch + patch_apply server-Parent_Process/0002-kernel32-tests-Add-test-for-process-object-destructi.patch + patch_apply server-Parent_Process/0003-server-token_duplicate-should-not-reference-the-orig.patch + patch_apply server-Parent_Process/0004-server-Increase-size-of-PID-table-to-512-to-reduce-r.patch + patch_apply server-Parent_Process/0005-server-Do-not-hold-reference-on-parent-process.patch ( + echo '+ { "Sebastian Lackner", "kernel32/tests: Remove unnecessary call to GetExitCodeProcess in process tests.", 1 },'; + echo '+ { "Sebastian Lackner", "kernel32/tests: Add test for process object destruction.", 1 },'; echo '+ { "Sebastian Lackner", "server: Token_duplicate should not reference the original token, which will get destroyed on process exit.", 1 },'; echo '+ { "Sebastian Lackner", "server: Increase size of PID table to 512 to reduce risk of collisions.", 1 },'; echo '+ { "Sebastian Lackner", "server: Do not hold reference on parent process.", 1 },'; diff --git a/patches/server-Parent_Process/0001-kernel32-tests-Remove-unnecessary-call-to-GetExitCod.patch b/patches/server-Parent_Process/0001-kernel32-tests-Remove-unnecessary-call-to-GetExitCod.patch new file mode 100644 index 00000000..281150be --- /dev/null +++ b/patches/server-Parent_Process/0001-kernel32-tests-Remove-unnecessary-call-to-GetExitCod.patch @@ -0,0 +1,33 @@ +From 3b2e19cfcb3d5d1a901fee4bcdeba7b424d128ed Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 12 Dec 2015 06:53:57 +0100 +Subject: kernel32/tests: Remove unnecessary call to GetExitCodeProcess in + process tests. + +--- + dlls/kernel32/tests/process.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c +index 6dc1f5e..f186c94 100644 +--- a/dlls/kernel32/tests/process.c ++++ b/dlls/kernel32/tests/process.c +@@ -2729,7 +2729,6 @@ static void test_StartupNoConsole(void) + char buffer[MAX_PATH]; + STARTUPINFOA startup; + PROCESS_INFORMATION info; +- DWORD code; + + if (!pNtCurrentTeb) + { +@@ -2746,7 +2745,6 @@ static void test_StartupNoConsole(void) + 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"); +- ok(GetExitCodeProcess(info.hProcess, &code), "Getting exit code\n"); + WritePrivateProfileStringA(NULL, NULL, NULL, resfile); + okChildInt("StartupInfoA", "hStdInput", (UINT)INVALID_HANDLE_VALUE); + okChildInt("StartupInfoA", "hStdOutput", (UINT)INVALID_HANDLE_VALUE); +-- +2.6.2 + diff --git a/patches/server-Parent_Process/0002-kernel32-tests-Add-test-for-process-object-destructi.patch b/patches/server-Parent_Process/0002-kernel32-tests-Add-test-for-process-object-destructi.patch new file mode 100644 index 00000000..41ab55ad --- /dev/null +++ b/patches/server-Parent_Process/0002-kernel32-tests-Add-test-for-process-object-destructi.patch @@ -0,0 +1,238 @@ +From 799244b5aa488e397c3744fbf9ce368ec52ab596 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 12 Dec 2015 15:08:40 +0100 +Subject: kernel32/tests: Add test for process object destruction. + +--- + dlls/kernel32/tests/process.c | 161 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 161 insertions(+) + +diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c +index f186c94..8e0f0c2 100644 +--- a/dlls/kernel32/tests/process.c ++++ b/dlls/kernel32/tests/process.c +@@ -33,11 +33,14 @@ + #include "wincon.h" + #include "winnls.h" + #include "winternl.h" ++#include "tlhelp32.h" + + #include "wine/test.h" + + /* PROCESS_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */ + #define PROCESS_ALL_ACCESS_NT4 (PROCESS_ALL_ACCESS & ~0xf000) ++/* THREAD_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */ ++#define THREAD_ALL_ACCESS_NT4 (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff) + + #define expect_eq_d(expected, actual) \ + do { \ +@@ -79,6 +82,12 @@ static BOOL (WINAPI *pGetNumaProcessorNode)(UCHAR, PUCHAR); + static NTSTATUS (WINAPI *pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); + static BOOL (WINAPI *pProcessIdToSessionId)(DWORD,DWORD*); + static DWORD (WINAPI *pWTSGetActiveConsoleSessionId)(void); ++static HANDLE (WINAPI *pCreateToolhelp32Snapshot)(DWORD, DWORD); ++static BOOL (WINAPI *pProcess32First)(HANDLE, PROCESSENTRY32*); ++static BOOL (WINAPI *pProcess32Next)(HANDLE, PROCESSENTRY32*); ++static BOOL (WINAPI *pThread32First)(HANDLE, THREADENTRY32*); ++static BOOL (WINAPI *pThread32Next)(HANDLE, THREADENTRY32*); ++ + + /* ############################### */ + static char base[MAX_PATH]; +@@ -237,6 +246,12 @@ static BOOL init(void) + pGetNumaProcessorNode = (void *)GetProcAddress(hkernel32, "GetNumaProcessorNode"); + pProcessIdToSessionId = (void *)GetProcAddress(hkernel32, "ProcessIdToSessionId"); + pWTSGetActiveConsoleSessionId = (void *)GetProcAddress(hkernel32, "WTSGetActiveConsoleSessionId"); ++ pCreateToolhelp32Snapshot = (void *)GetProcAddress(hkernel32, "CreateToolhelp32Snapshot"); ++ pProcess32First = (void *)GetProcAddress(hkernel32, "Process32First"); ++ pProcess32Next = (void *)GetProcAddress(hkernel32, "Process32Next"); ++ pThread32First = (void *)GetProcAddress(hkernel32, "Thread32First"); ++ pThread32Next = (void *)GetProcAddress(hkernel32, "Thread32Next"); ++ + return TRUE; + } + +@@ -287,6 +302,8 @@ static void doChild(const char* file, const char* option) + char bufA[MAX_PATH]; + WCHAR bufW[MAX_PATH]; + HANDLE hFile = CreateFileA(file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); ++ HANDLE snapshot; ++ PROCESSENTRY32 pe; + BOOL ret; + + if (hFile == INVALID_HANDLE_VALUE) return; +@@ -341,6 +358,26 @@ static void doChild(const char* file, const char* option) + childPrintf(hFile, "CommandLineA=%s\n", encodeA(GetCommandLineA())); + childPrintf(hFile, "CommandLineW=%s\n\n", encodeW(GetCommandLineW())); + ++ /* output toolhelp information */ ++ snapshot = pCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); ++ ok(snapshot != INVALID_HANDLE_VALUE, "CreateToolhelp32Snapshot failed %u\n", GetLastError()); ++ memset(&pe, 0, sizeof(pe)); ++ pe.dwSize = sizeof(pe); ++ if (pProcess32First(snapshot, &pe)) ++ { ++ while (pe.th32ProcessID != GetCurrentProcessId()) ++ if (!pProcess32Next(snapshot, &pe)) break; ++ } ++ CloseHandle(snapshot); ++ ok(pe.th32ProcessID == GetCurrentProcessId(), "failed to find current process in snapshot\n"); ++ childPrintf(hFile, ++ "[Toolhelp]\ncntUsage=%u\nth32DefaultHeapID=%lu\n" ++ "th32ModuleID=%u\ncntThreads=%u\nth32ParentProcessID=%u\n" ++ "pcPriClassBase=%u\ndwFlags=%u\nszExeFile=%s\n\n", ++ pe.cntUsage, pe.th32DefaultHeapID, pe.th32ModuleID, ++ pe.cntThreads, pe.th32ParentProcessID, pe.pcPriClassBase, ++ pe.dwFlags, encodeA(pe.szExeFile)); ++ + /* output of environment (Ansi) */ + ptrA_save = ptrA = GetEnvironmentStringsA(); + if (ptrA) +@@ -1065,6 +1102,112 @@ static void test_Directory(void) + ok(!TerminateProcess(info.hProcess, 0), "Child process should not exist\n"); + } + ++static void test_Toolhelp(void) ++{ ++ char buffer[MAX_PATH]; ++ STARTUPINFOA startup; ++ PROCESS_INFORMATION info; ++ HANDLE process, thread, snapshot; ++ PROCESSENTRY32 pe; ++ THREADENTRY32 te; ++ DWORD ret; ++ int i; ++ ++ memset(&startup, 0, sizeof(startup)); ++ startup.cb = sizeof(startup); ++ startup.dwFlags = STARTF_USESHOWWINDOW; ++ startup.wShowWindow = SW_SHOWNORMAL; ++ ++ get_file_name(resfile); ++ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\"", selfname, resfile); ++ ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess failed\n"); ++ ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); ++ CloseHandle(info.hProcess); ++ CloseHandle(info.hThread); ++ ++ WritePrivateProfileStringA(NULL, NULL, NULL, resfile); ++ okChildInt("Toolhelp", "cntUsage", 0); ++ okChildInt("Toolhelp", "th32DefaultHeapID", 0); ++ okChildInt("Toolhelp", "th32ModuleID", 0); ++ okChildInt("Toolhelp", "th32ParentProcessID", GetCurrentProcessId()); ++ todo_wine okChildInt("Toolhelp", "pcPriClassBase", 8); ++ okChildInt("Toolhelp", "dwFlags", 0); ++ ++ release_memory(); ++ DeleteFileA(resfile); ++ ++ get_file_name(resfile); ++ sprintf(buffer, "\"%s\" tests/process.c nested \"%s\"", selfname, resfile); ++ ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess failed\n"); ++ ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); ++ ++ process = OpenProcess(PROCESS_ALL_ACCESS_NT4, FALSE, info.dwProcessId); ++ ok(process != NULL, "OpenProcess failed %u\n", GetLastError()); ++ CloseHandle(process); ++ ++ CloseHandle(info.hProcess); ++ CloseHandle(info.hThread); ++ ++ for (i = 0; i < 20; i++) ++ { ++ SetLastError(0xdeadbeef); ++ process = OpenProcess(PROCESS_ALL_ACCESS_NT4, FALSE, info.dwProcessId); ++ ok(process || GetLastError() == ERROR_INVALID_PARAMETER, "OpenProcess failed %u\n", GetLastError()); ++ if (!process) break; ++ CloseHandle(process); ++ Sleep(100); ++ } ++ /* The following test fails randomly on some Windows versions */ ++ todo_wine ok(i < 20 || broken(i == 20), "process object not released\n"); ++ ++ snapshot = pCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); ++ ok(snapshot != INVALID_HANDLE_VALUE, "CreateToolhelp32Snapshot failed %u\n", GetLastError()); ++ memset(&pe, 0, sizeof(pe)); ++ pe.dwSize = sizeof(pe); ++ if (pProcess32First(snapshot, &pe)) ++ { ++ while (pe.th32ParentProcessID != info.dwProcessId) ++ if (!pProcess32Next(snapshot, &pe)) break; ++ } ++ CloseHandle(snapshot); ++ ok(pe.th32ParentProcessID == info.dwProcessId, "failed to find nested child process\n"); ++ ++ process = OpenProcess(PROCESS_ALL_ACCESS_NT4, FALSE, pe.th32ProcessID); ++ ok(process != NULL, "OpenProcess failed %u\n", GetLastError()); ++ ++ snapshot = pCreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); ++ ok(snapshot != INVALID_HANDLE_VALUE, "CreateToolhelp32Snapshot failed %u\n", GetLastError()); ++ memset(&te, 0, sizeof(te)); ++ te.dwSize = sizeof(te); ++ if (pThread32First(snapshot, &te)) ++ { ++ while (te.th32OwnerProcessID != pe.th32ProcessID) ++ if (!pThread32Next(snapshot, &te)) break; ++ } ++ CloseHandle(snapshot); ++ ok(te.th32OwnerProcessID == pe.th32ProcessID, "failed to find suspended thread\n"); ++ ++ thread = OpenThread(THREAD_ALL_ACCESS_NT4, FALSE, te.th32ThreadID); ++ ok(thread != NULL, "OpenThread failed %u\n", GetLastError()); ++ ret = ResumeThread(thread); ++ ok(ret == 1, "expected 1, got %u\n", ret); ++ CloseHandle(thread); ++ ++ ok(WaitForSingleObject(process, 30000) == WAIT_OBJECT_0, "Child process termination\n"); ++ CloseHandle(process); ++ ++ WritePrivateProfileStringA(NULL, NULL, NULL, resfile); ++ okChildInt("Toolhelp", "cntUsage", 0); ++ okChildInt("Toolhelp", "th32DefaultHeapID", 0); ++ okChildInt("Toolhelp", "th32ModuleID", 0); ++ okChildInt("Toolhelp", "th32ParentProcessID", info.dwProcessId); ++ todo_wine okChildInt("Toolhelp", "pcPriClassBase", 8); ++ okChildInt("Toolhelp", "dwFlags", 0); ++ ++ release_memory(); ++ DeleteFileA(resfile); ++} ++ + static BOOL is_str_env_drive_dir(const char* str) + { + return str[0] == '=' && str[1] >= 'A' && str[1] <= 'Z' && str[2] == ':' && +@@ -2989,6 +3132,23 @@ START_TEST(process) + Sleep(100); + return; + } ++ else if (!strcmp(myARGV[2], "nested") && myARGC >= 4) ++ { ++ char buffer[MAX_PATH]; ++ STARTUPINFOA startup; ++ PROCESS_INFORMATION info; ++ ++ memset(&startup, 0, sizeof(startup)); ++ startup.cb = sizeof(startup); ++ startup.dwFlags = STARTF_USESHOWWINDOW; ++ startup.wShowWindow = SW_SHOWNORMAL; ++ ++ sprintf(buffer, "\"%s\" tests/process.c dump \"%s\"", selfname, myARGV[3]); ++ ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startup, &info), "CreateProcess\n"); ++ CloseHandle(info.hProcess); ++ CloseHandle(info.hThread); ++ return; ++ } + + ok(0, "Unexpected command %s\n", myARGV[2]); + return; +@@ -2998,6 +3158,7 @@ START_TEST(process) + test_Startup(); + test_CommandLine(); + test_Directory(); ++ test_Toolhelp(); + test_Environment(); + test_SuspendFlag(); + test_DebuggingFlag(); +-- +2.6.2 + diff --git a/patches/server-Parent_Process/0002-server-Increase-size-of-PID-table-to-512-to-reduce-r.patch b/patches/server-Parent_Process/0002-server-Increase-size-of-PID-table-to-512-to-reduce-r.patch deleted file mode 100644 index 85b901ef..00000000 --- a/patches/server-Parent_Process/0002-server-Increase-size-of-PID-table-to-512-to-reduce-r.patch +++ /dev/null @@ -1,26 +0,0 @@ -From d99e740d73f63cb26e638c6daa550eb2bb28d061 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Thu, 10 Dec 2015 05:57:34 +0100 -Subject: server: Increase size of PID table to 512 to reduce risk of - collisions. - ---- - server/process.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/server/process.c b/server/process.c -index 1fdaaca..d7ddc21 100644 ---- a/server/process.c -+++ b/server/process.c -@@ -361,7 +361,7 @@ unsigned int alloc_ptid( void *ptr ) - else /* need to grow the array */ - { - unsigned int count = alloc_ptid_entries + (alloc_ptid_entries / 2); -- if (!count) count = 64; -+ if (!count) count = 512; - if (!(entry = realloc( ptid_entries, count * sizeof(*entry) ))) - { - set_error( STATUS_NO_MEMORY ); --- -2.6.2 - diff --git a/patches/server-Parent_Process/0001-server-token_duplicate-should-not-reference-the-orig.patch b/patches/server-Parent_Process/0003-server-token_duplicate-should-not-reference-the-orig.patch similarity index 100% rename from patches/server-Parent_Process/0001-server-token_duplicate-should-not-reference-the-orig.patch rename to patches/server-Parent_Process/0003-server-token_duplicate-should-not-reference-the-orig.patch diff --git a/patches/server-Parent_Process/0004-server-Increase-size-of-PID-table-to-512-to-reduce-r.patch b/patches/server-Parent_Process/0004-server-Increase-size-of-PID-table-to-512-to-reduce-r.patch new file mode 100644 index 00000000..fe81db26 --- /dev/null +++ b/patches/server-Parent_Process/0004-server-Increase-size-of-PID-table-to-512-to-reduce-r.patch @@ -0,0 +1,56 @@ +From d1cbc9aa239ab353301fe709b36bd260eb42aa83 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Thu, 10 Dec 2015 05:57:34 +0100 +Subject: server: Increase size of PID table to 512 to reduce risk of + collisions. + +In addition, add code to avoid reusing the last 256 used PIDs. +--- + server/process.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/server/process.c b/server/process.c +index e00b429..1b41037 100644 +--- a/server/process.c ++++ b/server/process.c +@@ -336,6 +336,7 @@ static unsigned int used_ptid_entries; /* number of entries in use */ + static unsigned int alloc_ptid_entries; /* number of allocated entries */ + static unsigned int next_free_ptid; /* next free entry */ + static unsigned int last_free_ptid; /* last free entry */ ++static unsigned int num_free_ptids; /* number of free ptids */ + + static void kill_all_processes(void); + +@@ -352,16 +353,17 @@ unsigned int alloc_ptid( void *ptr ) + id = used_ptid_entries + PTID_OFFSET; + entry = &ptid_entries[used_ptid_entries++]; + } +- else if (next_free_ptid) ++ else if (next_free_ptid && num_free_ptids >= 256) + { + id = next_free_ptid; + entry = &ptid_entries[id - PTID_OFFSET]; + if (!(next_free_ptid = entry->next)) last_free_ptid = 0; ++ num_free_ptids--; + } + else /* need to grow the array */ + { + unsigned int count = alloc_ptid_entries + (alloc_ptid_entries / 2); +- if (!count) count = 64; ++ if (!count) count = 512; + if (!(entry = realloc( ptid_entries, count * sizeof(*entry) ))) + { + set_error( STATUS_NO_MEMORY ); +@@ -388,8 +390,8 @@ void free_ptid( unsigned int id ) + /* append to end of free list so that we don't reuse it too early */ + if (last_free_ptid) ptid_entries[last_free_ptid - PTID_OFFSET].next = id; + else next_free_ptid = id; +- + last_free_ptid = id; ++ num_free_ptids++; + } + + /* retrieve the pointer corresponding to a process or thread id */ +-- +2.6.2 + diff --git a/patches/server-Parent_Process/0003-server-Do-not-hold-reference-on-parent-process.patch b/patches/server-Parent_Process/0005-server-Do-not-hold-reference-on-parent-process.patch similarity index 77% rename from patches/server-Parent_Process/0003-server-Do-not-hold-reference-on-parent-process.patch rename to patches/server-Parent_Process/0005-server-Do-not-hold-reference-on-parent-process.patch index 85af9b03..f1ddfbc3 100644 --- a/patches/server-Parent_Process/0003-server-Do-not-hold-reference-on-parent-process.patch +++ b/patches/server-Parent_Process/0005-server-Do-not-hold-reference-on-parent-process.patch @@ -1,16 +1,30 @@ -From b71aa6b6bdf71f3a5d006a5d2b1c109a29af75af Mon Sep 17 00:00:00 2001 +From 8d0b9020200ee933ed02fae3235fee2ade651394 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Thu, 10 Dec 2015 05:55:41 +0100 Subject: server: Do not hold reference on parent process. --- - server/console.c | 3 +-- - server/process.c | 7 +++---- - server/process.h | 2 +- - server/snapshot.c | 2 +- - server/thread.c | 2 +- - 5 files changed, 7 insertions(+), 9 deletions(-) + dlls/kernel32/tests/process.c | 2 +- + server/console.c | 3 +-- + server/process.c | 7 +++---- + server/process.h | 2 +- + server/snapshot.c | 2 +- + server/thread.c | 2 +- + 6 files changed, 8 insertions(+), 10 deletions(-) +diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c +index 8e0f0c2..9c07d09 100644 +--- a/dlls/kernel32/tests/process.c ++++ b/dlls/kernel32/tests/process.c +@@ -1158,7 +1158,7 @@ static void test_Toolhelp(void) + Sleep(100); + } + /* The following test fails randomly on some Windows versions */ +- todo_wine ok(i < 20 || broken(i == 20), "process object not released\n"); ++ ok(i < 20 || broken(i == 20), "process object not released\n"); + + snapshot = pCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + ok(snapshot != INVALID_HANDLE_VALUE, "CreateToolhelp32Snapshot failed %u\n", GetLastError()); diff --git a/server/console.c b/server/console.c index a57b2fe..3d0e0e0 100644 --- a/server/console.c @@ -31,10 +45,10 @@ index a57b2fe..3d0e0e0 100644 break; case 0xffffffff: diff --git a/server/process.c b/server/process.c -index e00b429..1fdaaca 100644 +index 1b41037..8ecc32e 100644 --- a/server/process.c +++ b/server/process.c -@@ -502,7 +502,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit +@@ -504,7 +504,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit close( fd ); goto error; } @@ -43,7 +57,7 @@ index e00b429..1fdaaca 100644 process->debugger = NULL; process->handles = NULL; process->msg_fd = NULL; -@@ -554,7 +554,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit +@@ -556,7 +556,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit else { struct process *parent = parent_thread->process; @@ -52,7 +66,7 @@ index e00b429..1fdaaca 100644 process->handles = inherit_all ? copy_handle_table( process, parent ) : alloc_handle_table( process, 0 ); /* Note: for security reasons, starting a new process does not attempt -@@ -621,7 +621,6 @@ static void process_destroy( struct object *obj ) +@@ -623,7 +623,6 @@ static void process_destroy( struct object *obj ) release_object( process->job ); } if (process->console) release_object( process->console ); @@ -60,7 +74,7 @@ index e00b429..1fdaaca 100644 if (process->msg_fd) release_object( process->msg_fd ); list_remove( &process->entry ); if (process->idle_event) release_object( process->idle_event ); -@@ -1350,7 +1349,7 @@ DECL_HANDLER(get_process_info) +@@ -1352,7 +1351,7 @@ DECL_HANDLER(get_process_info) if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_LIMITED_INFORMATION ))) { reply->pid = get_process_id( process );