Source code of Windows XP (NT5)
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

  1. #include "pch.h"
  2. #include "cdfskd.h"
  3. #include "fatkd.h"
  4. #include <ntddcdrm.h>
  5. #include <ntdddisk.h>
  6. #include <ntddscsi.h>
  7. #include "..\..\cdfs\nodetype.h"
  8. #include "..\..\cdfs\cd.h"
  9. #include "..\..\cdfs\cdstruc.h"
  10. #include "..\..\cdfs\cddata.h"
  11. #define WordAlign(Ptr) ( \
  12. ((((ULONG)(Ptr)) + 1) & 0xfffffffe) \
  13. )
  14. STATE CdFcbState[] = {
  15. { FCB_STATE_INITIALIZED, FCB_STATE_INITIALIZED, "Initialised"},
  16. { FCB_STATE_IN_FCB_TABLE, FCB_STATE_IN_FCB_TABLE, "InFcbTable"},
  17. { FCB_STATE_MODE2FORM2_FILE, FCB_STATE_MODE2FORM2_FILE, "Mode2Form2"},
  18. { FCB_STATE_MODE2_FILE, FCB_STATE_MODE2_FILE, "Mode2"},
  19. { FCB_STATE_DA_FILE, FCB_STATE_DA_FILE, "CdDa"},
  20. { 0 }
  21. };
  22. STATE CdIrpContextFlags[] = {
  23. { IRP_CONTEXT_FLAG_ON_STACK, IRP_CONTEXT_FLAG_ON_STACK, "OnStack"},
  24. { IRP_CONTEXT_FLAG_MORE_PROCESSING, IRP_CONTEXT_FLAG_MORE_PROCESSING, "MoreProcessing"},
  25. { IRP_CONTEXT_FLAG_FORCE_POST, IRP_CONTEXT_FLAG_FORCE_POST, "ForcePost"},
  26. { IRP_CONTEXT_FLAG_TOP_LEVEL, IRP_CONTEXT_FLAG_TOP_LEVEL, "TopLevel"},
  27. { IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS, IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS, "TopLevelCdfs"},
  28. { IRP_CONTEXT_FLAG_IN_TEARDOWN, IRP_CONTEXT_FLAG_IN_TEARDOWN, "InTeardown"},
  29. { IRP_CONTEXT_FLAG_ALLOC_IO, IRP_CONTEXT_FLAG_ALLOC_IO, "AllocIo"},
  30. { IRP_CONTEXT_FLAG_WAIT, IRP_CONTEXT_FLAG_WAIT, "Wait"},
  31. { IRP_CONTEXT_FLAG_DISABLE_POPUPS, IRP_CONTEXT_FLAG_DISABLE_POPUPS, "DisablePopups"},
  32. { IRP_CONTEXT_FLAG_IN_FSP, IRP_CONTEXT_FLAG_IN_FSP, "InFsp"},
  33. { IRP_CONTEXT_FLAG_FULL_NAME, IRP_CONTEXT_FLAG_FULL_NAME, "FullName"},
  34. { IRP_CONTEXT_FLAG_TRAIL_BACKSLASH, IRP_CONTEXT_FLAG_TRAIL_BACKSLASH, "TrailingBackSlash"},
  35. { 0 }
  36. };
  37. STATE CdVcbStateFlags[] = {
  38. { VCB_STATE_HSG, VCB_STATE_HSG, "HSG"},
  39. { VCB_STATE_ISO, VCB_STATE_ISO, "ISO"},
  40. { VCB_STATE_JOLIET, VCB_STATE_JOLIET, "Joliet"},
  41. { VCB_STATE_LOCKED, VCB_STATE_LOCKED, "Locked"},
  42. { VCB_STATE_REMOVABLE_MEDIA, VCB_STATE_REMOVABLE_MEDIA, "Removable"},
  43. { VCB_STATE_CDXA, VCB_STATE_CDXA, "XA"},
  44. { VCB_STATE_AUDIO_DISK, VCB_STATE_AUDIO_DISK, "Audio"},
  45. { VCB_STATE_NOTIFY_REMOUNT, VCB_STATE_NOTIFY_REMOUNT, "NotifyRemount"},
  46. { 0 }
  47. };
  48. STATE CdCcbFlags[] = {
  49. { CCB_FLAG_OPEN_BY_ID, CCB_FLAG_OPEN_BY_ID, "OpenById"},
  50. { CCB_FLAG_OPEN_RELATIVE_BY_ID, CCB_FLAG_OPEN_RELATIVE_BY_ID, "OpenRelById"},
  51. { CCB_FLAG_IGNORE_CASE, CCB_FLAG_IGNORE_CASE, "IgnoreCase"},
  52. { CCB_FLAG_OPEN_WITH_VERSION, CCB_FLAG_OPEN_WITH_VERSION, "OpenWithVersion"},
  53. { CCB_FLAG_DISMOUNT_ON_CLOSE, CCB_FLAG_DISMOUNT_ON_CLOSE, "DismountOnClose"},
  54. { CCB_FLAG_ENUM_NAME_EXP_HAS_WILD, CCB_FLAG_ENUM_NAME_EXP_HAS_WILD, "EnumNameHasWild"},
  55. { CCB_FLAG_ENUM_VERSION_EXP_HAS_WILD, CCB_FLAG_ENUM_VERSION_EXP_HAS_WILD, "EnumVersionHasWild"},
  56. { CCB_FLAG_ENUM_MATCH_ALL, CCB_FLAG_ENUM_MATCH_ALL, "EnumMatchAll"},
  57. { CCB_FLAG_ENUM_VERSION_MATCH_ALL, CCB_FLAG_ENUM_VERSION_MATCH_ALL, "EnumVersionMatchAll"},
  58. { CCB_FLAG_ENUM_RETURN_NEXT, CCB_FLAG_ENUM_RETURN_NEXT, "EnumReturnNext"},
  59. { CCB_FLAG_ENUM_INITIALIZED, CCB_FLAG_ENUM_INITIALIZED, "EnumInitialised"},
  60. { CCB_FLAG_ENUM_NOMATCH_CONSTANT_ENTRY, CCB_FLAG_ENUM_NOMATCH_CONSTANT_ENTRY, "NoMatchConstantEntry"},
  61. { 0 }
  62. };
  63. STATE IsoDirentFlags[] = {
  64. { CD_ATTRIBUTE_HIDDEN, CD_ATTRIBUTE_HIDDEN, "Hidden"},
  65. { CD_ATTRIBUTE_DIRECTORY, CD_ATTRIBUTE_DIRECTORY, "Directory"},
  66. { CD_ATTRIBUTE_MULTI, CD_ATTRIBUTE_MULTI, "Multi(MoreDirentsFollow)"},
  67. { CD_ATTRIBUTE_ASSOC, CD_ATTRIBUTE_ASSOC, "Associated"},
  68. { 0 }
  69. };
  70. VOID
  71. CdSummaryFcbDumpRoutine(
  72. IN UINT64 RemoteAddress,
  73. IN LONG Options
  74. )
  75. {
  76. ULONG Offset;
  77. if (Options >= 2) {
  78. DumpCdFcb( RemoteAddress, 0, 0);
  79. }
  80. else {
  81. USHORT Type;
  82. ReadM( &Type, RemoteAddress, sizeof( Type));
  83. if ((Type != CDFS_NTC_FCB_DATA) && (CDFS_NTC_FCB_INDEX != Type) &&
  84. (Type != CDFS_NTC_FCB_PATH_TABLE)
  85. ) {
  86. dprintf( "FCB signature does not match @%I64x", RemoteAddress);
  87. return;
  88. }
  89. dprintf( "%s @ %I64x ", NodeTypeName( TypeCodeInfoIndex( Type)), RemoteAddress);
  90. ROE( GetFieldOffset( "cdfs!FCB", "FileNamePrefix.ExactCaseName.FileName", &Offset));
  91. DumpStr( Offset, RemoteAddress + Offset, "Name: ", FALSE, TRUE);
  92. }
  93. }
  94. DUMP_ROUTINE( DumpCdFcb)
  95. /*++
  96. Routine Description:
  97. Dump a specific fcb.
  98. Arguments:
  99. Address - Gives the address of the fcb to dump
  100. Return Value:
  101. None
  102. --*/
  103. {
  104. USHORT Type;
  105. ULONG FcbState, Flags, Offset, Offsetb;
  106. UINT64 NonP;
  107. ReadM( &Type, Address, sizeof( Type));
  108. dprintf("[ Option flags: 1 = list children, 2 = Dump MCB ]\n\n");
  109. //
  110. // Having established that this looks like an fcb, let's dump the
  111. // interesting parts.
  112. //
  113. ROE( GetFieldValue( Address, InfoNode->TypeName, "FcbState", FcbState));
  114. dprintf("FcbState : ");
  115. PrintState( CdFcbState, FcbState );
  116. ROE( GetFieldValue( Address, InfoNode->TypeName, "Header.Flags", Flags));
  117. dprintf("Header.Flags : ");
  118. PrintState( HeaderFlags, Flags );
  119. ROE( GetFieldValue( Address, InfoNode->TypeName, "Header.Flags2", Flags));
  120. dprintf("Header.Flags2: ");
  121. PrintState( HeaderFlags2, Flags );
  122. dprintf("\n");
  123. Dt( InfoNode->TypeName, Address, 0, 0, NULL);
  124. //
  125. // Nonpaged portion
  126. //
  127. ROE( GetFieldValue( Address, InfoNode->TypeName, "FcbNonpaged", NonP));
  128. if (0 != NonP) {
  129. dprintf("\n");
  130. Dt( "cdfs!FCB_NONPAGED", Address, 0, 0, NULL);
  131. }
  132. //
  133. // Dump all children
  134. //
  135. if (( Options & 1) && (CDFS_NTC_FCB_INDEX == Type)) {
  136. dprintf("\nChild Fcb list\n\n");
  137. ROE( GetFieldOffset( InfoNode->TypeName, "FcbQueue", &Offset));
  138. ROE( GetFieldOffset( InfoNode->TypeName, "FcbLinks", &Offsetb));
  139. DumpList( Address + Offset,
  140. CdSummaryFcbDumpRoutine,
  141. Offsetb,
  142. FALSE,
  143. 0 );
  144. }
  145. if (Options & 2) {
  146. ROE( GetFieldOffset( InfoNode->TypeName, "Mcb", &Offset));
  147. DumpCdMcb( Address + Offset, 1, 0);
  148. }
  149. dprintf( "\n" );
  150. }
  151. DUMP_ROUTINE( DumpCdCcb)
  152. {
  153. ULONG Flags;
  154. ROE( GetFieldValue( Address, InfoNode->TypeName, "Flags", Flags));
  155. dprintf( "Ccb.Flags: ");
  156. PrintState( CdCcbFlags, Flags);
  157. dprintf( "\n");
  158. Dt( InfoNode->TypeName, Address, Options, 0, NULL);
  159. }
  160. DUMP_ROUTINE( DumpCdIrpContext )
  161. {
  162. ULONG Flags;
  163. ROE( GetFieldValue( Address, InfoNode->TypeName, "Flags", Flags));
  164. dprintf( "Flags: ");
  165. PrintState( CdIrpContextFlags, Flags);
  166. dprintf( "\n");
  167. Dt( InfoNode->TypeName, Address, Options, 0, NULL);
  168. }
  169. DUMP_ROUTINE( DumpCdMcb)
  170. {
  171. UINT64 Entries;
  172. ULONG Count, Size;
  173. dprintf( "\nCD_MCB @ %I64x\n\n", Address );
  174. Dt( "cdfs!CD_MCB", Address, 0, 0, NULL);
  175. ROE( GetFieldValue( Address, "cdfs!CD_MCB", "McbArray", Entries));
  176. ROE( GetFieldValue( Address, "cdfs!CD_MCB", "CurrentEntryCount", Count));
  177. Size = GetTypeSize( "cdfs!CD_MCB_ENTRY");
  178. dprintf("\n");
  179. if ((1 & Options) && (0 != Count)) {
  180. LONGLONG DO,BC,FO,DBB,TBB;
  181. while (Count) {
  182. ROE( GetFieldValue( Entries, "cdfs!CD_MCB_ENTRY", "DiskOffset", DO));
  183. ROE( GetFieldValue( Entries, "cdfs!CD_MCB_ENTRY", "ByteCount", BC));
  184. ROE( GetFieldValue( Entries, "cdfs!CD_MCB_ENTRY", "FileOffset", FO));
  185. ROE( GetFieldValue( Entries, "cdfs!CD_MCB_ENTRY", "DataBlockByteCount", DBB));
  186. ROE( GetFieldValue( Entries, "cdfs!CD_MCB_ENTRY", "TotalBlockByteCount", TBB));
  187. dprintf(" DO %016I64x BC %016I64x FO %016I64x DB %016I64x TB %016I64x",
  188. DO, BC, FO, DBB, TBB);
  189. Count--;
  190. Entries += Size;
  191. }
  192. }
  193. dprintf( "\n" );
  194. }
  195. DUMP_ROUTINE( DumpCdVcb)
  196. {
  197. ULONG Flags;
  198. ROE( GetFieldValue( Address, InfoNode->TypeName, "VcbState", Flags));
  199. dprintf( "Flags: ");
  200. PrintState( CdVcbStateFlags, Flags);
  201. dprintf( "\n");
  202. Dt( InfoNode->TypeName, Address, Options, 0, NULL);
  203. }
  204. VOID
  205. DumpCdRawDirent(
  206. IN ULONG64 Address,
  207. IN LONG Options,
  208. ULONG Processor,
  209. HANDLE hCurrentThread
  210. )
  211. {
  212. RAW_DIRENT Raw;
  213. PRAW_DIRENT pRaw;
  214. UCHAR Buffer[512];
  215. PUCHAR pBuffer;
  216. ULONG Result;
  217. UNREFERENCED_PARAMETER( Processor );
  218. UNREFERENCED_PARAMETER( hCurrentThread );
  219. if (Options == 0) { Options = 1; }
  220. while (Options--) {
  221. RM( Address, Raw, pRaw, PRAW_DIRENT, Result );
  222. dprintf("\nDumping ISO9660 dirent structure @ 0x%X\n", Address);
  223. dprintf("\nFileLoc: 0x%8x DataLen: 0x%8x\n", *(PULONG)&Raw.FileLoc, *(PULONG)&Raw.DataLen);
  224. dprintf("ISO Flags: ");
  225. PrintState( IsoDirentFlags, (ULONG)Raw.FlagsISO);
  226. DUMP8_WITH_OFFSET(RAW_DIRENT, Raw, DirLen, "DirLen");
  227. DUMP8_WITH_OFFSET(RAW_DIRENT, Raw, XarLen, "XarLen");
  228. DUMP8_WITH_OFFSET(RAW_DIRENT, Raw, FlagsHSG, "FlagsHSG");
  229. DUMP8_WITH_OFFSET(RAW_DIRENT, Raw, FlagsISO, "FlagsISO");
  230. DUMP8_WITH_OFFSET(RAW_DIRENT, Raw, IntLeaveSkip, "IntLeaveSkip");
  231. DUMP8_WITH_OFFSET(RAW_DIRENT, Raw, IntLeaveSize, "IntLeaveSize");
  232. DUMP8_WITH_OFFSET(RAW_DIRENT, Raw, FileIdLen, "FileIdLen");
  233. dprintf("\nSU area size = 0x%X, addr = 0x%X\n", Raw.DirLen - ((FIELD_OFFSET( RAW_DIRENT, FileId ) + Raw.FileIdLen) + 1),
  234. Address + WordAlign( FIELD_OFFSET( RAW_DIRENT, FileId ) + Raw.FileIdLen ));
  235. if (Raw.FileIdLen) {
  236. RMSS( Address, FIELD_OFFSET( RAW_DIRENT, FileId) + Raw.FileIdLen, Buffer, pBuffer, PUCHAR, Result );
  237. pRaw = (PRAW_DIRENT)Buffer;
  238. if ((1 == Raw.FileIdLen) && ((0 == pRaw->FileId[0]) || (1 == pRaw->FileId[0]))) {
  239. if (0 == pRaw->FileId[0]) {
  240. dprintf( "\n\nFileID: <Self>\n\n");
  241. } else {
  242. dprintf( "\n\nFileId: <Parent>\n\n");
  243. }
  244. }
  245. else {
  246. pRaw->FileId[Raw.FileIdLen] = '\0';
  247. dprintf("\n\nFileID: '%s'\n\n", pRaw->FileId);
  248. }
  249. }
  250. Address += Raw.DirLen;
  251. }
  252. }
  253. DUMP_ROUTINE( DumpCdVdo)
  254. {
  255. USHORT Ntc;
  256. ULONG Offset;
  257. ReadM( &Ntc, Address, sizeof( Ntc));
  258. if (CDFS_NTC_VCB == Ntc) {
  259. //
  260. // Looks like we've been given a VCB pointer. Work back to the containing vdo.
  261. //
  262. dprintf("Backtracking to containing VDO from VCB...\n");
  263. ROE( GetFieldOffset( "cdfs!VOLUME_DEVICE_OBJECT", "Vcb", &Offset));
  264. Address -= Offset;
  265. }
  266. dprintf( "\nCDFS Volume device object @ %I64x\n\n", Address );
  267. Dt( "cdfs!VOLUME_DEVICE_OBJECT", Address, Options, 0, NULL);
  268. }
  269. DECLARE_API( cdvdo )
  270. {
  271. UNREFERENCED_PARAMETER( dwCurrentPc );
  272. UNREFERENCED_PARAMETER( hCurrentProcess );
  273. ParseAndDump( (PCHAR) args, (STRUCT_DUMP_ROUTINE) DumpCdVdo, dwProcessor, hCurrentThread );
  274. }
  275. DECLARE_API( cdmcb )
  276. {
  277. UNREFERENCED_PARAMETER( dwCurrentPc );
  278. UNREFERENCED_PARAMETER( hCurrentProcess );
  279. ParseAndDump( (PCHAR) args, (STRUCT_DUMP_ROUTINE) DumpCdMcb, dwProcessor, hCurrentThread );
  280. }
  281. DECLARE_API( cdrawdirent )
  282. {
  283. UNREFERENCED_PARAMETER( dwCurrentPc );
  284. UNREFERENCED_PARAMETER( hCurrentProcess );
  285. ParseAndDump( (PCHAR) args, (STRUCT_DUMP_ROUTINE) DumpCdRawDirent, dwProcessor, hCurrentThread );
  286. }