You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
408 lines
12 KiB
408 lines
12 KiB
#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 );
|
|
}
|
|
|