ReactOS 0.4.15-dev-8093-g3285f69
TerminateProcess.c
Go to the documentation of this file.
1/*
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>
6 */
7
8#include "precomp.h"
9
10#include <ndk/obfuncs.h>
11
12static
15 _In_ PCWSTR Argument,
18{
21 WCHAR CommandLine[MAX_PATH];
22 STARTUPINFOW StartupInfo;
23 PROCESS_INFORMATION ProcessInfo;
24
26 StringCbPrintfW(CommandLine,
27 sizeof(CommandLine),
28 L"\"%ls\" TerminateProcess %ls",
30 Argument);
31
32 RtlZeroMemory(&StartupInfo, sizeof(StartupInfo));
33 StartupInfo.cb = sizeof(StartupInfo);
34 /* HACK: running the test under rosautotest seems to keep another reference
35 * to the child process around until the test finishes (on both ROS and
36 * Windows)... I'm too lazy to investigate very much so let's just redirect
37 * the child std handles to nowhere. ok() is useless in half the child
38 * processes anyway.
39 */
40 StartupInfo.dwFlags = STARTF_USESTDHANDLES;
41
43 CommandLine,
44 NULL,
45 NULL,
46 FALSE,
47 Flags,
48 NULL,
49 NULL,
50 &StartupInfo,
51 &ProcessInfo);
52 if (!Success)
53 {
54 skip("CreateProcess failed with %lu\n", GetLastError());
55 if (ProcessId)
56 *ProcessId = 0;
57 return NULL;
58 }
59 CloseHandle(ProcessInfo.hThread);
60 if (ProcessId)
61 *ProcessId = ProcessInfo.dwProcessId;
62 return ProcessInfo.hProcess;
63}
64
65static
66VOID
68 _In_ HANDLE hObject,
71{
74
75 Status = NtQueryObject(hObject,
77 &BasicInfo,
78 sizeof(BasicInfo),
79 NULL);
80 if (!NT_SUCCESS(Status))
81 {
82 ok_(File, Line)(0, "NtQueryObject failed with status 0x%lx\n", Status);
83 return;
84 }
85 ok_(File, Line)(0, "Handle %p still has %lu open handles, %lu references\n", hObject, BasicInfo.HandleCount, BasicInfo.PointerCount);
86}
87
88#define WaitExpectSuccess(h, ms) WaitExpect_(h, ms, WAIT_OBJECT_0, __FILE__, __LINE__)
89#define WaitExpectTimeout(h, ms) WaitExpect_(h, ms, WAIT_TIMEOUT, __FILE__, __LINE__)
90static
91VOID
93 _In_ HANDLE hWait,
94 _In_ DWORD Milliseconds,
95 _In_ DWORD ExpectedError,
98{
100
101 Error = WaitForSingleObject(hWait, Milliseconds);
102 ok_(File, Line)(Error == ExpectedError, "Wait for %p return %lu\n", hWait, Error);
103}
104
105#define CloseProcessAndVerify(hp, pid, code) CloseProcessAndVerify_(hp, pid, code, __FILE__, __LINE__)
106static
107VOID
111 _In_ UINT ExpectedExitCode,
113 _In_ INT Line)
114{
115 int i = 0;
116 DWORD Error;
117 DWORD ExitCode;
119
121 Success = GetExitCodeProcess(hProcess, &ExitCode);
122 ok_(File, Line)(Success, "GetExitCodeProcess failed with %lu\n", GetLastError());
125 {
126 if (++i >= 100)
127 {
130 break;
131 }
133 Sleep(100);
134 }
136 ok_(File, Line)(hProcess == NULL, "OpenProcess succeeded unexpectedly for pid 0x%lx\n", ProcessId);
137 ok_(File, Line)(Error == ERROR_INVALID_PARAMETER, "Error = %lu\n", Error);
138 ok_(File, Line)(ExitCode == ExpectedExitCode, "Exit code is %lu but expected %u\n", ExitCode, ExpectedExitCode);
139}
140
141static
142VOID
145{
148
149 /* Regular child process that returns from the test function */
150 /* HACK: These two tests don't work if stdout is a pipe. See StartChild */
152 hProcess = StartChild(L"child", 0, &ProcessId);
156
158 hProcess = StartChild(L"child", 0, &ProcessId);
162
163 /* Suspended process -- never gets a chance to initialize */
171
172 /* Waiting process -- we have to terminate it */
174 hProcess = StartChild(L"wait", 0, &ProcessId);
179
180 /* Process calls ExitProcess */
182 hProcess = StartChild(L"child exit 456", 0, &ProcessId);
186
187 /* Process calls TerminateProcess with GetCurrentProcess */
189 hProcess = StartChild(L"child terminate 456", 0, &ProcessId);
193
194 /* Process calls TerminateProcess with real handle to itself */
196 hProcess = StartChild(L"child terminate2 456", 0, &ProcessId);
200}
201
203{
206 DWORD Error;
207 int argc;
208 char **argv;
209
210 hEvent = CreateEventW(NULL, TRUE, FALSE, L"kernel32_apitest_TerminateProcess_event");
212 if (!hEvent)
213 {
214 skip("CreateEvent failed with error %lu\n", Error);
215 return;
216 }
218 if (argc >= 3)
219 {
220 ok(Error == ERROR_ALREADY_EXISTS, "Error = %lu\n", Error);
221 if (!strcmp(argv[2], "wait"))
222 {
224 }
225 else
226 {
228 ok(Success, "SetEvent failed with return %d, error %lu\n", Success, GetLastError());
229 }
230 }
231 else
232 {
233 ok(Error == NO_ERROR, "Error = %lu\n", Error);
235 }
237 if (argc >= 5)
238 {
239 UINT ExitCode = strtol(argv[4], NULL, 10);
240
241 fflush(stdout);
242 if (!strcmp(argv[3], "exit"))
243 ExitProcess(ExitCode);
244 else if (!strcmp(argv[3], "terminate"))
246 else if (!strcmp(argv[3], "terminate2"))
247 {
250 TerminateProcess(hProcess, ExitCode);
251 }
252 ok(0, "Should have terminated\n");
253 }
254}
@ ObjectBasicInformation
Definition: DriverTester.h:54
NTSTATUS NtQueryObject(IN HANDLE Handle, IN OBJECT_INFO_CLASS ObjectInformationClass, OUT PVOID ObjectInformation, IN ULONG ObjectInformationLength, OUT PULONG ReturnLength)
static int argc
Definition: ServiceArgs.c:12
static VOID CloseProcessAndVerify_(_In_ HANDLE hProcess, _In_ DWORD ProcessId, _In_ UINT ExpectedExitCode, _In_ PCSTR File, _In_ INT Line)
static HANDLE StartChild(_In_ PCWSTR Argument, _In_ DWORD Flags, _Out_opt_ PDWORD ProcessId)
static VOID TraceHandleCount_(_In_ HANDLE hObject, _In_ PCSTR File, _In_ INT Line)
#define CloseProcessAndVerify(hp, pid, code)
static VOID TestTerminateProcess(_In_ HANDLE hEvent)
#define WaitExpectTimeout(h, ms)
#define WaitExpectSuccess(h, ms)
static VOID WaitExpect_(_In_ HANDLE hWait, _In_ DWORD Milliseconds, _In_ DWORD ExpectedError, _In_ PCSTR File, _In_ INT Line)
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
LONG NTSTATUS
Definition: precomp.h:26
BOOL Error
Definition: chkdsk.c:66
Definition: File.h:16
#define NO_ERROR
Definition: dderror.h:5
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define GetCurrentProcess()
Definition: compat.h:759
#define MAX_PATH
Definition: compat.h:34
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4592
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1168
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1487
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
HANDLE WINAPI OpenProcess(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
Definition: proc.c:1227
@ Success
Definition: eventcreate.c:712
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2711
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define stdout
Definition: stdio.h:99
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
_Check_return_ long __cdecl strtol(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
#define PROCESS_TERMINATE
Definition: pstypes.h:157
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:166
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
static HANDLE hEvent
Definition: comm.c:54
#define argv
Definition: mplay32.c:18
#define _Out_opt_
Definition: ms_sal.h:346
#define _In_
Definition: ms_sal.h:308
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
DWORD * PDWORD
Definition: pedump.c:68
int winetest_get_mainargs(char ***pargv)
#define _countof(array)
Definition: sndvol32.h:70
STRSAFEAPI StringCbPrintfW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:557
Definition: ncftp.h:79
DWORD cb
Definition: winbase.h:852
DWORD dwFlags
Definition: winbase.h:863
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
const uint16_t * PCWSTR
Definition: typedefs.h:57
int32_t INT
Definition: typedefs.h:58
const char * PCSTR
Definition: typedefs.h:52
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
#define CREATE_SUSPENDED
Definition: winbase.h:178
#define WAIT_OBJECT_0
Definition: winbase.h:406
#define STARTF_USESTDHANDLES
Definition: winbase.h:499
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
__wchar_t WCHAR
Definition: xmlstorage.h:180