2 * PROJECT: ReactOS api tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for TerminateProcess
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
10 #include <ndk/obfuncs.h>
18 _Out_opt_ PDWORD ProcessId
)
21 WCHAR FileName
[MAX_PATH
];
22 WCHAR CommandLine
[MAX_PATH
];
23 STARTUPINFOW StartupInfo
;
24 PROCESS_INFORMATION ProcessInfo
;
26 GetModuleFileNameW(NULL
, FileName
, _countof(FileName
));
27 StringCbPrintfW(CommandLine
,
29 L
"\"%ls\" TerminateProcess %ls",
33 RtlZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
34 StartupInfo
.cb
= sizeof(StartupInfo
);
35 /* HACK: running the test under rosautotest seems to keep another reference
36 * to the child process around until the test finishes (on both ROS and
37 * Windows)... I'm too lazy to investigate very much so let's just redirect
38 * the child std handles to nowhere. ok() is useless in half the child
41 StartupInfo
.dwFlags
= STARTF_USESTDHANDLES
;
43 Success
= CreateProcessW(FileName
,
55 skip("CreateProcess failed with %lu\n", GetLastError());
60 CloseHandle(ProcessInfo
.hThread
);
62 *ProcessId
= ProcessInfo
.dwProcessId
;
63 return ProcessInfo
.hProcess
;
74 OBJECT_BASIC_INFORMATION BasicInfo
;
76 Status
= NtQueryObject(hObject
,
77 ObjectBasicInformation
,
81 if (!NT_SUCCESS(Status
))
83 ok_(File
, Line
)(0, "NtQueryObject failed with status 0x%lx\n", Status
);
86 ok_(File
, Line
)(0, "Handle %p still has %lu open handles, %lu references\n", hObject
, BasicInfo
.HandleCount
, BasicInfo
.PointerCount
);
89 #define WaitExpectSuccess(h, ms) WaitExpect_(h, ms, WAIT_OBJECT_0, __FILE__, __LINE__)
90 #define WaitExpectTimeout(h, ms) WaitExpect_(h, ms, WAIT_TIMEOUT, __FILE__, __LINE__)
95 _In_ DWORD Milliseconds
,
96 _In_ DWORD ExpectedError
,
102 Error
= WaitForSingleObject(hWait
, Milliseconds
);
103 ok_(File
, Line
)(Error
== ExpectedError
, "Wait for %p return %lu\n", hWait
, Error
);
106 #define CloseProcessAndVerify(hp, pid, code) CloseProcessAndVerify_(hp, pid, code, __FILE__, __LINE__)
109 CloseProcessAndVerify_(
110 _In_ HANDLE hProcess
,
111 _In_ DWORD ProcessId
,
112 _In_ UINT ExpectedExitCode
,
121 WaitExpect_(hProcess
, 0, WAIT_OBJECT_0
, File
, Line
);
122 Success
= GetExitCodeProcess(hProcess
, &ExitCode
);
123 ok_(File
, Line
)(Success
, "GetExitCodeProcess failed with %lu\n", GetLastError());
124 CloseHandle(hProcess
);
125 while ((hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, ProcessId
)) != NULL
)
129 TraceHandleCount_(hProcess
, File
, Line
);
130 CloseHandle(hProcess
);
133 CloseHandle(hProcess
);
136 Error
= GetLastError();
137 ok_(File
, Line
)(hProcess
== NULL
, "OpenProcess succeeded unexpectedly for pid 0x%lx\n", ProcessId
);
138 ok_(File
, Line
)(Error
== ERROR_INVALID_PARAMETER
, "Error = %lu\n", Error
);
139 ok_(File
, Line
)(ExitCode
== ExpectedExitCode
, "Exit code is %lu but expected %u\n", ExitCode
, ExpectedExitCode
);
144 TestTerminateProcess(
150 /* Regular child process that returns from the test function */
151 /* HACK: These two tests don't work if stdout is a pipe. See StartChild */
153 hProcess
= StartChild(L
"child", 0, &ProcessId
);
154 WaitExpectSuccess(hEvent
, 5000);
155 WaitExpectSuccess(hProcess
, 5000);
156 CloseProcessAndVerify(hProcess
, ProcessId
, 0);
159 hProcess
= StartChild(L
"child", 0, &ProcessId
);
160 WaitExpectSuccess(hProcess
, 5000);
161 WaitExpectSuccess(hEvent
, 0);
162 CloseProcessAndVerify(hProcess
, ProcessId
, 0);
164 /* Suspended process -- never gets a chance to initialize */
166 hProcess
= StartChild(L
"child", CREATE_SUSPENDED
, &ProcessId
);
167 WaitExpectTimeout(hEvent
, 100);
168 WaitExpectTimeout(hProcess
, 100);
169 TerminateProcess(hProcess
, 123);
170 WaitExpectSuccess(hProcess
, 5000);
171 CloseProcessAndVerify(hProcess
, ProcessId
, 123);
173 /* Waiting process -- we have to terminate it */
175 hProcess
= StartChild(L
"wait", 0, &ProcessId
);
176 WaitExpectTimeout(hProcess
, 100);
177 TerminateProcess(hProcess
, 123);
178 WaitExpectSuccess(hProcess
, 5000);
179 CloseProcessAndVerify(hProcess
, ProcessId
, 123);
181 /* Process calls ExitProcess */
183 hProcess
= StartChild(L
"child exit 456", 0, &ProcessId
);
184 WaitExpectSuccess(hEvent
, 5000);
185 WaitExpectSuccess(hProcess
, 5000);
186 CloseProcessAndVerify(hProcess
, ProcessId
, 456);
188 /* Process calls TerminateProcess with GetCurrentProcess */
190 hProcess
= StartChild(L
"child terminate 456", 0, &ProcessId
);
191 WaitExpectSuccess(hEvent
, 5000);
192 WaitExpectSuccess(hProcess
, 5000);
193 CloseProcessAndVerify(hProcess
, ProcessId
, 456);
195 /* Process calls TerminateProcess with real handle to itself */
197 hProcess
= StartChild(L
"child terminate2 456", 0, &ProcessId
);
198 WaitExpectSuccess(hEvent
, 5000);
199 WaitExpectSuccess(hProcess
, 5000);
200 CloseProcessAndVerify(hProcess
, ProcessId
, 456);
203 START_TEST(TerminateProcess
)
211 hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, L
"kernel32_apitest_TerminateProcess_event");
212 Error
= GetLastError();
215 skip("CreateEvent failed with error %lu\n", Error
);
218 argc
= winetest_get_mainargs(&argv
);
221 ok(Error
== ERROR_ALREADY_EXISTS
, "Error = %lu\n", Error
);
222 if (!strcmp(argv
[2], "wait"))
224 WaitExpectSuccess(hEvent
, 30000);
228 Success
= SetEvent(hEvent
);
229 ok(Success
, "SetEvent failed with return %d, error %lu\n", Success
, GetLastError());
234 ok(Error
== NO_ERROR
, "Error = %lu\n", Error
);
235 TestTerminateProcess(hEvent
);
240 UINT ExitCode
= strtol(argv
[4], NULL
, 10);
243 if (!strcmp(argv
[3], "exit"))
244 ExitProcess(ExitCode
);
245 else if (!strcmp(argv
[3], "terminate"))
246 TerminateProcess(GetCurrentProcess(), ExitCode
);
247 else if (!strcmp(argv
[3], "terminate2"))
250 hProcess
= OpenProcess(PROCESS_TERMINATE
, FALSE
, GetCurrentProcessId());
251 TerminateProcess(hProcess
, ExitCode
);
253 ok(0, "Should have terminated\n");