ReactOS 0.4.16-dev-329-g9223134
toolhelp.c File Reference
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "tlhelp32.h"
#include "wine/test.h"
#include "winuser.h"
Include dependency graph for toolhelp.c:

Go to the source code of this file.

Macros

#define WAIT_TIME   (60 * 1000)
 
#define NUM_OF(x)   (sizeof(x) / sizeof(x[0]))
 

Functions

static HANDLE (WINAPI *pCreateToolhelp32Snapshot)(DWORD
 
static BOOL (WINAPI *pModule32First)(HANDLE
 
static DWORD WINAPI sub_thread (void *pmt)
 
static int init (void)
 
static void test_process (DWORD curr_pid, DWORD sub_pcs_pid)
 
static void test_thread (DWORD curr_pid, DWORD sub_pcs_pid)
 
static void test_module (DWORD pid, const char *expected[], unsigned num_expected)
 
 START_TEST (toolhelp)
 

Variables

static char selfname [MAX_PATH]
 
static DWORD
 
static LPMODULEENTRY32
 
static LPPROCESSENTRY32
 
static LPTHREADENTRY32
 
static const charcurr_expected_modules []
 
static const charsub_expected_modules []
 

Macro Definition Documentation

◆ NUM_OF

#define NUM_OF (   x)    (sizeof(x) / sizeof(x[0]))

Definition at line 220 of file toolhelp.c.

◆ WAIT_TIME

#define WAIT_TIME   (60 * 1000)

Definition at line 43 of file toolhelp.c.

Function Documentation

◆ BOOL()

static BOOL ( WINAPI pModule32First)
static

◆ HANDLE()

static HANDLE ( WINAPI pCreateToolhelp32Snapshot)
static

◆ init()

static int init ( void  )
static

Definition at line 61 of file toolhelp.c.

62{
63 int argc;
64 char** argv;
65 HANDLE ev1, ev2, ev3, hThread;
66 DWORD w, tid;
67
69 strcpy(selfname, argv[0]);
70
71 switch (argc)
72 {
73 case 2: /* the test program */
74 return 0;
75 case 4: /* the sub-process */
76 ev1 = (HANDLE)(INT_PTR)atoi(argv[2]);
77 ev2 = (HANDLE)(INT_PTR)atoi(argv[3]);
79
80 if (ev3 == NULL) ExitProcess(WAIT_ABANDONED);
81 hThread = CreateThread(NULL, 0, sub_thread, ev3, 0, &tid);
83 if (!LoadLibraryA("shell32.dll")) ExitProcess(WAIT_ABANDONED);
84
85 /* signal init of sub-process is done */
86 SetEvent(ev1);
87 /* wait for parent to have done all its queries */
90 /* signal sub-thread to terminate */
91 SetEvent(ev3);
96 default:
97 return -1;
98 }
99}
static int argc
Definition: ServiceArgs.c:12
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1487
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:541
unsigned long DWORD
Definition: ntddk_ex.h:95
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
static DWORD WINAPI sub_thread(void *pmt)
Definition: toolhelp.c:45
#define WAIT_TIME
Definition: toolhelp.c:43
static char selfname[MAX_PATH]
Definition: toolhelp.c:31
static TfClientId tid
#define argv
Definition: mplay32.c:18
HANDLE hThread
Definition: wizard.c:28
int winetest_get_mainargs(char ***pargv)
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
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
int32_t INT_PTR
Definition: typedefs.h:64
PVOID HANDLE
Definition: typedefs.h:73
#define WAIT_ABANDONED
Definition: winbase.h:438
#define WAIT_OBJECT_0
Definition: winbase.h:432

Referenced by START_TEST().

◆ START_TEST()

START_TEST ( toolhelp  )

Definition at line 284 of file toolhelp.c.

285{
287 int r;
288 char *p, module[MAX_PATH];
289 char buffer[MAX_PATH];
293 HANDLE ev1, ev2;
294 DWORD w;
295 HANDLE hkernel32 = GetModuleHandleA("kernel32");
296
297 pCreateToolhelp32Snapshot = (VOID *) GetProcAddress(hkernel32, "CreateToolhelp32Snapshot");
298 pModule32First = (VOID *) GetProcAddress(hkernel32, "Module32First");
299 pModule32Next = (VOID *) GetProcAddress(hkernel32, "Module32Next");
300 pProcess32First = (VOID *) GetProcAddress(hkernel32, "Process32First");
301 pProcess32Next = (VOID *) GetProcAddress(hkernel32, "Process32Next");
302 pThread32First = (VOID *) GetProcAddress(hkernel32, "Thread32First");
303 pThread32Next = (VOID *) GetProcAddress(hkernel32, "Thread32Next");
304
305 if (!pCreateToolhelp32Snapshot ||
306 !pModule32First || !pModule32Next ||
307 !pProcess32First || !pProcess32Next ||
308 !pThread32First || !pThread32Next)
309 {
310 win_skip("Needed functions are not available, most likely running on Windows NT\n");
311 return;
312 }
313
314 r = init();
315 ok(r == 0, "Basic init of sub-process test\n");
316 if (r != 0) return;
317
318 sa.nLength = sizeof(sa);
319 sa.lpSecurityDescriptor = NULL;
320 sa.bInheritHandle = TRUE;
321
322 ev1 = CreateEventW(&sa, FALSE, FALSE, NULL);
323 ev2 = CreateEventW(&sa, FALSE, FALSE, NULL);
324 ok (ev1 != NULL && ev2 != NULL, "Couldn't create events\n");
325 memset(&startup, 0, sizeof(startup));
326 startup.cb = sizeof(startup);
328 startup.wShowWindow = SW_SHOWNORMAL;
329
330 sprintf(buffer, "%s tests/toolhelp.c %lu %lu", selfname, (DWORD_PTR)ev1, (DWORD_PTR)ev2);
331 ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, 0, NULL, NULL, &startup, &info), "CreateProcess\n");
332 /* wait for child to be initialized */
334 ok(w == WAIT_OBJECT_0, "Failed to wait on sub-process startup\n");
335
336 GetModuleFileNameA( 0, module, sizeof(module) );
337 if (!(p = strrchr( module, '\\' ))) p = module;
338 else p++;
341
342 test_process(pid, info.dwProcessId);
343 test_thread(pid, info.dwProcessId);
346
347 SetEvent(ev2);
349}
static void startup(void)
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
#define ok(value,...)
Definition: atltest.h:57
#define TRUE
Definition: types.h:120
#define GetProcAddress(x, y)
Definition: compat.h:753
#define MAX_PATH
Definition: compat.h:34
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:539
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4747
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint buffer
Definition: glext.h:5915
GLfloat GLfloat p
Definition: glext.h:8902
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static HINSTANCE hkernel32
Definition: process.c:66
static void test_module(DWORD pid, const char *expected[], unsigned num_expected)
Definition: toolhelp.c:222
static const char * curr_expected_modules[]
Definition: toolhelp.c:205
static void test_thread(DWORD curr_pid, DWORD sub_pcs_pid)
Definition: toolhelp.c:153
#define NUM_OF(x)
Definition: toolhelp.c:220
static void test_process(DWORD curr_pid, DWORD sub_pcs_pid)
Definition: toolhelp.c:101
static const char * sub_expected_modules[]
Definition: toolhelp.c:212
static int init(void)
Definition: toolhelp.c:61
_CRT_RESTORE_GCC_WARNINGS _CRT_DISABLE_GCC_WARNINGS _Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define win_skip
Definition: test.h:163
void winetest_wait_child_process(HANDLE process)
#define memset(x, y, z)
Definition: compat.h:39
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define STARTF_USESHOWWINDOW
Definition: winbase.h:517
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
#define SW_SHOWNORMAL
Definition: winuser.h:773

