|
|
/*++
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
--*/
#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 <windef.h>
#include <tdi.h>
#include <wincred.h>
#include <ntddnfs.h> // For communicating with
// the SMB Rdr
#include <ntddmup.h> // For UNC registration
#include <winnetwk.h> // For NETRESOURCE def'n
#include <dfsfsctl.h> // Dfs FsControl Codes.
#include <lmdfs.h> // DFS_INFO_X
#include "nodetype.h"
#include "dfsmrshl.h"
#include "dfsfsctl.h"
#include "pkt.h"
#include "dfsstruc.h"
#include "fcbsup.h"
#include "fsctrl.h"
#include "dnr.h"
#include "lock.h"
#include "mupstruc.h"
#include "mupdata.h"
#include <kdextlib.h>
#include <stdlib.h>
#define PRINTF dprintf
#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);
/*
* Mup global variables. * */
#define NO_SYMBOLS_MESSAGE \
"Unable to get address of Mup!DfsData - do you have symbols?\n"
LPSTR ExtensionNames[] = { "Mup debugger extensions", 0 };
LPSTR Extensions[] = { "DfsData - dumps Mup!DfsData", "Pkt - dumps the global Pkt", "FcbTable - dumps all the Dfs FCBs", "VcbList - dumps all the Vcbs & Dfs Device Objects (net used objects)", "DrtList - dumps all the Devless Roots (net used objects)", "OfflineList - dumps all the Offline Roots", "CredList - dumps all the defined Credentials", "SpecialTable - dumps the special table", "PrefixList - dumps all the mup prefixes", "Dump - dump a data structure. Type in 'mupkd.dump' for more info", 0 };
ENUM_VALUE_DESCRIPTOR DfsMachineStateEnum[] = { {DFS_UNKNOWN, "Dfs State Unknown"}, {DFS_CLIENT, "Dfs Client"}, {DFS_SERVER, "Dfs Server"}, {DFS_ROOT_SERVER, "Dfs Root"}, 0 };
/*
* DFS_DATA * */
FIELD_DESCRIPTOR DfsDataFields[] = { FIELD3(FieldTypeShort,DFS_DATA,NodeTypeCode), FIELD3(FieldTypeShort,DFS_DATA,NodeByteSize), FIELD3(FieldTypeStruct,DFS_DATA,VcbQueue), FIELD3(FieldTypeStruct,DFS_DATA,DeletedVcbQueue), FIELD3(FieldTypeStruct,DFS_DATA,DrtQueue), FIELD3(FieldTypeStruct,DFS_DATA,Credentials), FIELD3(FieldTypeStruct,DFS_DATA,DeletedCredentials), FIELD3(FieldTypeStruct,DFS_DATA,OfflineRoots), 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(FieldTypeStruct,DFS_DATA,DfsLock), FIELD3(FieldTypePointer,DFS_DATA,OurProcess), FIELD3(FieldTypeUnicodeString,DFS_DATA,LogRootDevName), FIELD4(FieldTypeEnum,DFS_DATA,MachineState,DfsMachineStateEnum), FIELD3(FieldTypeStruct,DFS_DATA,Pkt), FIELD3(FieldTypeStruct,DFS_DATA,PktWritePending), FIELD3(FieldTypeStruct,DFS_DATA,PktReferralRequests), FIELD3(FieldTypePointer,DFS_DATA,FcbHashTable), 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(FieldTypeULong,DFS_PKT,EntryTimeToLive), FIELD3(FieldTypeStruct,DFS_PKT,EntryList), FIELD3(FieldTypeUnicodeString,DFS_PKT,DCName), FIELD3(FieldTypeUnicodeString,DFS_PKT,DomainNameFlat), FIELD3(FieldTypeUnicodeString,DFS_PKT,DomainNameDns), FIELD3(FieldTypeStruct,DFS_PKT,SpecialTable), FIELD3(FieldTypeStruct,DFS_PKT,PrefixTable), FIELD3(FieldTypeStruct,DFS_PKT,ShortPrefixTable), FIELD3(FieldTypeStruct,DFS_PKT,DSMachineTable), 0 };
/*
* DFS_SPECIAL_TABLE * */ FIELD_DESCRIPTOR DfsSpecialTableFields[] = { FIELD3(FieldTypeStruct,DFS_SPECIAL_TABLE,SpecialEntryList), FIELD3(FieldTypeULong,DFS_SPECIAL_TABLE,SpecialEntryCount), FIELD3(FieldTypeULong,DFS_SPECIAL_TABLE,TimeToLive), 0 };
/*
* DFS_PKT_ENTRY * */
BIT_MASK_DESCRIPTOR PktEntryType[] = { {PKT_ENTRY_TYPE_DFS, "Uplevel Volume"}, {PKT_ENTRY_TYPE_MACHINE, "Machine Volume"}, {PKT_ENTRY_TYPE_NONDFS, "Downlevel Volume"}, {PKT_ENTRY_TYPE_SYSVOL, "Sysvol"}, {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_OFFLINE,"Offline Volume"}, 0 };
FIELD_DESCRIPTOR DfsPktEntryFields[] = { FIELD3(FieldTypeUShort,DFS_PKT_ENTRY,NodeTypeCode), FIELD3(FieldTypeUShort,DFS_PKT_ENTRY,NodeByteSize), FIELD3(FieldTypeStruct,DFS_PKT_ENTRY,Link), 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.ServiceCount), FIELD3(FieldTypePointer,DFS_PKT_ENTRY,Info.ServiceList), FIELD3(FieldTypeULong,DFS_PKT_ENTRY,ExpireTime), FIELD3(FieldTypeULong,DFS_PKT_ENTRY,TimeToLive), 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,ProviderId), FIELD3(FieldTypeUnicodeString,DFS_SERVICE,Name), FIELD3(FieldTypePointer,DFS_SERVICE,ConnFile), FIELD3(FieldTypePointer,DFS_SERVICE,pProvider), FIELD3(FieldTypeUnicodeString,DFS_SERVICE,Address), FIELD3(FieldTypePointer,DFS_SERVICE,pMachEntry), FIELD3(FieldTypeULong,DFS_SERVICE,Cost), 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), FIELD3(FieldTypePointer,DFS_MACHINE_ENTRY,AuthConn), FIELD3(FieldTypePointer,DFS_MACHINE_ENTRY,Credentials), 0 };
/*
* DFS_SPECIAL_ENTRY * */
FIELD_DESCRIPTOR DfsSpecialEntryFields[] = { FIELD3(FieldTypeShort,DFS_SPECIAL_ENTRY,NodeTypeCode), FIELD3(FieldTypeShort,DFS_SPECIAL_ENTRY,NodeByteSize), FIELD3(FieldTypeStruct,DFS_SPECIAL_ENTRY,Link), FIELD3(FieldTypeULong,DFS_SPECIAL_ENTRY,USN), FIELD3(FieldTypeULong,DFS_SPECIAL_ENTRY,UseCount), FIELD3(FieldTypeUnicodeString,DFS_SPECIAL_ENTRY,SpecialName), FIELD3(FieldTypeULong,DFS_SPECIAL_ENTRY,ExpandedCount), FIELD3(FieldTypeULong,DFS_SPECIAL_ENTRY,Active), FIELD3(FieldTypePointer,DFS_SPECIAL_ENTRY,ExpandedNames), FIELD3(FieldTypeBoolean,DFS_SPECIAL_ENTRY,NeedsExpansion), FIELD3(FieldTypeBoolean,DFS_SPECIAL_ENTRY,Stale), 0 };
/*
* DFS_EXPANDED_NAME * */
FIELD_DESCRIPTOR DfsExpandedNameFields[] = { FIELD3(FieldTypeUnicodeString,DFS_EXPANDED_NAME,ExpandedName), FIELD3(FieldTypeStruct,DFS_EXPANDED_NAME,Guid), 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 };
/*
* 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_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 };
/*
* DFS_FCB * */
FIELD_DESCRIPTOR FcbFields[] = { FIELD3(FieldTypeUShort, DFS_FCB, NodeTypeCode), FIELD3(FieldTypeUShort, DFS_FCB, NodeByteSize), FIELD3(FieldTypePointer, DFS_FCB, Vcb), FIELD3(FieldTypeUnicodeString, DFS_FCB, FullFileName), FIELD3(FieldTypePointer, DFS_FCB, FileObject), FIELD3(FieldTypePointer, DFS_FCB, TargetDevice), FIELD3(FieldTypePointer, DFS_FCB, DfsMachineEntry), 0 };
/*
* DFS_VCB * */
BIT_MASK_DESCRIPTOR VcbStateFlagBits[] = { {VCB_STATE_FLAG_LOCKED, "Vcb Locked"}, {VCB_STATE_FLAG_ALLOC_FCB, "Allocate Fcb"}, 0 };
FIELD_DESCRIPTOR VcbFields[] = { FIELD3(FieldTypeUShort,DFS_VCB,NodeTypeCode), FIELD3(FieldTypeUShort,DFS_VCB,NodeByteSize), FIELD3(FieldTypeStruct,DFS_VCB,VcbLinks), FIELD4(FieldTypeDWordBitMask,DFS_VCB,VcbState,VcbStateFlagBits), FIELD3(FieldTypeUnicodeString,DFS_VCB,LogicalRoot), FIELD3(FieldTypeUnicodeString,DFS_VCB,LogRootPrefix), FIELD3(FieldTypePointer,DFS_VCB,Credentials), FIELD3(FieldTypeULong,DFS_VCB,DirectAccessOpenCount), FIELD3(FieldTypeStruct,DFS_VCB,ShareAccess), FIELD3(FieldTypeULong,DFS_VCB,OpenFileCount), FIELD3(FieldTypePointer,DFS_VCB,FileObjectWithVcbLocked), #ifdef TERMSRV
FIELD3(FieldTypeULong,DFS_VCB,SessionID), #endif // TERMSRV
FIELD3(FieldTypeULong,DFS_VCB,LogonID), 0 };
FIELD_DESCRIPTOR DrtFields[] = { FIELD3(FieldTypeUShort,DFS_DEVLESS_ROOT,NodeTypeCode), FIELD3(FieldTypeUShort,DFS_DEVLESS_ROOT,NodeByteSize), FIELD3(FieldTypeStruct,DFS_DEVLESS_ROOT,DrtLinks), FIELD3(FieldTypeUnicodeString,DFS_DEVLESS_ROOT,DevlessPath), FIELD3(FieldTypePointer,DFS_DEVLESS_ROOT,Credentials), #ifdef TERMSRV
FIELD3(FieldTypeULong,DFS_DEVLESS_ROOT,SessionID), #endif // TERMSRV
FIELD3(FieldTypeULong,DFS_DEVLESS_ROOT,LogonID), 0 };
FIELD_DESCRIPTOR OfflineRootFields[] = { FIELD3(FieldTypeUnicodeString,DFS_OFFLINE_SERVER,LogicalServerName), FIELD3(FieldTypeStruct,DFS_OFFLINE_SERVER,ListEntry), 0 };
FIELD_DESCRIPTOR KnownPrefixFields[] = { FIELD3(FieldTypeULong,KNOWN_PREFIX,BlockHeader.ReferenceCount), FIELD3(FieldTypeStruct,KNOWN_PREFIX,TableEntry), FIELD3(FieldTypeUnicodeString,KNOWN_PREFIX,Prefix), FIELD3(FieldTypeStruct,KNOWN_PREFIX,LastUsedTime), FIELD3(FieldTypeLargeInteger,KNOWN_PREFIX,LastUsedTime), FIELD3(FieldTypePointer,KNOWN_PREFIX,UncProvider), FIELD3(FieldTypeBoolean,KNOWN_PREFIX,InTable), FIELD3(FieldTypeBoolean,KNOWN_PREFIX,Active), 0 };
FIELD_DESCRIPTOR UncProviderFields[] = { FIELD3(FieldTypeULong,UNC_PROVIDER,BlockHeader.ReferenceCount), FIELD3(FieldTypeUnicodeString,UNC_PROVIDER,DeviceName), FIELD3(FieldTypeStruct,UNC_PROVIDER,Handle), FIELD3(FieldTypePointer,UNC_PROVIDER,DeviceObject), FIELD3(FieldTypePointer,UNC_PROVIDER,FileObject), FIELD3(FieldTypeULong,UNC_PROVIDER,Priority), FIELD3(FieldTypeBoolean,UNC_PROVIDER,MailslotsSupported), 0 };
/*
* DFS_CREDENTIALS * */
FIELD_DESCRIPTOR CredentialsFields[] = { FIELD3(FieldTypeStruct,DFS_CREDENTIALS,Link), FIELD3(FieldTypeULong,DFS_CREDENTIALS,Flags), FIELD3(FieldTypeULong,DFS_CREDENTIALS,RefCount), FIELD3(FieldTypeULong,DFS_CREDENTIALS,NetUseCount), FIELD3(FieldTypeUnicodeString,DFS_CREDENTIALS,ServerName), FIELD3(FieldTypeUnicodeString,DFS_CREDENTIALS,ShareName), FIELD3(FieldTypeUnicodeString,DFS_CREDENTIALS,DomainName), FIELD3(FieldTypeUnicodeString,DFS_CREDENTIALS,UserName), FIELD3(FieldTypeUnicodeString,DFS_CREDENTIALS,Password), #ifdef TERMSRV
FIELD3(FieldTypeULong,DFS_CREDENTIALS,SessionID), #endif // TERMSRV
FIELD3(FieldTypeULong,DFS_CREDENTIALS,LogonID), FIELD3(FieldTypeULong,DFS_CREDENTIALS, EaLength), FIELD3(FieldTypeStruct,DFS_CREDENTIALS,EaBuffer), 0 };
/*
* DNR_CONTEXT * */
ENUM_VALUE_DESCRIPTOR DnrStateEnum[] = { {DnrStateEnter, "DNR State Enter"}, {DnrStateStart, "DNR State Start"}, {DnrStateGetFirstDC, "DNR State GetFirstDC"}, {DnrStateGetReferrals, "DNR State GetReferrals"}, {DnrStateGetNextDC, "DNR State GetNextDC"}, {DnrStateCompleteReferral, "DNR State CompleteReferral"}, {DnrStateSendRequest, "DNR State SendRequest"}, {DnrStatePostProcessOpen, "DNR State PostProcessOpen"}, {DnrStateGetFirstReplica, "DNR State GetFirstReplica"}, {DnrStateGetNextReplica, "DNR State GetNextReplica"}, {DnrStateSvcListCheck, "DNR State SvcListCheck"}, {DnrStateDone, "DNR State Done"}, {DnrStateLocalCompletion, "DNR State LocalCompletion"}, 0 };
FIELD_DESCRIPTOR DnrContextFields[] = { FIELD3(FieldTypeUShort, DNR_CONTEXT, NodeTypeCode), FIELD3(FieldTypeUShort, DNR_CONTEXT, NodeByteSize), FIELD4(FieldTypeEnum, DNR_CONTEXT, State, DnrStateEnum), FIELD3(FieldTypeStruct,DNR_CONTEXT,SecurityContext), FIELD3(FieldTypePointer,DNR_CONTEXT,pPktEntry), FIELD3(FieldTypeULong,DNR_CONTEXT,USN), FIELD3(FieldTypePointer,DNR_CONTEXT,pService), FIELD3(FieldTypePointer,DNR_CONTEXT,pProvider), FIELD3(FieldTypeUShort,DNR_CONTEXT,ProviderId), FIELD3(FieldTypePointer,DNR_CONTEXT,TargetDevice), FIELD3(FieldTypePointer,DNR_CONTEXT,AuthConn), FIELD3(FieldTypePointer,DNR_CONTEXT,DCConnFile), FIELD3(FieldTypePointer,DNR_CONTEXT,Credentials), FIELD3(FieldTypePointer,DNR_CONTEXT,pIrpContext), FIELD3(FieldTypePointer,DNR_CONTEXT,OriginalIrp), FIELD3(FieldTypeULong,DNR_CONTEXT,FinalStatus), FIELD3(FieldTypePointer,DNR_CONTEXT,FcbToUse), FIELD3(FieldTypePointer,DNR_CONTEXT,Vcb), FIELD3(FieldTypeUnicodeString,DNR_CONTEXT,FileName), FIELD3(FieldTypeUnicodeString,DNR_CONTEXT,RemainingPart), FIELD3(FieldTypeUnicodeString,DNR_CONTEXT,SavedFileName), FIELD3(FieldTypePointer,DNR_CONTEXT,SavedRelatedFileObject), FIELD3(FieldTypeStruct,DNR_CONTEXT,RSelectContext), FIELD3(FieldTypeStruct,DNR_CONTEXT,RDCSelectContext), FIELD3(FieldTypeULong,DNR_CONTEXT,ReferralSize), FIELD3(FieldTypeULong,DNR_CONTEXT,Attempts), FIELD3(FieldTypeBoolean,DNR_CONTEXT,ReleasePkt), FIELD3(FieldTypeBoolean,DNR_CONTEXT,DnrActive), FIELD3(FieldTypeBoolean,DNR_CONTEXT,GotReferral), FIELD3(FieldTypeBoolean,DNR_CONTEXT,FoundInconsistency), FIELD3(FieldTypeBoolean,DNR_CONTEXT,CalledDCLocator), FIELD3(FieldTypeBoolean,DNR_CONTEXT,Impersonate), FIELD3(FieldTypeBoolean,DNR_CONTEXT,NameAllocated), FIELD3(FieldTypePointer,DNR_CONTEXT,DeviceObject), 0 };
/*
* REPL_SELECT_CONTEXT * */
BIT_MASK_DESCRIPTOR ReplSelectFlagBits[] = { {REPL_UNINITIALIZED, "Uninitialized Context"}, {REPL_SVC_IS_LOCAL, "Local Svc Selected"}, {REPL_SVC_IS_REMOTE, "Remote Svc Selected"}, {REPL_PRINCIPAL_SPECD, "Svc Principal Specified"}, {REPL_NO_MORE_ENTRIES, "Svc List Exhausted"}, 0 };
FIELD_DESCRIPTOR ReplSelectContextFields[] = { FIELD4(FieldTypeWordBitMask,REPL_SELECT_CONTEXT,Flags,ReplSelectFlagBits), FIELD3(FieldTypeULong,REPL_SELECT_CONTEXT,iFirstSvcIndex), FIELD3(FieldTypeULong,REPL_SELECT_CONTEXT,iSvcIndex), 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(DFS_SPECIAL_ENTRY,DfsSpecialEntryFields), STRUCT(DFS_SPECIAL_TABLE,DfsSpecialTableFields), STRUCT(DFS_EXPANDED_NAME,DfsExpandedNameFields), STRUCT(PROVIDER_DEF,ProviderDefFields), STRUCT(DFS_FCB,FcbFields), STRUCT(DNR_CONTEXT,DnrContextFields), STRUCT(DFS_VCB,VcbFields), STRUCT(DFS_DEVLESS_ROOT,DrtFields), STRUCT(DFS_OFFLINE_SERVER,OfflineRootFields), STRUCT(DFS_CREDENTIALS,CredentialsFields), STRUCT(DFS_PREFIX_TABLE,DfsPrefixTableFields), STRUCT(DFS_PREFIX_TABLE_ENTRY,DfsPrefixTableEntryFields), STRUCT(KNOWN_PREFIX,KnownPrefixFields), STRUCT(UNC_PROVIDER,UncProviderFields), 0 };
/*
* Dfs specific dump routines * */
VOID dumplist( ULONG_PTR dwListEntryAddress, DWORD linkOffset, VOID (*dumpRoutine)(ULONG_PTR dwStructAddress) );
VOID dumpPktEntry( ULONG_PTR dwAddress );
VOID dumpFcb( ULONG_PTR dwAddress );
VOID dumpVcb( ULONG_PTR dwAddress );
VOID dumpDrt( ULONG_PTR dwAddress );
VOID dumpOfflineRoots( ULONG_PTR dwAddress );
VOID dumpPrefix( ULONG_PTR dwAddress );
VOID dumpCredentials( ULONG_PTR dwAddress );
BOOL dumpspecialtable( ULONG_PTR dwAddress );
VOID dumpspecialentry( ULONG_PTR dwAddress );
/*
* dfsdata : Routine to dump the global dfs data structure * */
BOOL dfsdata( ULONG_PTR dwCurrentPC, PWINDBG_EXTENSION_APIS lpExtensionApis, LPSTR lpArgumentString ) { ULONG_PTR dwAddress;
// SETCALLBACKS();
dwAddress = (GetExpression)("Mup!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;
// SETCALLBACKS();
//
// Figure out the address of the Pkt. This is an offset within
// Mup!DfsData.
//
dwAddress = (GetExpression)("Mup!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 );
}
/*
* specialtable : Routine to dump out the special table * */
BOOL specialtable( ULONG_PTR dwCurrentPC, PWINDBG_EXTENSION_APIS lpExtensionApis, LPSTR lpArgumentString) { ULONG i; ULONG_PTR dwAddress;
// SETCALLBACKS();
//
// Figure out the address of the Pkt. This is an offset within
// dfs!DfsData.
//
dwAddress = (GetExpression)("Mup!DfsData");
if (dwAddress) {
dwAddress += FIELD_OFFSET(DFS_DATA, Pkt.SpecialTable); PRINTF("SpecialTable@0x%x\n", dwAddress); return dumpspecialtable(dwAddress); } 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); }
}
BOOL dumpspecialtable( ULONG_PTR dwAddress) { ULONG i; DFS_SPECIAL_TABLE SpecialTable; LIST_ENTRY ListEntry;
if (wGetData(dwAddress,&SpecialTable,sizeof(DFS_SPECIAL_TABLE))) { ULONG nEntries = SpecialTable.SpecialEntryCount; PRINTF("\n--- Special Table @ %08lx\n", dwAddress); PrintStructFields( dwAddress, &SpecialTable, DfsSpecialTableFields );
dwAddress += FIELD_OFFSET(DFS_SPECIAL_TABLE, SpecialEntryList); dumplist( dwAddress, FIELD_OFFSET(DFS_SPECIAL_ENTRY,Link), dumpspecialentry); } else { PRINTF( NO_SYMBOLS_MESSAGE ); } return TRUE; }
/*
* dumpspecialentry : Routine suitable as argument to dumplist; used to dump list of * special entries * */
VOID dumpspecialentry( ULONG_PTR dwAddress ) { ULONG_PTR dwName; ULONG i; DFS_EXPANDED_NAME ExpName; DFS_SPECIAL_ENTRY specialentry;
if (wGetData( dwAddress, &specialentry, sizeof(specialentry))) { PRINTF("\ndfs_special_entry @ %08lx\n", dwAddress); PrintStructFields( dwAddress, &specialentry, DfsSpecialEntryFields ); dwName = (ULONG_PTR) specialentry.ExpandedNames; for (i = 0; i < specialentry.ExpandedCount; i++) { if (CheckControlC()) return; wGetData(dwName, &ExpName, sizeof(DFS_EXPANDED_NAME)); wPrintStringW("\t\tName:", &ExpName.ExpandedName, TRUE); dwName += sizeof(DFS_EXPANDED_NAME); } } else { PRINTF("\nUnable to read specialentry @ %08lx\n", dwAddress); } }
/*
* prefixhash : Routine to compute hash of path component * */
BOOL prefixhash( ULONG_PTR dwCurrentPC, PWINDBG_EXTENSION_APIS lpExtensionApis, LPSTR lpArgumentString ) { DWORD BucketNo = 0; LPSTR lpPath;
// SETCALLBACKS();
if ((lpArgumentString == NULL) || (*lpArgumentString == 0)) { PRINTF("Usage: prefixhash <path-component>\n"); } else {
lpPath = lpArgumentString;
while (*lpPath != 0) { WCHAR wc;
wc = (*lpPath < 'a') ? (WCHAR) *lpPath : ((*lpPath < 'z') ? (WCHAR) (*lpPath - 'a' + 'A') : (WCHAR) *lpPath); BucketNo *= 131; BucketNo += wc;
lpPath++;
}
BucketNo = BucketNo % NO_OF_HASH_BUCKETS;
PRINTF("Hash for <%s> is %d\n", lpArgumentString, BucketNo);
}
return( TRUE ); }
/*
* fcbtable : Routine to dump the dfs fcb hash table * */
BOOL fcbtable( ULONG_PTR dwCurrentPC, PWINDBG_EXTENSION_APIS lpExtensionApis, LPSTR lpArgumentString ) { ULONG_PTR dwAddress;
// SETCALLBACKS();
//
// Figure out the address of the Pkt. This is an offset withing
// Mup!DfsData.
//
dwAddress = (GetExpression)("Mup!DfsData");
if (dwAddress) { DFS_DATA DfsData;
if (wGetData(dwAddress, &DfsData, sizeof(DFS_DATA))) { FCB_HASH_TABLE FcbTable; dwAddress = (ULONG_PTR) DfsData.FcbHashTable; if (wGetData(dwAddress, &FcbTable, sizeof(FCB_HASH_TABLE))) { ULONG i, cBuckets; ULONG_PTR dwListHeadAddress; cBuckets = FcbTable.HashMask + 1; dwListHeadAddress = dwAddress + FIELD_OFFSET(FCB_HASH_TABLE, HashBuckets); PRINTF( "+++ Fcb Hash Table @ %08lx (%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( ULONG_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); } }
/*
* vcblist : Routine to dump out all the Dfs VCBs (ie, all the Dfs Device * object descriptors). * */
BOOL vcblist( ULONG_PTR dwCurrentPC, PWINDBG_EXTENSION_APIS lpExtensionApis, LPSTR lpArgumentString ) { ULONG_PTR dwAddress;
// SETCALLBACKS();
//
// Figure out the address of the Pkt. This is an offset withing
// Mup!DfsData.
//
dwAddress = (GetExpression)("Mup!DfsData");
if (dwAddress) { dwAddress += FIELD_OFFSET(DFS_DATA, VcbQueue); dumplist( dwAddress, FIELD_OFFSET(DFS_VCB,VcbLinks), dumpVcb); } else { PRINTF( NO_SYMBOLS_MESSAGE ); } return( TRUE ); }
/*
* prefixlist : Routine to dump out all the mup prefixes * */
BOOL prefixlist( ULONG_PTR dwCurrentPC, PWINDBG_EXTENSION_APIS lpExtensionApis, LPSTR lpArgumentString ) { ULONG_PTR dwAddress;
// SETCALLBACKS();
//
// Figure out the address of the Pkt. This is an offset withing
// Mup!DfsData.
//
dwAddress = (GetExpression)("Mup!MupPrefixList");
if (dwAddress) { dumplist( dwAddress, FIELD_OFFSET(KNOWN_PREFIX,ListEntry), dumpPrefix); } else { PRINTF( NO_SYMBOLS_MESSAGE ); } return( TRUE ); }
/*
* dumpDeviceObject */
void dumpDeviceObject( ULONG_PTR dwAddress) { ULONG_PTR dwTempAddress; OBJECT_HEADER obhd; OBJECT_HEADER_NAME_INFO obni;
dwTempAddress = dwAddress - FIELD_OFFSET(OBJECT_HEADER, Body);
if (wGetData(dwTempAddress, &obhd, sizeof(obhd))) { if (obhd.NameInfoOffset != 0) { dwTempAddress -= obhd.NameInfoOffset; if (wGetData(dwTempAddress, &obni, sizeof(obni))) { wPrintStringW( " Device Name: ", &obni.Name, TRUE); } else { PRINTF("Unable to read Name Info @%08lx\n", dwTempAddress); } } else { PRINTF("\tDevice Name: NULL\n"); } } else { PRINTF("Unable to read Object Header @%08lx\n", dwTempAddress); } }
void dumpVcb( ULONG_PTR dwAddress) { ULONG_PTR dwLogicalRootAddress; DFS_VCB vcb;
dwLogicalRootAddress = dwAddress - FIELD_OFFSET(LOGICAL_ROOT_DEVICE_OBJECT, Vcb);
if (wGetData(dwAddress, &vcb, sizeof(vcb))) { PRINTF("+++ Vcb @%08lx : Logical Root Device Object @%08lx +++\n", dwAddress, dwLogicalRootAddress); PrintStructFields(dwAddress, &vcb, VcbFields); dumpDeviceObject( dwLogicalRootAddress ); PRINTF("--- Vcb @%08lx : Logical Root Device Object @%08lx ---\n", dwAddress, dwLogicalRootAddress); } else { PRINTF("Unable to read Vcb @%08lx\n",dwAddress); } }
void dumpPrefix( ULONG_PTR dwAddress) { KNOWN_PREFIX knownprefix;
if (wGetData(dwAddress, &knownprefix, sizeof(knownprefix))) { PRINTF("+++ KnownPrefix @%08lx +++\n", dwAddress); PrintStructFields(dwAddress, &knownprefix, KnownPrefixFields); PRINTF("+++ KnownPrefix @%08lx +++\n", dwAddress); } else { PRINTF("Unable to read knownprefix @%08lx\n",dwAddress); } }
/*
* credList - dump global list of user credentials * */
BOOL credlist( ULONG_PTR dwCurrentPC, PWINDBG_EXTENSION_APIS lpExtensionApis, LPSTR lpArgumentString ) { ULONG_PTR dwAddress;
// SETCALLBACKS();
//
// Figure out the address of the Pkt. This is an offset withing
// Mup!DfsData.
//
dwAddress = (GetExpression)("Mup!DfsData");
if (dwAddress) { dwAddress += FIELD_OFFSET(DFS_DATA, Credentials); dumplist( dwAddress, FIELD_OFFSET(DFS_CREDENTIALS,Link), dumpCredentials); } else { PRINTF( NO_SYMBOLS_MESSAGE ); } return( TRUE ); }
/*
* dumpCredentials : Routine suitable as argument to dumplist; used to dump * a list of DFS_CREDENTIALs. */
void dumpCredentials( ULONG_PTR dwAddress) { DFS_CREDENTIALS creds;
if (wGetData(dwAddress, &creds, sizeof(creds))) { PRINTF("+++ Credentials @%08lx +++\n", dwAddress); PrintStructFields(dwAddress, &creds, CredentialsFields); PRINTF("--- Credentials @%08lx ---\n", dwAddress); } else { PRINTF("Unable to read Credentials @%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;
//
// 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;
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; }
} }
} else {
PRINTF("Unable to read list head @ %08lx\n", dwListEntryAddress);
}
}
/*
* drtlist : Routine to dump out all the Dfs Devless Roots * */
BOOL drtlist( ULONG_PTR dwCurrentPC, PWINDBG_EXTENSION_APIS lpExtensionApis, LPSTR lpArgumentString ) { ULONG_PTR dwAddress;
// SETCALLBACKS();
//
// Figure out the address of the Pkt. This is an offset withing
// Mup!DfsData.
//
dwAddress = (GetExpression)("Mup!DfsData");
if (dwAddress) { dwAddress += FIELD_OFFSET(DFS_DATA, DrtQueue); dumplist( dwAddress, FIELD_OFFSET(DFS_DEVLESS_ROOT,DrtLinks), dumpDrt); } else { PRINTF( NO_SYMBOLS_MESSAGE ); } return( TRUE ); }
void dumpDrt( ULONG_PTR dwAddress) { DFS_DEVLESS_ROOT drt;
if (wGetData(dwAddress, &drt, sizeof(drt))) { PRINTF("+++ Drt @%08lx : +++\n", dwAddress); PrintStructFields(dwAddress, &drt, DrtFields); PRINTF("--- Drt @%08lx : ---\n", dwAddress); } else { PRINTF("Unable to read Drt @%08lx\n",dwAddress); } }
BOOL offlinelist( ULONG_PTR dwCurrentPC, PWINDBG_EXTENSION_APIS lpExtensionApis, LPSTR lpArgumentString ) { ULONG_PTR dwAddress;
// SETCALLBACKS();
//
// Figure out the address of the Pkt. This is an offset withing
// Mup!DfsData.
//
dwAddress = (GetExpression)("Mup!DfsData");
if (dwAddress) { dwAddress += FIELD_OFFSET(DFS_DATA, OfflineRoots); dumplist( dwAddress, FIELD_OFFSET(DFS_OFFLINE_SERVER,ListEntry), dumpOfflineRoots); } else { PRINTF( NO_SYMBOLS_MESSAGE ); } return( TRUE ); }
VOID dumpOfflineRoots( ULONG_PTR dwAddress) { DFS_OFFLINE_SERVER srv;
if (wGetData(dwAddress, &srv, sizeof(srv))) { PRINTF("+++ OfflineRoot @%08lx : +++\n", dwAddress); PrintStructFields(dwAddress, &srv, OfflineRootFields); PRINTF("--- Drt @%08lx : ---\n", dwAddress); } else { PRINTF("Unable to read Srv @%08lx\n",dwAddress); } }
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 *)(((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; }
|