windows-nt/Source/XPSP1/NT/base/fs/fastfat/fskd/cdfs.c
2020-09-26 16:20:57 +08:00

409 lines
12 KiB
C

#include "pch.h"
#include "cdfskd.h"
#include "fatkd.h"
#include <ntddcdrm.h>
#include <ntdddisk.h>
#include <ntddscsi.h>
#include "..\..\cdfs\nodetype.h"
#include "..\..\cdfs\cd.h"
#include "..\..\cdfs\cdstruc.h"
#include "..\..\cdfs\cddata.h"
#define WordAlign(Ptr) ( \
((((ULONG)(Ptr)) + 1) & 0xfffffffe) \
)
STATE CdFcbState[] = {
{ FCB_STATE_INITIALIZED, FCB_STATE_INITIALIZED, "Initialised"},
{ FCB_STATE_IN_FCB_TABLE, FCB_STATE_IN_FCB_TABLE, "InFcbTable"},
{ FCB_STATE_MODE2FORM2_FILE, FCB_STATE_MODE2FORM2_FILE, "Mode2Form2"},
{ FCB_STATE_MODE2_FILE, FCB_STATE_MODE2_FILE, "Mode2"},
{ FCB_STATE_DA_FILE, FCB_STATE_DA_FILE, "CdDa"},
{ 0 }
};
STATE CdIrpContextFlags[] = {
{ IRP_CONTEXT_FLAG_ON_STACK, IRP_CONTEXT_FLAG_ON_STACK, "OnStack"},
{ IRP_CONTEXT_FLAG_MORE_PROCESSING, IRP_CONTEXT_FLAG_MORE_PROCESSING, "MoreProcessing"},
{ IRP_CONTEXT_FLAG_FORCE_POST, IRP_CONTEXT_FLAG_FORCE_POST, "ForcePost"},
{ IRP_CONTEXT_FLAG_TOP_LEVEL, IRP_CONTEXT_FLAG_TOP_LEVEL, "TopLevel"},
{ IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS, IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS, "TopLevelCdfs"},
{ IRP_CONTEXT_FLAG_IN_TEARDOWN, IRP_CONTEXT_FLAG_IN_TEARDOWN, "InTeardown"},
{ IRP_CONTEXT_FLAG_ALLOC_IO, IRP_CONTEXT_FLAG_ALLOC_IO, "AllocIo"},
{ IRP_CONTEXT_FLAG_WAIT, IRP_CONTEXT_FLAG_WAIT, "Wait"},
{ IRP_CONTEXT_FLAG_DISABLE_POPUPS, IRP_CONTEXT_FLAG_DISABLE_POPUPS, "DisablePopups"},
{ IRP_CONTEXT_FLAG_IN_FSP, IRP_CONTEXT_FLAG_IN_FSP, "InFsp"},
{ IRP_CONTEXT_FLAG_FULL_NAME, IRP_CONTEXT_FLAG_FULL_NAME, "FullName"},
{ IRP_CONTEXT_FLAG_TRAIL_BACKSLASH, IRP_CONTEXT_FLAG_TRAIL_BACKSLASH, "TrailingBackSlash"},
{ 0 }
};
STATE CdVcbStateFlags[] = {
{ VCB_STATE_HSG, VCB_STATE_HSG, "HSG"},
{ VCB_STATE_ISO, VCB_STATE_ISO, "ISO"},
{ VCB_STATE_JOLIET, VCB_STATE_JOLIET, "Joliet"},
{ VCB_STATE_LOCKED, VCB_STATE_LOCKED, "Locked"},
{ VCB_STATE_REMOVABLE_MEDIA, VCB_STATE_REMOVABLE_MEDIA, "Removable"},
{ VCB_STATE_CDXA, VCB_STATE_CDXA, "XA"},
{ VCB_STATE_AUDIO_DISK, VCB_STATE_AUDIO_DISK, "Audio"},
{ VCB_STATE_NOTIFY_REMOUNT, VCB_STATE_NOTIFY_REMOUNT, "NotifyRemount"},
{ 0 }
};
STATE CdCcbFlags[] = {
{ CCB_FLAG_OPEN_BY_ID, CCB_FLAG_OPEN_BY_ID, "OpenById"},
{ CCB_FLAG_OPEN_RELATIVE_BY_ID, CCB_FLAG_OPEN_RELATIVE_BY_ID, "OpenRelById"},
{ CCB_FLAG_IGNORE_CASE, CCB_FLAG_IGNORE_CASE, "IgnoreCase"},
{ CCB_FLAG_OPEN_WITH_VERSION, CCB_FLAG_OPEN_WITH_VERSION, "OpenWithVersion"},
{ CCB_FLAG_DISMOUNT_ON_CLOSE, CCB_FLAG_DISMOUNT_ON_CLOSE, "DismountOnClose"},
{ CCB_FLAG_ENUM_NAME_EXP_HAS_WILD, CCB_FLAG_ENUM_NAME_EXP_HAS_WILD, "EnumNameHasWild"},
{ CCB_FLAG_ENUM_VERSION_EXP_HAS_WILD, CCB_FLAG_ENUM_VERSION_EXP_HAS_WILD, "EnumVersionHasWild"},
{ CCB_FLAG_ENUM_MATCH_ALL, CCB_FLAG_ENUM_MATCH_ALL, "EnumMatchAll"},
{ CCB_FLAG_ENUM_VERSION_MATCH_ALL, CCB_FLAG_ENUM_VERSION_MATCH_ALL, "EnumVersionMatchAll"},
{ CCB_FLAG_ENUM_RETURN_NEXT, CCB_FLAG_ENUM_RETURN_NEXT, "EnumReturnNext"},
{ CCB_FLAG_ENUM_INITIALIZED, CCB_FLAG_ENUM_INITIALIZED, "EnumInitialised"},
{ CCB_FLAG_ENUM_NOMATCH_CONSTANT_ENTRY, CCB_FLAG_ENUM_NOMATCH_CONSTANT_ENTRY, "NoMatchConstantEntry"},
{ 0 }
};
STATE IsoDirentFlags[] = {
{ CD_ATTRIBUTE_HIDDEN, CD_ATTRIBUTE_HIDDEN, "Hidden"},
{ CD_ATTRIBUTE_DIRECTORY, CD_ATTRIBUTE_DIRECTORY, "Directory"},
{ CD_ATTRIBUTE_MULTI, CD_ATTRIBUTE_MULTI, "Multi(MoreDirentsFollow)"},
{ CD_ATTRIBUTE_ASSOC, CD_ATTRIBUTE_ASSOC, "Associated"},
{ 0 }
};
VOID
CdSummaryFcbDumpRoutine(
IN UINT64 RemoteAddress,
IN LONG Options
)
{
ULONG Offset;
if (Options >= 2) {
DumpCdFcb( RemoteAddress, 0, 0);
}
else {
USHORT Type;
ReadM( &Type, RemoteAddress, sizeof( Type));
if ((Type != CDFS_NTC_FCB_DATA) && (CDFS_NTC_FCB_INDEX != Type) &&
(Type != CDFS_NTC_FCB_PATH_TABLE)
) {
dprintf( "FCB signature does not match @%I64x", RemoteAddress);
return;
}
dprintf( "%s @ %I64x ", NodeTypeName( TypeCodeInfoIndex( Type)), RemoteAddress);
ROE( GetFieldOffset( "cdfs!FCB", "FileNamePrefix.ExactCaseName.FileName", &Offset));
DumpStr( Offset, RemoteAddress + Offset, "Name: ", FALSE, TRUE);
}
}
DUMP_ROUTINE( DumpCdFcb)
/*++
Routine Description:
Dump a specific fcb.
Arguments:
Address - Gives the address of the fcb to dump
Return Value:
None
--*/
{
USHORT Type;
ULONG FcbState, Flags, Offset, Offsetb;
UINT64 NonP;
ReadM( &Type, Address, sizeof( Type));
dprintf("[ Option flags: 1 = list children, 2 = Dump MCB ]\n\n");
//
// Having established that this looks like an fcb, let's dump the
// interesting parts.
//
ROE( GetFieldValue( Address, InfoNode->TypeName, "FcbState", FcbState));
dprintf("FcbState : ");
PrintState( CdFcbState, FcbState );
ROE( GetFieldValue( Address, InfoNode->TypeName, "Header.Flags", Flags));
dprintf("Header.Flags : ");
PrintState( HeaderFlags, Flags );
ROE( GetFieldValue( Address, InfoNode->TypeName, "Header.Flags2", Flags));
dprintf("Header.Flags2: ");
PrintState( HeaderFlags2, Flags );
dprintf("\n");
Dt( InfoNode->TypeName, Address, 0, 0, NULL);
//
// Nonpaged portion
//
ROE( GetFieldValue( Address, InfoNode->TypeName, "FcbNonpaged", NonP));
if (0 != NonP) {
dprintf("\n");
Dt( "cdfs!FCB_NONPAGED", Address, 0, 0, NULL);
}
//
// Dump all children
//
if (( Options & 1) && (CDFS_NTC_FCB_INDEX == Type)) {
dprintf("\nChild Fcb list\n\n");
ROE( GetFieldOffset( InfoNode->TypeName, "FcbQueue", &Offset));
ROE( GetFieldOffset( InfoNode->TypeName, "FcbLinks", &Offsetb));
DumpList( Address + Offset,
CdSummaryFcbDumpRoutine,
Offsetb,
FALSE,
0 );
}
if (Options & 2) {
ROE( GetFieldOffset( InfoNode->TypeName, "Mcb", &Offset));
DumpCdMcb( Address + Offset, 1, 0);
}
dprintf( "\n" );
}
DUMP_ROUTINE( DumpCdCcb)
{
ULONG Flags;
ROE( GetFieldValue( Address, InfoNode->TypeName, "Flags", Flags));
dprintf( "Ccb.Flags: ");
PrintState( CdCcbFlags, Flags);
dprintf( "\n");
Dt( InfoNode->TypeName, Address, Options, 0, NULL);
}
DUMP_ROUTINE( DumpCdIrpContext )
{
ULONG Flags;
ROE( GetFieldValue( Address, InfoNode->TypeName, "Flags", Flags));
dprintf( "Flags: ");
PrintState( CdIrpContextFlags, Flags);
dprintf( "\n");
Dt( InfoNode->TypeName, Address, Options, 0, NULL);
}
DUMP_ROUTINE( DumpCdMcb)
{
UINT64 Entries;
ULONG Count, Size;
dprintf( "\nCD_MCB @ %I64x\n\n", Address );
Dt( "cdfs!CD_MCB", Address, 0, 0, NULL);
ROE( GetFieldValue( Address, "cdfs!CD_MCB", "McbArray", Entries));
ROE( GetFieldValue( Address, "cdfs!CD_MCB", "CurrentEntryCount", Count));
Size = GetTypeSize( "cdfs!CD_MCB_ENTRY");
dprintf("\n");
if ((1 & Options) && (0 != Count)) {
LONGLONG DO,BC,FO,DBB,TBB;
while (Count) {
ROE( GetFieldValue( Entries, "cdfs!CD_MCB_ENTRY", "DiskOffset", DO));
ROE( GetFieldValue( Entries, "cdfs!CD_MCB_ENTRY", "ByteCount", BC));
ROE( GetFieldValue( Entries, "cdfs!CD_MCB_ENTRY", "FileOffset", FO));
ROE( GetFieldValue( Entries, "cdfs!CD_MCB_ENTRY", "DataBlockByteCount", DBB));
ROE( GetFieldValue( Entries, "cdfs!CD_MCB_ENTRY", "TotalBlockByteCount", TBB));
dprintf(" DO %016I64x BC %016I64x FO %016I64x DB %016I64x TB %016I64x",
DO, BC, FO, DBB, TBB);
Count--;
Entries += Size;
}
}
dprintf( "\n" );
}
DUMP_ROUTINE( DumpCdVcb)
{
ULONG Flags;
ROE( GetFieldValue( Address, InfoNode->TypeName, "VcbState", Flags));
dprintf( "Flags: ");
PrintState( CdVcbStateFlags, Flags);
dprintf( "\n");
Dt( InfoNode->TypeName, Address, Options, 0, NULL);
}
VOID
DumpCdRawDirent(
IN ULONG64 Address,
IN LONG Options,
ULONG Processor,
HANDLE hCurrentThread
)
{
RAW_DIRENT Raw;
PRAW_DIRENT pRaw;
UCHAR Buffer[512];
PUCHAR pBuffer;
ULONG Result;
UNREFERENCED_PARAMETER( Processor );
UNREFERENCED_PARAMETER( hCurrentThread );
if (Options == 0) { Options = 1; }
while (Options--) {
RM( Address, Raw, pRaw, PRAW_DIRENT, Result );
dprintf("\nDumping ISO9660 dirent structure @ 0x%X\n", Address);
dprintf("\nFileLoc: 0x%8x DataLen: 0x%8x\n", *(PULONG)&Raw.FileLoc, *(PULONG)&Raw.DataLen);
dprintf("ISO Flags: ");
PrintState( IsoDirentFlags, (ULONG)Raw.FlagsISO);
DUMP8_WITH_OFFSET(RAW_DIRENT, Raw, DirLen, "DirLen");
DUMP8_WITH_OFFSET(RAW_DIRENT, Raw, XarLen, "XarLen");
DUMP8_WITH_OFFSET(RAW_DIRENT, Raw, FlagsHSG, "FlagsHSG");
DUMP8_WITH_OFFSET(RAW_DIRENT, Raw, FlagsISO, "FlagsISO");
DUMP8_WITH_OFFSET(RAW_DIRENT, Raw, IntLeaveSkip, "IntLeaveSkip");
DUMP8_WITH_OFFSET(RAW_DIRENT, Raw, IntLeaveSize, "IntLeaveSize");
DUMP8_WITH_OFFSET(RAW_DIRENT, Raw, FileIdLen, "FileIdLen");
dprintf("\nSU area size = 0x%X, addr = 0x%X\n", Raw.DirLen - ((FIELD_OFFSET( RAW_DIRENT, FileId ) + Raw.FileIdLen) + 1),
Address + WordAlign( FIELD_OFFSET( RAW_DIRENT, FileId ) + Raw.FileIdLen ));
if (Raw.FileIdLen) {
RMSS( Address, FIELD_OFFSET( RAW_DIRENT, FileId) + Raw.FileIdLen, Buffer, pBuffer, PUCHAR, Result );
pRaw = (PRAW_DIRENT)Buffer;
if ((1 == Raw.FileIdLen) && ((0 == pRaw->FileId[0]) || (1 == pRaw->FileId[0]))) {
if (0 == pRaw->FileId[0]) {
dprintf( "\n\nFileID: <Self>\n\n");
} else {
dprintf( "\n\nFileId: <Parent>\n\n");
}
}
else {
pRaw->FileId[Raw.FileIdLen] = '\0';
dprintf("\n\nFileID: '%s'\n\n", pRaw->FileId);
}
}
Address += Raw.DirLen;
}
}
DUMP_ROUTINE( DumpCdVdo)
{
USHORT Ntc;
ULONG Offset;
ReadM( &Ntc, Address, sizeof( Ntc));
if (CDFS_NTC_VCB == Ntc) {
//
// Looks like we've been given a VCB pointer. Work back to the containing vdo.
//
dprintf("Backtracking to containing VDO from VCB...\n");
ROE( GetFieldOffset( "cdfs!VOLUME_DEVICE_OBJECT", "Vcb", &Offset));
Address -= Offset;
}
dprintf( "\nCDFS Volume device object @ %I64x\n\n", Address );
Dt( "cdfs!VOLUME_DEVICE_OBJECT", Address, Options, 0, NULL);
}
DECLARE_API( cdvdo )
{
UNREFERENCED_PARAMETER( dwCurrentPc );
UNREFERENCED_PARAMETER( hCurrentProcess );
ParseAndDump( (PCHAR) args, (STRUCT_DUMP_ROUTINE) DumpCdVdo, dwProcessor, hCurrentThread );
}
DECLARE_API( cdmcb )
{
UNREFERENCED_PARAMETER( dwCurrentPc );
UNREFERENCED_PARAMETER( hCurrentProcess );
ParseAndDump( (PCHAR) args, (STRUCT_DUMP_ROUTINE) DumpCdMcb, dwProcessor, hCurrentThread );
}
DECLARE_API( cdrawdirent )
{
UNREFERENCED_PARAMETER( dwCurrentPc );
UNREFERENCED_PARAMETER( hCurrentProcess );
ParseAndDump( (PCHAR) args, (STRUCT_DUMP_ROUTINE) DumpCdRawDirent, dwProcessor, hCurrentThread );
}