822 lines
21 KiB
C
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");
|
||
|
}
|
||
|
|
||
|
|