//+------------------------------------------------------------------------- // // Copyright (C) 1992, Microsoft Corporation. // // File: DfsDump.c // // Contents: DFS driver debugging dump. // // Classes: // // Functions: main // Usage // DfsReadAndPrintString - Print a string in a dfs structure // DumpPkt - Dump PKT, entries and services // DumpDevs - Dump device structures // DumpFcbs - Dump FCB hash table and all FCBs // // History: 03 Jan 92 Alanw Created. // //-------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include "nodetype.h" #include "dfsmrshl.h" #include "dfsfsctl.h" #include "pkt.h" #include "dsstruc.h" #include "fcbsup.h" #include "dsfsctl.h" #include "attach.h" #include "testsup.h" #define START_OF_NONPAGED_MEM 0x0ff000000 VOID Usage( char* progname ); NTSTATUS DfsReadAndPrintString( PUNICODE_STRING pStr ); VOID DfsDump( PVOID Ptr ); VOID DfsDumpDfsService( PDFS_SERVICE Ptr); VOID DfsDumpDSMachine( PDS_MACHINE Ptr); VOID DfsDumpDSTransport( PDS_TRANSPORT Ptr); VOID DumpPkt( void ); VOID DumpDevs( void ); VOID DumpFcbs( void ); #define MemUsage(ptr, size) { \ if (((ULONG) (ptr))>START_OF_NONPAGED_MEM) { \ NonPagedMem = NonPagedMem + size; \ } else { \ PagedMem = PagedMem + size; \ } \ } #define MemUsageStr(str) MemUsage((str).Buffer, (str).MaximumLength) ULONG NonPagedMem, PagedMem; DS_DATA DfsData, *pDfsData; VCB Vcb; BOOLEAN Dflag = FALSE; // dump device objects BOOLEAN Fflag = FALSE; // dump FCB hash table and FCBs BOOLEAN Pflag = FALSE; // dump PKT and services BOOLEAN Vflag = FALSE; // verbose - dump all fields PWSTR gpwszServer = NULL; __cdecl main(argc, argv) int argc; char **argv; { FILE_DFS_READ_STRUCT_PARAM RsParam; PLIST_ENTRY Link; char* progname; NTSTATUS Stat; VCB *pVcb; WCHAR wszServer[CNLEN + 1]; BOOL fInvalidArg = FALSE; printf("\n"); progname = argv[0]; // if (argc >= 3) { // Usage(progname); // return 3; // } while (argc > 1 && *argv[1] == '-') { char *pszFlags = &argv[1][1]; while (*pszFlags) { switch (*pszFlags++) { case 'a': Dflag = Fflag = Pflag = TRUE; break; case 'd': Dflag = TRUE; break; case 'f': Fflag = TRUE; break; case 'p': Pflag = TRUE; break; case 'v': Vflag = TRUE; break; case 's': if(*pszFlags != ':' || strlen(pszFlags) > CNLEN || strlen(pszFlags) < 2) { Usage(progname); fInvalidArg = TRUE; break; } pszFlags++; mbstowcs(wszServer,pszFlags, strlen(pszFlags) + 1); gpwszServer = wszServer; pszFlags += strlen(pszFlags); break; default: Usage(progname); fInvalidArg = TRUE; } } argv++; argc--; } if(fInvalidArg) return 3; if (!Dflag && !Fflag && !Pflag) { Pflag = TRUE; } // // Dump out the data structures of the DFS driver. // RsParam.StructKey = (ULONG)NULL; RsParam.TypeCode = DSFS_NTC_DATA_HEADER; RsParam.ByteCount = sizeof DfsData; Stat = DsfsReadStruct(&RsParam, (PUCHAR)&DfsData); if (!NT_SUCCESS(Stat)) { printf("%s: DsfsReadStruct for DfsData returned %08x\n", progname, Stat); return 3; } Link = DfsData.VcbQueue.Flink; pVcb = CONTAINING_RECORD(Link, VCB, VcbLinks); RsParam.StructKey = (ULONG) pVcb; RsParam.TypeCode = DSFS_NTC_VCB; RsParam.ByteCount = sizeof Vcb; Stat = DsfsReadStruct(&RsParam, (PUCHAR) &Vcb); if (!NT_SUCCESS(Stat)) { return 3; } pDfsData = CONTAINING_RECORD((Vcb.VcbLinks.Blink), DS_DATA, VcbQueue); MemUsage(pDfsData, RsParam.ByteCount); MemUsageStr(DfsData.LogRootDevName); if (Vflag) { printf("DfsData @ %08x:\t", pDfsData); DfsDump(&DfsData); printf("\n"); } else { printf("DfsData @ %08x:\n\n", pDfsData); } if (Dflag) { DumpDevs(); } if (Fflag) { DumpFcbs(); } if (Pflag) { DumpPkt(); } printf("Total Paged Mem Used: %d\n", PagedMem); printf("Total NonPaged Mem Used: %d\n", NonPagedMem); return 0; } VOID Usage( char* progname ) { printf("Usage: %s [-vdfp] [-s:server]\n", progname); printf(" -v\tVerbose\n"); printf(" -d\tDump device structures\n"); printf(" -f\tDump FCB structures\n"); printf(" -p\tDump PKT structures(default)\n"); printf(" -s:server\tDump the PKT on the indicated Cairo server\n"); exit (1); } NTSTATUS DfsReadAndPrintString( PUNICODE_STRING pStr ) { FILE_DFS_READ_STRUCT_PARAM RsParam; UCHAR Buf[500]; UNICODE_STRING Str; NTSTATUS Stat; if (pStr->Buffer == NULL) { printf("*NULL*"); return STATUS_SUCCESS; } if (pStr->Length > sizeof Buf) { printf("*StringTooLong*"); return STATUS_SUCCESS; } RsParam.StructKey = (ULONG) pStr->Buffer; RsParam.TypeCode = 0; RsParam.ByteCount = pStr->Length; if (! NT_SUCCESS( Stat = DsfsReadStruct(&RsParam, Buf))) return Stat; // MemUsage(RsParam.StructKey, RsParam.ByteCount); Str = *pStr; Str.Buffer = (WCHAR *)Buf; printf("%wZ", &Str); return STATUS_SUCCESS; } //+------------------------------------------------------------------- // // Function: DumpPkt, local // // Synopsis: This routine will dump the contents of the PKT and // all the associated data. // // Arguments: None // // Returns: None // // Requires: DfsData must have previously been loaded into memory. // //-------------------------------------------------------------------- VOID DumpPkt( void ) { FILE_DFS_READ_STRUCT_PARAM RsParam; PLIST_ENTRY Link, Sentinel = NULL; DFS_PKT_ENTRY PktEntry, *pPktEntry; DFS_SERVICE Service; PDS_TRANSPORT pTransport; DFS_MACHINE_ENTRY MachEntry; PDS_MACHINE pMachine; NTSTATUS Stat; ULONG i, j, k; char* pszMsg; pTransport = (PDS_TRANSPORT) malloc ( sizeof(DS_TRANSPORT)+512*sizeof(UCHAR) ); pMachine = (PDS_MACHINE) malloc ( sizeof(DS_MACHINE)+512*sizeof(PVOID) ); // // Now we take care of the Pkt dump. // if (Vflag) { printf("Pkt @ %08x:\t", &(pDfsData->Pkt)); DfsDump(&(DfsData.Pkt)); printf("\n"); } else { // // In here place whatever needs to be dumped from Pkt. // printf("Pkt @ %08x:\n", &(pDfsData->Pkt)); printf("\tDomainPktEntry @ %08x\n", DfsData.Pkt.DomainPktEntry); printf("\n"); } // // We now work with the Pkt Entries in the Pkt. // Link = DfsData.Pkt.EntryList.Flink; for (i=0; icTransports != 0) { RsParam.StructKey = (ULONG) (((CHAR *) MachEntry.pMachine) + DS_MACHINE_SIZE); RsParam.TypeCode = 0; RsParam.ByteCount = (USHORT) pMachine->cTransports*sizeof(PDS_TRANSPORT); Stat = DsfsReadStruct(&RsParam, (PUCHAR) &pMachine->rpTrans[0]); if (!NT_SUCCESS(Stat)) { exit(3); } } MemUsage(RsParam.StructKey, RsParam.ByteCount); DfsDumpDSMachine(pMachine); // // We really need to read the PrincipalName also but lets skip // for now. // for (k=0; kcTransports; k++) { RsParam.StructKey = (ULONG) (pMachine->rpTrans[k]); RsParam.ByteCount = DS_TRANSPORT_SIZE; RsParam.TypeCode = 0; Stat = DsfsReadStruct(&RsParam, (PUCHAR) pTransport); if (!NT_SUCCESS(Stat)) exit(3); MemUsage(RsParam.StructKey, RsParam.ByteCount); // // Now we need to read the actual address buffer in. // if (pTransport->taddr.AddressLength != 0) { RsParam.StructKey = (ULONG) (((CHAR *) (pMachine->rpTrans[k])) + DS_TRANSPORT_SIZE); RsParam.ByteCount = pTransport->taddr.AddressLength; RsParam.TypeCode = 0; Stat = DsfsReadStruct(&RsParam, (PUCHAR) &pTransport->taddr.Address[0]); if (!NT_SUCCESS(Stat)) exit(3); } DfsDumpDSTransport(pTransport); } } else { printf("\t\tService#%d%s: ", j, pszMsg); DfsReadAndPrintString((PUNICODE_STRING) &(Service.Address)); printf("\n"); } } printf("\n"); Link = PktEntry.Link.Flink; } free(pTransport); free(pMachine); } //+------------------------------------------------------------------- // // Function: DumpDevs, local // // Synopsis: This routine will dump the contents of the devices // associated with the DFS FSD. // // Arguments: None // // Returns: None // // Requires: DfsData must have previously been loaded into memory. // //-------------------------------------------------------------------- VOID DumpDevs( void ) { FILE_DFS_READ_STRUCT_PARAM RsParam; PLIST_ENTRY Link, Sentinel = NULL; PROVIDER_DEF Provider; DFS_VOLUME_OBJECT DfsVdo, *pDfsVdo; LOGICAL_ROOT_DEVICE_OBJECT DfsLrdo, *pDfsLrdo; NTSTATUS Stat; ULONG i; // // Now we dump the Provider list. // if (DfsData.pProvider) { for (i=0; i<(ULONG)DfsData.cProvider; i++) { RsParam.StructKey = (ULONG) (DfsData.pProvider+i); RsParam.TypeCode = DSFS_NTC_PROVIDER; RsParam.ByteCount = sizeof(PROVIDER_DEF); Stat = DsfsReadStruct(&RsParam, (PUCHAR) &Provider); if (NT_SUCCESS(Stat)) { break; } MemUsage(RsParam.StructKey, RsParam.ByteCount); MemUsageStr(Provider.DeviceName); printf("Provider#%d @ %08x:\t", i, RsParam.StructKey); if (Vflag) { DfsDump(&Provider); } else { printf("Device Name: "); DfsReadAndPrintString(&(Provider.DeviceName)); } printf("\n"); } printf("\n"); } // // Dump the file system device object // if (Vflag) { DEVICE_OBJECT Fsdo, *pFsdo; pFsdo = DfsData.FileSysDeviceObject; RsParam.StructKey = (ULONG) pFsdo; RsParam.TypeCode = IO_TYPE_DEVICE; RsParam.ByteCount = sizeof Fsdo; Stat = DsfsReadStruct(&RsParam, (PUCHAR) &Fsdo); if (NT_SUCCESS(Stat)) { MemUsage(RsParam.StructKey, RsParam.ByteCount); printf("FileSysDeviceObject @ %08x:\t", pFsdo); DfsDump(&Fsdo); printf("\n"); } } else MemUsage(DfsData.FileSysDeviceObject, sizeof (DEVICE_OBJECT)); // // Now we look at the volume device objects // for (Link = DfsData.AVdoQueue.Flink; Link != Sentinel; Link = DfsVdo.VdoLinks.Flink) { pDfsVdo = CONTAINING_RECORD( Link, DFS_VOLUME_OBJECT, VdoLinks ); RsParam.StructKey = (ULONG) pDfsVdo; RsParam.TypeCode = IO_TYPE_DEVICE; RsParam.ByteCount = sizeof DfsVdo; if (! NT_SUCCESS( Stat = DsfsReadStruct(&RsParam, (PUCHAR)&DfsVdo))) exit(3); MemUsage(RsParam.StructKey, RsParam.ByteCount); MemUsageStr(DfsVdo.Provider.DeviceName); if (Link == DfsData.AVdoQueue.Flink) Sentinel = DfsVdo.VdoLinks.Blink; if (Vflag) { printf("DfsVdo @ %08x:\t", pDfsVdo); DfsDump(&DfsVdo); printf("\n"); } else { printf("DfsVdo @ %08x:\t", pDfsVdo); Stat = DfsReadAndPrintString(&DfsVdo.Provider.DeviceName); printf("\n"); } } // // Now we look at the Vcbs (logical root device object extensions). // for (Link = DfsData.VcbQueue.Flink; Link != Sentinel; Link = DfsLrdo.Vcb.VcbLinks.Flink) { pDfsLrdo = CONTAINING_RECORD( Link, LOGICAL_ROOT_DEVICE_OBJECT, Vcb.VcbLinks ); RsParam.StructKey = (ULONG) pDfsLrdo; RsParam.TypeCode = IO_TYPE_DEVICE; RsParam.ByteCount = sizeof DfsLrdo; if (! NT_SUCCESS( Stat = DsfsReadStruct(&RsParam, (PUCHAR)&DfsLrdo))) exit(3); MemUsage(RsParam.StructKey, RsParam.ByteCount); MemUsageStr(DfsLrdo.Vcb.LogicalRoot); MemUsageStr(DfsLrdo.Vcb.LogRootPrefix); if (Link == DfsData.VcbQueue.Flink) Sentinel = DfsLrdo.Vcb.VcbLinks.Blink; if (Vflag) { printf("DfsLrdo @ %08x:\t", pDfsLrdo); DfsDump(&DfsLrdo); printf("\n"); } else { printf("DfsLrdo @ %08x:\t", pDfsLrdo); Stat = DfsReadAndPrintString(&DfsLrdo.Vcb.LogicalRoot); if (! NT_SUCCESS(Stat)) exit(3); printf("\n\tPrefix =\t"); Stat = DfsReadAndPrintString(&DfsLrdo.Vcb.LogRootPrefix); if (! NT_SUCCESS(Stat) ) exit(3); printf("\n"); } } } //+------------------------------------------------------------------- // // Function: DumpFcbs, local // // Synopsis: This routine will dump the contents of the FCB hash // table, and all the associated FCBs. // // Arguments: None // // Returns: None // // Requires: DfsData must have previously been loaded into memory. // //-------------------------------------------------------------------- VOID DumpFcbs( void ) { FILE_DFS_READ_STRUCT_PARAM RsParam; struct _FCB_HASH{ FCB_HASH_TABLE FcbHash; LIST_ENTRY FcbHashBuckets2[127]; } FcbHashTab, *pFcbHashTab; FCB Fcb, *pFcb; NTSTATUS Stat; ULONG i; RsParam.StructKey = (ULONG) (pFcbHashTab = (struct _FCB_HASH *)DfsData.FcbHashTable); RsParam.TypeCode = 0; RsParam.ByteCount = sizeof (NODE_TYPE_CODE) + sizeof (NODE_BYTE_SIZE); if (! NT_SUCCESS( Stat = DsfsReadStruct(&RsParam, (PUCHAR) &FcbHashTab))) { printf("Error accessing DfsData.FcbHashTable\n"); exit(4); } RsParam.StructKey = (ULONG) DfsData.FcbHashTable; RsParam.TypeCode = FcbHashTab.FcbHash.NodeTypeCode; RsParam.ByteCount = FcbHashTab.FcbHash.NodeByteSize; if (! NT_SUCCESS( Stat = DsfsReadStruct(&RsParam, (PUCHAR) &FcbHashTab))) { printf("Error accessing DfsData.FcbHashTable\n"); exit(4); } MemUsage(RsParam.StructKey, RsParam.ByteCount); if (Vflag) { printf("\nFcbHashTable @ %08x:\t", DfsData.FcbHashTable); DfsDump(&FcbHashTab); } else { printf("FcbHashTable @ %08x\n", DfsData.FcbHashTable); } // // Now we look at the FCBs. // for (i = 0; i <= FcbHashTab.FcbHash.HashMask; i++) { PLIST_ENTRY ListHead, Link, Sentinel = NULL; ListHead = &FcbHashTab.FcbHash.HashBuckets[i]; if (ListHead->Flink == NULL) // Never initialized continue; if ((PUCHAR) ListHead->Flink == ((PUCHAR)ListHead - (PUCHAR) &FcbHashTab) + (PUCHAR)pFcbHashTab) { printf(" HashBucket[%2d] ==> \n", i); continue; } printf(" HashBucket[%2d] ==> ", i); for (Link = ListHead->Flink; Link != Sentinel; Link = Fcb.HashChain.Flink) { pFcb = CONTAINING_RECORD( Link, FCB, HashChain ); RsParam.StructKey = (ULONG) pFcb; RsParam.TypeCode = DSFS_NTC_FCB; RsParam.ByteCount = sizeof Fcb; if (! NT_SUCCESS( Stat = DsfsReadStruct(&RsParam, (PUCHAR)&Fcb))) { printf("Error accessing Fcb\n"); exit(4); } MemUsage(RsParam.StructKey, RsParam.ByteCount); if (Link == ListHead->Flink) Sentinel = Fcb.HashChain.Blink; if (Vflag) { printf("Fcb @ %08x:\t", pFcb); DfsDump(&Fcb); printf("\n"); } else { printf("%08x ", pFcb); } } printf("\n"); } printf("\n"); }