Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

447 lines
12 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
afds.c
Abstract:
Implements afds command
Author:
Vadim Eydelman, March 2000
Environment:
User Mode.
Revision History:
--*/
#include "afdkdp.h"
#pragma hdrstop
#define AFDKD_TOKEN "@$."
#define AFDKD_TOKSZ (sizeof (AFDKD_TOKEN)-1)
ULONG
ListCallback (
PFIELD_INFO pField,
PVOID UserContext
);
//
// Public functions.
//
ULONG LinkOffset;
DECLARE_API( afds )
/*++
Routine Description:
Dumps afd endpoints
Arguments:
None.
Return Value:
None.
--*/
{
ULONG64 address;
CHAR expr[MAX_ADDRESS_EXPRESSION];
PCHAR argp;
INT i;
ULONG result;
gClient = pClient;
argp = ProcessOptions ((PCHAR)args);
if (argp==NULL)
return E_INVALIDARG;
if ((Options & (AFDKD_LINK_FIELD|AFDKD_LIST_TYPE)) !=
(AFDKD_LINK_FIELD|AFDKD_LIST_TYPE)) {
dprintf ("\nafds: Missing link or list type specification");
dprintf ("\nUsage:\nafds -l link -t type [options] address\n");
return E_INVALIDARG;
}
if (sscanf( argp, "%s%n", expr, &i )!=1) {
dprintf ("\nafds: Missing address specification");
dprintf ("\nUsage:\nafds -l link -t type [options] address\n");
return E_INVALIDARG;
}
argp += i;
address = GetExpression (expr);
if (Options & AFDKD_LINK_SELF) {
result = GetFieldOffset (ListedType, LinkField, &LinkOffset);
if (result!=0) {
dprintf ("\nafds: Cannot get offset of %s in %s, err: %ld\n",
LinkField, ListedType, result);
return E_INVALIDARG;
}
}
ListType (
(Options & AFDKD_LINK_SELF)
? "LIST_ENTRY"
: ListedType, // Type
address, // Address
(Options & AFDKD_LINK_AOF)
? 1
: 0, // ListByFieldAddress
(Options & AFDKD_LINK_SELF)
? "Flink"
: LinkField, // NextPointer
ListedType, // Context
ListCallback);
dprintf ("\n");
return S_OK;
}
ULONG
ListCallback (
PFIELD_INFO pField,
PVOID UserContext
)
{
ULONG64 address;
address = pField->address;
if (Options & AFDKD_LINK_SELF) {
address -= LinkOffset;
}
if (!(Options & AFDKD_CONDITIONAL) ||
CheckConditional (address, UserContext)) {
dprintf ("\n%s @ %p", UserContext, address);
ProcessFieldOutput (address, UserContext);
}
else {
dprintf (".");
}
return 0;
}
/*
{
ULONG64
GetExpressionFromType (
ULONG64 Address,
PCHAR Type,
PCHAR Expression
)
CHAR expr[MAX_CONDITIONAL_EXPRESSION];
PCHAR argp = Expression, pe = expr, pestop=pe+sizeof(expr)-1;
ULONG result;
ULONG64 value;
PCHAR type = Type;
ULONG64 address = Address;
while (*argp) {
if (*argp=='@' && strncmp (argp, AFDKD_TOKEN, AFDKD_TOKSZ)==0) {
PCHAR end = pe;
argp+= AFDKD_TOKSZ;
while (isalnum (*argp) ||
*argp=='[' ||
*argp==']' ||
*argp=='_' ||
*argp=='.' ||
*argp=='-') {
if (*argp=='-') {
if (*(argp+1)=='>') {
if (*(argp+2)=='(') {
*end = 0;
result = GetFieldValue (address, type, pe, value);
if (result!=0) {
dprintf ("\nCheckConditional: Can't get %s.%s at %p (err:%d)\n", type, pe, address, result);
return FALSE;
}
if (value==0)
return FALSE;
argp += 3;
type = argp;
while (*argp && *argp!=')') {
argp += 1;
}
*argp++ = 0;
address = value;
end = pe;
continue;
}
if (end>=pestop)
break;
*end++ = *argp++;
}
else
break;
}
if (end>=pestop)
break;
*end++ = *argp++;
}
*end = 0;
result = GetFieldValue (address, type, pe, value);
if (result!=0) {
dprintf ("\nCheckConditional: Can't get %s.%s at %p (err:%d)\n", type, pe, address, result);
return FALSE;
}
pe += _snprintf (pe, pestop-pe, "0x%I64X", value);
address = Address;
type = Type;
}
else {
if (pe>=pestop)
break;
*pe++ = *argp++;
}
}
*pe = 0;
return GetExpression (expr);
}
*/
BOOLEAN
CheckConditional (
ULONG64 Address,
PCHAR Type
)
{
DEBUG_VALUE val;
if (GetExpressionFromType (Address, Type, Conditional, DEBUG_VALUE_INT64, &val)==S_OK)
return val.I64!=0;
else
return FALSE;
}
VOID
ProcessFieldOutput (
ULONG64 Address,
PCHAR Type
)
{
ULONG result;
FldParam.addr = Address;
FldParam.sName = Type;
if (Options & AFDKD_NO_DISPLAY) {
FldParam.Options |= DBG_DUMP_COMPACT_OUT;
}
dprintf ("\n");
if (FldParam.nFields>0 ||
(FldParam.nFields==0 && CppFieldEnd==0)) {
result = Ioctl (IG_DUMP_SYMBOL_INFO, &FldParam, FldParam.size );
if (result!=0) {
dprintf ("\nProcessFieldOutput: IG_DUMP_SYMBOL_INFO failed, err: %ld\n", result);
}
}
if (CppFieldEnd>FldParam.nFields) {
ULONG i;
for (i=FldParam.nFields; i<CppFieldEnd; i++) {
DEBUG_VALUE val;
if (GetExpressionFromType (Address, Type, FldParam.Fields[i].fName,
DEBUG_VALUE_INVALID,
&val)==S_OK) {
dprintf (" %s = 0x%I64x(%d)\n",
&FldParam.Fields[i].fName[AFDKD_CPP_PREFSZ],
val.I64,
val.Type
);
}
/*
SYM_DUMP_PARAM fldParam;
CHAR fieldStr[MAX_FIELD_CHARS], *p;
FIELD_INFO field = FldParam.Fields[i];
ULONG64 value;
ULONG skip = 0;
fldParam = FldParam;
fldParam.nFields = 1;
fldParam.Fields = &field;
//fldParam.Options |= DBG_DUMP_NO_PRINT;
strncpy (fieldStr, field.fName, sizeof (fieldStr));
field.fName = p = fieldStr;
field.fOptions |= DBG_DUMP_FIELD_COPY_FIELD_DATA;
field.fieldCallBack = &value;
while ((p=strstr (p, "->("))!=NULL) {
*p = 0;
result = Ioctl (IG_DUMP_SYMBOL_INFO, &fldParam, fldParam.size );
if (result!=0) {
dprintf ("\nProcessFieldOutput: GetFieldValue (%p,%s,%s) failed, err: %ld\n",
fldParam.addr,
fldParam.sName,
field.fName,
result);
goto DoneField;
}
fldParam.addr = value;
p += sizeof ("->(")-1;
fldParam.sName = p;
p = strchr (p, ')');
if (p==NULL) {
dprintf ("\nProcessFieldOutput: missing ')' in %s\n", fldParam.sName);
goto DoneField;
}
*p++ = 0;
skip += 3;
dprintf ("%*.80s%s : %I64x->(%s)\n", skip, " ",
field.fName,
DISP_PTR(value),
fldParam.sName);
field.fName = p;
if (value==0) {
goto DoneField;
}
}
//fldParam.Options &= (~DBG_DUMP_NO_PRINT);
field.fOptions &= ~(DBG_DUMP_FIELD_COPY_FIELD_DATA);
field.fieldCallBack = NULL;
result = Ioctl (IG_DUMP_SYMBOL_INFO, &fldParam, fldParam.size );
if (result!=0) {
dprintf ("\nProcessFieldOutput: IG_DUMP_SYMBOL_INFO %p %s %s failed, err: %ld\n",
fldParam.addr,
fldParam.sName,
field.fName,
result);
break;
}
DoneField:
;
*/
}
}
}
DECLARE_API( filefind )
/*++
Routine Description:
Searches non-paged pool for FILE_OBJECT given its FsContext field.
Arguments:
None.
Return Value:
None.
--*/
{
ULONG64 FsContext;
ULONG64 PoolStart, PoolEnd, PoolPage;
ULONG64 PoolExpansionStart, PoolExpansionEnd;
ULONG result;
ULONG64 val;
BOOLEAN twoPools;
gClient = pClient;
if (!CheckKmGlobals ()) {
return E_INVALIDARG;
}
FsContext = GetExpression (args);
if (FsContext==0 || FsContext<UserProbeAddress) {
return E_INVALIDARG;
}
if ( (result = ReadPtr (DebuggerData.MmNonPagedPoolStart, &PoolStart))!=0 ||
(result = ReadPtr (DebuggerData.MmNonPagedPoolEnd, &PoolEnd))!=0 ) {
dprintf ("\nfilefind - Cannot get non-paged pool limits, err: %ld\n",
result);
return E_INVALIDARG;
}
if (PoolStart + DebuggerData.MmMaximumNonPagedPoolInBytes!=PoolEnd) {
if ( (result = GetFieldValue (0,
"NT!MmSizeOfNonPagedPoolInBytes",
NULL,
val))!=0 ||
(result = GetFieldValue (0,
"NT!MmNonPagedPoolExpansionStart",
NULL,
PoolExpansionStart))!=0 ) {
dprintf ("\nfilefind - Cannot get non-paged pool expansion limits, err: %ld\n",
result);
return E_INVALIDARG;
}
PoolExpansionEnd = PoolEnd;
PoolEnd = PoolStart + val;
twoPools = TRUE;
}
else {
twoPools = FALSE;
}
PoolPage = PoolStart;
dprintf ("Searching non-paged pool %p - %p...\n", PoolStart, PoolEnd);
while (PoolPage<PoolEnd) {
SEARCHMEMORY Search;
if (CheckControlC ()) {
break;
}
Search.SearchAddress = PoolPage;
Search.SearchLength = PoolEnd-PoolPage;
Search.Pattern = &FsContext;
Search.PatternLength = IsPtr64 () ? sizeof (ULONG64) : sizeof (ULONG);
Search.FoundAddress = 0;
if (Ioctl (IG_SEARCH_MEMORY, &Search, sizeof (Search)) &&
Search.FoundAddress!=0) {
ULONG64 fileAddr;
fileAddr = Search.FoundAddress-FsContextOffset;
result = (ULONG)InitTypeRead (fileAddr, NT!_FILE_OBJECT);
if (result==0 && (CSHORT)ReadField (Type)==IO_TYPE_FILE) {
dprintf ("File object at %p\n", fileAddr);
}
else {
dprintf (" pool search match at %p\n", Search.FoundAddress);
}
PoolPage = Search.FoundAddress +
(IsPtr64() ? sizeof (ULONG64) : sizeof (ULONG));
}
else {
if (!twoPools || PoolEnd==PoolExpansionEnd) {
break;
}
else {
dprintf ("Searching expansion non-paged pool %p - %p...\n",
PoolExpansionStart, PoolExpansionEnd);
PoolEnd = PoolExpansionEnd;
PoolPage = PoolExpansionStart;
}
}
}
return S_OK;
}