/*++ 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 #include #include "ntverp.h" #include #include #include #include #include #include #include #include #include // For communicating with // the SMB Rdr #include // For UNC registration #include // For NETRESOURCE def'n #include // Dfs FsControl Codes. #include // 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 #include #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 \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 @
// // 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 // // 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; }