📄 pid_pname.c
字号:
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
//
// $Id: pid_pname.c,v 1.2 2002/12/03 13:32:17 dev Exp $
/*
* Get process name by its pid and all related routines
*/
#include <ntddk.h>
#include "memtrack.h"
#include "pid_pname.h"
/* process list entry */
struct plist_entry {
struct plist_entry *next;
// id & name
ULONG pid;
char *pname;
KEVENT *pname_event;
int context;
};
/* process list */
static struct {
struct plist_entry *head;
struct plist_entry *tail;
KSPIN_LOCK guard;
} g_plist;
static struct plist_entry *add_ple(ULONG pid, KIRQL *irql);
static struct plist_entry *find_ple(ULONG pid, KIRQL *irql, struct plist_entry **prev);
static VOID ProcessNotifyProc(IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create);
void
pid_pname_init(void)
{
KeInitializeSpinLock(&g_plist.guard);
g_plist.head = g_plist.tail = NULL;
PsSetCreateProcessNotifyRoutine(ProcessNotifyProc, FALSE);
}
// free plist
void
pid_pname_free(void)
{
KIRQL irql;
struct plist_entry *ple;
PsSetCreateProcessNotifyRoutine(ProcessNotifyProc, TRUE);
KeAcquireSpinLock(&g_plist.guard, &irql);
for (ple = g_plist.head; ple != NULL;) {
struct plist_entry *ple2 = ple->next;
if (ple->pname != NULL)
free(ple->pname);
free(ple);
ple = ple2;
}
g_plist.head = g_plist.tail = NULL;
KeReleaseSpinLock(&g_plist.guard, irql);
}
// try to get pname by pid
BOOLEAN
pid_pname_resolve(ULONG pid, char *buf, int buf_size)
{
BOOLEAN result;
KIRQL irql;
struct plist_entry *ple = find_ple(pid, &irql, NULL);
if (ple == NULL)
return FALSE;
if (ple->pname != NULL) {
if (buf_size > 0) {
strncpy(buf, ple->pname, buf_size);
buf[buf_size - 1] = '\0';
}
result = TRUE;
} else
result = FALSE;
KeReleaseSpinLock(&g_plist.guard, irql);
return result;
}
// set pname_event by pid
NTSTATUS
pid_pname_set_event(ULONG pid, KEVENT *event)
{
KIRQL irql;
struct plist_entry *ple = find_ple(pid, &irql, NULL);
if (ple == NULL) {
// try to add
ple = add_ple(pid, &irql);
if (ple == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
}
ple->pname_event = event;
KeReleaseSpinLock(&g_plist.guard, irql);
return STATUS_SUCCESS;
}
NTSTATUS
pid_pname_set(ULONG pid, const char *pname, int context)
{
KIRQL irql;
struct plist_entry *ple = find_ple(pid, &irql, NULL);
NTSTATUS status;
if (ple == NULL) {
// try to add
ple = add_ple(pid, &irql);
if (ple == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
}
if (ple->pname == NULL) {
ple->pname = (char *)malloc_np(strlen(pname) + 1);
if (ple->pname != NULL) {
strcpy(ple->pname, pname);
status = STATUS_SUCCESS;
} else {
KdPrint(("[tdi_fw] set_pid_name: malloc_np!\n"));
status = STATUS_INSUFFICIENT_RESOURCES;
}
// and signal event we have name! (almost)
if (ple->pname_event != NULL)
KeSetEvent(ple->pname_event, IO_NO_INCREMENT, FALSE);
}
ple->context = context;
KeReleaseSpinLock(&g_plist.guard, irql);
return status;
}
int
pid_pname_get_context(ULONG pid)
{
KIRQL irql;
int context;
struct plist_entry *ple = find_ple(pid, &irql, NULL);
if (ple == NULL)
return 0;
context = ple->context;
KeReleaseSpinLock(&g_plist.guard, irql);
return context;
}
struct plist_entry *
add_ple(ULONG pid, KIRQL *irql)
{
struct plist_entry *ple;
if (irql != NULL)
KeAcquireSpinLock(&g_plist.guard, irql);
// add new entry to g_plist
ple = (struct plist_entry *)malloc_np(sizeof(*ple));
if (ple != NULL) {
memset(ple, 0, sizeof(*ple));
ple->pid = pid;
// append
if (g_plist.tail != NULL) {
g_plist.tail->next = ple;
g_plist.tail = ple;
} else
g_plist.head = g_plist.tail = ple;
} else {
KdPrint(("[tdi_fw] add_ple: malloc_np!\n"));
if (irql != NULL)
KeReleaseSpinLock(&g_plist.guard, *irql);
}
return ple;
}
struct plist_entry *
find_ple(ULONG pid, KIRQL *irql, struct plist_entry **prev)
{
struct plist_entry *ple, *prev_ple;
if (irql != NULL)
KeAcquireSpinLock(&g_plist.guard, irql);
prev_ple = NULL;
for (ple = g_plist.head; ple != NULL; ple = ple->next) {
if (ple->pid == pid) {
if (prev != NULL)
*prev = prev_ple;
return ple;
}
prev_ple = ple;
}
if (irql != NULL)
KeReleaseSpinLock(&g_plist.guard, *irql);
return NULL;
}
// notify routine on process creation or removing
VOID
ProcessNotifyProc(IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create)
{
KIRQL irql;
struct plist_entry *ple, *prev_ple;
if (Create) {
KdPrint(("[tdi_fw] ProcessNotifyProc: create process with pid:%u\n", ProcessId));
add_ple((ULONG)ProcessId, &irql);
KeReleaseSpinLock(&g_plist.guard, irql);
} else {
// remove entry from plist
KdPrint(("[tdi_fw] ProcessNotifyProc: remove process with pid:%u\n", ProcessId));
ple = find_ple((ULONG)ProcessId, &irql, &prev_ple);
if (ple == NULL)
return;
if (prev_ple != NULL)
prev_ple->next = ple->next;
else
g_plist.head = ple->next;
if (ple->next == NULL)
g_plist.tail = prev_ple;
if (ple->pname != NULL) {
KdPrint(("[tdi_fw] ProcessNotifyProc: pname was %s\n", ple->pname));
free(ple->pname);
}
free(ple);
KeReleaseSpinLock(&g_plist.guard, irql);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -