2 * Misc Toolhelp functions
4 * Copyright 1996 Marcus Meissner
23 * Support for toolhelp's snapshots. They
24 * are supposed to be Kernel32 Objects.
25 * Only the Destroy() method is implemented
28 static void SNAPSHOT_Destroy( K32OBJ
*obj
);
30 const K32OBJ_OPS SNAPSHOT_Ops
=
35 NULL
, /* remove_wait */
38 SNAPSHOT_Destroy
/* destroy */
41 /* The K32 snapshot object object */
42 /* Process snapshot kernel32 object */
43 typedef struct _Process32Snapshot
50 * Store a reference to the PDB list.
51 * Insuure in the alloc and dealloc routines for this structure that
52 * I increment and decrement the pdb->head.refcount, so that the
53 * original pdb will stay around for as long as I use it, but it's
54 * not locked forver into memory.
60 /* FIXME: to make this working, we have to callback all these registered
61 * functions from all over the WINE code. Someone with more knowledge than
62 * me please do that. -Marcus
67 FARPROC16 lpfnCallback
;
71 static int nrofnotifys
= 0;
73 static FARPROC16 HookNotify
= NULL
;
75 BOOL16 WINAPI
NotifyRegister( HTASK16 htask
, FARPROC16 lpfnCallback
,
80 TRACE(toolhelp
, "(%x,%lx,%x) called.\n",
81 htask
, (DWORD
)lpfnCallback
, wFlags
);
82 if (!htask
) htask
= GetCurrentTask();
83 for (i
=0;i
<nrofnotifys
;i
++)
84 if (notifys
[i
].htask
==htask
)
88 notifys
=(struct notify
*)HeapAlloc( SystemHeap
, 0,
89 sizeof(struct notify
) );
91 notifys
=(struct notify
*)HeapReAlloc( SystemHeap
, 0, notifys
,
92 sizeof(struct notify
)*(nrofnotifys
+1));
93 if (!notifys
) return FALSE
;
96 notifys
[i
].htask
=htask
;
97 notifys
[i
].lpfnCallback
=lpfnCallback
;
98 notifys
[i
].wFlags
=wFlags
;
102 BOOL16 WINAPI
NotifyUnregister( HTASK16 htask
)
106 TRACE(toolhelp
, "(%x) called.\n", htask
);
107 if (!htask
) htask
= GetCurrentTask();
108 for (i
=nrofnotifys
;i
--;)
109 if (notifys
[i
].htask
==htask
)
113 memcpy(notifys
+i
,notifys
+(i
+1),sizeof(struct notify
)*(nrofnotifys
-i
-1));
114 notifys
=(struct notify
*)HeapReAlloc( SystemHeap
, 0, notifys
,
115 (nrofnotifys
-1)*sizeof(struct notify
));
120 BOOL16 WINAPI
StackTraceCSIPFirst(STACKTRACEENTRY
*ste
, WORD wSS
, WORD wCS
, WORD wIP
, WORD wBP
)
125 BOOL16 WINAPI
StackTraceFirst(STACKTRACEENTRY
*ste
, HTASK16 Task
)
130 BOOL16 WINAPI
StackTraceNext(STACKTRACEENTRY
*ste
)
135 /***********************************************************************
136 * ToolHelpHook (KERNEL.341)
137 * see "Undocumented Windows"
139 FARPROC16 WINAPI
ToolHelpHook(FARPROC16 lpfnNotifyHandler
)
143 HookNotify
= lpfnNotifyHandler
;
144 /* just return previously installed notification function */
148 /***********************************************************************
151 * Deallocate K32 snapshot objects
153 static void SNAPSHOT_Destroy (K32OBJ
*obj
)
156 SNAPSHOT_OBJECT
*snapshot
= (SNAPSHOT_OBJECT
*) obj
;
157 assert (obj
->type
== K32OBJ_CHANGE
);
159 if (snapshot
->processArray
)
161 for (i
= 0; snapshot
->processArray
[i
] && i
<snapshot
->numProcs
; i
++)
163 K32OBJ_DecCount (&snapshot
->processArray
[i
]->header
);
165 HeapFree (GetProcessHeap (), 0, snapshot
->processArray
);
166 snapshot
->processArray
= NULL
;
169 obj
->type
= K32OBJ_UNKNOWN
;
170 HeapFree (GetProcessHeap (), 0, snapshot
);
173 /***********************************************************************
174 * CreateToolHelp32Snapshot (KERNEL32.179)
175 * see "Undocumented Windows"
177 HANDLE32 WINAPI
CreateToolhelp32Snapshot(DWORD dwFlags
, DWORD
181 SNAPSHOT_OBJECT
*snapshot
;
186 TRACE(toolhelp
, "%lx & TH32CS_INHERIT (%x) = %lx %s\n", dwFlags
,
188 dwFlags
& TH32CS_INHERIT
,
189 dwFlags
& TH32CS_INHERIT
? "TRUE" : "FALSE");
190 TRACE(toolhelp
, "%lx & TH32CS_SNAPHEAPLIST (%x) = %lx %s\n", dwFlags
,
192 dwFlags
& TH32CS_SNAPHEAPLIST
,
193 dwFlags
& TH32CS_SNAPHEAPLIST
? "TRUE" : "FALSE");
194 TRACE(toolhelp
, "%lx & TH32CS_SNAPMODULE (%x) = %lx %s\n", dwFlags
,
196 dwFlags
& TH32CS_SNAPMODULE
,
197 dwFlags
& TH32CS_SNAPMODULE
? "TRUE" : "FALSE");
198 TRACE(toolhelp
, "%lx & TH32CS_SNAPPROCESS (%x) = %lx %s\n", dwFlags
,
200 dwFlags
& TH32CS_SNAPPROCESS
,
201 dwFlags
& TH32CS_SNAPPROCESS
? "TRUE" : "FALSE");
202 TRACE(toolhelp
, "%lx & TH32CS_SNAPTHREAD (%x) = %lx %s\n", dwFlags
,
204 dwFlags
& TH32CS_SNAPTHREAD
,
205 dwFlags
& TH32CS_SNAPTHREAD
? "TRUE" : "FALSE");
207 /**** FIXME: Not implmented ***/
208 if (dwFlags
& TH32CS_INHERIT
)
210 FIXME(toolhelp
,"(0x%08lx (TH32CS_INHERIT),0x%08lx), stub!\n",
211 dwFlags
,th32ProcessID
);
213 return INVALID_HANDLE_VALUE32
;
215 if (dwFlags
& TH32CS_SNAPHEAPLIST
)
217 FIXME(toolhelp
,"(0x%08lx (TH32CS_SNAPHEAPLIST),0x%08lx), stub!\n",
218 dwFlags
,th32ProcessID
);
219 return INVALID_HANDLE_VALUE32
;
221 if (dwFlags
& TH32CS_SNAPMODULE
)
223 FIXME(toolhelp
,"(0x%08lx (TH32CS_SNAPMODULE),0x%08lx), stub!\n",
224 dwFlags
,th32ProcessID
);
225 return INVALID_HANDLE_VALUE32
;
228 if (dwFlags
& TH32CS_SNAPPROCESS
)
230 TRACE (toolhelp
, "(0x%08lx (TH32CS_SNAPMODULE),0x%08lx)\n",
231 dwFlags
,th32ProcessID
);
232 snapshot
= HeapAlloc (GetProcessHeap (), 0, sizeof
236 return INVALID_HANDLE_VALUE32
;
239 snapshot
->header
.type
= K32OBJ_TOOLHELP_SNAPSHOT
;
240 snapshot
->header
.refcount
= 1;
241 snapshot
->arrayCounter
= 0;
244 * Lock here, to prevent processes from being created or
245 * destroyed while the snapshot is gathered
249 numProcesses
= PROCESS_PDBList_Getsize ();
251 snapshot
->processArray
= (PDB32
**)
252 HeapAlloc (GetProcessHeap (), 0, sizeof (PDB32
*) * numProcesses
);
254 if (!snapshot
->processArray
)
256 HeapFree (GetProcessHeap (), 0, snapshot
->processArray
);
257 SetLastError (INVALID_HANDLE_VALUE32
);
258 ERR (toolhelp
, "Error allocating %d bytes for snapshot\n",
259 sizeof (PDB32
*) * numProcesses
);
260 return INVALID_HANDLE_VALUE32
;
263 snapshot
->numProcs
= numProcesses
;
265 pdb
= PROCESS_PDBList_Getfirst ();
266 for (i
= 0; pdb
&& i
< numProcesses
; i
++)
268 TRACE (toolhelp
, "Saving ref to pdb %ld\n", PDB_TO_PROCESS_ID(pdb
));
269 snapshot
->processArray
[i
] = pdb
;
270 K32OBJ_IncCount (&pdb
->header
);
271 pdb
= PROCESS_PDBList_Getnext (pdb
);
275 ssHandle
= HANDLE_Alloc (PROCESS_Current (), &snapshot
->header
,
276 FILE_ALL_ACCESS
, TRUE
, -1);
277 if (ssHandle
== INVALID_HANDLE_VALUE32
)
279 /* HANDLE_Alloc is supposed to deallocate the
280 * heap memory if it fails. This code doesn't need to.
282 SetLastError (INVALID_HANDLE_VALUE32
);
283 ERR (toolhelp
, "Error allocating handle\n");
284 return INVALID_HANDLE_VALUE32
;
287 TRACE (toolhelp
, "snapshotted %d processes, expected %d\n",
292 if (dwFlags
& TH32CS_SNAPTHREAD
)
294 FIXME(toolhelp
,"(0x%08lx (TH32CS_SNAPMODULE),0x%08lx), stub!\n",
295 dwFlags
,th32ProcessID
);
296 return INVALID_HANDLE_VALUE32
;
299 return INVALID_HANDLE_VALUE32
;
302 /***********************************************************************
304 * Return info about the first process in a toolhelp32 snapshot
306 BOOL32 WINAPI
Process32First(HANDLE32 hSnapshot
, LPPROCESSENTRY32 lppe
)
309 SNAPSHOT_OBJECT
*snapshot
;
312 TRACE (toolhelp
, "(0x%08lx,0x%08lx)\n", (DWORD
) hSnapshot
,
315 if (lppe
->dwSize
< sizeof (PROCESSENTRY32
))
317 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
318 ERR (toolhelp
, "Result buffer too small\n");
323 snapshot
= (SNAPSHOT_OBJECT
*) HANDLE_GetObjPtr (PROCESS_Current (),
331 SetLastError (ERROR_INVALID_HANDLE
);
332 ERR (toolhelp
, "Error retreiving snapshot\n");
336 snapshot
->arrayCounter
= i
= 0;
337 pdb
= snapshot
->processArray
[i
];
341 SetLastError (ERROR_NO_MORE_FILES
);
342 ERR (toolhelp
, "End of snapshot array\n");
346 TRACE (toolhelp
, "Returning info on process %d, id %ld\n",
347 i
, PDB_TO_PROCESS_ID (pdb
));
350 lppe
->th32ProcessID
= PDB_TO_PROCESS_ID (pdb
);
351 lppe
->th32DefaultHeapID
= (DWORD
) pdb
->heap
;
352 lppe
->cntThreads
= pdb
->threads
;
353 lppe
->th32ParentProcessID
= PDB_TO_PROCESS_ID (pdb
->parent
);
354 lppe
->pcPriClassBase
= 6; /* FIXME: this is a made-up value */
355 lppe
->dwFlags
= -1; /* FIXME: RESERVED by Microsoft :-) */
358 lppe
->th32ModuleID
= (DWORD
) pdb
->exe_modref
->module
;
359 strncpy (lppe
->szExeFile
, pdb
->exe_modref
->longname
,
360 sizeof (lppe
->szExeFile
));
364 lppe
->th32ModuleID
= (DWORD
) 0;
365 strcpy (lppe
->szExeFile
, "");
373 /***********************************************************************
375 * Return info about the "next" process in a toolhelp32 snapshot
377 BOOL32 WINAPI
Process32Next(HANDLE32 hSnapshot
, LPPROCESSENTRY32 lppe
)
380 SNAPSHOT_OBJECT
*snapshot
;
383 TRACE (toolhelp
, "(0x%08lx,0x%08lx)\n", (DWORD
) hSnapshot
,
386 if (lppe
->dwSize
< sizeof (PROCESSENTRY32
))
388 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
389 ERR (toolhelp
, "Result buffer too small\n");
394 snapshot
= (SNAPSHOT_OBJECT
*) HANDLE_GetObjPtr (PROCESS_Current (),
402 SetLastError (ERROR_INVALID_HANDLE
);
403 ERR (toolhelp
, "Error retreiving snapshot\n");
407 snapshot
->arrayCounter
++;
408 i
= snapshot
->arrayCounter
;
409 pdb
= snapshot
->processArray
[i
];
411 if (!pdb
|| snapshot
->arrayCounter
>= snapshot
->numProcs
)
413 SetLastError (ERROR_NO_MORE_FILES
);
414 ERR (toolhelp
, "End of snapshot array\n");
418 TRACE (toolhelp
, "Returning info on process %d, id %ld\n",
419 i
, PDB_TO_PROCESS_ID (pdb
));
422 lppe
->th32ProcessID
= PDB_TO_PROCESS_ID (pdb
);
423 lppe
->th32DefaultHeapID
= (DWORD
) pdb
->heap
;
424 lppe
->cntThreads
= pdb
->threads
;
425 lppe
->th32ParentProcessID
= PDB_TO_PROCESS_ID (pdb
->parent
);
426 lppe
->pcPriClassBase
= 6; /* FIXME: this is a made-up value */
427 lppe
->dwFlags
= -1; /* FIXME: RESERVED by Microsoft :-) */
430 lppe
->th32ModuleID
= (DWORD
) pdb
->exe_modref
->module
;
431 strncpy (lppe
->szExeFile
, pdb
->exe_modref
->longname
,
432 sizeof (lppe
->szExeFile
));
436 lppe
->th32ModuleID
= (DWORD
) 0;
437 strcpy (lppe
->szExeFile
, "");