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.

398 lines
8.6 KiB

  1. /*++
  2. Copyright (c) 1999-2001 Microsoft Corporation
  3. Module Name:
  4. irp.c
  5. Abstract:
  6. Implements the irplog command.
  7. Author:
  8. Keith Moore (keithmo) 10-Aug-1999
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. //
  15. // Private constants.
  16. //
  17. //
  18. // Private globals.
  19. //
  20. PSTR g_pIrpActions[] =
  21. {
  22. "INCOMING",
  23. "ALLOCATE",
  24. "FREE ",
  25. "CALL ",
  26. "COMPLETE"
  27. };
  28. C_ASSERT( DIM(g_pIrpActions) == IRP_ACTION_COUNT );
  29. //
  30. // Public functions.
  31. //
  32. DECLARE_API( irplog )
  33. /*++
  34. Routine Description:
  35. Dumps the IRP trace log.
  36. Arguments:
  37. None.
  38. Return Value:
  39. None.
  40. --*/
  41. {
  42. ULONG_PTR address = 0;
  43. ULONGLONG context = 0;
  44. ULONGLONG flags = 0;
  45. ULONG_PTR entryAddress;
  46. ULONG_PTR logPointer;
  47. ULONG result;
  48. TRACE_LOG logHeader;
  49. LONGLONG numEntries;
  50. IRP_TRACE_LOG_ENTRY logEntry;
  51. PSTR pFileName;
  52. PSTR pAction;
  53. LONGLONG index;
  54. LONGLONG StartingIndex = 0;
  55. ULONG_PTR offset1;
  56. ULONG_PTR offset2;
  57. CHAR filePath[MAX_PATH];
  58. CHAR symbol1[MAX_SYMBOL_LENGTH];
  59. CHAR symbol2[MAX_SYMBOL_LENGTH];
  60. CHAR invalidAction[sizeof("2047")];
  61. ULONG64 context64 = 0;
  62. ULONG64 flags64 = 0;
  63. ULONG64 StartingIndex64 = 0;
  64. SNAPSHOT_EXTENSION_DATA();
  65. //
  66. // Snag the optional context, flags, and StartingIndex from the command line.
  67. //
  68. if (GetExpressionEx(args, &context64, &args))
  69. if (GetExpressionEx(args, &flags64, &args))
  70. GetExpressionEx(args, &StartingIndex64, &args);
  71. context = (ULONG_PTR) context64;
  72. flags = (ULONG_PTR) flags64;
  73. StartingIndex = (ULONG_PTR) StartingIndex64;
  74. //
  75. // Find the log.
  76. //
  77. address = GetExpression( "&http!g_pIrpTraceLog" );
  78. if (address == 0)
  79. {
  80. dprintf( "irplog: cannot find http!g_pIrpTraceLog\n" );
  81. return;
  82. }
  83. //
  84. // Read the pointer.
  85. //
  86. if (!ReadMemory(
  87. address,
  88. &logPointer,
  89. sizeof(logPointer),
  90. &result
  91. ))
  92. {
  93. dprintf(
  94. "irplog: cannot read PTRACE_LOG @ %p\n",
  95. address
  96. );
  97. return;
  98. }
  99. //
  100. // Read the log header.
  101. //
  102. if (!ReadMemory(
  103. logPointer,
  104. &logHeader,
  105. sizeof(logHeader),
  106. &result
  107. ))
  108. {
  109. dprintf(
  110. "ref: cannot read TRACE_LOG @ %p\n",
  111. logPointer
  112. );
  113. return;
  114. }
  115. dprintf(
  116. "ref: log @ %p\n"
  117. " Signature = %08lx '%c%c%c%c' (%s)\n"
  118. " TypeSignature = %08lx '%c%c%c%c'\n"
  119. " LogSize = %lu\n"
  120. " NextEntry = %I64d\n"
  121. " EntrySize = %lu\n"
  122. " LogBuffer = %p\n",
  123. address,
  124. logHeader.Signature,
  125. DECODE_SIGNATURE(logHeader.Signature),
  126. logHeader.Signature == TRACE_LOG_SIGNATURE
  127. ? "OK"
  128. : logHeader.Signature == TRACE_LOG_SIGNATURE_X
  129. ? "FREED"
  130. : "INVALID",
  131. logHeader.TypeSignature,
  132. DECODE_SIGNATURE(logHeader.TypeSignature),
  133. logHeader.LogSize,
  134. logHeader.NextEntry,
  135. logHeader.EntrySize,
  136. logHeader.pLogBuffer
  137. );
  138. if (logHeader.pLogBuffer > ( (PUCHAR)address + sizeof(logHeader) ))
  139. {
  140. dprintf(
  141. " ExtraData @ %p\n",
  142. address + sizeof(logHeader)
  143. );
  144. }
  145. if (logHeader.Signature != TRACE_LOG_SIGNATURE &&
  146. logHeader.Signature != TRACE_LOG_SIGNATURE_X)
  147. {
  148. dprintf(
  149. "irplog: log @ %p has invalid signature %08lx:\n",
  150. address,
  151. logHeader.Signature
  152. );
  153. return;
  154. }
  155. if (logHeader.EntrySize != sizeof(logEntry)
  156. || logHeader.TypeSignature != IRP_TRACE_LOG_SIGNATURE)
  157. {
  158. dprintf(
  159. "irplog: log @ %p is not an IRP trace log\n",
  160. address
  161. );
  162. return;
  163. }
  164. if (logHeader.NextEntry == -1)
  165. {
  166. dprintf(
  167. "irplog: empty log @ %p\n",
  168. address
  169. );
  170. return;
  171. }
  172. //
  173. // Calculate the log size to dump.
  174. //
  175. if (logHeader.NextEntry < logHeader.LogSize)
  176. {
  177. numEntries = logHeader.NextEntry + 1;
  178. index = 0;
  179. }
  180. else
  181. {
  182. numEntries = logHeader.LogSize;
  183. index = (logHeader.NextEntry + 1) % logHeader.LogSize;
  184. }
  185. entryAddress = (ULONG_PTR)logHeader.pLogBuffer +
  186. (ULONG_PTR)( index * sizeof(logEntry) );
  187. if (entryAddress >=
  188. ( (ULONG_PTR)logHeader.pLogBuffer + (ULONG_PTR)( numEntries * sizeof(logEntry) ) ) )
  189. {
  190. dprintf(
  191. "irplog: log @ %p has invalid data\n",
  192. address
  193. );
  194. return;
  195. }
  196. if ((flags & 4) && (StartingIndex!=0) && (StartingIndex<numEntries))
  197. {
  198. index = StartingIndex;
  199. entryAddress += (ULONG_PTR)(sizeof(logEntry)*index);
  200. numEntries -= StartingIndex;
  201. }
  202. //
  203. // Dump the log.
  204. //
  205. for (;
  206. numEntries > 0 ;
  207. index++,
  208. numEntries--,
  209. entryAddress += sizeof(logEntry))
  210. {
  211. if (CheckControlC())
  212. {
  213. break;
  214. }
  215. if (index >= logHeader.LogSize)
  216. {
  217. index = 0;
  218. entryAddress = (ULONG_PTR)logHeader.pLogBuffer;
  219. }
  220. if (!ReadMemory(
  221. entryAddress,
  222. &logEntry,
  223. sizeof(logEntry),
  224. NULL
  225. ))
  226. {
  227. dprintf(
  228. "irplog: cannot read memory @ %p\n",
  229. entryAddress
  230. );
  231. return;
  232. }
  233. if (context == 0 ||
  234. context == (ULONG_PTR)logEntry.pIrp)
  235. {
  236. if (ReadMemory(
  237. (ULONG_PTR)logEntry.pFileName,
  238. filePath,
  239. sizeof(filePath),
  240. &result
  241. ))
  242. {
  243. pFileName = strrchr( filePath, '\\' );
  244. if (pFileName != NULL)
  245. {
  246. pFileName++;
  247. }
  248. else
  249. {
  250. pFileName = filePath;
  251. }
  252. }
  253. else
  254. {
  255. sprintf(
  256. filePath,
  257. "%p",
  258. logEntry.pFileName
  259. );
  260. pFileName = filePath;
  261. }
  262. if (logEntry.Action < IRP_ACTION_COUNT)
  263. {
  264. pAction = g_pIrpActions[logEntry.Action];
  265. }
  266. else
  267. {
  268. sprintf( invalidAction, "%lu", (ULONG)logEntry.Action );
  269. pAction = invalidAction;
  270. }
  271. dprintf(
  272. "Entry=%lu CPU=%lu IRP=%p Act=%s Src=%s:%lu\n",
  273. index,
  274. (ULONG)logEntry.Processor,
  275. logEntry.pIrp,
  276. pAction,
  277. pFileName,
  278. logEntry.LineNumber
  279. );
  280. if (flags & 1)
  281. {
  282. GetSymbol(
  283. logEntry.pCaller,
  284. symbol1,
  285. &offset1
  286. );
  287. GetSymbol(
  288. logEntry.pCallersCaller,
  289. symbol2,
  290. &offset2
  291. );
  292. dprintf(
  293. " Process=%p Thread=%p\n"
  294. " Caller1=%p (%s+0x%p)\n"
  295. " Caller2=%p (%s+0x%p)\n",
  296. logEntry.pProcess,
  297. logEntry.pThread,
  298. logEntry.pCaller,
  299. symbol1,
  300. offset1,
  301. logEntry.pCallersCaller,
  302. symbol2,
  303. offset2
  304. );
  305. }
  306. #if ENABLE_IRP_CAPTURE
  307. if (flags & 2)
  308. {
  309. CHAR temp[sizeof("1234567812345678 f")];
  310. sprintf(
  311. temp,
  312. "%p",
  313. REMOTE_OFFSET(
  314. entryAddress,
  315. IRP_TRACE_LOG_ENTRY,
  316. CapturedIrp
  317. )
  318. );
  319. if (flags & 4)
  320. {
  321. strcat( temp, " f" );
  322. }
  323. CallExtensionRoutine( "irp", temp );
  324. }
  325. #endif
  326. }
  327. }
  328. } // irplog