#include "pch.h" #include "cdfskd.h" #include "fatkd.h" #include #include #include #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: \n\n"); } else { dprintf( "\n\nFileId: \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 ); }