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
=
32 SNAPSHOT_Destroy
/* destroy */
35 /* The K32 snapshot object object */
36 /* Process snapshot kernel32 object */
37 typedef struct _Process32Snapshot
44 * Store a reference to the PDB list.
45 * Insuure in the alloc and dealloc routines for this structure that
46 * I increment and decrement the pdb->head.refcount, so that the
47 * original pdb will stay around for as long as I use it, but it's
48 * not locked forver into memory.
54 /* FIXME: to make this working, we have to callback all these registered
55 * functions from all over the WINE code. Someone with more knowledge than
56 * me please do that. -Marcus
61 FARPROC16 lpfnCallback
;
65 static int nrofnotifys
= 0;
67 static FARPROC16 HookNotify
= NULL
;
69 BOOL16 WINAPI
NotifyRegister( HTASK16 htask
, FARPROC16 lpfnCallback
,
74 TRACE(toolhelp
, "(%x,%lx,%x) called.\n",
75 htask
, (DWORD
)lpfnCallback
, wFlags
);
76 if (!htask
) htask
= GetCurrentTask();
77 for (i
=0;i
<nrofnotifys
;i
++)
78 if (notifys
[i
].htask
==htask
)
82 notifys
=(struct notify
*)HeapAlloc( SystemHeap
, 0,
83 sizeof(struct notify
) );
85 notifys
=(struct notify
*)HeapReAlloc( SystemHeap
, 0, notifys
,
86 sizeof(struct notify
)*(nrofnotifys
+1));
87 if (!notifys
) return FALSE
;
90 notifys
[i
].htask
=htask
;
91 notifys
[i
].lpfnCallback
=lpfnCallback
;
92 notifys
[i
].wFlags
=wFlags
;
96 BOOL16 WINAPI
NotifyUnregister( HTASK16 htask
)
100 TRACE(toolhelp
, "(%x) called.\n", htask
);
101 if (!htask
) htask
= GetCurrentTask();
102 for (i
=nrofnotifys
;i
--;)
103 if (notifys
[i
].htask
==htask
)
107 memcpy(notifys
+i
,notifys
+(i
+1),sizeof(struct notify
)*(nrofnotifys
-i
-1));
108 notifys
=(struct notify
*)HeapReAlloc( SystemHeap
, 0, notifys
,
109 (nrofnotifys
-1)*sizeof(struct notify
));
114 BOOL16 WINAPI
StackTraceCSIPFirst(STACKTRACEENTRY
*ste
, WORD wSS
, WORD wCS
, WORD wIP
, WORD wBP
)
119 BOOL16 WINAPI
StackTraceFirst(STACKTRACEENTRY
*ste
, HTASK16 Task
)
124 BOOL16 WINAPI
StackTraceNext(STACKTRACEENTRY
*ste
)
129 /***********************************************************************
130 * ToolHelpHook (KERNEL.341)
131 * see "Undocumented Windows"
133 FARPROC16 WINAPI
ToolHelpHook(FARPROC16 lpfnNotifyHandler
)
137 HookNotify
= lpfnNotifyHandler
;
138 /* just return previously installed notification function */
142 /***********************************************************************
145 * Deallocate K32 snapshot objects
147 static void SNAPSHOT_Destroy (K32OBJ
*obj
)
150 SNAPSHOT_OBJECT
*snapshot
= (SNAPSHOT_OBJECT
*) obj
;
151 assert (obj
->type
== K32OBJ_CHANGE
);
153 if (snapshot
->processArray
)
155 for (i
= 0; snapshot
->processArray
[i
] && i
<snapshot
->numProcs
; i
++)
157 K32OBJ_DecCount (&snapshot
->processArray
[i
]->header
);
159 HeapFree (GetProcessHeap (), 0, snapshot
->processArray
);
160 snapshot
->processArray
= NULL
;
163 obj
->type
= K32OBJ_UNKNOWN
;
164 HeapFree (GetProcessHeap (), 0, snapshot
);
167 /***********************************************************************
168 * CreateToolHelp32Snapshot (KERNEL32.179)
169 * see "Undocumented Windows"
171 HANDLE32 WINAPI
CreateToolhelp32Snapshot(DWORD dwFlags
, DWORD
175 SNAPSHOT_OBJECT
*snapshot
;
180 TRACE(toolhelp
, "%lx & TH32CS_INHERIT (%x) = %lx %s\n", dwFlags
,
182 dwFlags
& TH32CS_INHERIT
,
183 dwFlags
& TH32CS_INHERIT
? "TRUE" : "FALSE");
184 TRACE(toolhelp
, "%lx & TH32CS_SNAPHEAPLIST (%x) = %lx %s\n", dwFlags
,
186 dwFlags
& TH32CS_SNAPHEAPLIST
,
187 dwFlags
& TH32CS_SNAPHEAPLIST
? "TRUE" : "FALSE");
188 TRACE(toolhelp
, "%lx & TH32CS_SNAPMODULE (%x) = %lx %s\n", dwFlags
,
190 dwFlags
& TH32CS_SNAPMODULE
,
191 dwFlags
& TH32CS_SNAPMODULE
? "TRUE" : "FALSE");
192 TRACE(toolhelp
, "%lx & TH32CS_SNAPPROCESS (%x) = %lx %s\n", dwFlags
,
194 dwFlags
& TH32CS_SNAPPROCESS
,
195 dwFlags
& TH32CS_SNAPPROCESS
? "TRUE" : "FALSE");
196 TRACE(toolhelp
, "%lx & TH32CS_SNAPTHREAD (%x) = %lx %s\n", dwFlags
,
198 dwFlags
& TH32CS_SNAPTHREAD
,
199 dwFlags
& TH32CS_SNAPTHREAD
? "TRUE" : "FALSE");
201 /**** FIXME: Not implmented ***/
202 if (dwFlags
& TH32CS_INHERIT
)
204 FIXME(toolhelp
,"(0x%08lx (TH32CS_INHERIT),0x%08lx), stub!\n",
205 dwFlags
,th32ProcessID
);
207 return INVALID_HANDLE_VALUE32
;
209 if (dwFlags
& TH32CS_SNAPHEAPLIST
)
211 FIXME(toolhelp
,"(0x%08lx (TH32CS_SNAPHEAPLIST),0x%08lx), stub!\n",
212 dwFlags
,th32ProcessID
);
213 return INVALID_HANDLE_VALUE32
;
215 if (dwFlags
& TH32CS_SNAPMODULE
)
217 FIXME(toolhelp
,"(0x%08lx (TH32CS_SNAPMODULE),0x%08lx), stub!\n",
218 dwFlags
,th32ProcessID
);
219 return INVALID_HANDLE_VALUE32
;
222 if (dwFlags
& TH32CS_SNAPPROCESS
)
224 TRACE (toolhelp
, "(0x%08lx (TH32CS_SNAPMODULE),0x%08lx)\n",
225 dwFlags
,th32ProcessID
);
226 snapshot
= HeapAlloc (GetProcessHeap (), 0, sizeof
230 return INVALID_HANDLE_VALUE32
;
233 snapshot
->header
.type
= K32OBJ_TOOLHELP_SNAPSHOT
;
234 snapshot
->header
.refcount
= 1;
235 snapshot
->arrayCounter
= 0;
238 * Lock here, to prevent processes from being created or
239 * destroyed while the snapshot is gathered
243 numProcesses
= PROCESS_PDBList_Getsize ();
245 snapshot
->processArray
= (PDB32
**)
246 HeapAlloc (GetProcessHeap (), 0, sizeof (PDB32
*) * numProcesses
);
248 if (!snapshot
->processArray
)
250 HeapFree (GetProcessHeap (), 0, snapshot
->processArray
);
251 SetLastError (INVALID_HANDLE_VALUE32
);
252 ERR (toolhelp
, "Error allocating %d bytes for snapshot\n",
253 sizeof (PDB32
*) * numProcesses
);
254 return INVALID_HANDLE_VALUE32
;
257 snapshot
->numProcs
= numProcesses
;
259 pdb
= PROCESS_PDBList_Getfirst ();
260 for (i
= 0; pdb
&& i
< numProcesses
; i
++)
262 TRACE (toolhelp
, "Saving ref to pdb %ld\n", PDB_TO_PROCESS_ID(pdb
));
263 snapshot
->processArray
[i
] = pdb
;
264 K32OBJ_IncCount (&pdb
->header
);
265 pdb
= PROCESS_PDBList_Getnext (pdb
);
269 ssHandle
= HANDLE_Alloc (PROCESS_Current (), &snapshot
->header
,
270 FILE_ALL_ACCESS
, TRUE
, -1);
271 if (ssHandle
== INVALID_HANDLE_VALUE32
)
273 /* HANDLE_Alloc is supposed to deallocate the
274 * heap memory if it fails. This code doesn't need to.
276 SetLastError (INVALID_HANDLE_VALUE32
);
277 ERR (toolhelp
, "Error allocating handle\n");
278 return INVALID_HANDLE_VALUE32
;
281 TRACE (toolhelp
, "snapshotted %d processes, expected %d\n",
286 if (dwFlags
& TH32CS_SNAPTHREAD
)
288 FIXME(toolhelp
,"(0x%08lx (TH32CS_SNAPMODULE),0x%08lx), stub!\n",
289 dwFlags
,th32ProcessID
);
290 return INVALID_HANDLE_VALUE32
;
293 return INVALID_HANDLE_VALUE32
;
296 /***********************************************************************
298 * Return info about the first process in a toolhelp32 snapshot
300 BOOL32 WINAPI
Process32First(HANDLE32 hSnapshot
, LPPROCESSENTRY32 lppe
)
303 SNAPSHOT_OBJECT
*snapshot
;
306 TRACE (toolhelp
, "(0x%08lx,0x%08lx)\n", (DWORD
) hSnapshot
,
309 if (lppe
->dwSize
< sizeof (PROCESSENTRY32
))
311 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
312 ERR (toolhelp
, "Result buffer too small\n");
317 snapshot
= (SNAPSHOT_OBJECT
*) HANDLE_GetObjPtr (PROCESS_Current (),
325 SetLastError (ERROR_INVALID_HANDLE
);
326 ERR (toolhelp
, "Error retreiving snapshot\n");
330 snapshot
->arrayCounter
= i
= 0;
331 pdb
= snapshot
->processArray
[i
];
335 SetLastError (ERROR_NO_MORE_FILES
);
336 ERR (toolhelp
, "End of snapshot array\n");
340 TRACE (toolhelp
, "Returning info on process %d, id %ld\n",
341 i
, PDB_TO_PROCESS_ID (pdb
));
344 lppe
->th32ProcessID
= PDB_TO_PROCESS_ID (pdb
);
345 lppe
->th32DefaultHeapID
= (DWORD
) pdb
->heap
;
346 lppe
->cntThreads
= pdb
->threads
;
347 lppe
->th32ParentProcessID
= PDB_TO_PROCESS_ID (pdb
->parent
);
348 lppe
->pcPriClassBase
= 6; /* FIXME: this is a made-up value */
349 lppe
->dwFlags
= -1; /* FIXME: RESERVED by Microsoft :-) */
352 lppe
->th32ModuleID
= (DWORD
) pdb
->exe_modref
->module
;
353 strncpy (lppe
->szExeFile
, pdb
->exe_modref
->longname
,
354 sizeof (lppe
->szExeFile
));
358 lppe
->th32ModuleID
= (DWORD
) 0;
359 strcpy (lppe
->szExeFile
, "");
367 /***********************************************************************
369 * Return info about the "next" process in a toolhelp32 snapshot
371 BOOL32 WINAPI
Process32Next(HANDLE32 hSnapshot
, LPPROCESSENTRY32 lppe
)
374 SNAPSHOT_OBJECT
*snapshot
;
377 TRACE (toolhelp
, "(0x%08lx,0x%08lx)\n", (DWORD
) hSnapshot
,
380 if (lppe
->dwSize
< sizeof (PROCESSENTRY32
))
382 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
383 ERR (toolhelp
, "Result buffer too small\n");
388 snapshot
= (SNAPSHOT_OBJECT
*) HANDLE_GetObjPtr (PROCESS_Current (),
396 SetLastError (ERROR_INVALID_HANDLE
);
397 ERR (toolhelp
, "Error retreiving snapshot\n");
401 snapshot
->arrayCounter
++;
402 i
= snapshot
->arrayCounter
;
403 pdb
= snapshot
->processArray
[i
];
405 if (!pdb
|| snapshot
->arrayCounter
>= snapshot
->numProcs
)
407 SetLastError (ERROR_NO_MORE_FILES
);
408 ERR (toolhelp
, "End of snapshot array\n");
412 TRACE (toolhelp
, "Returning info on process %d, id %ld\n",
413 i
, PDB_TO_PROCESS_ID (pdb
));
416 lppe
->th32ProcessID
= PDB_TO_PROCESS_ID (pdb
);
417 lppe
->th32DefaultHeapID
= (DWORD
) pdb
->heap
;
418 lppe
->cntThreads
= pdb
->threads
;
419 lppe
->th32ParentProcessID
= PDB_TO_PROCESS_ID (pdb
->parent
);
420 lppe
->pcPriClassBase
= 6; /* FIXME: this is a made-up value */
421 lppe
->dwFlags
= -1; /* FIXME: RESERVED by Microsoft :-) */
424 lppe
->th32ModuleID
= (DWORD
) pdb
->exe_modref
->module
;
425 strncpy (lppe
->szExeFile
, pdb
->exe_modref
->longname
,
426 sizeof (lppe
->szExeFile
));
430 lppe
->th32ModuleID
= (DWORD
) 0;
431 strcpy (lppe
->szExeFile
, "");