PROCESS.C

/*++ 

Copyright 1995 - 1998 Microsoft Corporation

Module Name:

process.c

Abstract:

This module maintains state about each process/thread created by the application
pfmon program.

Author:

Mark Lucovsky (markl) 26-Jan-1995

Revision History:

--*/

#include "pfmonp.h"

BOOL
AddProcess(
LPDEBUG_EVENT DebugEvent,
PPROCESS_INFO *ReturnedProcess
)
{
PPROCESS_INFO Process;

Process = LocalAlloc(LMEM_ZEROINIT, sizeof( *Process ) );
if (Process == NULL) {
return FALSE;
}

Process->Id = DebugEvent->dwProcessId;
Process->Handle = DebugEvent->u.CreateProcessInfo.hProcess;
InitializeListHead( &Process->ThreadListHead );
InsertTailList( &ProcessListHead, &Process->Entry );
*ReturnedProcess = Process;

return TRUE;
}

BOOL
DeleteProcess(
PPROCESS_INFO Process
)
{
PLIST_ENTRY Next, Head;
PTHREAD_INFO Thread;
PMODULE_INFO Module;
CHAR Line[256];

RemoveEntryList( &Process->Entry );

Head = &Process->ThreadListHead;
Next = Head->Flink;
while (Next != Head) {
Thread = CONTAINING_RECORD( Next, THREAD_INFO, Entry );
Next = Next->Flink;
DeleteThread( Process, Thread );
}

LocalFree( Process );
fprintf(stdout,"\n");

Next = ModuleListHead.Flink;
while ( Next != &ModuleListHead ) {
Module = CONTAINING_RECORD(Next,MODULE_INFO,Entry);


sprintf(Line,"%16s Caused %6d faults had %6d Soft %6d Hard faulted VA's\n",
Module->DebugInfo->ImageFileName,
Module->NumberCausedFaults,
Module->NumberFaultedSoftVas,
Module->NumberFaultedHardVas
);
if ( !fLogOnly ) {
fprintf(stdout,"%s",Line);
}
if ( LogFile ) {
fprintf(LogFile,"%s",Line);
}

Next = Next->Flink;
}


return TRUE;
}


BOOL
AddThread(
LPDEBUG_EVENT DebugEvent,
PPROCESS_INFO Process,
PTHREAD_INFO *ReturnedThread
)
{
PTHREAD_INFO Thread;

Thread = LocalAlloc(LMEM_ZEROINIT, sizeof( *Thread ) );
if (Thread == NULL) {
return FALSE;
}

Thread->Id = DebugEvent->dwThreadId;
if (DebugEvent->dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) {
Thread->Handle = DebugEvent->u.CreateProcessInfo.hThread;
Thread->StartAddress = DebugEvent->u.CreateProcessInfo.lpStartAddress;
}
else {
Thread->Handle = DebugEvent->u.CreateThread.hThread;
Thread->StartAddress = DebugEvent->u.CreateThread.lpStartAddress;
}
InsertTailList( &Process->ThreadListHead, &Thread->Entry );
*ReturnedThread = Thread;
return TRUE;
}

BOOL
DeleteThread(
PPROCESS_INFO Process,
PTHREAD_INFO Thread
)
{

RemoveEntryList( &Thread->Entry );

LocalFree( Thread );
return TRUE;
}


PPROCESS_INFO
FindProcessById(
ULONG Id
)
{
PLIST_ENTRY Next, Head;
PPROCESS_INFO Process;

Head = &ProcessListHead;
Next = Head->Flink;
while (Next != Head) {
Process = CONTAINING_RECORD( Next, PROCESS_INFO, Entry );
if (Process->Id == Id) {
return Process;
}

Next = Next->Flink;
}

return NULL;
}

BOOL
FindProcessAndThreadForEvent(
LPDEBUG_EVENT DebugEvent,
PPROCESS_INFO *ReturnedProcess,
PTHREAD_INFO *ReturnedThread
)
{
PLIST_ENTRY Next, Head;
PPROCESS_INFO Process;
PTHREAD_INFO Thread;

Head = &ProcessListHead;
Next = Head->Flink;
Process = NULL;
Thread = NULL;
while (Next != Head) {
Process = CONTAINING_RECORD( Next, PROCESS_INFO, Entry );
if (Process->Id == DebugEvent->dwProcessId) {
Head = &Process->ThreadListHead;
Next = Head->Flink;
while (Next != Head) {
Thread = CONTAINING_RECORD( Next, THREAD_INFO, Entry );
if (Thread->Id == DebugEvent->dwThreadId) {
break;
}

Thread = NULL;
Next = Next->Flink;
}

break;
}

Process = NULL;
Next = Next->Flink;
}

*ReturnedProcess = Process;
*ReturnedThread = Thread;

if (DebugEvent->dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) {
if (Process != NULL) {
DeclareError( PFMON_DUPLICATE_PROCESS_ID, 0, DebugEvent->dwProcessId );
return FALSE;
}
}
else
if (DebugEvent->dwDebugEventCode == CREATE_THREAD_DEBUG_EVENT) {
if (Thread != NULL) {
DeclareError( PFMON_DUPLICATE_THREAD_ID, 0, DebugEvent->dwThreadId, DebugEvent->dwProcessId );
return FALSE;
}
if (Process == NULL) {
DeclareError( PFMON_MISSING_PROCESS_ID, 0, DebugEvent->dwProcessId );
return FALSE;
}
}
else
if (Process == NULL) {
DeclareError( PFMON_MISSING_PROCESS_ID, 0, DebugEvent->dwProcessId );
return FALSE;
}
else
if (Thread == NULL) {
DeclareError( PFMON_MISSING_THREAD_ID, 0, DebugEvent->dwThreadId, DebugEvent->dwProcessId );
return FALSE;
}

return TRUE;
}