Skip to content
Snippets Groups Projects
Commit 3f8e1e4d authored by Patrick Spinler's avatar Patrick Spinler Committed by Alexandre Julliard
Browse files

Implemented CreateToolhelp32Snapshot, including two of the routines

using snapshots, Process32First and Process32Next.
parent bc93bc83
No related branches found
No related tags found
No related merge requests found
......@@ -108,6 +108,8 @@ typedef struct _PDB32
LCID locale; /* c4 Locale to be queried by GetThreadLocale (NT) */
/* The following are Wine-specific fields */
void *server_pid; /* Server id for this process */
struct _PDB32 *list_next; /* List reference - list of PDB's */
struct _PDB32 *list_prev; /* List reference - list of PDB's */
} PDB32;
/* Process flags */
......@@ -157,5 +159,9 @@ extern PDB32 *PROCESS_Create( struct _NE_MODULE *pModule, LPCSTR cmd_line,
PROCESS_INFORMATION *info );
extern void PROCESS_SuspendOtherThreads(void);
extern void PROCESS_ResumeOtherThreads(void);
extern int PROCESS_PDBList_Getsize (void);
extern PDB32* PROCESS_PDBList_Getfirst (void);
extern PDB32* PROCESS_PDBList_Getnext (PDB32*);
#endif /* __WINE_PROCESS_H */
#ifndef __WINE_TLHELP32_H
#define __WINE_TLHELP32_H
#include "windows.h"
#ifdef __cplusplus
extern "C" {
#endif
/*===================================================================
* Arguments for Toolhelp routines
*/
/*
* CreateToolhelp32Snapshot
*/
#define TH32CS_SNAPHEAPLIST 0x00000001
#define TH32CS_SNAPPROCESS 0x00000002
#define TH32CS_SNAPTHREAD 0x00000004
#define TH32CS_SNAPMODULE 0x00000008
#define TH32CS_SNAPALL (TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE)
#define TH32CS_INHERIT 0x80000000
#ifdef __cplusplus
extern "C" {
#endif
#endif /* __WINE_TLHELP32_H */
......@@ -2,10 +2,13 @@
#define __WINE_TOOLHELP_H
#include "windows.h"
#include "tlhelp32.h"
#define MAX_DATA 11
#define MAX_MODULE_NAME 9
#ifndef MAX_PATH
#define MAX_PATH 255
#endif
#define MAX_CLASSNAME 255
#pragma pack(1)
......
......@@ -8,11 +8,54 @@
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <assert.h>
#include "windows.h"
#include "win.h"
#include "winerror.h"
#include "tlhelp32.h"
#include "toolhelp.h"
#include "debug.h"
#include "heap.h"
#include "process.h"
#include "k32obj.h"
/*
* Support for toolhelp's snapshots. They
* are supposed to be Kernel32 Objects.
* Only the Destroy() method is implemented
*/
static void SNAPSHOT_Destroy( K32OBJ *obj );
const K32OBJ_OPS SNAPSHOT_Ops =
{
NULL, /* signaled */
NULL, /* satisfied */
NULL, /* add_wait */
NULL, /* remove_wait */
NULL, /* read */
NULL, /* write */
SNAPSHOT_Destroy /* destroy */
};
/* The K32 snapshot object object */
/* Process snapshot kernel32 object */
typedef struct _Process32Snapshot
{
K32OBJ header;
DWORD numProcs;
DWORD arrayCounter;
/*
* Store a reference to the PDB list.
* Insuure in the alloc and dealloc routines for this structure that
* I increment and decrement the pdb->head.refcount, so that the
* original pdb will stay around for as long as I use it, but it's
* not locked forver into memory.
*/
PDB32 **processArray;
}
SNAPSHOT_OBJECT;
/* FIXME: to make this working, we have to callback all these registered
* functions from all over the WINE code. Someone with more knowledge than
......@@ -102,11 +145,299 @@ FARPROC16 tmp;
return tmp;
}
/***********************************************************************
* SNAPSHOT_Destroy
*
* Deallocate K32 snapshot objects
*/
static void SNAPSHOT_Destroy (K32OBJ *obj)
{
int i;
SNAPSHOT_OBJECT *snapshot = (SNAPSHOT_OBJECT *) obj;
assert (obj->type == K32OBJ_CHANGE);
if (snapshot->processArray)
{
for (i = 0; snapshot->processArray[i] && i <snapshot->numProcs; i++)
{
K32OBJ_DecCount (&snapshot->processArray[i]->header);
}
HeapFree (GetProcessHeap (), 0, snapshot->processArray);
snapshot->processArray = NULL;
}
obj->type = K32OBJ_UNKNOWN;
HeapFree (GetProcessHeap (), 0, snapshot);
}
/***********************************************************************
* CreateToolHelp32Snapshot (KERNEL32.179)
* see "Undocumented Windows"
*/
HANDLE32 WINAPI CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID) {
FIXME(toolhelp,"(0x%08lx,0x%08lx), stub!\n",dwFlags,th32ProcessID);
return INVALID_HANDLE_VALUE32;
HANDLE32 WINAPI CreateToolhelp32Snapshot(DWORD dwFlags, DWORD
th32ProcessID)
{
HANDLE32 ssHandle;
SNAPSHOT_OBJECT *snapshot;
int numProcesses;
int i;
PDB32* pdb;
printf ("%x & TH32CS_INHERIT (%x) = %x %s\n", dwFlags,
TH32CS_INHERIT, TH32CS_INHERIT,
dwFlags & TH32CS_INHERIT,
dwFlags & TH32CS_INHERIT ? "TRUE" : "FALSE");
printf ("%x & TH32CS_SNAPHEAPLIST (%x) = %x %s\n", dwFlags,
TH32CS_SNAPHEAPLIST, TH32CS_SNAPHEAPLIST,
dwFlags & TH32CS_SNAPHEAPLIST,
dwFlags & TH32CS_SNAPHEAPLIST ? "TRUE" : "FALSE");
printf ("%x & TH32CS_SNAPMODULE (%x) = %x %s\n", dwFlags,
TH32CS_SNAPMODULE, TH32CS_SNAPMODULE,
dwFlags & TH32CS_SNAPMODULE,
dwFlags & TH32CS_SNAPMODULE ? "TRUE" : "FALSE");
printf ("%x & TH32CS_SNAPPROCESS (%x) = %x %s\n", dwFlags,
TH32CS_SNAPPROCESS, TH32CS_SNAPPROCESS,
dwFlags & TH32CS_SNAPPROCESS,
dwFlags & TH32CS_SNAPPROCESS ? "TRUE" : "FALSE");
printf ("%x & TH32CS_SNAPTHREAD (%x) = %x %s\n", dwFlags,
TH32CS_SNAPTHREAD, TH32CS_SNAPTHREAD,
dwFlags & TH32CS_SNAPTHREAD,
dwFlags & TH32CS_SNAPTHREAD ? "TRUE" : "FALSE");
/**** FIXME: Not implmented ***/
if (dwFlags & TH32CS_INHERIT)
{
FIXME(toolhelp,"(0x%08lx (TH32CS_INHERIT),0x%08lx), stub!\n",
dwFlags,th32ProcessID);
return INVALID_HANDLE_VALUE32;
}
if (dwFlags & TH32CS_SNAPHEAPLIST)
{
FIXME(toolhelp,"(0x%08lx (TH32CS_SNAPHEAPLIST),0x%08lx), stub!\n",
dwFlags,th32ProcessID);
return INVALID_HANDLE_VALUE32;
}
if (dwFlags & TH32CS_SNAPMODULE)
{
FIXME(toolhelp,"(0x%08lx (TH32CS_SNAPMODULE),0x%08lx), stub!\n",
dwFlags,th32ProcessID);
return INVALID_HANDLE_VALUE32;
}
if (dwFlags & TH32CS_SNAPPROCESS)
{
TRACE (toolhelp, "(0x%08lx (TH32CS_SNAPMODULE),0x%08lx)\n",
dwFlags,th32ProcessID);
snapshot = HeapAlloc (GetProcessHeap (), 0, sizeof
(SNAPSHOT_OBJECT));
if (!snapshot)
{
return INVALID_HANDLE_VALUE32;
}
snapshot->header.type = K32OBJ_TOOLHELP_SNAPSHOT;
snapshot->header.refcount = 1;
snapshot->arrayCounter = 0;
/*
* Lock here, to prevent processes from being created or
* destroyed while the snapshot is gathered
*/
SYSTEM_LOCK ();
numProcesses = PROCESS_PDBList_Getsize ();
snapshot->processArray = (PDB32**)
HeapAlloc (GetProcessHeap (), 0, sizeof (PDB32*) * numProcesses);
if (!snapshot->processArray)
{
HeapFree (GetProcessHeap (), 0, snapshot->processArray);
SetLastError (INVALID_HANDLE_VALUE32);
ERR (toolhelp, "Error allocating %d bytes for snapshot\n",
sizeof (PDB32*) * numProcesses);
return INVALID_HANDLE_VALUE32;
}
snapshot->numProcs = numProcesses;
pdb = PROCESS_PDBList_Getfirst ();
for (i = 0; pdb && i < numProcesses; i++)
{
TRACE (toolhelp, "Saving ref to pdb %ld\n", PDB_TO_PROCESS_ID(pdb));
snapshot->processArray[i] = pdb;
K32OBJ_IncCount (&pdb->header);
pdb = PROCESS_PDBList_Getnext (pdb);
}
SYSTEM_UNLOCK ();
ssHandle = HANDLE_Alloc (PROCESS_Current (), &snapshot->header,
FILE_ALL_ACCESS, TRUE, -1);
if (ssHandle == INVALID_HANDLE_VALUE32)
{
/* HANDLE_Alloc is supposed to deallocate the
* heap memory if it fails. This code doesn't need to.
*/
SetLastError (INVALID_HANDLE_VALUE32);
ERR (toolhelp, "Error allocating handle\n");
return INVALID_HANDLE_VALUE32;
}
TRACE (toolhelp, "snapshotted %d processes, expected %d\n",
i, numProcesses);
return ssHandle;
}
if (dwFlags & TH32CS_SNAPTHREAD)
{
FIXME(toolhelp,"(0x%08lx (TH32CS_SNAPMODULE),0x%08lx), stub!\n",
dwFlags,th32ProcessID);
return INVALID_HANDLE_VALUE32;
}
return INVALID_HANDLE_VALUE32;
}
/***********************************************************************
* Process32First
* Return info about the first process in a toolhelp32 snapshot
*/
BOOL32 WINAPI Process32First(HANDLE32 hSnapshot, LPPROCESSENTRY32 lppe)
{
PDB32 *pdb;
SNAPSHOT_OBJECT *snapshot;
int i;
TRACE (toolhelp, "(0x%08lx,0x%08lx)\n", (DWORD) hSnapshot,
(DWORD) lppe);
if (lppe->dwSize < sizeof (PROCESSENTRY32))
{
SetLastError (ERROR_INSUFFICIENT_BUFFER);
ERR (toolhelp, "Result buffer too small\n");
return FALSE;
}
SYSTEM_LOCK ();
snapshot = (SNAPSHOT_OBJECT*) HANDLE_GetObjPtr (PROCESS_Current (),
hSnapshot,
K32OBJ_UNKNOWN,
FILE_ALL_ACCESS,
NULL);
if (!snapshot)
{
SYSTEM_UNLOCK ();
SetLastError (ERROR_INVALID_HANDLE);
ERR (toolhelp, "Error retreiving snapshot\n");
return FALSE;
}
snapshot->arrayCounter = i = 0;
pdb = snapshot->processArray[i];
if (!pdb)
{
SetLastError (ERROR_NO_MORE_FILES);
ERR (toolhelp, "End of snapshot array\n");
return FALSE;
}
TRACE (toolhelp, "Returning info on process %d, id %ld\n",
i, PDB_TO_PROCESS_ID (pdb));
lppe->cntUsage = 1;
lppe->th32ProcessID = PDB_TO_PROCESS_ID (pdb);
lppe->th32DefaultHeapID = (DWORD) pdb->heap;
lppe->cntThreads = pdb->threads;
lppe->th32ParentProcessID = PDB_TO_PROCESS_ID (pdb->parent);
lppe->pcPriClassBase = 6; /* FIXME: this is a made-up value */
lppe->dwFlags = -1; /* FIXME: RESERVED by Microsoft :-) */
if (pdb->exe_modref)
{
lppe->th32ModuleID = (DWORD) pdb->exe_modref->module;
strncpy (lppe->szExeFile, pdb->exe_modref->longname,
sizeof (lppe->szExeFile));
}
else
{
lppe->th32ModuleID = (DWORD) 0;
strcpy (lppe->szExeFile, "");
}
SYSTEM_UNLOCK ();
return TRUE;
}
/***********************************************************************
* Process32Next
* Return info about the "next" process in a toolhelp32 snapshot
*/
BOOL32 WINAPI Process32Next(HANDLE32 hSnapshot, LPPROCESSENTRY32 lppe)
{
PDB32 *pdb;
SNAPSHOT_OBJECT *snapshot;
int i;
TRACE (toolhelp, "(0x%08lx,0x%08lx)\n", (DWORD) hSnapshot,
(DWORD) lppe);
if (lppe->dwSize < sizeof (PROCESSENTRY32))
{
SetLastError (ERROR_INSUFFICIENT_BUFFER);
ERR (toolhelp, "Result buffer too small\n");
return FALSE;
}
SYSTEM_LOCK ();
snapshot = (SNAPSHOT_OBJECT*) HANDLE_GetObjPtr (PROCESS_Current (),
hSnapshot,
K32OBJ_UNKNOWN,
FILE_ALL_ACCESS,
NULL);
if (!snapshot)
{
SYSTEM_UNLOCK ();
SetLastError (ERROR_INVALID_HANDLE);
ERR (toolhelp, "Error retreiving snapshot\n");
return FALSE;
}
snapshot->arrayCounter ++;
i = snapshot->arrayCounter;
pdb = snapshot->processArray[i];
if (!pdb || snapshot->arrayCounter >= snapshot->numProcs)
{
SetLastError (ERROR_NO_MORE_FILES);
ERR (toolhelp, "End of snapshot array\n");
return FALSE;
}
TRACE (toolhelp, "Returning info on process %d, id %ld\n",
i, PDB_TO_PROCESS_ID (pdb));
lppe->cntUsage = 1;
lppe->th32ProcessID = PDB_TO_PROCESS_ID (pdb);
lppe->th32DefaultHeapID = (DWORD) pdb->heap;
lppe->cntThreads = pdb->threads;
lppe->th32ParentProcessID = PDB_TO_PROCESS_ID (pdb->parent);
lppe->pcPriClassBase = 6; /* FIXME: this is a made-up value */
lppe->dwFlags = -1; /* FIXME: RESERVED by Microsoft :-) */
if (pdb->exe_modref)
{
lppe->th32ModuleID = (DWORD) pdb->exe_modref->module;
strncpy (lppe->szExeFile, pdb->exe_modref->longname,
sizeof (lppe->szExeFile));
}
else
{
lppe->th32ModuleID = (DWORD) 0;
strcpy (lppe->szExeFile, "");
}
SYSTEM_UNLOCK ();
return TRUE;
}
......@@ -23,6 +23,7 @@ extern const K32OBJ_OPS CHANGE_Ops;
extern const K32OBJ_OPS MEM_MAPPED_FILE_Ops;
extern const K32OBJ_OPS DEVICE_Ops;
extern const K32OBJ_OPS CONSOLE_Ops;
extern const K32OBJ_OPS SNAPSHOT_Ops;
static const K32OBJ_OPS K32OBJ_NullOps =
{
......
......@@ -22,7 +22,6 @@
#include "task.h"
#include "server.h"
#include "debug.h"
#include "toolhelp.h"
static BOOL32 PROCESS_Signaled( K32OBJ *obj, DWORD thread_id );
static BOOL32 PROCESS_Satisfied( K32OBJ *obj, DWORD thread_id );
......@@ -42,7 +41,8 @@ const K32OBJ_OPS PROCESS_Ops =
};
static DWORD PROCESS_InitialProcessID = 0;
static PDB32 *PROCESS_PDBList = NULL;
static DWORD PROCESS_PDBList_Size = 0;
/***********************************************************************
* PROCESS_Current
......@@ -177,6 +177,105 @@ static BOOL32 PROCESS_InheritEnvDB( PDB32 *pdb, LPCSTR cmd_line, LPCSTR env,
return TRUE;
}
/***********************************************************************
* PROCESS_PDBList_Insert
* Insert this PDB into the global PDB list
*/
static void PROCESS_PDBList_Insert (PDB32 *pdb)
{
TRACE (process, "Inserting PDB 0x%0lx, #%ld current\n",
PDB_TO_PROCESS_ID (pdb), PROCESS_PDBList_Size);
SYSTEM_LOCK (); /* FIXME: Do I need to worry about this ?
* I.e., could more than one process be
* created at once ?
*/
if (PROCESS_PDBList == NULL)
{
PROCESS_PDBList = pdb;
pdb->list_next = NULL;
pdb->list_prev = NULL;
}
else
{
PDB32 *first = PROCESS_PDBList, *last = PROCESS_PDBList;
if (first->list_prev) last = first->list_prev;
PROCESS_PDBList = pdb;
pdb->list_next = first;
pdb->list_prev = last;
last->list_next = pdb;
first->list_prev = pdb;
}
PROCESS_PDBList_Size ++;
SYSTEM_UNLOCK ();
}
/***********************************************************************
* PROCESS_PDBList_Remove
* Remove this PDB from the global PDB list
*/
static void PROCESS_PDBList_Remove (PDB32 *pdb)
{
PDB32 *next = pdb->list_next, *prev = pdb->list_prev;
TRACE (process, "Removing PDB 0x%0lx, #%ld current\n",
PDB_TO_PROCESS_ID (pdb), PROCESS_PDBList_Size);
SYSTEM_LOCK ();
if (prev == next)
{
next->list_prev = NULL;
next->list_next = NULL;
}
else
{
if (next) next->list_prev = prev;
if (prev) prev->list_next = next;
}
if (pdb == PROCESS_PDBList)
{
PROCESS_PDBList = next ? next : prev;
}
PROCESS_PDBList_Size --;
SYSTEM_UNLOCK ();
}
/***********************************************************************
* PROCESS_PDBList_Getsize
* Return the number of items in the global PDB list
*/
int PROCESS_PDBList_Getsize ()
{
return PROCESS_PDBList_Size;
}
/***********************************************************************
* PROCESS_PDBList_Getfirst
* Return the head of the PDB list
*/
PDB32* PROCESS_PDBList_Getfirst ()
{
return PROCESS_PDBList;
}
/***********************************************************************
* PROCESS_PDBList_Getnext
* Return the "next" pdb as referenced from the argument.
* If at the end of the list, return NULL.
*/
PDB32* PROCESS_PDBList_Getnext (PDB32 *pdb)
{
return (pdb->list_next != PROCESS_PDBList) ? pdb->list_next : NULL;
}
/***********************************************************************
* PROCESS_FreePDB
......@@ -185,6 +284,13 @@ static BOOL32 PROCESS_InheritEnvDB( PDB32 *pdb, LPCSTR cmd_line, LPCSTR env,
*/
static void PROCESS_FreePDB( PDB32 *pdb )
{
/*
* FIXME:
* If this routine is called because PROCESS_CreatePDB fails, the
* following call to PROCESS_PDBList_Remove will probably screw
* up.
*/
PROCESS_PDBList_Remove (pdb);
pdb->header.type = K32OBJ_UNKNOWN;
if (pdb->handle_table) HANDLE_CloseAll( pdb, NULL );
ENV_FreeEnvironment( pdb );
......@@ -230,6 +336,8 @@ static PDB32 *PROCESS_CreatePDB( PDB32 *parent )
if (!HANDLE_CreateTable( pdb, TRUE )) goto error;
PROCESS_PDBList_Insert (pdb);
return pdb;
error:
......@@ -934,17 +1042,3 @@ void PROCESS_ResumeOtherThreads(void)
SYSTEM_UNLOCK();
}
BOOL32 WINAPI Process32First(HANDLE32 hSnapshot, LPPROCESSENTRY32 lppe)
{
FIXME (process, "(0x%08x,%p), stub!\n", hSnapshot, lppe);
SetLastError (ERROR_NO_MORE_FILES);
return FALSE;
}
BOOL32 WINAPI Process32Next(HANDLE32 hSnapshot, LPPROCESSENTRY32 lppe)
{
FIXME (process, "(0x%08x,%p), stub!\n", hSnapshot, lppe);
SetLastError (ERROR_NO_MORE_FILES);
return FALSE;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment