8187f637e38be12c1b94f99151bd1830d7e80d32
[reactos.git] / modules / rostests / winetests / ntdll / process.c
1 /*
2 * Unit test suite for process functions
3 *
4 * Copyright 2017 Michael Müller
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include "ntdll_test.h"
22
23 static NTSTATUS (WINAPI *pNtResumeProcess)(HANDLE);
24 static NTSTATUS (WINAPI *pNtSuspendProcess)(HANDLE);
25 static NTSTATUS (WINAPI *pNtSuspendThread)(HANDLE,PULONG);
26 static NTSTATUS (WINAPI *pNtResumeThread)(HANDLE);
27
28 static void test_NtSuspendProcess(char *process_name)
29 {
30 PROCESS_INFORMATION info;
31 DEBUG_EVENT ev;
32 STARTUPINFOA startup;
33 NTSTATUS status;
34 HANDLE event;
35 char buffer[MAX_PATH];
36 ULONG count;
37 DWORD ret;
38
39 status = pNtResumeProcess(GetCurrentProcess());
40 ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
41
42 event = CreateEventA(NULL, TRUE, FALSE, "wine_suspend_event");
43 ok(!!event, "Failed to create event: %u\n", GetLastError());
44
45 memset(&startup, 0, sizeof(startup));
46 startup.cb = sizeof(startup);
47
48 sprintf(buffer, "%s tests/process.c dummy_process wine_suspend_event", process_name);
49 ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info);
50 ok(ret, "CreateProcess failed with error %u\n", GetLastError());
51
52 ret = WaitForSingleObject(event, 500);
53 ok(ret == WAIT_OBJECT_0, "Event was not signaled: %d\n", ret);
54
55 status = pNtSuspendProcess(info.hProcess);
56 ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
57
58 ResetEvent(event);
59
60 ret = WaitForSingleObject(event, 200);
61 ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);
62
63 status = NtResumeThread(info.hThread, &count);
64 ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
65 ok(count == 1, "Expected count 1, got %d\n", count);
66
67 ret = WaitForSingleObject(event, 200);
68 ok(ret == WAIT_OBJECT_0, "Event was not signaled: %d\n", ret);
69
70 status = pNtResumeProcess(info.hProcess);
71 ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
72
73 status = pNtSuspendThread(info.hThread, &count);
74 ok(status == STATUS_SUCCESS, "NtSuspendThread failed: %x\n", status);
75 ok(count == 0, "Expected count 0, got %d\n", count);
76
77 ResetEvent(event);
78
79 ret = WaitForSingleObject(event, 200);
80 ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);
81
82 status = pNtResumeProcess(info.hProcess);
83 ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
84
85 ret = WaitForSingleObject(event, 200);
86 ok(ret == WAIT_OBJECT_0, "Event was not signaled: %d\n", ret);
87
88 status = pNtSuspendThread(info.hThread, &count);
89 ok(status == STATUS_SUCCESS, "NtSuspendThread failed: %x\n", status);
90 ok(count == 0, "Expected count 0, got %d\n", count);
91
92 status = pNtSuspendThread(info.hThread, &count);
93 ok(status == STATUS_SUCCESS, "NtSuspendThread failed: %x\n", status);
94 ok(count == 1, "Expected count 1, got %d\n", count);
95
96 ResetEvent(event);
97
98 ret = WaitForSingleObject(event, 200);
99 ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);
100
101 status = pNtResumeProcess(info.hProcess);
102 ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
103
104 ret = WaitForSingleObject(event, 200);
105 ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);
106
107 status = pNtResumeProcess(info.hProcess);
108 ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
109
110 ret = WaitForSingleObject(event, 200);
111 ok(ret == WAIT_OBJECT_0, "Event was not signaled: %d\n", ret);
112
113 ret = DebugActiveProcess(info.dwProcessId);
114 ok(ret, "Failed to debug process: %d\n", GetLastError());
115
116 ResetEvent(event);
117
118 ret = WaitForSingleObject(event, 200);
119 ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);
120
121 for (;;)
122 {
123 ret = WaitForDebugEvent(&ev, INFINITE);
124 ok(ret, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
125 if (!ret) break;
126
127 if (ev.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT) break;
128
129 ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
130 ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
131 if (!ret) break;
132 }
133
134 ResetEvent(event);
135
136 ret = WaitForSingleObject(event, 200);
137 ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);
138
139 status = pNtResumeProcess(info.hProcess);
140 ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
141
142 ret = WaitForSingleObject(event, 200);
143 ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);
144
145 status = NtResumeThread(info.hThread, &count);
146 ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
147 ok(count == 0, "Expected count 0, got %d\n", count);
148
149 ret = WaitForSingleObject(event, 200);
150 ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);
151
152 ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
153 ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
154
155 ret = WaitForSingleObject(event, 200);
156 ok(ret == WAIT_OBJECT_0, "Event was not signaled: %d\n", ret);
157
158 TerminateProcess(info.hProcess, 0);
159
160 CloseHandle(info.hProcess);
161 CloseHandle(info.hThread);
162 }
163
164 static void dummy_process(char *event_name)
165 {
166 HANDLE event = OpenEventA(EVENT_ALL_ACCESS, FALSE, event_name);
167
168 while (TRUE)
169 {
170 SetEvent(event);
171 OutputDebugStringA("test");
172 Sleep(5);
173 }
174 }
175
176 START_TEST(process)
177 {
178 HMODULE mod;
179 char **argv;
180 int argc;
181
182 argc = winetest_get_mainargs(&argv);
183 if (argc >= 4 && strcmp(argv[2], "dummy_process") == 0)
184 {
185 dummy_process(argv[3]);
186 return;
187 }
188
189 mod = GetModuleHandleA("ntdll.dll");
190 if (!mod)
191 {
192 win_skip("Not running on NT, skipping tests\n");
193 return;
194 }
195
196 pNtResumeProcess = (void*)GetProcAddress(mod, "NtResumeProcess");
197 pNtSuspendProcess = (void*)GetProcAddress(mod, "NtSuspendProcess");
198 pNtResumeThread = (void*)GetProcAddress(mod, "NtResumeThread");
199 pNtSuspendThread = (void*)GetProcAddress(mod, "NtSuspendThread");
200
201 test_NtSuspendProcess(argv[0]);
202 }