windows-nt/Source/XPSP1/NT/base/fs/dfs/util/dfskd/dfskd.c

1957 lines
62 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
dfskd.c
Abstract:
Dfs Kernel Debugger extension
Author:
Milan Shah (milans) 21-Aug-1995
Revision History:
21-Aug-1995 Milans Created
30-Aug-1997 JHarper Updated
--*/
#include <ntos.h>
#include <nturtl.h>
#include "ntverp.h"
#include <windows.h>
#include <wdbgexts.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "nodetype.h"
#include "dfsmrshl.h"
#include "dfsfsctl.h"
#include "pkt.h"
#include "dfslpc.h"
#include "spcsup.h"
#include "sitesup.h"
#include "ipsup.h"
#include "dfsstruc.h"
#include "fsctrl.h"
#include "attach.h"
#include "fcbsup.h"
#include <kdextlib.h>
#define PRINTF dprintf
#define IPRINTF DoIndent(); dprintf
#define IPRINTSTRINGW DoIndent(); wPrintStringW
#define NTC_UNDEFINED ((NODE_TYPE_CODE)0x0000)
#define DSFS_NTC_DATA_HEADER ((NODE_TYPE_CODE)0x0D01)
#define DSFS_NTC_IRP_CONTEXT ((NODE_TYPE_CODE)0x0D02)
#define DSFS_NTC_REFERRAL ((NODE_TYPE_CODE)0x0D03)
#define DSFS_NTC_VCB ((NODE_TYPE_CODE)0x0D04)
#define DSFS_NTC_PROVIDER ((NODE_TYPE_CODE)0x0D05)
#define DSFS_NTC_FCB_HASH ((NODE_TYPE_CODE)0x0D06)
#define DSFS_NTC_FCB ((NODE_TYPE_CODE)0x0D07)
#define DSFS_NTC_DNR_CONTEXT ((NODE_TYPE_CODE)0x0D08)
#define DSFS_NTC_PKT ((NODE_TYPE_CODE)0x0D09)
#define DSFS_NTC_PKT_ENTRY ((NODE_TYPE_CODE)0x0D0A)
#define DSFS_NTC_PKT_STUB ((NODE_TYPE_CODE)0x0D0B)
#define DSFS_NTC_INSTRUM ((NODE_TYPE_CODE)0x0D0C)
#define DSFS_NTC_INSTRUM_FREED ((NODE_TYPE_CODE)0x0D0D)
#define DSFS_NTC_PWSTR ((NODE_TYPE_CODE)0x0D0E)
#define FIELD_NAME_LENGTH 30
#define NewLineForFields(FieldNo) \
((((FieldNo) % s_NoOfColumns) == 0) ? NewLine : FieldSeparator)
char *NewLine = "\n";
char *FieldSeparator = " ";
BOOLEAN wGetData( ULONG_PTR dwAddress, PVOID ptr, ULONG size);
BOOL wGetString( ULONG_PTR dwAddress, PSZ buf );
BOOL wPrintStringW( IN LPSTR msg OPTIONAL, IN PUNICODE_STRING pStr, IN BOOL nl );
BOOL wPrintStringA( IN LPSTR msg OPTIONAL, IN PANSI_STRING pStr, IN BOOL nl );
BOOL wPrintLargeInt(LARGE_INTEGER *bigint);
#define MAX_ENTRIES 100
/*
* Dfs global variables.
*
*/
#define NO_SYMBOLS_MESSAGE \
"Unable to get address of Dfs!DfsData - do you have symbols?\n"
LPSTR ExtensionNames[] = {
"Dfs debugger extensions",
0
};
LPSTR Extensions[] = {
"DfsData - dumps Dfs!DfsData",
"Pkt - dumps the global Pkt",
"SpecialTable - dumps the Special table",
"FtDfsTable - dumps the FtDfs table",
"SiteTable - dumps the Site table",
"IpTable - dumps the Ip table",
"FcbTable - dumps all the Dfs FCBs",
"VdoList - dumps all the Dfs Volume Objects (attached device objects)",
"VcbList - dumps all the Vcbs & Dfs Device Objects (net used objects)",
"Dump - dump a data structure. Type in 'dfskd.dump' for more info",
"Dumpdfs address -- dumps DfsData, prefix table",
0
};
ENUM_VALUE_DESCRIPTOR DfsOperationalStateEnum[] = {
{DFS_STATE_UNINITIALIZED, "Dfs State Uninitialized"},
{DFS_STATE_INITIALIZED, "Dfs State Initialized"},
{DFS_STATE_STARTED, "Dfs Started"},
{DFS_STATE_STOPPING, "Dfs Stopping"},
{DFS_STATE_STOPPED, "Dfs Stopped"},
0
};
ENUM_VALUE_DESCRIPTOR DfsMachineStateEnum[] = {
{DFS_UNKNOWN, "Dfs State Unknown"},
{DFS_CLIENT, "Dfs Client"},
{DFS_SERVER, "Dfs Server"},
{DFS_ROOT_SERVER, "Dfs Root"},
0
};
ENUM_VALUE_DESCRIPTOR LpcPortStateEnum[] = {
{LPC_STATE_UNINITIALIZED, "Unitialized"},
{LPC_STATE_INITIALIZING, "Initializing"},
{LPC_STATE_INITIALIZED, "Initialized"},
0
};
ENUM_VALUE_DESCRIPTOR LvStateEnum[] = {
{LV_UNINITIALIZED,"Local Vols Uninitialized"},
{LV_INITSCHEDULED,"Local Vols init scheduled"},
{LV_INITINPROGRESS,"Local Vols init in progress"},
{LV_INITIALIZED,"Local Vols Initialized"},
{LV_VALIDATED,"Local Vols Validated with DC"},
0
};
/*
* DFS_DATA
*
*/
FIELD_DESCRIPTOR DfsDataFields[] = {
FIELD3(FieldTypeShort,DFS_DATA,NodeTypeCode),
FIELD3(FieldTypeShort,DFS_DATA,NodeByteSize),
FIELD3(FieldTypeStruct,DFS_DATA,AVdoQueue),
FIELD3(FieldTypePointer,DFS_DATA,DriverObject),
FIELD3(FieldTypePointer,DFS_DATA,FileSysDeviceObject),
FIELD3(FieldTypePointer,DFS_DATA,pProvider),
FIELD3(FieldTypeULong,DFS_DATA,cProvider),
FIELD3(FieldTypeULong,DFS_DATA,maxProvider),
FIELD3(FieldTypeStruct,DFS_DATA,Resource),
FIELD3(FieldTypeUnicodeString,DFS_DATA,PrincipalName),
FIELD3(FieldTypeUnicodeString,DFS_DATA,NetBIOSName),
FIELD4(FieldTypeEnum,DFS_DATA,OperationalState,DfsOperationalStateEnum),
FIELD4(FieldTypeEnum,DFS_DATA,MachineState,DfsMachineStateEnum),
FIELD3(FieldTypeBoolean,DFS_DATA,IsDC),
FIELD4(FieldTypeEnum,DFS_DATA,LvState,LvStateEnum),
FIELD3(FieldTypeStruct,DFS_DATA,Pkt),
FIELD3(FieldTypePointer,DFS_DATA,FcbHashTable),
FIELD3(FieldTypePointer,DFS_DATA,SiteHashTable),
FIELD3(FieldTypePointer,DFS_DATA,IpHashTable),
FIELD3(FieldTypePointer,DFS_DATA,SpcHashTable),
FIELD3(FieldTypePointer,DFS_DATA,FtDfsHashTable),
FIELD3(FieldTypeStruct,DFS_DATA,DfsLpcInfo),
0
};
/*
* DFS_PKT
*
*/
FIELD_DESCRIPTOR DfsPktFields[] = {
FIELD3(FieldTypeUShort,DFS_PKT,NodeTypeCode),
FIELD3(FieldTypeUShort,DFS_PKT,NodeByteSize),
FIELD3(FieldTypeStruct,DFS_PKT,Resource),
FIELD3(FieldTypeStruct,DFS_PKT,UseCountLock),
FIELD3(FieldTypeULong,DFS_PKT,EntryCount),
FIELD3(FieldTypeStruct,DFS_PKT,EntryList),
FIELD3(FieldTypePointer,DFS_PKT,DomainPktEntry),
FIELD3(FieldTypeStruct,DFS_PKT,LocalVolTable),
FIELD3(FieldTypeStruct,DFS_PKT,PrefixTable),
FIELD3(FieldTypeStruct,DFS_PKT,ShortPrefixTable),
FIELD3(FieldTypeStruct,DFS_PKT,DSMachineTable),
0
};
/*
* DFS_PKT_ENTRY
*
*/
BIT_MASK_DESCRIPTOR PktEntryType[] = {
{PKT_ENTRY_TYPE_CAIRO, "Cairo Volume"},
{PKT_ENTRY_TYPE_MACHINE, "Machine Volume"},
{PKT_ENTRY_TYPE_NONCAIRO, "Non-Cairo Volume"},
{PKT_ENTRY_TYPE_OUTSIDE_MY_DOM, "Inter-Domain Volume"},
{PKT_ENTRY_TYPE_REFERRAL_SVC, "Referral Service (DC)"},
{PKT_ENTRY_TYPE_PERMANENT, "Permanent Entry"},
{PKT_ENTRY_TYPE_LOCAL,"Local Volume"},
{PKT_ENTRY_TYPE_LOCAL_XPOINT,"Local Exit Point"},
{PKT_ENTRY_TYPE_MACH_SHARE,"Local Machine Share"},
{PKT_ENTRY_TYPE_OFFLINE,"Offline Volume"},
0
};
FIELD_DESCRIPTOR DfsPktEntryFields[] = {
FIELD3(FieldTypeUShort,DFS_PKT_ENTRY,NodeTypeCode),
FIELD3(FieldTypeUShort,DFS_PKT_ENTRY,NodeByteSize),
FIELD4(FieldTypeDWordBitMask,DFS_PKT_ENTRY,Type,PktEntryType),
FIELD3(FieldTypeULong,DFS_PKT_ENTRY,USN),
FIELD3(FieldTypeUnicodeString,DFS_PKT_ENTRY,Id.Prefix),
FIELD3(FieldTypeUnicodeString,DFS_PKT_ENTRY,Id.ShortPrefix),
FIELD3(FieldTypeULong,DFS_PKT_ENTRY,Info.Timeout),
FIELD3(FieldTypeULong,DFS_PKT_ENTRY,Info.ServiceCount),
FIELD3(FieldTypePointer,DFS_PKT_ENTRY,Info.ServiceList),
FIELD3(FieldTypeULong,DFS_PKT_ENTRY,UseCount),
FIELD3(FieldTypeULong,DFS_PKT_ENTRY,FileOpenCount),
FIELD3(FieldTypePointer,DFS_PKT_ENTRY,ActiveService),
FIELD3(FieldTypePointer,DFS_PKT_ENTRY,LocalService),
FIELD3(FieldTypePointer,DFS_PKT_ENTRY,Superior),
FIELD3(FieldTypeULong,DFS_PKT_ENTRY,SubordinateCount),
FIELD3(FieldTypeStruct,DFS_PKT_ENTRY,SubordinateList),
FIELD3(FieldTypeStruct,DFS_PKT_ENTRY,SiblingLink),
FIELD3(FieldTypePointer,DFS_PKT_ENTRY,ClosestDC),
FIELD3(FieldTypeStruct,DFS_PKT_ENTRY,ChildList),
FIELD3(FieldTypeStruct,DFS_PKT_ENTRY,NextLink),
FIELD3(FieldTypeStruct,DFS_PKT_ENTRY,PrefixTableEntry),
0
};
/*
* DFS_SERVICE
*
*/
BIT_MASK_DESCRIPTOR ServiceType[] = {
{DFS_SERVICE_TYPE_MASTER, "Master Svc"},
{DFS_SERVICE_TYPE_READONLY, "Read-Only Svc"},
{DFS_SERVICE_TYPE_LOCAL, "Local Svc"},
{DFS_SERVICE_TYPE_REFERRAL, "Referral Svc"},
{DFS_SERVICE_TYPE_ACTIVE, "Active Svc"},
{DFS_SERVICE_TYPE_DOWN_LEVEL, "Down-level Svc"},
{DFS_SERVICE_TYPE_COSTLIER, "Costlier than previous"},
{DFS_SERVICE_TYPE_OFFLINE, "Svc Offline"},
0
};
BIT_MASK_DESCRIPTOR ServiceCapability[] = {
{PROV_DFS_RDR, "Use Dfs Rdr"},
{PROV_STRIP_PREFIX, "Strip Prefix (downlevel or local) Svc"},
0
};
FIELD_DESCRIPTOR DfsServiceFields[] = {
FIELD4(FieldTypeDWordBitMask,DFS_SERVICE,Type,ServiceType),
FIELD4(FieldTypeDWordBitMask,DFS_SERVICE,Capability,ServiceCapability),
FIELD3(FieldTypeULong,DFS_SERVICE,Status),
FIELD3(FieldTypeULong,DFS_SERVICE,ProviderId),
FIELD3(FieldTypeULong,DFS_SERVICE,Cost),
FIELD3(FieldTypePointer,DFS_SERVICE,ConnFile),
FIELD3(FieldTypePointer,DFS_SERVICE,pProvider),
FIELD3(FieldTypePointer,DFS_SERVICE,pMachEntry),
FIELD3(FieldTypeUnicodeString,DFS_SERVICE,Name),
FIELD3(FieldTypeUnicodeString,DFS_SERVICE,Address),
FIELD3(FieldTypeUnicodeString,DFS_SERVICE,StgId),
0
};
/*
* DFS_MACHINE_ENTRY
*
*/
FIELD_DESCRIPTOR DfsMachineEntryFields[] = {
FIELD3(FieldTypePointer,DFS_MACHINE_ENTRY,pMachine),
FIELD3(FieldTypeUnicodeString,DFS_MACHINE_ENTRY,MachineName),
FIELD3(FieldTypeULong,DFS_MACHINE_ENTRY,UseCount),
FIELD3(FieldTypeULong,DFS_MACHINE_ENTRY,ConnectionCount),
0
};
/*
* DS_MACHINE
*
*/
FIELD_DESCRIPTOR DsMachineFields[] = {
FIELD3(FieldTypeGuid,DS_MACHINE,guidSite),
FIELD3(FieldTypeGuid,DS_MACHINE,guidMachine),
FIELD3(FieldTypeULong,DS_MACHINE,grfFlags),
FIELD3(FieldTypePWStr,DS_MACHINE,pwszShareName),
FIELD3(FieldTypeULong,DS_MACHINE,cPrincipals),
FIELD3(FieldTypePointer,DS_MACHINE,prgpwszPrincipals),
FIELD3(FieldTypeULong,DS_MACHINE,cTransports),
FIELD3(FieldTypeStruct,DS_MACHINE,rpTrans),
0
};
/*
* DFS_LPC_INFO
*
*/
FIELD_DESCRIPTOR LpcInfoFields[] = {
FIELD3(FieldTypeUnicodeString,DFS_LPC_INFO,LpcPortName),
FIELD4(FieldTypeEnum,DFS_LPC_INFO,LpcPortState,LpcPortStateEnum),
FIELD3(FieldTypePointer,DFS_LPC_INFO,LpcPortHandle),
0
};
/*
* PROVIDER_DEF
*
*/
FIELD_DESCRIPTOR ProviderDefFields[] = {
FIELD3(FieldTypeUShort,PROVIDER_DEF,NodeTypeCode),
FIELD3(FieldTypeUShort,PROVIDER_DEF,NodeByteSize),
FIELD3(FieldTypeUShort,PROVIDER_DEF,eProviderId),
FIELD4(FieldTypeDWordBitMask,PROVIDER_DEF,fProvCapability,ServiceCapability),
FIELD3(FieldTypeUnicodeString,PROVIDER_DEF,DeviceName),
FIELD3(FieldTypePointer,PROVIDER_DEF,DeviceObject),
FIELD3(FieldTypePointer,PROVIDER_DEF,FileObject),
0
};
/*
* DFS_VOLUME_OBJECT
*
*/
FIELD_DESCRIPTOR DfsVolumeObjectFields[] = {
FIELD3(FieldTypeStruct,DFS_VOLUME_OBJECT,DeviceObject),
FIELD3(FieldTypeULong,DFS_VOLUME_OBJECT,AttachCount),
FIELD3(FieldTypeStruct,DFS_VOLUME_OBJECT,VdoLinks),
FIELD3(FieldTypeStruct,DFS_VOLUME_OBJECT,Provider),
FIELD3(FieldTypeUnicodeString,DFS_VOLUME_OBJECT,Provider.DeviceName),
FIELD3(FieldTypePointer,DFS_VOLUME_OBJECT,Provider.DeviceObject),
FIELD3(FieldTypePointer,DFS_VOLUME_OBJECT,Provider.FileObject),
0
};
/*
* DFS_PREFIX_TABLE
*
*/
FIELD_DESCRIPTOR DfsPrefixTableFields[] = {
FIELD3(FieldTypeBoolean,DFS_PREFIX_TABLE,CaseSensitive),
FIELD3(FieldTypePointer,DFS_PREFIX_TABLE,NamePageList.pFirstPage),
FIELD3(FieldTypePointer,DFS_PREFIX_TABLE,NextEntry),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,RootEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[0].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[0].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[1].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[1].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[2].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[2].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[3].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[3].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[4].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[4].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[5].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[5].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[6].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[6].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[7].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[7].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[8].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[8].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[9].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[9].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[10].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[10].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[11].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[11].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[12].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[12].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[13].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[13].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[14].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[14].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[15].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[15].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[16].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[16].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[17].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[17].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[18].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[18].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[19].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[19].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[20].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[20].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[21].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[21].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[22].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[22].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[23].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[23].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[24].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[24].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[25].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[25].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[26].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[26].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[27].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[27].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[28].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[28].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[29].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[29].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[30].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[30].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[31].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[31].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[32].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[32].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[33].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[33].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[34].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[34].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[35].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[35].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[36].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[36].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[37].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[37].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[38].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[38].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[39].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[39].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[40].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[40].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[41].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[41].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[42].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[42].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[43].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[43].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[44].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[44].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[45].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[45].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[46].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[46].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[47].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[47].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[48].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[48].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[49].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[49].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[50].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[50].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[51].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[51].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[52].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[52].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[53].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[53].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[54].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[54].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[55].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[55].SentinelEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[56].NoOfEntries),
FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[56].SentinelEntry),
0
};
/*
* DFS_PREFIX_TABLE_ENTRY
*
*/
FIELD_DESCRIPTOR DfsPrefixTableEntryFields[] = {
FIELD3(FieldTypePointer,DFS_PREFIX_TABLE_ENTRY,pParentEntry),
FIELD3(FieldTypePointer,DFS_PREFIX_TABLE_ENTRY,pNextEntry),
FIELD3(FieldTypePointer,DFS_PREFIX_TABLE_ENTRY,pPrevEntry),
FIELD3(FieldTypePointer,DFS_PREFIX_TABLE_ENTRY,pFirstChildEntry),
FIELD3(FieldTypePointer,DFS_PREFIX_TABLE_ENTRY,pSiblingEntry),
FIELD3(FieldTypeULong,DFS_PREFIX_TABLE_ENTRY,NoOfChildren),
FIELD3(FieldTypeUnicodeString,DFS_PREFIX_TABLE_ENTRY,PathSegment),
FIELD3(FieldTypePointer,DFS_PREFIX_TABLE_ENTRY,pData),
0
};
FIELD_DESCRIPTOR DfsLocalVolEntryFields[] = {
FIELD3(FieldTypeStruct,DFS_LOCAL_VOL_ENTRY,PktEntry),
FIELD3(FieldTypeUnicodeString,DFS_LOCAL_VOL_ENTRY,LocalPath),
FIELD3(FieldTypeUnicodeString,DFS_LOCAL_VOL_ENTRY,ShareName),
FIELD3(FieldTypeStruct,DFS_LOCAL_VOL_ENTRY,PrefixTableEntry),
0
};
/*
* DFS_FCB
*
*/
FIELD_DESCRIPTOR FcbFields[] = {
FIELD3(FieldTypeUShort, DFS_FCB, NodeTypeCode),
FIELD3(FieldTypeUShort, DFS_FCB, NodeByteSize),
FIELD3(FieldTypeUnicodeString, DFS_FCB, FullFileName),
FIELD3(FieldTypePointer, DFS_FCB, FileObject),
0
};
STRUCT_DESCRIPTOR Structs[] = {
STRUCT(DFS_DATA,DfsDataFields),
STRUCT(DFS_PKT,DfsPktFields),
STRUCT(DFS_PKT_ENTRY,DfsPktEntryFields),
STRUCT(DFS_SERVICE,DfsServiceFields),
STRUCT(DFS_MACHINE_ENTRY,DfsMachineEntryFields),
STRUCT(DS_MACHINE,DsMachineFields),
STRUCT(PROVIDER_DEF,ProviderDefFields),
STRUCT(DFS_VOLUME_OBJECT,DfsVolumeObjectFields),
STRUCT(DFS_PREFIX_TABLE,DfsPrefixTableFields),
STRUCT(DFS_PREFIX_TABLE_ENTRY,DfsPrefixTableEntryFields),
STRUCT(DFS_LOCAL_VOL_ENTRY,DfsLocalVolEntryFields),
STRUCT(DFS_LPC_INFO,LpcInfoFields),
STRUCT(DFS_FCB,FcbFields),
0
};
/*
* Dfs specific dump routines
*
*/
VOID
dumplist(
ULONG_PTR dwListEntryAddress,
DWORD linkOffset,
VOID (*dumpRoutine)(ULONG_PTR dwStructAddress)
);
VOID
dumpPktEntry(
ULONG_PTR dwAddress
);
VOID
PktEntryDump(
ULONG_PTR dwAddress
);
VOID
dumpFcb(
ULONG_PTR dwAddress
);
VOID
dumpVcb(
ULONG_PTR dwAddress
);
VOID
dumpVdo(
ULONG_PTR dwAddress
);
VOID
dumpSiteInfo(
ULONG_PTR dwAddress
);
VOID
dumpSpcInfo(
ULONG_PTR dwAddress
);
VOID
dumpIpInfo(
ULONG_PTR dwAddress
);
VOID
DumpDfsPrefixTableEntry(
ULONG_PTR dwAddress,
VOID (*DispFunc)(ULONG_PTR dwAddress)
);
VOID
DumpUnicodePrefixTable(
ULONG_PTR dwAddress
);
VOID
DumpUnicodePrefixTableEntry(
ULONG_PTR dwAddress
);
VOID
DoIndent(
VOID
);
VOID
MyDumpPktEntry(
ULONG_PTR dwAddress
);
VOID
MyDumpLocalVolEntry(
ULONG_PTR dwAddress
);
VOID
MyDumpServices(
ULONG_PTR dwAddress,
ULONG ServiceCount
);
/*
* globals
*/
INT Indent = 0;
/*
* dfsdata : Routine to dump the global dfs data structure
*
*/
BOOL
dfsdata(
ULONG_PTR dwCurrentPC,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString
)
{
ULONG_PTR dwAddress;
dwAddress = (GetExpression)("dfs!DfsData");
if (dwAddress) {
DFS_DATA DfsData;
if (wGetData( dwAddress, &DfsData, sizeof(DfsData) )) {
PrintStructFields( dwAddress, &DfsData, DfsDataFields);
} else {
PRINTF( "Unable to read DfsData @ %08lx\n", dwAddress );
}
} else {
PRINTF( NO_SYMBOLS_MESSAGE );
}
return( TRUE );
}
/*
* pkt : Routine to dump the Dfs PKT data structure
*
*/
BOOL
pkt(
ULONG_PTR dwCurrentPC,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString
)
{
ULONG_PTR dwAddress;
//
// Figure out the address of the Pkt. This is an offset within
// dfs!DfsData.
//
dwAddress = (GetExpression)("dfs!DfsData");
if (dwAddress) {
DFS_PKT pkt;
dwAddress += FIELD_OFFSET(DFS_DATA, Pkt);
if (wGetData(dwAddress,&pkt,sizeof(pkt))) {
PrintStructFields( dwAddress, &pkt, DfsPktFields );
dwAddress += FIELD_OFFSET(DFS_PKT, EntryList);
dumplist(
dwAddress,
FIELD_OFFSET(DFS_PKT_ENTRY,Link),
dumpPktEntry);
}
} else {
PRINTF( NO_SYMBOLS_MESSAGE );
}
return( TRUE );
}
/*
* dumpPktEntry : Routine suitable as argument for dumplist; used to dump
* list of pkt entries.
*
*/
VOID
dumpPktEntry(
ULONG_PTR dwAddress
)
{
DFS_PKT_ENTRY pktEntry;
if (wGetData(dwAddress, &pktEntry, sizeof(DFS_PKT_ENTRY))) {
PRINTF( "\n--- Pkt Entry @ %08lx\n", dwAddress);
wPrintStringW("Prefix : ", &pktEntry.Id.Prefix, TRUE);
wPrintStringW("ShortPrefix : ", &pktEntry.Id.ShortPrefix, TRUE);
//
// Print the local service, if any
//
if (pktEntry.LocalService != NULL) {
DFS_SERVICE Svc;
PRINTF( " Local Svc @%08lx : ",pktEntry.LocalService);
if (wGetData( (ULONG_PTR)pktEntry.LocalService, &Svc, sizeof(Svc))) {
wPrintStringW("Storage Id = ", &Svc.Address, TRUE);
} else {
PRINTF( "Storage Id = ?\n");
}
}
//
// Now, print the service list
//
if (pktEntry.Info.ServiceCount != 0) {
ULONG i;
for (i = 0; i < pktEntry.Info.ServiceCount; i++) {
DFS_SERVICE Svc;
ULONG_PTR dwServiceAddress;
if (CheckControlC())
return;
dwServiceAddress =
((ULONG_PTR)pktEntry.Info.ServiceList) +
i * sizeof(DFS_SERVICE);
PRINTF( " Service %d @%08lx : ",i, dwServiceAddress);
if (wGetData(dwServiceAddress, &Svc, sizeof(Svc))) {
wPrintStringW( "Address =", &Svc.Address, TRUE );
} else {
PRINTF( "Address = ?\n");
}
}
}
} else {
PRINTF( "Unable to get Pkt Entry @%08lx\n", dwAddress);
}
}
VOID
PktEntryDump(ULONG_PTR dwAddress)
{
DFS_PKT_ENTRY pktEntry;
if (wGetData(dwAddress, &pktEntry, sizeof(DFS_PKT_ENTRY))) {
PRINTF( "\n--- Pkt Entry @ %08lx\n", dwAddress);
wPrintStringW("Prefix : ", &pktEntry.Id.Prefix, TRUE);
wPrintStringW("ShortPrefix : ", &pktEntry.Id.ShortPrefix, TRUE);
//
// Print the local service, if any
//
if (pktEntry.LocalService != NULL) {
DFS_SERVICE Svc;
PRINTF( " Local Svc @%08lx : ",pktEntry.LocalService);
if (wGetData( (ULONG_PTR)pktEntry.LocalService, &Svc, sizeof(Svc))) {
wPrintStringW("Storage Id = ", &Svc.Address, TRUE);
} else {
PRINTF( "Storage Id = ?\n");
}
}
} else {
PRINTF( "Unable to get Pkt Entry @%08lx\n", dwAddress);
}
}
/*
* fcbtable : Routine to dump the dfs fcb hash table
*
*/
BOOL
fcbtable(
DWORD dwCurrentPC,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString
)
{
DWORD_PTR dwAddress;
//
// Figure out the address of the Pkt. This is an offset withing
// Dfs!DfsData.
//
dwAddress = (GetExpression)("Dfs!DfsData");
if (dwAddress) {
DFS_DATA DfsData;
if (wGetData(dwAddress, &DfsData, sizeof(DFS_DATA))) {
FCB_HASH_TABLE FcbTable;
dwAddress = (DWORD_PTR) DfsData.FcbHashTable;
if (wGetData(dwAddress, &FcbTable, sizeof(FCB_HASH_TABLE))) {
ULONG i, cBuckets;
DWORD_PTR dwListHeadAddress;
cBuckets = FcbTable.HashMask + 1;
dwListHeadAddress =
dwAddress + FIELD_OFFSET(FCB_HASH_TABLE, HashBuckets);
PRINTF(
"+++ Fcb Hash Table @ %p (%d Buckets) +++\n",
dwAddress, cBuckets);
for (i = 0; i < cBuckets; i++) {
if (CheckControlC())
return TRUE;
PRINTF( "--- Bucket(%d)\n", i );
dumplist(
dwListHeadAddress,
FIELD_OFFSET(DFS_FCB, HashChain),
dumpFcb);
dwListHeadAddress += sizeof(LIST_ENTRY);
}
PRINTF("--- Fcb Hash Table @ %08lx ---\n", dwAddress);
} else {
PRINTF( "Unable to read FcbTable @%08lx\n", dwAddress );
}
} else {
PRINTF( "Unable to read DfsData @%08lx\n", dwAddress);
}
} else {
PRINTF( NO_SYMBOLS_MESSAGE );
}
return( TRUE );
}
/*
* dumpFcb : Routine suitable as argument to dumplist; used to dump list of
* Fcbs
*
*/
VOID
dumpFcb(
DWORD_PTR dwAddress
)
{
DFS_FCB fcb;
if (wGetData( dwAddress, &fcb, sizeof(fcb))) {
PRINTF("\nFcb @ %08lx\n", dwAddress);
PrintStructFields( dwAddress, &fcb, FcbFields );
} else {
PRINTF("\nUnable to read Fcb @ %08lx\n", dwAddress);
}
}
/*
* vdolist : Routine to dump out all the Dfs Volume Device Objects (ie, the
* attached device objects)
*
*/
BOOL
vdolist(
ULONG_PTR dwCurrentPC,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString
)
{
ULONG_PTR dwAddress;
//
// Figure out the address of the Pkt. This is an offset within
// dfs!DfsData.
//
dwAddress = (GetExpression)("dfs!DfsData");
if (dwAddress) {
dwAddress += FIELD_OFFSET(DFS_DATA, AVdoQueue);
dumplist(
dwAddress,
FIELD_OFFSET(DFS_VOLUME_OBJECT,VdoLinks),
dumpVdo);
} else {
PRINTF( NO_SYMBOLS_MESSAGE );
}
return(TRUE);
}
BOOL
dumpspecialtable(
ULONG_PTR dwAddress)
{
ULONG i;
SPECIAL_HASH_TABLE HashTable;
if (wGetData(dwAddress,&HashTable,sizeof(SPECIAL_HASH_TABLE))) {
ULONG nBuckets = HashTable.HashMask+1;
PRINTF( "NodeByteCode: 0x%x\n", HashTable.NodeTypeCode);
PRINTF( "NodeByteSize: 0x%x\n", HashTable.NodeByteSize);
PRINTF( "Timeout: 0x%x\n", HashTable.SpcTimeout);
PRINTF( "HashMask: 0x%x\n", HashTable.HashMask);
if (HashTable.NodeTypeCode != DFS_NTC_SPECIAL_HASH) {
PRINTF( "NodeTypeCode != DFS_NTC_SPECIAL_HASH\n");
}
if ((HashTable.HashMask & (HashTable.HashMask+1)) != 0) {
PRINTF( "HashMask not a power of 2!\n");
return (TRUE);
}
dwAddress += FIELD_OFFSET(SPECIAL_HASH_TABLE, HashBuckets[0]);
for (i = 0; i < nBuckets; i++) {
LIST_ENTRY ListEntry;
if (wGetData(dwAddress,&ListEntry,sizeof(LIST_ENTRY))) {
if (ListEntry.Flink) {
dumplist(
dwAddress,
FIELD_OFFSET(DFS_SPECIAL_INFO,HashChain),
dumpSpcInfo);
}
} else {
PRINTF("Couldn't get Bucket[%d]\n", i);
return (TRUE);
}
dwAddress += sizeof(LIST_ENTRY);
}
}
return TRUE;
}
/*
* specialtable : Routine to dump out the special table
*
*/
BOOL
specialtable(
ULONG_PTR dwCurrentPC,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
ULONG i;
ULONG_PTR dwAddress;
//
// Figure out the address of the Pkt. This is an offset within
// dfs!DfsData.
//
dwAddress = (GetExpression)("dfs!DfsData");
if (dwAddress) {
dwAddress += FIELD_OFFSET(DFS_DATA, SpcHashTable);
if (!wGetData(dwAddress,&dwAddress,sizeof(dwAddress))) {
PRINTF("Couldn't get address of SpcHashTable\n");
return (TRUE);
}
PRINTF("SpcHashTable@0x%x\n", dwAddress);
return dumpspecialtable(dwAddress);
} else {
PRINTF( NO_SYMBOLS_MESSAGE );
}
return(TRUE);
}
/*
* specialtable : Routine to dump out the special table
*
*/
BOOL
ftdfstable(
ULONG_PTR dwCurrentPC,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
ULONG i;
ULONG_PTR dwAddress;
//
// Figure out the address of the Pkt. This is an offset within
// dfs!DfsData.
//
dwAddress = (GetExpression)("dfs!DfsData");
if (dwAddress) {
dwAddress += FIELD_OFFSET(DFS_DATA, FtDfsHashTable);
if (!wGetData(dwAddress,&dwAddress,sizeof(dwAddress))) {
PRINTF("Couldn't get address of FtDfsHashTable\n");
return (TRUE);
}
PRINTF("FtDfsHashTable@0x%x\n", dwAddress);
return dumpspecialtable(dwAddress);
} else {
PRINTF( NO_SYMBOLS_MESSAGE );
}
return(TRUE);
}
/*
* sitetable : Routine to dump out the site table
*
*/
BOOL
sitetable(
ULONG_PTR dwCurrentPC,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
ULONG i;
ULONG_PTR dwAddress;
//
// Figure out the address of the Pkt. This is an offset within
// dfs!DfsData.
//
dwAddress = (GetExpression)("dfs!DfsData");
if (dwAddress) {
SITE_HASH_TABLE HashTable;
dwAddress += FIELD_OFFSET(DFS_DATA, SiteHashTable);
if (!wGetData(dwAddress,&dwAddress,sizeof(dwAddress))) {
PRINTF("Couldn't get address of SiteHashTable\n");
return (TRUE);
}
PRINTF("SiteHashTable@0x%x\n", dwAddress);
if (wGetData(dwAddress,&HashTable,sizeof(SITE_HASH_TABLE))) {
ULONG nBuckets = HashTable.HashMask+1;
PRINTF( "NodeByteCode: 0x%x\n", HashTable.NodeTypeCode);
PRINTF( "NodeByteSize: 0x%x\n", HashTable.NodeByteSize);
PRINTF( "HashMask: 0x%x\n", HashTable.HashMask);
if (HashTable.NodeTypeCode != DFS_NTC_SITE_HASH) {
PRINTF( "NodeTypeCode != DFS_NTC_SITE_HASH\n");
}
if ((HashTable.HashMask & (HashTable.HashMask+1)) != 0) {
PRINTF( "HashMask not a power of 2!\n");
return (TRUE);
}
dwAddress += FIELD_OFFSET(SITE_HASH_TABLE, HashBuckets[0]);
for (i = 0; i < nBuckets; i++) {
LIST_ENTRY ListEntry;
if (CheckControlC())
return TRUE;
if (wGetData(dwAddress,&ListEntry,sizeof(LIST_ENTRY))) {
if (ListEntry.Flink) {
dumplist(
dwAddress,
FIELD_OFFSET(DFS_SITE_INFO,HashChain),
dumpSiteInfo);
}
} else {
PRINTF("Couldn't get Bucket[%d]\n", i);
return (TRUE);
}
dwAddress += sizeof(LIST_ENTRY);
}
}
} else {
PRINTF( NO_SYMBOLS_MESSAGE );
}
return(TRUE);
}
/*
* iptable : Routine to dump out the ip table
*
*/
BOOL
iptable(
ULONG_PTR dwCurrentPC,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
ULONG i;
ULONG_PTR dwAddress;
//
// Figure out the address of the Pkt. This is an offset within
// dfs!DfsData.
//
dwAddress = (GetExpression)("dfs!DfsData");
if (dwAddress) {
IP_HASH_TABLE HashTable;
dwAddress += FIELD_OFFSET(DFS_DATA, IpHashTable);
if (!wGetData(dwAddress,&dwAddress,sizeof(dwAddress))) {
PRINTF("Couldn't get address of IpHashTable\n");
return (TRUE);
}
PRINTF("IpHashTable@0x%x\n", dwAddress);
if (wGetData(dwAddress,&HashTable,sizeof(IP_HASH_TABLE))) {
ULONG nBuckets = HashTable.HashMask+1;
PRINTF( "NodeByteCode: 0x%x\n", HashTable.NodeTypeCode);
PRINTF( "NodeByteSize: 0x%x\n", HashTable.NodeByteSize);
PRINTF( "MaxEntries: 0x%x\n", HashTable.MaxEntries);
PRINTF( "EntryCount: 0x%x\n", HashTable.EntryCount);
PRINTF( "HashMask: 0x%x\n", HashTable.HashMask);
if (HashTable.NodeTypeCode != DFS_NTC_IP_HASH) {
PRINTF( "NodeTypeCode != DFS_NTC_IP_HASH\n");
}
if ((HashTable.HashMask & (HashTable.HashMask+1)) != 0) {
PRINTF( "HashMask not a power of 2!\n");
return (TRUE);
}
dwAddress += FIELD_OFFSET(IP_HASH_TABLE, HashBuckets[0]);
for (i = 0; i < nBuckets; i++) {
LIST_ENTRY ListEntry;
if (CheckControlC())
return TRUE;
if (wGetData(dwAddress,&ListEntry,sizeof(LIST_ENTRY))) {
if (ListEntry.Flink) {
dumplist(
dwAddress,
FIELD_OFFSET(DFS_IP_INFO,HashChain),
dumpIpInfo);
}
} else {
PRINTF("Couldn't get Bucket[%d]\n", i);
return (TRUE);
}
dwAddress += sizeof(LIST_ENTRY);
}
}
} else {
PRINTF( NO_SYMBOLS_MESSAGE );
}
return(TRUE);
}
/*
* Dumpdfs : recursively dumps a DFS_PREFIX_TABLE
*
*/
BOOL
dumpdfs(
ULONG_PTR dwCurrentPC,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString
)
{
PDFS_DATA pDfsData;
PDFS_PKT pPkt;
ULONG_PTR dwAddress;
ULONG_PTR dwPrefixTable;
if( lpArgumentString && *lpArgumentString ) {
BYTE DataBuffer[sizeof(DFS_DATA)];
pDfsData = (PDFS_DATA) DataBuffer;
dwAddress = (GetExpression)( lpArgumentString );
if (wGetData(dwAddress,pDfsData,sizeof(DFS_DATA))) {
if (pDfsData->NodeTypeCode != DSFS_NTC_DATA_HEADER) {
PRINTF( "Bad NodeTypeCode - not a DfsData struct\n");
return (FALSE);
}
PRINTF( "--DFSDATA@0x%x--\n", dwAddress);
PRINTF( "DfsData->NodeTypeCode: 0x%x\n", pDfsData->NodeTypeCode);
PRINTF( "DfsData->Pkt@0x%x\n", FIELD_OFFSET(DFS_DATA, Pkt) + dwAddress);
PRINTF( "DfsData->Pkt.NodeTypeCode: 0x%x\n", pDfsData->Pkt.NodeTypeCode);
// LocalVolTable
dwPrefixTable = dwAddress + FIELD_OFFSET(DFS_DATA, Pkt.LocalVolTable.RootEntry);
DumpDfsPrefixTableEntry(dwPrefixTable, MyDumpLocalVolEntry);
// PrefixTable
dwPrefixTable = dwAddress + FIELD_OFFSET(DFS_DATA, Pkt.PrefixTable.RootEntry);
DumpDfsPrefixTableEntry(dwPrefixTable, MyDumpPktEntry);
// PrefixTable
dwPrefixTable = dwAddress + FIELD_OFFSET(DFS_DATA, Pkt.ShortPrefixTable.RootEntry);
DumpDfsPrefixTableEntry(dwPrefixTable, MyDumpPktEntry);
} else {
PRINTF( "Error reading Memory @ %lx\n",dwAddress);
}
} else {
//
// The command is of the form
// dumpdfs addr
//
// The user didn't give us an address.
//
PRINTF(
"!dfskd.dumpDfsPrefixTable address\n"
);
}
return TRUE;
}
/*
* DumpUnicodePrefixTable : Dump a UNICODE_PREFIX_TABLE
*
*/
VOID
DumpUnicodePrefixTable(ULONG_PTR dwAddress)
{
PUNICODE_PREFIX_TABLE pUnicodePrefixTable;
BYTE DataBuffer[sizeof(UNICODE_PREFIX_TABLE)];
pUnicodePrefixTable = (PUNICODE_PREFIX_TABLE) DataBuffer;
if (wGetData(dwAddress,pUnicodePrefixTable,sizeof(UNICODE_PREFIX_TABLE))) {
IPRINTF(0, "UNICODE_PREFIX_TABLE @ 0x%lx:\n", dwAddress);
IPRINTF(0, "NodeTypeCode : 0x%x\n", pUnicodePrefixTable->NodeTypeCode);
IPRINTF(0, "NextPrefixTree : 0x%lx\n", pUnicodePrefixTable->NextPrefixTree);
IPRINTF(0, "LastNextEntry : 0x%lx\n", pUnicodePrefixTable->LastNextEntry);
DumpUnicodePrefixTableEntry((ULONG_PTR)pUnicodePrefixTable->NextPrefixTree);
} else {
PRINTF( "Error reading Memory @ %lx\n",dwAddress);
}
}
/*
* DumpUnicodePrefixTableEntry : UNICODE_PREFIX_TABLE_ENTRY
*
*/
VOID
DumpUnicodePrefixTableEntry(ULONG_PTR dwAddress)
{
PUNICODE_PREFIX_TABLE_ENTRY pUnicodePrefixTableEntry;
BYTE DataBuffer[sizeof(UNICODE_PREFIX_TABLE_ENTRY)];
pUnicodePrefixTableEntry = (PUNICODE_PREFIX_TABLE_ENTRY) DataBuffer;
if (wGetData(dwAddress,pUnicodePrefixTableEntry,sizeof(UNICODE_PREFIX_TABLE_ENTRY))) {
// Get and print PathSegment
if (pUnicodePrefixTableEntry->Prefix->Buffer) {
IPRINTF( "UNICODE_PREFIX_TABLE_ENTRY @ 0x%lx:\n", dwAddress);
IPRINTF( "NodeTypeCode : 0x%x\n", pUnicodePrefixTableEntry->NodeTypeCode);
IPRINTSTRINGW("", pUnicodePrefixTableEntry->Prefix, TRUE);
}
} else {
PRINTF( "Error reading Memory @ %lx\n",dwAddress);
}
}
/*
* DumpDfsPrefixTableEntry : Recursively dump a DFS_PREFIX_TABLE
*
* Prints the DFS_PREFIX_TABLE_ENTRY, then calls itself to print any siblings,
* then calls itself to print children.
*
*/
VOID
DumpDfsPrefixTableEntry(ULONG_PTR dwAddress, VOID (*DumpFunc)(ULONG_PTR dwAddress))
{
PDFS_PREFIX_TABLE_ENTRY pDfsPrefixTableEntry;
BYTE DataBuffer[sizeof(DFS_PREFIX_TABLE_ENTRY)];
BOOLEAN Verbose = 0;
if (CheckControlC())
return;
pDfsPrefixTableEntry = (PDFS_PREFIX_TABLE_ENTRY) DataBuffer;
if (wGetData(dwAddress,pDfsPrefixTableEntry,sizeof(DFS_PREFIX_TABLE_ENTRY))) {
IPRINTF( "------DFS_PREFIX_TABLE_ENTRY@0x%x-----------\n", dwAddress);
IPRINTF( "pParentEntry: 0x%lx\n", pDfsPrefixTableEntry->pParentEntry);
IPRINTF( "pNextEntry: 0x%lx\n", pDfsPrefixTableEntry->pNextEntry);
IPRINTF( "pPrevEntry: 0x%lx\n", pDfsPrefixTableEntry->pPrevEntry);
IPRINTF( "pFirstChildEntry: 0x%lx\n", pDfsPrefixTableEntry->pFirstChildEntry);
IPRINTF( "pSiblingEntry: 0x%lx\n", pDfsPrefixTableEntry->pSiblingEntry);
IPRINTF( "NoOfChildren: 0x%lx\n", pDfsPrefixTableEntry->NoOfChildren);
IPRINTF( "PathSegment: %lx\n", pDfsPrefixTableEntry->PathSegment.Buffer);
IPRINTF( "pData: 0x%lx\n", pDfsPrefixTableEntry->pData);
// Get and print PathSegment
if (pDfsPrefixTableEntry->PathSegment.Buffer) {
IPRINTSTRINGW("", &pDfsPrefixTableEntry->PathSegment, FALSE);
IPRINTF( " --> 0x%x\n", pDfsPrefixTableEntry->pData);
if (pDfsPrefixTableEntry->pData) {
ULONG_PTR dwDfsPktEntry;
dwDfsPktEntry = (ULONG_PTR) pDfsPrefixTableEntry->pData;
Indent++;
DumpFunc(dwDfsPktEntry);
Indent--;
}
}
IPRINTF( "--------------------------------------------\n", dwAddress);
// recursively dump Siblings
if (pDfsPrefixTableEntry->pSiblingEntry)
DumpDfsPrefixTableEntry(
(ULONG_PTR)pDfsPrefixTableEntry->pSiblingEntry,
DumpFunc);
// then children
Indent++;
if (pDfsPrefixTableEntry->pFirstChildEntry)
DumpDfsPrefixTableEntry(
(ULONG_PTR)pDfsPrefixTableEntry->pFirstChildEntry,
DumpFunc);
Indent--;
} else {
PRINTF( "Error reading Memory @ %lx\n",dwAddress);
}
}
VOID
MyDumpPktEntry(ULONG_PTR dwAddress)
{
PDFS_PKT_ENTRY pDfsPktEntry;
BYTE DataBuffer[sizeof(DFS_PKT_ENTRY)];
// dwAddress points to PrefixTableEntry within the DFS_PKT_ENTRY struct
dwAddress -= FIELD_OFFSET(DFS_PKT_ENTRY, PrefixTableEntry);
pDfsPktEntry = (PDFS_PKT_ENTRY) DataBuffer;
if (wGetData(dwAddress,pDfsPktEntry,sizeof(DFS_PKT_ENTRY))) {
IPRINTF( "---------DFS_PKT_ENTRY@0x%x----\n", dwAddress);
IPRINTF( "NodeTypeCode: 0x%x\n", pDfsPktEntry->NodeTypeCode);
IPRINTF( "Type: 0x%x\n", pDfsPktEntry->Type);
Indent++;
IPRINTF( "----DFS_PKT_ENTRY_ID@0x%x------\n", dwAddress + FIELD_OFFSET(DFS_PKT_ENTRY, Id));
IPRINTSTRINGW("Prefix: ", &pDfsPktEntry->Id.Prefix, TRUE);
IPRINTSTRINGW("ShortPrefix:", &pDfsPktEntry->Id.Prefix, TRUE);
IPRINTF( "-------------------------------\n");
IPRINTF( "---DFS_PKT_ENTRY_INFO@0x%x-----\n", dwAddress + FIELD_OFFSET(DFS_PKT_ENTRY, Info));
IPRINTF( "Timeout\n", pDfsPktEntry->Info.Timeout);
IPRINTF( "ServiceList (%d services)\n", pDfsPktEntry->Info.ServiceCount);
Indent++;
MyDumpServices((ULONG_PTR)pDfsPktEntry->Info.ServiceList, pDfsPktEntry->Info.ServiceCount);
Indent--;
IPRINTF( "-------------------------------\n");
IPRINTF( "ActiveService:\n");
Indent++;
MyDumpServices((ULONG_PTR)pDfsPktEntry->ActiveService, 1);
Indent--;
IPRINTF( "LocalService:\n");
Indent++;
MyDumpServices((ULONG_PTR)pDfsPktEntry->LocalService, 1);
Indent--;
IPRINTF( "-------------------------------\n");
Indent--;
IPRINTF( "-------------------------------\n");
}
}
VOID
MyDumpServices(ULONG_PTR dwAddress, ULONG ServiceCount)
{
PDFS_SERVICE pDfsService;
BYTE DataBuffer[sizeof(DFS_SERVICE) * 32];
ULONG i;
pDfsService = (PDFS_SERVICE) DataBuffer;
if (wGetData(dwAddress,pDfsService,sizeof(DFS_SERVICE) * ServiceCount)) {
for (i = 0; i < ServiceCount; i++) {
if (CheckControlC())
return;
IPRINTF( "----DFS_SERVICE@0x%x---\n", dwAddress);
IPRINTSTRINGW("Service:", &pDfsService[i].Address, TRUE);
IPRINTF( "-----------------------\n");
dwAddress += sizeof(DFS_SERVICE);
}
}
}
VOID
MyDumpLocalVolEntry(ULONG_PTR dwPrefixTableEntry)
{
PDFS_LOCAL_VOL_ENTRY pDfsLocalVolEntry;
BYTE DataBuffer[sizeof(DFS_LOCAL_VOL_ENTRY)];
ULONG_PTR dwAddress;
dwAddress = dwPrefixTableEntry - FIELD_OFFSET(DFS_LOCAL_VOL_ENTRY, PrefixTableEntry);
pDfsLocalVolEntry = (PDFS_LOCAL_VOL_ENTRY) DataBuffer;
if (wGetData(dwAddress,pDfsLocalVolEntry,sizeof(DFS_LOCAL_VOL_ENTRY))) {
IPRINTF( "---------DFS_LOCAL_VOL_ENTRY@0x%x-----\n", dwAddress);
IPRINTSTRINGW("LocalPath:", &pDfsLocalVolEntry->LocalPath, TRUE);
IPRINTSTRINGW("ShareName:", &pDfsLocalVolEntry->ShareName, TRUE);
Indent++;
MyDumpPktEntry(
(ULONG_PTR) pDfsLocalVolEntry->PktEntry +
FIELD_OFFSET(DFS_PKT_ENTRY, PrefixTableEntry)
);
Indent--;
IPRINTF( "--------------------------------------\n", dwAddress);
}
}
/*
* dumpVdo : Routine suitable as argument to dumplist; used to dump list of
* Vdos
*/
void dumpVdo(
ULONG_PTR dwAddress
)
{
DFS_VOLUME_OBJECT dfsVdo;
if (wGetData( dwAddress, &dfsVdo, sizeof(dfsVdo) )) {
PRINTF( "\nVDO @ %08lx\n", dwAddress);
PrintStructFields( dwAddress, &dfsVdo, DfsVolumeObjectFields );
} else {
PRINTF( "\nUnable to read VDO @%08lx\n", dwAddress);
}
}
/*
* dumpSpcInfo : Routine suitable as argument to dumplist; used to dump list of
* DFS_SPECIAL_INFO's
*/
void dumpSpcInfo(
ULONG_PTR dwAddress
)
{
ULONG_PTR dwName;
DFS_SPECIAL_INFO dfsSpcInfo;
LONG i;
UNICODE_STRING uStr;
if (wGetData( dwAddress, &dfsSpcInfo, sizeof(dfsSpcInfo) )) {
PRINTF( " DFS_SPECIAL_INFO @ %08lx\n", dwAddress);
PRINTF( "\tExpireTime: 0x%08x:0x%08x\n",
dfsSpcInfo.ExpireTime.HighPart,
dfsSpcInfo.ExpireTime.LowPart);
PRINTF( "\tFlags: 0x%08x\n", dfsSpcInfo.Flags, TRUE);
PRINTF( "\tTrustDirection: 0x%08x\n", dfsSpcInfo.TrustDirection, TRUE);
PRINTF( "\tTrustType: 0x%08x\n", dfsSpcInfo.TrustType, TRUE);
PRINTF( "\tTypeFlags: 0x%08x\n", dfsSpcInfo.TypeFlags, TRUE);
PRINTF( "\tNameCount: %d\n", dfsSpcInfo.NameCount, TRUE);
wPrintStringW("\tSpecialName:", &dfsSpcInfo.SpecialName, TRUE);
dwName = dwAddress + FIELD_OFFSET(DFS_SPECIAL_INFO, Name[0]);
for (i = 0; i < dfsSpcInfo.NameCount; i++) {
if (CheckControlC())
return;
wGetData(dwName, &uStr, sizeof(UNICODE_STRING));
wPrintStringW("\t\tName:", &uStr, TRUE);
dwName += sizeof(UNICODE_STRING);
}
} else {
PRINTF( "Unable to read DFS_SITE_INFO @%08lx\n", dwAddress);
}
}
/*
* dumpSiteInfo : Routine suitable as argument to dumplist; used to dump list of
* DFS_SITE_INFO's
*/
void dumpSiteInfo(
ULONG_PTR dwAddress
)
{
ULONG_PTR dwSiteName;
DFS_SITE_INFO dfsSiteInfo;
ULONG i;
UNICODE_STRING uStr;
if (wGetData( dwAddress, &dfsSiteInfo, sizeof(dfsSiteInfo) )) {
PRINTF( " DFS_SITE_INFO @ %08lx\n", dwAddress);
wPrintStringW("\tServerName:", &dfsSiteInfo.ServerName, TRUE);
dwSiteName = dwAddress + FIELD_OFFSET(DFS_SITE_INFO, SiteName[0]);
for (i = 0; i < dfsSiteInfo.SiteCount; i++) {
wGetData(dwSiteName, &uStr, sizeof(UNICODE_STRING));
wPrintStringW("\t\tName:", &uStr, TRUE);
dwSiteName += sizeof(UNICODE_STRING);
}
} else {
PRINTF( "Unable to read DFS_SITE_INFO @%08lx\n", dwAddress);
}
}
/*
* dumpIpInfo : Routine suitable as argument to dumplist; used to dump list of
* DFS_IP_INFO's
*/
void dumpIpInfo(
ULONG_PTR dwAddress
)
{
DFS_IP_INFO dfsIpInfo;
ULONG IpAddress;
if (wGetData( dwAddress, &dfsIpInfo, sizeof(dfsIpInfo) )) {
IpAddress = *((ULONG *)&dfsIpInfo.IpAddress.IpData);
PRINTF( " DFS_IP_INFO @ %08lx\n", dwAddress);
PRINTF( "\tIpAddress: %d.%d.%d.%d\n",
IpAddress & 0xff,
(IpAddress >> 8) & 0xff,
(IpAddress >> 16) & 0xff,
(IpAddress >> 24) & 0xff);
wPrintStringW("\tSiteName: ", &dfsIpInfo.SiteName, TRUE);
} else {
PRINTF( "Unable to read DFS_SITE_INFO @%08lx\n", dwAddress);
}
}
/*
* dumplist : A general-purpose routine to dump a list of structures
*
*/
VOID
dumplist(
ULONG_PTR dwListEntryAddress,
DWORD linkOffset,
VOID (*dumpRoutine)(ULONG_PTR dwStructAddress)
)
{
LIST_ENTRY listHead, listNext;
ULONG max_list_entry = MAX_ENTRIES;
//
// Get the value in the LIST_ENTRY at dwAddress
//
PRINTF( "Dumping list @ %08lx\n", dwListEntryAddress );
if (wGetData(dwListEntryAddress, &listHead, sizeof(LIST_ENTRY))) {
ULONG_PTR dwNextLink = (ULONG_PTR) listHead.Flink;
ULONG_PTR dwNextdupLink = (ULONG_PTR) listHead.Flink;
ULONG loop_count = 0;
if (dwNextLink == 0) {
PRINTF( "Uninitialized list!\n" );
} else if (dwNextLink == dwListEntryAddress) {
PRINTF( "Empty list!\n" );
} else {
while( dwNextLink != dwListEntryAddress) {
ULONG_PTR dwStructAddress;
if (CheckControlC())
return;
dwStructAddress = dwNextLink - linkOffset;
dumpRoutine(dwStructAddress);
if (wGetData( dwNextLink, &listNext, sizeof(LIST_ENTRY))) {
dwNextLink = (ULONG_PTR) listNext.Flink;
} else {
PRINTF( "Unable to get next item @%08lx\n", dwNextLink );
break;
}
if (++loop_count > max_list_entry) {
PRINTF( "Dumped maximum %d entries... aborting\n", loop_count);
break;
}
}
}
} else {
PRINTF( "Unable to read list head @ %08lx\n", dwListEntryAddress);
}
}
VOID
DoIndent(VOID)
{
INT i;
for (i = 0; i < 2 * Indent; i++)
PRINTF(" ");
}
VOID
PrintStructFields( ULONG_PTR dwAddress, VOID *ptr, FIELD_DESCRIPTOR *pFieldDescriptors )
{
int i;
WCHAR wszBuffer[80];
// Display the fields in the struct.
for( i=0; pFieldDescriptors->Name; i++, pFieldDescriptors++ ) {
// Indentation to begin the struct display.
PRINTF( " " );
if( strlen( pFieldDescriptors->Name ) > FIELD_NAME_LENGTH ) {
PRINTF( "%-17s...%s ", pFieldDescriptors->Name, pFieldDescriptors->Name+strlen(pFieldDescriptors->Name)-10 );
} else {
PRINTF( "%-30s ", pFieldDescriptors->Name );
}
switch( pFieldDescriptors->FieldType ) {
case FieldTypeByte:
case FieldTypeChar:
PRINTF( "%-16d%s",
*(BYTE *)(((char *)ptr) + pFieldDescriptors->Offset ),
NewLineForFields(i) );
break;
case FieldTypeBoolean:
PRINTF( "%-16s%s",
*(BOOLEAN *)(((char *)ptr) + pFieldDescriptors->Offset ) ? "TRUE" : "FALSE",
NewLineForFields(i));
break;
case FieldTypeBool:
PRINTF( "%-16s%s",
*(BOOLEAN *)(((char *)ptr) + pFieldDescriptors->Offset ) ? "TRUE" : "FALSE",
NewLineForFields(i));
break;
case FieldTypePointer:
PRINTF( "%-16X%s",
*(ULONG *)(((char *)ptr) + pFieldDescriptors->Offset ),
NewLineForFields(i) );
break;
case FieldTypeULong:
case FieldTypeLong:
PRINTF( "%-16d%s",
*(ULONG *)(((char *)ptr) + pFieldDescriptors->Offset ),
NewLineForFields(i) );
break;
case FieldTypeShort:
PRINTF( "%-16X%s",
*(SHORT *)(((char *)ptr) + pFieldDescriptors->Offset ),
NewLineForFields(i) );
break;
case FieldTypeUShort:
PRINTF( "%-16X%s",
*(USHORT *)(((char *)ptr) + pFieldDescriptors->Offset ),
NewLineForFields(i) );
break;
case FieldTypeGuid:
PrintGuid( (GUID *)(((char *)ptr) + pFieldDescriptors->Offset) );
PRINTF( NewLine );
break;
case FieldTypePWStr:
if (wGetString( (ULONG_PTR)(((char *)ptr) + pFieldDescriptors->Offset), (char *)wszBuffer )) {
PRINTF( "%ws", wszBuffer );
} else {
PRINTF( "Unable to get string at %08lx", (ULONG_PTR)(((char *)ptr) + pFieldDescriptors->Offset));
}
PRINTF( NewLine );
break;
case FieldTypeUnicodeString:
wPrintStringW( NULL, (UNICODE_STRING *)(((char *)ptr) + pFieldDescriptors->Offset ), 0 );
PRINTF( NewLine );
break;
case FieldTypeAnsiString:
wPrintStringA( NULL, (ANSI_STRING *)(((char *)ptr) + pFieldDescriptors->Offset ), 0 );
PRINTF( NewLine );
break;
case FieldTypeSymbol:
{
UCHAR SymbolName[ 200 ];
ULONG Displacement;
PVOID sym = (PVOID)(*(ULONG_PTR *)(((char *)ptr) + pFieldDescriptors->Offset ));
GetSymbol(sym, SymbolName, (ULONG_PTR *)&Displacement );
PRINTF( "%-16s%s",
SymbolName,
NewLineForFields(i) );
}
break;
case FieldTypeEnum:
{
ULONG EnumValue;
ENUM_VALUE_DESCRIPTOR *pEnumValueDescr;
// Get the associated numerical value.
EnumValue = *((ULONG *)((BYTE *)ptr + pFieldDescriptors->Offset));
if ((pEnumValueDescr = pFieldDescriptors->AuxillaryInfo.pEnumValueDescriptor)
!= NULL) {
//
// An auxilary textual description of the value is
// available. Display it instead of the numerical value.
//
LPSTR pEnumName = NULL;
while (pEnumValueDescr->EnumName != NULL) {
if (EnumValue == pEnumValueDescr->EnumValue) {
pEnumName = pEnumValueDescr->EnumName;
break;
}
pEnumValueDescr++;
}
if (pEnumName != NULL) {
PRINTF( "%-16s ", pEnumName );
} else {
PRINTF( "%-4d (%-10s) ", EnumValue,"Unknown!");
}
} else {
//
// No auxilary information is associated with the ehumerated type
// print the numerical value.
//
PRINTF( "%-16d",EnumValue);
}
PRINTF( NewLineForFields(i) );
}
break;
case FieldTypeByteBitMask:
case FieldTypeWordBitMask:
case FieldTypeDWordBitMask:
{
BOOL fFirstFlag;
ULONG BitMaskValue;
BIT_MASK_DESCRIPTOR *pBitMaskDescr;
BitMaskValue = *((ULONG *)((BYTE *)ptr + pFieldDescriptors->Offset));
PRINTF("%-8x ", BitMaskValue);
PRINTF( NewLineForFields(i) );
pBitMaskDescr = pFieldDescriptors->AuxillaryInfo.pBitMaskDescriptor;
fFirstFlag = TRUE;
if (BitMaskValue != 0 && pBitMaskDescr != NULL) {
while (pBitMaskDescr->BitmaskName != NULL) {
if ((BitMaskValue & pBitMaskDescr->BitmaskValue) != 0) {
if (fFirstFlag) {
fFirstFlag = FALSE;
PRINTF(" ( %-s", pBitMaskDescr->BitmaskName);
} else {
PRINTF( " |\n" );
PRINTF(" %-s", pBitMaskDescr->BitmaskName);
}
}
pBitMaskDescr++;
}
PRINTF(" )");
PRINTF( NewLineForFields(i) );
}
}
break;
case FieldTypeStruct:
PRINTF( "@%-15X%s",
(dwAddress + pFieldDescriptors->Offset ),
NewLineForFields(i) );
break;
case FieldTypeLargeInteger:
wPrintLargeInt( (LARGE_INTEGER *)(((char *)ptr) + pFieldDescriptors->Offset) );
PRINTF( NewLine );
break;
case FieldTypeFileTime:
default:
dprintf( "Unrecognized field type %c for %s\n", pFieldDescriptors->FieldType, pFieldDescriptors->Name );
break;
}
}
}
#define NAME_DELIMITER '@'
#define INVALID_INDEX 0xffffffff
#define MIN(x,y) ((x) < (y) ? (x) : (y))
ULONG SearchStructs(LPSTR lpArgument)
{
ULONG i = 0;
STRUCT_DESCRIPTOR *pStructs = Structs;
ULONG NameIndex = INVALID_INDEX;
ULONG ArgumentLength = strlen(lpArgument);
BOOLEAN fAmbiguous = FALSE;
while ((pStructs->StructName != 0)) {
ULONG StructLength;
StructLength = strlen(pStructs->StructName);
if (StructLength >= ArgumentLength) {
int Result = _strnicmp(
lpArgument,
pStructs->StructName,
ArgumentLength);
if (Result == 0) {
if (StructLength == ArgumentLength) {
// Exact match. They must mean this struct!
fAmbiguous = FALSE;
NameIndex = i;
break;
} else if (NameIndex != INVALID_INDEX) {
// We have encountered duplicate matches. Print out the
// matching strings and let the user disambiguate.
fAmbiguous = TRUE;
break;
} else {
NameIndex = i;
}
}
}
pStructs++;i++;
}
if (fAmbiguous) {
PRINTF("Ambigous Name Specification -- The following structs match\n");
PRINTF("%s\n",Structs[NameIndex].StructName);
PRINTF("%s\n",Structs[i].StructName);
while (pStructs->StructName != 0) {
if (_strnicmp(lpArgument,
pStructs->StructName,
MIN(strlen(pStructs->StructName),ArgumentLength)) == 0) {
PRINTF("%s\n",pStructs->StructName);
}
pStructs++;
}
PRINTF("Dumping Information for %s\n",Structs[NameIndex].StructName);
}
return(NameIndex);
}
VOID DisplayStructs()
{
STRUCT_DESCRIPTOR *pStructs = Structs;
PRINTF("The following structs are handled .... \n");
while (pStructs->StructName != 0) {
PRINTF("\t%s\n",pStructs->StructName);
pStructs++;
}
}
#define NAME_DELIMITERS "@"
DECLARE_API( dump )
{
ULONG_PTR dwAddress;
//SETCALLBACKS();
if( args && *args ) {
// Parse the argument string to determine the structure to be displayed.
// Scan for the NAME_DELIMITER ( '@' ).
LPSTR lpName = (PSTR)args;
LPSTR lpArgs = strpbrk(args, NAME_DELIMITERS);
ULONG Index;
if (lpArgs) {
//
// The specified command is of the form
// dump <name>@<address expr.>
//
// Locate the matching struct for the given name. In the case
// of ambiguity we seek user intervention for disambiguation.
//
// We do an inplace modification of the argument string to
// facilitate matching.
//
*lpArgs = '\0';
for (;*lpName==' ';) { lpName++; } //skip leading blanks
Index = SearchStructs(lpName);
//
// Let us restore the original value back.
//
*lpArgs = NAME_DELIMITER;
if (INVALID_INDEX != Index) {
BYTE DataBuffer[512];
dwAddress = GetExpression( ++lpArgs );
if (wGetData(dwAddress,DataBuffer,Structs[Index].StructSize)) {
PRINTF(
"++++++++++++++++ %s@%lx ++++++++++++++++\n",
Structs[Index].StructName,
dwAddress);
PrintStructFields(
dwAddress,
&DataBuffer,
Structs[Index].FieldDescriptors);
PRINTF(
"---------------- %s@%lx ----------------\n",
Structs[Index].StructName,
dwAddress);
} else {
PRINTF("Error reading Memory @ %lx\n",dwAddress);
}
} else {
// No matching struct was found. Display the list of
// structs currently handled.
DisplayStructs();
}
} else {
//
// The command is of the form
// dump <name>
//
// Currently we do not handle this. In future we will map it to
// the name of a global variable and display it if required.
//
DisplayStructs();
}
} else {
//
// display the list of structs currently handled.
//
DisplayStructs();
}
return;
}