◆ sub_thread()

static DWORD WINAPI sub_thread ( void pmt)
static

Definition at line 45 of file toolhelp.c.

46{
48 return w;
49}

Referenced by init().

◆ test_module()

static void test_module ( DWORD  pid,
const char expected[],
unsigned  num_expected 
)
static

Definition at line 222 of file toolhelp.c.

223{
224 HANDLE hSnapshot;
226 THREADENTRY32 te;
227 MODULEENTRY32 me;
228 unsigned found[32];
229 unsigned i;
230 int num = 0;
231
232 ok(NUM_OF(found) >= num_expected, "Internal: bump found[] size\n");
233
234 hSnapshot = pCreateToolhelp32Snapshot( TH32CS_SNAPMODULE, pid );
235 ok(hSnapshot != NULL, "Cannot create snapshot\n");
236
237 for (i = 0; i < num_expected; i++) found[i] = 0;
238 me.dwSize = sizeof(me);
239 if (pModule32First( hSnapshot, &me ))
240 {
241 do
242 {
243 trace("PID=%x base=%p size=%x %s %s\n",
245 ok(me.th32ProcessID == pid, "wrong returned process id\n");
246 for (i = 0; i < num_expected; i++)
247 if (!lstrcmpiA(expected[i], me.szModule)) found[i]++;
248 num++;
249 } while (pModule32Next( hSnapshot, &me ));
250 }
251 for (i = 0; i < num_expected; i++)
252 ok(found[i] == 1, "Module %s is %s\n",
253 expected[i], found[i] ? "listed more than once" : "not listed");
254
255 /* check that first really resets the enumeration */
256 for (i = 0; i < num_expected; i++) found[i] = 0;
257 me.dwSize = sizeof(me);
258 if (pModule32First( hSnapshot, &me ))
259 {
260 do
261 {
262 trace("PID=%x base=%p size=%x %s %s\n",
264 for (i = 0; i < num_expected; i++)
265 if (!lstrcmpiA(expected[i], me.szModule)) found[i]++;
266 num--;
267 } while (pModule32Next( hSnapshot, &me ));
268 }
269 for (i = 0; i < num_expected; i++)
270 ok(found[i] == 1, "Module %s is %s\n",
271 expected[i], found[i] ? "listed more than once" : "not listed");
272 ok(!num, "mismatch in counting\n");
273
274 pe.dwSize = sizeof(pe);
275 ok(!pProcess32First( hSnapshot, &pe ), "shouldn't return a process\n");
276
277 te.dwSize = sizeof(te);
278 ok(!pThread32First( hSnapshot, &te ), "shouldn't return a thread\n");
279
280 CloseHandle(hSnapshot);
281 ok(!pModule32First( hSnapshot, &me ), "shouldn't return a module\n");
282}
#define trace
Definition: atltest.h:70
#define CloseHandle
Definition: compat.h:739
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4224
GLuint GLuint num
Definition: glext.h:9618
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
BOOL expected
Definition: store.c:2063
BYTE * modBaseAddr
Definition: tlhelp32.h:99
char szModule[MAX_MODULE_NAME32+1]
Definition: tlhelp32.h:102
DWORD th32ProcessID
Definition: tlhelp32.h:96
DWORD modBaseSize
Definition: tlhelp32.h:100
char szExePath[MAX_PATH]
Definition: tlhelp32.h:103
#define TH32CS_SNAPMODULE
Definition: tlhelp32.h:28

Referenced by START_TEST().

◆ test_process()

static void test_process ( DWORD  curr_pid,
DWORD  sub_pcs_pid 
)
static

Definition at line 101 of file toolhelp.c.

102{
103 HANDLE hSnapshot;
105 MODULEENTRY32 me;
106 unsigned found = 0;
107 int num = 0;
108 int childpos = -1;
109
110 hSnapshot = pCreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
111 ok(hSnapshot != NULL, "Cannot create snapshot\n");
112
113 /* check that this current process is enumerated */
114 pe.dwSize = sizeof(pe);
115 if (pProcess32First( hSnapshot, &pe ))
116 {
117 do
118 {
119 if (pe.th32ProcessID == curr_pid) found++;
120 if (pe.th32ProcessID == sub_pcs_pid) { childpos = num; found++; }
121 trace("PID=%x %s\n", pe.th32ProcessID, pe.szExeFile);
122 num++;
123 } while (pProcess32Next( hSnapshot, &pe ));
124 }
125 ok(found == 2, "couldn't find self and/or sub-process in process list\n");
126
127 /* check that first really resets the enumeration */
128 found = 0;
129 if (pProcess32First( hSnapshot, &pe ))
130 {
131 do
132 {
133 if (pe.th32ProcessID == curr_pid) found++;
134 if (pe.th32ProcessID == sub_pcs_pid) found++;
135 trace("PID=%x %s\n", pe.th32ProcessID, pe.szExeFile);
136 num--;
137 } while (pProcess32Next( hSnapshot, &pe ));
138 }
139 ok(found == 2, "couldn't find self and/or sub-process in process list\n");
140 ok(!num, "mismatch in counting\n");
141
142 /* one broken program does Process32First() and does not expect anything
143 * interesting to be there, especially not the just forked off child */
144 ok (childpos !=0, "child is not expected to be at position 0.\n");
145
146 me.dwSize = sizeof(me);
147 ok(!pModule32First( hSnapshot, &me ), "shouldn't return a module\n");
148
149 CloseHandle(hSnapshot);
150 ok(!pProcess32First( hSnapshot, &pe ), "shouldn't return a process\n");
151}
CHAR szExeFile[MAX_PATH]
Definition: tlhelp32.h:70
DWORD th32ProcessID
Definition: tlhelp32.h:63
#define TH32CS_SNAPPROCESS
Definition: tlhelp32.h:26

Referenced by START_TEST().

◆ test_thread()

static void test_thread ( DWORD  curr_pid,
DWORD  sub_pcs_pid 
)
static

Definition at line 153 of file toolhelp.c.

154{
155 HANDLE hSnapshot;
156 THREADENTRY32 te;
157 MODULEENTRY32 me;
158 int num = 0;
159 unsigned curr_found = 0;
160 unsigned sub_found = 0;
161
162 hSnapshot = pCreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
163 ok(hSnapshot != NULL, "Cannot create snapshot\n");
164
165 /* check that this current process is enumerated */
166 te.dwSize = sizeof(te);
167 if (pThread32First( hSnapshot, &te ))
168 {
169 do
170 {
171 if (te.th32OwnerProcessID == curr_pid) curr_found++;
172 if (te.th32OwnerProcessID == sub_pcs_pid) sub_found++;
173 if (winetest_debug > 1)
174 trace("PID=%x TID=%x %d\n", te.th32OwnerProcessID, te.th32ThreadID, te.tpBasePri);
175 num++;
176 } while (pThread32Next( hSnapshot, &te ));
177 }
178 ok(curr_found, "couldn't find self in thread list\n");
179 ok(sub_found >= 2, "couldn't find sub-process threads in thread list\n");
180
181 /* check that first really resets enumeration */
182 curr_found = 0;
183 sub_found = 0;
184 if (pThread32First( hSnapshot, &te ))
185 {
186 do
187 {
188 if (te.th32OwnerProcessID == curr_pid) curr_found++;
189 if (te.th32OwnerProcessID == sub_pcs_pid) sub_found++;
190 if (winetest_debug > 1)
191 trace("PID=%x TID=%x %d\n", te.th32OwnerProcessID, te.th32ThreadID, te.tpBasePri);
192 num--;
193 } while (pThread32Next( hSnapshot, &te ));
194 }
195 ok(curr_found, "couldn't find self in thread list\n");
196 ok(sub_found >= 2, "couldn't find sub-process threads in thread list\n");
197
198 me.dwSize = sizeof(me);
199 ok(!pModule32First( hSnapshot, &me ), "shouldn't return a module\n");
200
201 CloseHandle(hSnapshot);
202 ok(!pThread32First( hSnapshot, &te ), "shouldn't return a thread\n");
203}
int winetest_debug
DWORD th32ThreadID
Definition: tlhelp32.h:75
DWORD th32OwnerProcessID
Definition: tlhelp32.h:76
#define TH32CS_SNAPTHREAD
Definition: tlhelp32.h:27

Referenced by START_TEST().

Variable Documentation

◆ curr_expected_modules

const char* curr_expected_modules[]
static
Initial value:
=
{
"kernel32_test.exe",
"kernel32.dll",
"ntdll.dll"
}

Definition at line 205 of file toolhelp.c.

Referenced by START_TEST().

◆ DWORD

Definition at line 34 of file toolhelp.c.

◆ LPMODULEENTRY32

Definition at line 35 of file toolhelp.c.

◆ LPPROCESSENTRY32

Definition at line 37 of file toolhelp.c.

◆ LPTHREADENTRY32

Definition at line 39 of file toolhelp.c.

◆ selfname

char selfname[MAX_PATH]
static

Definition at line 31 of file toolhelp.c.

Referenced by init(), and START_TEST().

◆ sub_expected_modules

const char* sub_expected_modules[]
static
Initial value:
=
{
"kernel32_test.exe",
"kernel32.dll",
"shell32.dll",
"ntdll.dll"
}

Definition at line 212 of file toolhelp.c.

Referenced by START_TEST().