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.

493 lines
9.1 KiB

  1. /*++
  2. Copyright (c) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. filt.c
  5. Abstract:
  6. Extensions for dumping filter information.
  7. Author:
  8. Michael Courage (mcourage) 6-Apr-2000
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. //
  15. // Private globals.
  16. //
  17. PSTR g_pFiltqActions[] =
  18. {
  19. "QUEUE_IRP ",
  20. "DEQUEUE_IRP ",
  21. "START_WRITE ",
  22. "FINISH_WRITE ",
  23. "BLOCK_WRITE ",
  24. "WAKE_WRITE ",
  25. "BLOCK_PARTIAL_WRITE",
  26. "WAKE_PARTIAL_WRITE "
  27. };
  28. C_ASSERT( DIM(g_pFiltqActions) == FILTQ_ACTION_COUNT );
  29. //
  30. // Public functions.
  31. //
  32. DECLARE_API( filter )
  33. /*++
  34. Routine Description:
  35. Dumps a filter channel.
  36. Arguments:
  37. None.
  38. Return Value:
  39. None.
  40. --*/
  41. {
  42. ULONG_PTR address = 0;
  43. ULONG result;
  44. UL_FILTER_CHANNEL channel;
  45. SNAPSHOT_EXTENSION_DATA();
  46. //
  47. // Snag the address from the command line.
  48. //
  49. address = GetExpression( args );
  50. if (address == 0)
  51. {
  52. address = GetExpression( "&http!g_pFilterChannel" );
  53. }
  54. if (address != 0)
  55. {
  56. if (!ReadMemory(
  57. address,
  58. &address,
  59. sizeof(address),
  60. NULL
  61. ))
  62. {
  63. dprintf(
  64. "filter: Cannot read memory @ %p\n",
  65. address
  66. );
  67. return;
  68. }
  69. }
  70. if (address == 0)
  71. {
  72. PrintUsage( "filter" );
  73. return;
  74. }
  75. //
  76. // Read the filter.
  77. //
  78. if (!ReadMemory(
  79. address,
  80. &channel,
  81. sizeof(channel),
  82. &result
  83. ))
  84. {
  85. dprintf(
  86. "filter: cannot read UL_FILTER_CHANNEL @ %p\n",
  87. address
  88. );
  89. return;
  90. }
  91. DumpFilterChannel(
  92. "",
  93. "filter: ",
  94. address,
  95. &channel,
  96. 0
  97. );
  98. } // filter
  99. DECLARE_API( fproc )
  100. /*++
  101. Routine Description:
  102. Dumps a filter process.
  103. Arguments:
  104. None.
  105. Return Value:
  106. None.
  107. --*/
  108. {
  109. ULONG_PTR address = 0;
  110. ULONG result;
  111. UL_FILTER_PROCESS process;
  112. SNAPSHOT_EXTENSION_DATA();
  113. //
  114. // Snag the address from the command line.
  115. //
  116. address = GetExpression( args );
  117. if (address == 0)
  118. {
  119. PrintUsage( "fproc" );
  120. return;
  121. }
  122. //
  123. // Read the filter proc.
  124. //
  125. if (!ReadMemory(
  126. address,
  127. &process,
  128. sizeof(process),
  129. &result
  130. ))
  131. {
  132. dprintf(
  133. "fproc: cannot read UL_FILTER_PROCESS @ %p\n",
  134. address
  135. );
  136. return;
  137. }
  138. DumpFilterProc(
  139. "",
  140. "fproc: ",
  141. address,
  142. &process,
  143. 0
  144. );
  145. } // fproc
  146. DECLARE_API( fqlog )
  147. /*++
  148. Routine Description:
  149. Dumps the filter queue trace log.
  150. Arguments:
  151. None.
  152. Return Value:
  153. None.
  154. --*/
  155. {
  156. ULONG_PTR address = 0;
  157. ULONG_PTR context = 0;
  158. ULONG_PTR flags = 0;
  159. ULONG_PTR entryAddress;
  160. ULONG_PTR logPointer;
  161. ULONG result;
  162. TRACE_LOG logHeader;
  163. LONGLONG numEntries;
  164. FILTQ_TRACE_LOG_ENTRY logEntry;
  165. PSTR pAction;
  166. LONGLONG index;
  167. ULONG offset1;
  168. ULONG offset2;
  169. CHAR invalidAction[sizeof("2047")];
  170. PSTR fileName;
  171. CHAR filePath[MAX_PATH];
  172. SNAPSHOT_EXTENSION_DATA();
  173. //
  174. // Snag the optional context from the command line.
  175. //
  176. context = GetExpression( args );
  177. //
  178. // Find the log.
  179. //
  180. address = GetExpression( "&http!g_pFilterQueueTraceLog" );
  181. if (address == 0)
  182. {
  183. dprintf( "fqlog: cannot find http!g_pFilterQueueTraceLog\n" );
  184. return;
  185. }
  186. //
  187. // Read the pointer.
  188. //
  189. if (!ReadMemory(
  190. address,
  191. &logPointer,
  192. sizeof(logPointer),
  193. &result
  194. ))
  195. {
  196. dprintf(
  197. "fqlog: cannot read PTRACE_LOG @ %p\n",
  198. address
  199. );
  200. return;
  201. }
  202. //
  203. // Read the log header.
  204. //
  205. if (!ReadMemory(
  206. logPointer,
  207. &logHeader,
  208. sizeof(logHeader),
  209. &result
  210. ))
  211. {
  212. dprintf(
  213. "fqlog: cannot read TRACE_LOG @ %p\n",
  214. logPointer
  215. );
  216. return;
  217. }
  218. dprintf(
  219. "fqlog: log @ %p\n"
  220. " Signature = %08lx '%c%c%c%c' (%s)\n"
  221. " TypeSignature = %08lx '%c%c%c%c'\n"
  222. " LogSize = %lu\n"
  223. " NextEntry = %I64d\n"
  224. " EntrySize = %lu\n"
  225. " LogBuffer = %p\n",
  226. address,
  227. logHeader.Signature,
  228. DECODE_SIGNATURE(logHeader.Signature),
  229. logHeader.Signature == TRACE_LOG_SIGNATURE
  230. ? "OK"
  231. : logHeader.Signature == TRACE_LOG_SIGNATURE_X
  232. ? "FREED"
  233. : "INVALID",
  234. logHeader.TypeSignature,
  235. DECODE_SIGNATURE(logHeader.TypeSignature),
  236. logHeader.LogSize,
  237. logHeader.NextEntry,
  238. logHeader.EntrySize,
  239. logHeader.pLogBuffer
  240. );
  241. if (logHeader.pLogBuffer > ( (PUCHAR)address + sizeof(logHeader) ))
  242. {
  243. dprintf(
  244. " ExtraData @ %p\n",
  245. address + sizeof(logHeader)
  246. );
  247. }
  248. if (logHeader.Signature != TRACE_LOG_SIGNATURE &&
  249. logHeader.Signature != TRACE_LOG_SIGNATURE_X)
  250. {
  251. dprintf(
  252. "fqlog: log @ %p has invalid signature %08lx:\n",
  253. address,
  254. logHeader.Signature
  255. );
  256. return;
  257. }
  258. if (logHeader.EntrySize != sizeof(logEntry)
  259. || logHeader.TypeSignature != FILTQ_TRACE_LOG_SIGNATURE)
  260. {
  261. dprintf(
  262. "fqlog: log @ %p is not a filter queue trace log\n",
  263. address
  264. );
  265. return;
  266. }
  267. if (logHeader.NextEntry == -1)
  268. {
  269. dprintf(
  270. "fqlog: empty log @ %p\n",
  271. address
  272. );
  273. return;
  274. }
  275. //
  276. // Calculate the log size to dump.
  277. //
  278. if (logHeader.NextEntry < logHeader.LogSize)
  279. {
  280. numEntries = logHeader.NextEntry + 1;
  281. index = 0;
  282. }
  283. else
  284. {
  285. numEntries = logHeader.LogSize;
  286. index = (logHeader.NextEntry + 1) % logHeader.LogSize;
  287. }
  288. entryAddress = (ULONG_PTR)logHeader.pLogBuffer +
  289. (ULONG_PTR)( index * sizeof(logEntry) );
  290. if (entryAddress >=
  291. ( (ULONG_PTR)logHeader.pLogBuffer + (ULONG_PTR)( numEntries * sizeof(logEntry) ) ) )
  292. {
  293. dprintf(
  294. "fqlog: log @ %p has invalid data\n",
  295. address
  296. );
  297. return;
  298. }
  299. //
  300. // Dump the log.
  301. //
  302. for (;
  303. numEntries > 0 ;
  304. index++,
  305. numEntries--,
  306. entryAddress += sizeof(logEntry))
  307. {
  308. if (CheckControlC())
  309. {
  310. break;
  311. }
  312. if (index >= logHeader.LogSize)
  313. {
  314. index = 0;
  315. entryAddress = (ULONG_PTR)logHeader.pLogBuffer;
  316. }
  317. if (!ReadMemory(
  318. entryAddress,
  319. &logEntry,
  320. sizeof(logEntry),
  321. NULL
  322. ))
  323. {
  324. dprintf(
  325. "fqlog: cannot read memory @ %p\n",
  326. entryAddress
  327. );
  328. return;
  329. }
  330. if (context == 0 ||
  331. context == (ULONG_PTR)logEntry.pConnection)
  332. {
  333. //
  334. // Grab the file name.
  335. //
  336. if (ReadMemory(
  337. (ULONG_PTR)logEntry.pFileName,
  338. filePath,
  339. sizeof(filePath),
  340. &result
  341. ))
  342. {
  343. fileName = strrchr( filePath, '\\' );
  344. if (fileName != NULL)
  345. {
  346. fileName++;
  347. }
  348. else
  349. {
  350. fileName = filePath;
  351. }
  352. }
  353. else
  354. {
  355. sprintf(
  356. filePath,
  357. "%p",
  358. logEntry.pFileName
  359. );
  360. fileName = filePath;
  361. }
  362. //
  363. // And the action name.
  364. //
  365. if (logEntry.Action < FILTQ_ACTION_COUNT)
  366. {
  367. pAction = g_pFiltqActions[logEntry.Action];
  368. }
  369. else
  370. {
  371. sprintf( invalidAction, "%lu", (ULONG)logEntry.Action );
  372. pAction = invalidAction;
  373. }
  374. dprintf(
  375. "CPU=%lu Conn=%p Act=%s ReadIrps=%lu Writers=%lu, %s:%u\n",
  376. logEntry.Processor,
  377. logEntry.pConnection,
  378. pAction,
  379. logEntry.ReadIrps,
  380. logEntry.Writers,
  381. fileName,
  382. logEntry.LineNumber
  383. );
  384. }
  385. }
  386. } // fqlog