windows-nt/Source/XPSP1/NT/base/tools/kdexts2/session.c
2020-09-26 16:20:57 +08:00

334 lines
7.6 KiB
C

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
process.c
Abstract:
WinDbg Extension Api
Author:
John Richardson (v-johnjr) 05-Nov-1998
Environment:
User Mode.
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
BOOL
DumpSession(
IN char * pad,
IN ULONG64 RealProcessBase,
IN ULONG Flags,
IN PCHAR ImageFileName
);
DECLARE_API( session )
/*++
Routine Description:
Dumps the active sessions list.
Arguments:
None.
Return Value:
None.
--*/
{
ULONG64 ProcessToDump;
ULONG SessionToDump;
ULONG Flags;
ULONG Result;
ULONG64 Next;
ULONG64 ProcessHead;
ULONG64 Process;
ULONG64 Thread;
PCHAR ImageFileName;
STRING string1, string2;
CHAR Buf[256];
CHAR Buf2[256];
ULONG ActiveProcessLinksOffset;
// Dump all processes
ProcessToDump = 0;
SessionToDump = 0xFFFFFFFF;
Flags = 0xFFFFFFFF;
RtlZeroMemory(Buf, 256);
if (!sscanf(args,"%lx %lx %s",&SessionToDump, &Flags, Buf)) {
Flags = 0xFFFFFFFF;
SessionToDump = 0xFFFFFFFF;
}
if (Flags == 0xFFFFFFFF) {
Flags = 3;
}
// We use csrss.exe to represent sessions by default
if (Buf[0] != '\0') {
ImageFileName = Buf;
} else {
ImageFileName = "csrss.exe";
}
dprintf("*** !session obsolete, Use !process");
if (SessionToDump == -1) {
dprintf(" 0 0 %s\n", ImageFileName);
} else {
dprintf(" /s %lx 0 0 %s\n", SessionToDump, ImageFileName);
}
dprintf("**** NT ACTIVE SESSION DUMP ****\n");
ProcessHead = GetNtDebuggerData( PsActiveProcessHead );
if (!ProcessHead) {
dprintf("Unable to get value of PsActiveProcessHead\n");
return E_INVALIDARG;
}
if (GetFieldValue( ProcessHead, "nt!_LIST_ENTRY", "Flink", Next)) {
dprintf("Unable to get value of PsActiveProcessHead\n");
return E_INVALIDARG;
}
if (Next == 0) {
dprintf("PsActiveProcessHead is NULL!\n");
return E_INVALIDARG;
}
if (GetFieldOffset("nt!_EPROCESS", "ActiveProcessLinks", &ActiveProcessLinksOffset)) {
dprintf("Cannot find nt!_EPROCESS type.\n");
return E_INVALIDARG;
}
//dprintf("Offset %#x\n", ActiveProcessLinksOffset);
while(Next != ProcessHead) {
ULONG SessionId;
if (Next != 0) {
Process = (Next - ActiveProcessLinksOffset);
}
else {
Process = ProcessToDump;
}
if (GetFieldValue( Process, "nt!_EPROCESS", "ImageFileName", Buf2)) {
dprintf("Unable to read nt!_EPROCESS at %p\n",Process);
return E_INVALIDARG;
}
if (Buf2[0] == '\0' ) {
strcpy((PCHAR)Buf2,"System Process");
}
RtlInitString(&string1, ImageFileName);
RtlInitString(&string2, (PCSZ) Buf2);
GetFieldValue( Process, "nt!_EPROCESS", "SessionId" ,SessionId);
if ( ((SessionToDump == (ULONG) -1) || (SessionToDump == SessionId))
&&
RtlCompareString(&string1, &string2, TRUE) == 0) {
if (DumpSession ("", Process, Flags, ImageFileName) && (Flags & 6)) {
EXPRLastDump = Process;
dprintf("\n");
}
if (ProcessToDump != 0) {
return E_INVALIDARG;
}
}
GetFieldValue( Process, "nt!_EPROCESS", "ActiveProcessLinks.Flink", Next);
if (Next == 0) {
return E_INVALIDARG;
}
if (CheckControlC()) {
return E_INVALIDARG;
}
}
return S_OK;
}
DECLARE_API( dss )
/*++
Routine Description:
Dumps the session space structure
Arguments:
None.
Return Value:
None.
--*/
{
ULONG Result;
ULONG64 MmSessionSpace;
ULONG64 MmSessionSpacePtr = 0;
ULONG64 Wsle;
MmSessionSpacePtr = GetExpression(args);
if( MmSessionSpacePtr == 0 ) {
MmSessionSpacePtr = GetExpression("nt!MmSessionSpace");
if( !MmSessionSpacePtr ) {
dprintf("Unable to get address of MmSessionSpace\n");
return E_INVALIDARG;
}
if (!ReadPointer( MmSessionSpacePtr, &MmSessionSpace)) {
dprintf("Unable to get value of MmSessionSpace\n");
return E_INVALIDARG;
}
} else {
MmSessionSpace = MmSessionSpacePtr;
}
dprintf("MM_SESSION_SPACE at 0x%p\n",
MmSessionSpace
);
if (GetFieldValue(MmSessionSpace, "MM_SESSION_SPACE", "Wsle", Wsle)) {
dprintf("Unable to get value of MM_SESSION_SPACE at 0x%p\n",MmSessionSpace);
return E_INVALIDARG;
}
GetFieldOffset("MM_SESSION_SPACE", "PageTables", &Result);
dprintf("&PageTables %p\n",
MmSessionSpace + Result
);
GetFieldOffset("MM_SESSION_SPACE", "PagedPoolInfo", &Result);
dprintf("&MM_PAGED_POOL_INFO %x\n",
MmSessionSpace + Result
);
GetFieldOffset("MM_SESSION_SPACE", "Vm", &Result);
dprintf("&MMSUPPORT %p\n",
MmSessionSpace + Result
);
GetFieldOffset("MM_SESSION_SPACE", "Wsle", &Result);
dprintf("&PMMWSLE %p\n",
MmSessionSpace + Result
);
GetFieldOffset("MM_SESSION_SPACE", "Session", &Result);
dprintf("&MMSESSION %p\n",
MmSessionSpace + Result
);
GetFieldOffset("MM_SESSION_SPACE", "WorkingSetLockOwner", &Result);
dprintf("&WorkingSetLockOwner %p\n",
MmSessionSpace + Result
);
GetFieldOffset("MM_SESSION_SPACE", "PagedPool", &Result);
dprintf("&POOL_DESCRIPTOR %p\n",
MmSessionSpace + Result
);
return S_OK;
}
BOOL
DumpSession(
IN char * pad,
IN ULONG64 RealProcessBase,
IN ULONG Flags,
IN PCHAR ImageFileName
)
{
ULONG NumberOfHandles;
ULONG Result;
LARGE_INTEGER RunTime;
ULONG KeTimeIncrement;
ULONG TimeIncrement;
STRING string1, string2;
ULONG Type, SessionId,StackCount;
ULONG64 ObjectTable,UniqueProcessId, Peb,DirBase;
#define ProcFld(F, V) GetFieldValue(RealProcessBase, "EPROCESS", #F, V)
#define ProcFld2(F) GetFieldValue(RealProcessBase, "EPROCESS", #F, F)
if (ProcFld(Pcb.Header.Type, Type)) {
dprintf("Unable to read EPROCESS at %p\n", RealProcessBase);
return FALSE;
}
if (Type != (ULONG) ProcessObject) {
dprintf("TYPE mismatch for process object at %p\n",RealProcessBase);
return FALSE;
}
ProcFld2(ObjectTable); ProcFld2(UniqueProcessId); ProcFld2(Peb);
ProcFld2(SessionId); ProcFld(Pcb.StackCount, StackCount);
ProcFld(Pcb.DirectoryTableBase[0], DirBase);
NumberOfHandles = 0;
if (ObjectTable) {
GetFieldValue(ObjectTable,
"HANDLE_TABLE",
"HandleCount",
NumberOfHandles);
}
dprintf("%sPROCESS %08p Cid: %04I64lx Peb: %08p SessionId: %08u\n",
pad,
RealProcessBase,
UniqueProcessId,
Peb,
SessionId
);
// If Pcb.StackCount is 0, PD is not resident!
if( StackCount == 0 ) {
dprintf("%s DirBase: NotResident ObjectTable: %08p TableSize: %3u.\n",
pad,
ObjectTable,
NumberOfHandles
);
}
else {
dprintf("%s DirBase: %08p ObjectTable: %08p TableSize: %3u.\n",
pad,
DirBase,
ObjectTable,
NumberOfHandles
);
}
dprintf("%s Image: %s\n",pad,ImageFileName);
#undef ProcFld
#undef ProcFld2
return TRUE;
}