ReactOS  0.4.13-dev-52-g0efcfec
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 
12 static
13 HANDLE
15  _In_ PCWSTR Argument,
18 {
19  BOOL Success;
21  WCHAR CommandLine[MAX_PATH];
22  STARTUPINFOW StartupInfo;
23  PROCESS_INFORMATION ProcessInfo;
24 
26  StringCbPrintfW(CommandLine,
27  sizeof(CommandLine),
28  L"\"%ls\" TerminateProcess %ls",
29  FileName,
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 
65 static
66 VOID
68  _In_ HANDLE hObject,
69  _In_ PCSTR File,
70  _In_ INT Line)
71 {
73  OBJECT_BASIC_INFORMATION BasicInfo;
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__)
90 static
91 VOID
93  _In_ HANDLE hWait,
94  _In_ DWORD Milliseconds,
95  _In_ DWORD ExpectedError,
96  _In_ PCSTR File,
97  _In_ INT Line)
98 {
99  DWORD Error;
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__)
106 static
107 VOID
111  _In_ UINT ExpectedExitCode,
112  _In_ PCSTR File,
113  _In_ INT Line)
114 {
115  int i = 0;
116  DWORD Error;
117  DWORD ExitCode;
118  BOOL Success;
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  }
135  Error = GetLastError();
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 
141 static
142 VOID
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);
153  WaitExpectSuccess(hEvent, 5000);
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);
183  WaitExpectSuccess(hEvent, 5000);
186 
187  /* Process calls TerminateProcess with GetCurrentProcess */
189  hProcess = StartChild(L"child terminate 456", 0, &ProcessId);
190  WaitExpectSuccess(hEvent, 5000);
193 
194  /* Process calls TerminateProcess with real handle to itself */
196  hProcess = StartChild(L"child terminate2 456", 0, &ProcessId);
197  WaitExpectSuccess(hEvent, 5000);
200 }
201 
203 {
204  HANDLE hEvent;
205  BOOL Success;
206  DWORD Error;
207  int argc;
208  char **argv;
209 
210  hEvent = CreateEventW(NULL, TRUE, FALSE, L"kernel32_apitest_TerminateProcess_event");
211  Error = GetLastError();
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  {
223  WaitExpectSuccess(hEvent, 30000);
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"))
245  TerminateProcess(GetCurrentProcess(), ExitCode);
246  else if (!strcmp(argv[3], "terminate2"))
247  {
250  TerminateProcess(hProcess, ExitCode);
251  }
252  ok(0, "Should have terminated\n");
253  }
254 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:607
static int argc
Definition: ServiceArgs.c:12
const uint16_t * PCWSTR
Definition: typedefs.h:55
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2697
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:158
#define ok_(x1, x2)
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1198
#define _countof(array)
Definition: fontsub.cpp:30
LONG NTSTATUS
Definition: precomp.h:26
#define CloseProcessAndVerify(hp, pid, code)
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1517
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
static HANDLE StartChild(_In_ PCWSTR Argument, _In_ DWORD Flags, _Out_opt_ PDWORD ProcessId)
#define argv
Definition: mplay32.c:18
#define NO_ERROR
Definition: dderror.h:5
int32_t INT
Definition: typedefs.h:56
FILE * stdout
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:597
static HANDLE hEvent
Definition: comm.c:54
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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 CREATE_SUSPENDED
Definition: winbase.h:178
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ok(value,...)
smooth NULL
Definition: ftsmooth.c:416
STRSAFEAPI StringCbPrintfW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:557
static VOID TraceHandleCount_(_In_ HANDLE hObject, _In_ PCSTR File, _In_ INT Line)
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:4623
#define STARTF_USESTDHANDLES
Definition: winbase.h:480
#define _Out_opt_
Definition: no_sal2.h:339
#define WAIT_OBJECT_0
Definition: winbase.h:387
DWORD cb
Definition: winbase.h:817
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NtQueryObject(IN HANDLE Handle, IN OBJECT_INFO_CLASS ObjectInformationClass, OUT PVOID ObjectInformation, IN ULONG ObjectInformationLength, OUT PULONG ReturnLength)
static VOID TestTerminateProcess(_In_ HANDLE hEvent)
HANDLE WINAPI GetCurrentProcess(VOID)
Definition: proc.c:1168
#define MAX_PATH
Definition: compat.h:26
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL Error
Definition: chkdsk.c:66
int winetest_get_mainargs(char ***pargv)
static VOID CloseProcessAndVerify_(_In_ HANDLE hProcess, _In_ DWORD ProcessId, _In_ UINT ExpectedExitCode, _In_ PCSTR File, _In_ INT Line)
Definition: ncftp.h:79
START_TEST(TerminateProcess)
static const WCHAR L[]
Definition: oid.c:1250
#define WaitExpectSuccess(h, ms)
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
HANDLE WINAPI OpenProcess(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
Definition: proc.c:1257
#define PROCESS_TERMINATE
Definition: pstypes.h:149
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1562
static VOID WaitExpect_(_In_ HANDLE hWait, _In_ DWORD Milliseconds, _In_ DWORD ExpectedError, _In_ PCSTR File, _In_ INT Line)
unsigned int UINT
Definition: ndis.h:50
DWORD * PDWORD
Definition: pedump.c:68
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:660
#define skip(...)
_Check_return_ long __cdecl strtol(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
DWORD dwFlags
Definition: winbase.h:828
const char * PCSTR
Definition: typedefs.h:51
Definition: File.h:15
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
#define WaitExpectTimeout(h, ms)
DWORD WINAPI GetCurrentProcessId(VOID)
Definition: proc.c:1188