windows-nt/Source/XPSP1/NT/base/fs/dfs/util/dfsdump/dfsdump.c
2020-09-26 16:20:57 +08:00

822 lines
21 KiB
C

//+-------------------------------------------------------------------------
//
// 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 <ntos.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <tdi.h>
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <lmcons.h>
#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; i<DfsData.Pkt.EntryCount; i++)
{
pPktEntry = CONTAINING_RECORD(Link, DFS_PKT_ENTRY, Link);
RsParam.StructKey = (ULONG) pPktEntry;
RsParam.TypeCode = DSFS_NTC_PKT_ENTRY;
RsParam.ByteCount = sizeof(DFS_PKT_ENTRY);
Stat = DsfsReadStruct(&RsParam, (PUCHAR) &PktEntry);
if (!NT_SUCCESS(Stat))
{
exit(3);
}
MemUsage(RsParam.StructKey, RsParam.ByteCount);
MemUsageStr(PktEntry.Id.Prefix);
if (Vflag)
{
printf("\nPktEntry @ %08x:\t",pPktEntry);
DfsDump(&PktEntry);
printf("\n");
}
else
{
//
// Place any other fields from PktEntry that need to
// be dumped out here.
//
printf("\tPktEntry @ %08x:\t",pPktEntry);
printf("EntryId.Prefix: ");
Stat = DfsReadAndPrintString(&(PktEntry.Id.Prefix));
printf("\n");
}
//
// We now need to deal with the local service
// in the Pkt entry.
//
if (PktEntry.LocalService)
{
RsParam.StructKey = (ULONG) PktEntry.LocalService;
RsParam.TypeCode = 0;
RsParam.ByteCount = sizeof(DFS_SERVICE);
Stat = DsfsReadStruct(&RsParam, (PUCHAR) &Service);
if (!NT_SUCCESS(Stat))
{
exit(3);
}
MemUsage(RsParam.StructKey, RsParam.ByteCount);
MemUsageStr(Service.Name);
MemUsageStr(Service.Address);
if (Vflag)
{
printf("\nLOCAL_SERVICE:\n");
DfsDumpDfsService(&Service);
}
else
{
printf("\t\tLocalService: ");
DfsReadAndPrintString((PUNICODE_STRING)&(Service.Address));
printf("\n");
}
}
//
// We now need to dump the service list in the EntryInfo
// structure in the PktEntry above.
//
for (j=0; j<PktEntry.Info.ServiceCount; j++)
{
RsParam.StructKey = (ULONG) (PktEntry.Info.ServiceList
+ j);
RsParam.TypeCode = 0;
RsParam.ByteCount = sizeof(DFS_SERVICE);
Stat = DsfsReadStruct(&RsParam, (PUCHAR) &Service);
if (!NT_SUCCESS(Stat))
{
exit(3);
}
MemUsage(RsParam.StructKey, RsParam.ByteCount);
MemUsageStr(Service.Name);
MemUsageStr(Service.Address);
if (PktEntry.Info.ServiceList + j == PktEntry.ActiveService)
{
pszMsg = " (active)";
}
else
{
pszMsg = "";
}
if (Vflag)
{
printf("\nSERVICE# %d%s:\n", j, pszMsg);
DfsDumpDfsService(&Service);
//
// Now we need to dump the MACHINE_ADDR structure as well.
//
RsParam.StructKey = (ULONG) (Service.pMachEntry);
RsParam.TypeCode = 0;
RsParam.ByteCount = sizeof(DFS_MACHINE_ENTRY);
Stat = DsfsReadStruct(&RsParam, (PUCHAR) &MachEntry);
if (!NT_SUCCESS(Stat))
{
printf("Failed to read pDFS_MACHINE_ENTRY address %08lx\n", Stat);
exit(3);
}
RsParam.StructKey = (ULONG) MachEntry.pMachine;
RsParam.TypeCode = 0;
RsParam.ByteCount = sizeof(DS_MACHINE);
Stat = DsfsReadStruct(&RsParam, (PUCHAR) pMachine);
if (!NT_SUCCESS(Stat))
{
exit(3);
}
if (pMachine->cTransports != 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; k<pMachine->cTransports; 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] ==> <empty>\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");
}