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.

1059 lines
30 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. irp.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Environment:
  8. User Mode.
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. //#include "irpverif.h"
  13. #pragma hdrstop
  14. typedef
  15. BOOLEAN
  16. (WINAPI *IRP_FILTER_ROUTINE)(
  17. ULONG64 Irp,
  18. PVOID FilterContext
  19. );
  20. typedef struct _IRP_FILTER {
  21. IRP_FILTER_ROUTINE FilterRoutine;
  22. PVOID FilterContext;
  23. } IRP_FILTER, *PIRP_FILTER;
  24. typedef struct _SEARCH_CONTEXT {
  25. ULONG FirstTime;
  26. IRP_FILTER Filter;
  27. } SEARCH_CONTEXT, *PSEARCH_CONTEXT;
  28. #define TAG 0
  29. #define NONPAGED_ALLOC 1
  30. #define NONPAGED_FREE 2
  31. #define PAGED_ALLOC 3
  32. #define PAGED_FREE 4
  33. #define NONPAGED_USED 5
  34. #define PAGED_USED 6
  35. VOID
  36. DumpIrp(
  37. ULONG64 IrpToDump,
  38. ULONG DumpLevel
  39. );
  40. BOOLEAN
  41. IrpFilterUserEvent(
  42. ULONG64 Irp,
  43. PVOID FilterContext
  44. );
  45. BOOLEAN
  46. IrpFilterDevice(
  47. ULONG64 Irp,
  48. PVOID FilterContext
  49. );
  50. BOOLEAN
  51. IrpFilterFileObject(
  52. ULONG64 Irp,
  53. PVOID FilterContext
  54. );
  55. BOOLEAN
  56. IrpFilterThread(
  57. ULONG64 Irp,
  58. PVOID FilterContext
  59. );
  60. BOOLEAN
  61. IrpFilterMdlProcess(
  62. ULONG64 Irp,
  63. PVOID FilterContext
  64. );
  65. BOOLEAN
  66. IrpFilterArg(
  67. ULONG64 Irp,
  68. PVOID FilterContext
  69. );
  70. DECLARE_API( irp )
  71. /*++
  72. Routine Description:
  73. Dumps the specified Irp
  74. Arguments:
  75. args - Address
  76. Return Value:
  77. None
  78. --*/
  79. {
  80. ULONG64 irpToDump;
  81. ULONG dumpLevel = 0 ;
  82. char irpExprBuf[256] ;
  83. char dumpLevelBuf[256] ;
  84. if (!*args) {
  85. irpToDump = EXPRLastDump;
  86. } else {
  87. //
  88. // !Irp IrpAddress DumpLevel
  89. // where IrpAddress can be an expression
  90. // and DumpLevel is a decimal level of any non-decimal string for 1
  91. irpExprBuf[0] = '\0' ;
  92. dumpLevelBuf[0] = '\0' ;
  93. if (!sscanf(args, "%s %s", irpExprBuf, dumpLevelBuf)) {
  94. irpExprBuf[0] = '\0' ;
  95. dumpLevelBuf[0] = '\0' ;
  96. }
  97. if (irpExprBuf) {
  98. if (IsHexNumber(irpExprBuf)) {
  99. irpToDump = GetExpression( irpExprBuf ) ;
  100. } else {
  101. irpToDump = GetExpression( irpExprBuf ) ;
  102. if (irpToDump==0) {
  103. dprintf("An error occured trying to evaluate the expression\n") ;
  104. return E_INVALIDARG ;
  105. }
  106. }
  107. if (IsDecNumber(dumpLevelBuf)) {
  108. if (!sscanf(dumpLevelBuf, "%d", &dumpLevel) ) {
  109. dumpLevel = 0;
  110. }
  111. } else if (dumpLevelBuf[0]) {
  112. dumpLevel = 1 ;
  113. } else {
  114. dumpLevel = 0 ;
  115. }
  116. }
  117. }
  118. if (irpToDump == 0) {
  119. dprintf("Free build - use !irpfind to scan memory for any active IRPs\n") ;
  120. } else {
  121. DumpIrp(irpToDump, (ULONG) dumpLevel);
  122. }
  123. return S_OK;
  124. }
  125. DECLARE_API( irpzone )
  126. /*++
  127. Routine Description:
  128. Dumps both the small irp zone and the large irp zone. Only irps that
  129. are currently allocated are dumped. "args" controls the type of dump.
  130. If "args" is present then the Irp is sent to the DumpIrp routine to be
  131. disected. Otherwise, only the irp, its thread and the driver holding the
  132. irp (i.e. the driver of the last stack) is printed.
  133. Arguments:
  134. args - a string pointer. If anything is in the string it indicates full
  135. information (i.e. call DumpIrp).
  136. Return Value:
  137. None.
  138. --*/
  139. {
  140. ULONG listAddress;
  141. BOOLEAN fullOutput = FALSE;
  142. dprintf("irpzone is no longer supported. Use irpfind to search " \
  143. "nonpaged pool for active Irps\n");
  144. return S_OK;
  145. }
  146. VOID
  147. DumpIrp(
  148. ULONG64 IrpToDump,
  149. ULONG DumpLevel
  150. )
  151. /*++
  152. Routine Description:
  153. This routine dumps an Irp. It does not check to see that the address
  154. supplied actually locates an Irp. This is done to allow for dumping
  155. Irps post mortem, or after they have been freed or completed.
  156. Arguments:
  157. IrpToDump - the address of the irp.
  158. DumpLevel - 0 Summary
  159. 1 Extended information
  160. 2 Debug tracking info iff available
  161. Return Value:
  162. None
  163. --*/
  164. {
  165. PCHAR buffer;
  166. ULONG64 irpStackAddress;
  167. ULONG64 result64=0;
  168. ULONG result;
  169. // IRP irp;
  170. CCHAR irpStackIndex;
  171. LARGE_INTEGER runTime ;
  172. #if DBG
  173. // PIOV_REQUEST_PACKET irpTrackingData ;
  174. #endif
  175. BOOLEAN delayed ;
  176. ULONG Type=0, StackCount=0, CurrentLocation=0, Flags=0, PendingReturned=0;
  177. ULONG Io_Status=0, Cancel=0, CancelIrql=0, ApcEnvironment=0, Overlay_Alloc_High=0;
  178. ULONG Overlay_Alloc_Low=0, RequestorMode=0, IrpSize;
  179. ULONG64 Tail_Overlay_CurrStack=0, MdlAddress=0, Associated_MasterIrp=0;
  180. ULONG64 ThreadListEntry_Flink=0, ThreadListEntry_Blink=0, Io_Information=0;
  181. ULONG64 CancelRoutine=0, UserIosb=0, UserEvent=0, UserBuffer=0, Overlay_Async_UserApcRoutine=0;
  182. ULONG64 Overlay_Async_UserApcContext=0, Tail_Overlay_Thread=0, Tail_Overlay_AuxBuffer=0;
  183. ULONG64 Tail_Overlay_List_Flink=0, Tail_Overlay_List_Blink=0, Tail_Overlay_OrigFile=0;
  184. ULONG64 Tail_CompletionKey=0;
  185. BYTE Tail_Apc[100]={0};
  186. UCHAR IrpType[]= "nt!_IRP";
  187. if ( (GetFieldValue(IrpToDump, IrpType, "Type", Type)) ) {
  188. dprintf("%08p: Could not read Irp\n", IrpToDump);
  189. return;
  190. }
  191. GetFieldValue(IrpToDump, IrpType, "StackCount", StackCount);
  192. GetFieldValue(IrpToDump, IrpType, "CurrentLocation", CurrentLocation);
  193. GetFieldValue(IrpToDump, IrpType, "Tail.Overlay.CurrentStackLocation", Tail_Overlay_CurrStack);
  194. GetFieldValue(IrpToDump, IrpType, "MdlAddress", MdlAddress);
  195. GetFieldValue(IrpToDump, IrpType, "AssociatedIrp.MasterIrp", Associated_MasterIrp);
  196. GetFieldValue(IrpToDump, IrpType, "Flags", Flags);
  197. GetFieldValue(IrpToDump, IrpType, "RequestorMode", RequestorMode);
  198. GetFieldValue(IrpToDump, IrpType, "PendingReturned", PendingReturned);
  199. GetFieldValue(IrpToDump, IrpType, "ThreadListEntry.Flink", ThreadListEntry_Flink);
  200. GetFieldValue(IrpToDump, IrpType, "ThreadListEntry.Blink", ThreadListEntry_Blink);
  201. GetFieldValue(IrpToDump, IrpType, "IoStatus.Status", Io_Status);
  202. GetFieldValue(IrpToDump, IrpType, "IoStatus.Information", Io_Information);
  203. GetFieldValue(IrpToDump, IrpType, "Cancel", Cancel);
  204. GetFieldValue(IrpToDump, IrpType, "CancelIrql", CancelIrql);
  205. GetFieldValue(IrpToDump, IrpType, "CancelRoutine", CancelRoutine);
  206. GetFieldValue(IrpToDump, IrpType, "ApcEnvironment", ApcEnvironment);
  207. GetFieldValue(IrpToDump, IrpType, "UserIosb", UserIosb);
  208. GetFieldValue(IrpToDump, IrpType, "UserEvent", UserEvent);
  209. GetFieldValue(IrpToDump, IrpType, "UserBuffer", UserBuffer);
  210. GetFieldValue(IrpToDump, IrpType, "Overlay.AsynchronousParameters.UserApcRoutine", Overlay_Async_UserApcRoutine);
  211. GetFieldValue(IrpToDump, IrpType, "Overlay.AsynchronousParameters.UserApcContext", Overlay_Async_UserApcContext);
  212. GetFieldValue(IrpToDump, IrpType, "Overlay.AllocationSize.High", Overlay_Alloc_High);
  213. GetFieldValue(IrpToDump, IrpType, "Overlay.AllocationSize.Low", Overlay_Alloc_Low);
  214. GetFieldValue(IrpToDump, IrpType, "Tail.Overlay.Thread", Tail_Overlay_Thread);
  215. GetFieldValue(IrpToDump, IrpType, "Tail.Overlay.AuxiliaryBuffer", Tail_Overlay_AuxBuffer);
  216. GetFieldValue(IrpToDump, IrpType, "Tail.Overlay.ListEntry.Flink", Tail_Overlay_List_Flink);
  217. GetFieldValue(IrpToDump, IrpType, "Tail.Overlay.ListEntry.Blink", Tail_Overlay_List_Blink);
  218. GetFieldValue(IrpToDump, IrpType, "Tail.Overlay.OriginalFileObject", Tail_Overlay_OrigFile);
  219. GetFieldValue(IrpToDump, IrpType, "Tail.Apc", Tail_Apc);
  220. GetFieldValue(IrpToDump, IrpType, "Tail.CompletionKey", Tail_CompletionKey);
  221. IrpSize = GetTypeSize("nt!_IRP");
  222. if (Type != IO_TYPE_IRP) {
  223. dprintf("IRP signature does not match, probably not an IRP\n");
  224. return;
  225. }
  226. dprintf("Irp is active with %d stacks %d is current (= %#08p)\n",
  227. StackCount,
  228. CurrentLocation,
  229. Tail_Overlay_CurrStack);
  230. if ((MdlAddress != 0) && (Type == IO_TYPE_IRP)) {
  231. dprintf(" Mdl = %08p ", MdlAddress);
  232. } else {
  233. dprintf(" No Mdl ");
  234. }
  235. if (Associated_MasterIrp != 0) {
  236. dprintf("%s = %08p ",
  237. (Flags & IRP_ASSOCIATED_IRP) ? "Associated Irp" :
  238. (Flags & IRP_DEALLOCATE_BUFFER) ? "System buffer" :
  239. "Irp count",
  240. Associated_MasterIrp);
  241. }
  242. dprintf("Thread %08p: ", Tail_Overlay_Thread);
  243. if (StackCount > 30) {
  244. dprintf("Too many Irp stacks to be believed (>30)!!\n");
  245. return;
  246. } else {
  247. if (CurrentLocation > StackCount) {
  248. dprintf("Irp is completed. ");
  249. } else {
  250. dprintf("Irp stack trace. ");
  251. }
  252. }
  253. if (PendingReturned) {
  254. dprintf("Pending has been returned\n");
  255. } else {
  256. dprintf("\n");
  257. }
  258. if (DumpLevel>0) {
  259. dprintf("Flags = %08lx\n", Flags);
  260. dprintf("ThreadListEntry.Flink = %08p\n", ThreadListEntry_Flink);
  261. dprintf("ThreadListEntry.Blink = %08p\n", ThreadListEntry_Blink);
  262. dprintf("IoStatus.Status = %08lx\n", Io_Status);
  263. dprintf("IoStatus.Information = %08p\n", Io_Information);
  264. dprintf("RequestorMode = %08lx\n", RequestorMode);
  265. dprintf("Cancel = %02lx\n", Cancel);
  266. dprintf("CancelIrql = %lx\n", CancelIrql);
  267. dprintf("ApcEnvironment = %02lx\n", ApcEnvironment);
  268. dprintf("UserIosb = %08p\n", UserIosb);
  269. dprintf("UserEvent = %08p\n", UserEvent);
  270. dprintf("Overlay.AsynchronousParameters.UserApcRoutine = %08p\n", Overlay_Async_UserApcRoutine);
  271. dprintf("Overlay.AsynchronousParameters.UserApcContext = %08p\n", Overlay_Async_UserApcContext);
  272. dprintf(
  273. "Overlay.AllocationSize = %08lx - %08lx\n",
  274. Overlay_Alloc_High,
  275. Overlay_Alloc_Low);
  276. dprintf("CancelRoutine = %08p\n", CancelRoutine);
  277. dprintf("UserBuffer = %08p\n", UserBuffer);
  278. dprintf("&Tail.Overlay.DeviceQueueEntry = %08p\n", 0);// &Tail_Overlay_DeviceQueueEntry);
  279. dprintf("Tail.Overlay.Thread = %08p\n", Tail_Overlay_Thread);
  280. dprintf("Tail.Overlay.AuxiliaryBuffer = %08p\n", Tail_Overlay_AuxBuffer);
  281. dprintf("Tail.Overlay.ListEntry.Flink = %08p\n", Tail_Overlay_List_Flink);
  282. dprintf("Tail.Overlay.ListEntry.Blink = %08p\n", Tail_Overlay_List_Blink);
  283. dprintf("Tail.Overlay.CurrentStackLocation = %08p\n", Tail_Overlay_CurrStack);
  284. dprintf("Tail.Overlay.OriginalFileObject = %08p\n", Tail_Overlay_OrigFile);
  285. dprintf("Tail.Apc = %08lx\n", *((PULONG) &Tail_Apc));
  286. dprintf("Tail.CompletionKey = %08p\n", Tail_CompletionKey);
  287. }
  288. irpStackAddress = (ULONG64) IrpToDump + GetTypeSize("nt!_IRP");
  289. buffer = LocalAlloc(LPTR, 256);
  290. if (buffer == NULL) {
  291. dprintf("Can't allocate 256 bytes\n");
  292. return;
  293. }
  294. dprintf(" cmd flg cl Device File Completion-Context\n");
  295. for (irpStackIndex = 1; (ULONG) irpStackIndex <= StackCount; irpStackIndex++) {
  296. ULONG MajorFunction=0, MinorFunction=0, Flags=0, Control=0, irpStackSize;
  297. ULONG64 DeviceObject=0, FileObject=0, CompletionRoutine=0, Context=0;
  298. ULONG64 Others_Argument1=0, Others_Argument2=0, Others_Argument3=0, Others_Argument4=0;
  299. UCHAR IOStack[] = "nt!_IO_STACK_LOCATION";
  300. if ( GetFieldValue(irpStackAddress, IOStack, "MajorFunction", MajorFunction)) {
  301. dprintf("%p: Could not read IrpStack\n", irpStackAddress);
  302. goto exit;
  303. }
  304. irpStackSize = GetTypeSize(IOStack);
  305. GetFieldValue(irpStackAddress, IOStack, "MinorFunction", MinorFunction);
  306. GetFieldValue(irpStackAddress, IOStack, "Flags", Flags);
  307. GetFieldValue(irpStackAddress, IOStack, "DeviceObject", DeviceObject);
  308. GetFieldValue(irpStackAddress, IOStack, "FileObject", FileObject);
  309. GetFieldValue(irpStackAddress, IOStack, "CompletionRoutine", CompletionRoutine);
  310. GetFieldValue(irpStackAddress, IOStack, "Context", Context);
  311. GetFieldValue(irpStackAddress, IOStack, "Control", Control);
  312. GetFieldValue(irpStackAddress, IOStack, "Parameters.Others.Argument1",Others_Argument1);
  313. GetFieldValue(irpStackAddress, IOStack, "Parameters.Others.Argument2",Others_Argument2);
  314. GetFieldValue(irpStackAddress, IOStack, "Parameters.Others.Argument3",Others_Argument3);
  315. GetFieldValue(irpStackAddress, IOStack, "Parameters.Others.Argument4",Others_Argument4);
  316. dprintf("%c[%3x,%2x] %2x %2x %08p %08p %08p-%08p %s %s %s %s\n",
  317. (ULONG) irpStackIndex == CurrentLocation ? '>' : ' ',
  318. MajorFunction,
  319. MinorFunction,
  320. Flags,
  321. Control,
  322. DeviceObject,
  323. FileObject,
  324. CompletionRoutine,
  325. Context,
  326. (Control & SL_INVOKE_ON_SUCCESS) ? "Success" : "",
  327. (Control & SL_INVOKE_ON_ERROR) ? "Error" : "",
  328. (Control & SL_INVOKE_ON_CANCEL) ? "Cancel" : "",
  329. (Control & SL_PENDING_RETURNED) ? "pending" : "");
  330. if (DeviceObject != 0) {
  331. dprintf("\t ");
  332. DumpDevice(DeviceObject, 0, FALSE);
  333. }
  334. if (CompletionRoutine != 0) {
  335. GetSymbol(CompletionRoutine, buffer, &result64);
  336. dprintf("\t%s\n", buffer);
  337. } else {
  338. dprintf("\n");
  339. }
  340. dprintf("\t\t\tArgs: %08p %08p %08p %08p\n",
  341. Others_Argument1,
  342. Others_Argument2,
  343. Others_Argument3,
  344. Others_Argument4);
  345. irpStackAddress += irpStackSize;
  346. if (CheckControlC()) {
  347. goto exit;
  348. }
  349. }
  350. if (DumpLevel>=2) {
  351. dprintf("Extra information not available.\n") ;
  352. }
  353. exit:
  354. LocalFree(buffer);
  355. }
  356. //+---------------------------------------------------------------------------
  357. //
  358. // Function: CheckForIrp
  359. //
  360. // Synopsis: Matches pool chunk against an irp
  361. //
  362. // Arguments: [Tag] --
  363. // [Filter] --
  364. // [Flags] -- 0 nonpaged pool 1 paged pool 2 special pool 4 dump irp
  365. // [PoolTrackTable] --
  366. // [PoolHeader] --
  367. // [BlockSize] --
  368. // [Data] --
  369. //
  370. // Returns:
  371. //
  372. // History: 7-28-1999 benl Created
  373. //
  374. // Notes:
  375. //
  376. //----------------------------------------------------------------------------
  377. BOOLEAN WINAPI CheckForIrp(
  378. PCHAR Tag,
  379. PCHAR Filter,
  380. ULONG Flags,
  381. ULONG64 PoolHeader,
  382. ULONG BlockSize,
  383. ULONG64 Data,
  384. PVOID Context
  385. )
  386. {
  387. ULONG64 Irp = Data;
  388. ULONG Result;
  389. ULONG64 irpSp;
  390. // MDL Mdl;
  391. PSEARCH_CONTEXT SearchContext = (PSEARCH_CONTEXT)Context;
  392. ULONG PoolType, SizeOfIRP;
  393. // dprintf("Call Hdr %p, Data %p \n", PoolHeader, Data);
  394. if (PoolHeader) {
  395. if (GetFieldValue(PoolHeader, "nt!_POOL_HEADER", "PoolType", PoolType)) {
  396. dprintf("Unable to read nt!_POOL_HEADER type.\n");
  397. }
  398. }
  399. if (((PoolHeader == 0) ||
  400. (Flags & 0x2) ||
  401. (PoolType != 0)) &&
  402. (CheckSingleFilter (Tag, Filter))) {
  403. ULONG Type=0, CurrentLocation, StackCount, MajorFunction, MinorFunction;
  404. ULONG64 Thread, DeviceObject, MdlAddress;
  405. if (!GetFieldValue(Irp, "nt!_IRP", "Type", Type)) {
  406. if (Type == IO_TYPE_IRP) {
  407. SizeOfIRP = GetTypeSize("nt!_IRP");
  408. if (Flags & 0x4) {
  409. if (SearchContext->FirstTime) {
  410. dprintf(" Irp [ Thread ] irpStack: (Mj,Mn) DevObj [Driver]\n");
  411. SearchContext->FirstTime = FALSE;
  412. }
  413. dprintf("%08p: ", Data);
  414. DumpIrp(Data, 0);
  415. dprintf("\n");
  416. } else {
  417. if ((SearchContext->Filter.FilterRoutine == NULL) ||
  418. (SearchContext->Filter.FilterRoutine(Irp, SearchContext->Filter.FilterContext))) {
  419. if (SearchContext->FirstTime) {
  420. dprintf(" Irp [ Thread ] irpStack: (Mj,Mn) DevObj [Driver]\n");
  421. SearchContext->FirstTime = FALSE;
  422. }
  423. GetFieldValue(Irp, "nt!_IRP", "CurrentLocation", CurrentLocation);
  424. GetFieldValue(Irp, "nt!_IRP", "StackCount", StackCount);
  425. GetFieldValue(Irp, "nt!_IRP", "MdlAddress", MdlAddress);
  426. GetFieldValue(Irp, "nt!_IRP", "Tail.Overlay.Thread",
  427. Thread);
  428. irpSp = Irp + SizeOfIRP +
  429. (CurrentLocation - 1)*GetTypeSize("nt!_IO_STACK_LOCATION");
  430. dprintf("%08p [%08p] ", Data, Thread);
  431. if (CurrentLocation > StackCount) {
  432. dprintf("Irp is complete (CurrentLocation "
  433. "%d > StackCount %d)",
  434. CurrentLocation,
  435. StackCount);
  436. } else {
  437. GetFieldValue(irpSp, "nt!_IO_STACK_LOCATION", "MajorFunction", MajorFunction);
  438. GetFieldValue(irpSp, "nt!_IO_STACK_LOCATION", "MinorFunction", MinorFunction);
  439. GetFieldValue(irpSp, "nt!_IO_STACK_LOCATION", "DeviceObject", DeviceObject);
  440. dprintf("irpStack: (%2x,%2x)",
  441. MajorFunction,
  442. MinorFunction);
  443. dprintf(" %08p [", DeviceObject);
  444. DumpDevice(DeviceObject, 0, FALSE);
  445. dprintf("]");
  446. }
  447. if (MdlAddress) {
  448. ULONG64 Process;
  449. if (!GetFieldValue(MdlAddress,
  450. "nt!_MDL",
  451. "Process",
  452. Process)) {
  453. dprintf( " 0x%p", Process );
  454. }
  455. }
  456. dprintf("\n");
  457. }
  458. }
  459. } else {
  460. // dprintf("%08lx (size %04lx) uninitialized or overwritten IRP\n",
  461. // irpAddress,
  462. // PoolBlock.Header.BlockSize << POOL_BLOCK_SHIFT);
  463. }
  464. } else {
  465. dprintf("Possible IRP @ %p - unable to read addr/type\n", Data );
  466. }
  467. return TRUE;
  468. } else {
  469. #ifdef SHOW_PROGRESS
  470. dprintf("%c", turnTable[turn]);
  471. turn = (turn + 1) % 4;
  472. #endif
  473. }
  474. return FALSE;
  475. } // CheckForIrp
  476. DECLARE_API(irpfind)
  477. /*++
  478. Routine Description:
  479. finds Irps in non-paged pool
  480. Arguments:
  481. args -
  482. Return Value:
  483. None
  484. --*/
  485. {
  486. ULONG Flags = 0;
  487. ULONG64 RestartAddr = 0;
  488. ULONG TagName;
  489. UCHAR Field[20];
  490. ULONG64 Match=0;
  491. SEARCH_CONTEXT Context;
  492. Context.FirstTime = TRUE;
  493. Context.Filter.FilterRoutine = NULL;
  494. Field[0] = '\0';
  495. if (args) {
  496. PCHAR pc;
  497. ULONG64 tmp;
  498. if (GetExpressionEx(args, &tmp, &args)) {
  499. Flags = (ULONG) tmp;
  500. if (GetExpressionEx(args, &RestartAddr, &args)) {
  501. if (!sscanf(args, "%19s %x", &Field, &Match)) {
  502. Match = 0;
  503. }
  504. }
  505. }
  506. }
  507. //
  508. // Sign extend the address if necc.
  509. //
  510. if (RestartAddr != 0) {
  511. if (RestartAddr >= 0x80000000 && RestartAddr <= 0xFFFFFFFF) {
  512. RestartAddr += 0xFFFFFFFF00000000;
  513. }
  514. }
  515. if ((_stricmp(Field, "userevent") == 0) &&
  516. (Match != 0)) {
  517. Context.Filter.FilterRoutine = IrpFilterUserEvent;
  518. Context.Filter.FilterContext = (PVOID)&Match;
  519. dprintf("Looking for IRP with UserEvent == %08p\n",Match);
  520. } else if ((_stricmp(Field, "device") == 0) &&
  521. (Match != 0)) {
  522. Context.Filter.FilterRoutine = IrpFilterDevice;
  523. Context.Filter.FilterContext = (PVOID)&Match;
  524. dprintf("Looking for IRPs with device object == %08p\n",Match);
  525. } else if ((_stricmp(Field, "fileobject") == 0) &&
  526. (Match != 0)) {
  527. Context.Filter.FilterRoutine = IrpFilterFileObject;
  528. Context.Filter.FilterContext = (PVOID)&Match;
  529. dprintf("Looking for IRPs with file object == %08p\n",Match);
  530. } else if ((_stricmp(Field, "mdlprocess") == 0) &&
  531. (Match != 0)) {
  532. Context.Filter.FilterRoutine = IrpFilterMdlProcess;
  533. Context.Filter.FilterContext = (PVOID)&Match;
  534. dprintf("Looking for IRPs with mdl process == %08p\n",Match);
  535. } else if ((_stricmp(Field, "thread") == 0) &&
  536. (Match != 0)) {
  537. Context.Filter.FilterRoutine = IrpFilterThread;
  538. Context.Filter.FilterContext = (PVOID)&Match;
  539. dprintf("Looking for IRPs with thread == %08p\n",Match);
  540. } else if ((_stricmp(Field, "arg") == 0) &&
  541. (Match != 0)) {
  542. Context.Filter.FilterRoutine = IrpFilterArg;
  543. Context.Filter.FilterContext = (PVOID)&Match;
  544. dprintf("Looking for IRPs with arg == %08p\n",Match);
  545. }
  546. TagName = '?prI';
  547. SearchPool( TagName, Flags, RestartAddr, &CheckForIrp, &Context );
  548. return S_OK;
  549. }
  550. BOOLEAN
  551. IrpFilterUserEvent(
  552. IN ULONG64 Irp,
  553. IN PVOID FilterContext
  554. )
  555. /*++
  556. Routine Description:
  557. Checks to see if the userevent field of an IRP matches the supplied
  558. parameter
  559. Arguments:
  560. Irp - Supplies the irp to filter
  561. FilterContext - supplies the user event
  562. Return Value:
  563. TRUE if the specified irp has userevent == FilterContext
  564. FALSE otherwise
  565. --*/
  566. {
  567. ULONG64 pEvent = *((PULONG64) FilterContext);
  568. ULONG64 UserEvent;
  569. if (GetFieldValue(Irp, "nt!_IRP", "UserEvent", UserEvent)) {
  570. return FALSE;
  571. }
  572. if (UserEvent == pEvent) {
  573. return(TRUE);
  574. } else {
  575. return(FALSE);
  576. }
  577. }
  578. BOOLEAN
  579. IrpFilterDevice(
  580. IN ULONG64 Irp,
  581. IN PVOID FilterContext
  582. )
  583. /*++
  584. Routine Description:
  585. Checks to see if the specified IRP matches the supplied
  586. device object
  587. Arguments:
  588. Irp - Supplies the irp to filter
  589. FilterContext - supplies the device object
  590. Return Value:
  591. TRUE if the specified irp has a device == FilterContext
  592. FALSE otherwise
  593. --*/
  594. {
  595. ULONG64 IrpStack = (Irp+GetTypeSize("nt!_IRP"));
  596. ULONG StackCount, Stksize;
  597. ULONG64 DeviceObject;
  598. ULONG i;
  599. if (GetFieldValue(Irp, "nt!_IRP", "StackCount", StackCount)) {
  600. return FALSE;
  601. }
  602. if (StackCount > 30) {
  603. return(FALSE);
  604. }
  605. Stksize = GetTypeSize("nt!_IO_STACK_LOCATION");
  606. for (i=0; i<StackCount; i++) {
  607. if (!GetFieldValue(Irp + i*Stksize,
  608. "nt!_IO_STACK_LOCATION",
  609. "DeviceObject",
  610. DeviceObject)) {
  611. if (DeviceObject == *((PULONG64) FilterContext)) {
  612. return(TRUE);
  613. }
  614. }
  615. }
  616. return(FALSE);
  617. }
  618. BOOLEAN
  619. IrpFilterFileObject(
  620. IN ULONG64 Irp,
  621. IN PVOID FilterContext
  622. )
  623. /*++
  624. Routine Description:
  625. Checks to see if the Tail.Overlay.OriginalFileObject field of an IRP matches the
  626. supplied parameter
  627. Arguments:
  628. Irp - Supplies the irp to filter
  629. FilterContext - supplies the file object
  630. Return Value:
  631. TRUE if the specified irp has userevent == FilterContext
  632. FALSE otherwise
  633. --*/
  634. {
  635. ULONG64 pFile = *((PULONG64) FilterContext);
  636. ULONG64 OriginalFileObject;
  637. if (GetFieldValue(Irp, "nt!_IRP",
  638. "Tail.Overlay.OriginalFileObject",
  639. OriginalFileObject)) {
  640. return FALSE;
  641. }
  642. if (OriginalFileObject == pFile) {
  643. return(TRUE);
  644. } else {
  645. return(FALSE);
  646. }
  647. }
  648. BOOLEAN
  649. IrpFilterThread(
  650. IN ULONG64 Irp,
  651. IN PVOID FilterContext
  652. )
  653. /*++
  654. Routine Description:
  655. Checks to see if the Tail.Overlay.OriginalFileObject field of an IRP matches the
  656. supplied parameter
  657. Arguments:
  658. Irp - Supplies the irp to filter
  659. FilterContext - supplies the file object
  660. Return Value:
  661. TRUE if the specified irp has userevent == FilterContext
  662. FALSE otherwise
  663. --*/
  664. {
  665. ULONG64 pThread = *((PULONG64) FilterContext);
  666. ULONG64 Thread;
  667. if (GetFieldValue(Irp, "nt!_IRP",
  668. "Tail.Overlay.Thread",
  669. Thread)) {
  670. return FALSE;
  671. }
  672. if (Thread == pThread) {
  673. return(TRUE);
  674. } else {
  675. return(FALSE);
  676. }
  677. }
  678. BOOLEAN
  679. IrpFilterMdlProcess(
  680. IN ULONG64 Irp,
  681. IN PVOID FilterContext
  682. )
  683. /*++
  684. Routine Description:
  685. Checks to see if the Tail.Overlay.OriginalFileObject field of an IRP matches the
  686. supplied parameter
  687. Arguments:
  688. Irp - Supplies the irp to filter
  689. FilterContext - supplies the file object
  690. Return Value:
  691. TRUE if the specified irp has userevent == FilterContext
  692. FALSE otherwise
  693. --*/
  694. {
  695. ULONG64 pProcess = *((PULONG64) FilterContext);
  696. ULONG64 Process, MdlAddress;
  697. if (GetFieldValue(Irp, "nt!_IRP",
  698. "MdlAddress",
  699. MdlAddress)) {
  700. return FALSE;
  701. }
  702. if (MdlAddress == 0) {
  703. return(FALSE);
  704. }
  705. if (GetFieldValue(MdlAddress, "nt!_MDL", "Process", Process)) {
  706. return FALSE;
  707. }
  708. if (Process == pProcess) {
  709. return(TRUE);
  710. } else {
  711. return(FALSE);
  712. }
  713. }
  714. BOOLEAN
  715. IrpFilterArg(
  716. IN ULONG64 Irp,
  717. IN PVOID FilterContext
  718. )
  719. /*++
  720. Routine Description:
  721. Checks to see if the specified IRP matches the supplied
  722. argument
  723. Arguments:
  724. Irp - Supplies the irp to filter
  725. FilterContext - supplies the argument to match
  726. Return Value:
  727. TRUE if the specified irp has argument == FilterContext
  728. FALSE otherwise
  729. --*/
  730. {
  731. ULONG64 IrpStack = (Irp+GetTypeSize("nt!_IRP"));
  732. ULONG StackCount, Stksize;
  733. ULONG i;
  734. if (GetFieldValue(Irp, "nt!_IRP", "StackCount", StackCount)) {
  735. return FALSE;
  736. }
  737. Stksize = GetTypeSize("nt!_IO_STACK_LOCATION");
  738. if (!Stksize || (StackCount > 30)) {
  739. return(FALSE);
  740. }
  741. for (i=0; i<StackCount; i++) {
  742. ULONG64 Argument1,Argument2,Argument3,Argument4;
  743. GetFieldValue(Irp + i*Stksize, "nt!_IO_STACK_LOCATION",
  744. "Parameters.Others.Argument1",Argument1);
  745. GetFieldValue(Irp + i*Stksize, "nt!_IO_STACK_LOCATION",
  746. "Parameters.Others.Argument2",Argument2);
  747. GetFieldValue(Irp + i*Stksize, "nt!_IO_STACK_LOCATION",
  748. "Parameters.Others.Argument3",Argument3);
  749. GetFieldValue(Irp + i*Stksize, "nt!_IO_STACK_LOCATION",
  750. "Parameters.Others.Argument4",Argument4);
  751. if ((Argument1 == *((PULONG64)FilterContext)) ||
  752. (Argument2 == *((PULONG64)FilterContext)) ||
  753. (Argument3 == *((PULONG64)FilterContext)) ||
  754. (Argument4 == *((PULONG64)FilterContext))) {
  755. return(TRUE);
  756. }
  757. }
  758. return(FALSE);
  759. }
  760. HRESULT
  761. GetIrpInfo(
  762. ULONG64 Irp,
  763. PDEBUG_IRP_INFO pIrp
  764. )
  765. {
  766. ULONG Type;
  767. UCHAR TypeName[]= "nt!_IRP";
  768. ULONG irpStackIndex;
  769. ULONG64 irpStackAddress;
  770. ZeroMemory(pIrp, sizeof(DEBUG_IRP_INFO));
  771. pIrp->SizeOfStruct = sizeof(DEBUG_IRP_INFO);
  772. pIrp->IrpAddress = Irp;
  773. if ( (GetFieldValue(Irp, TypeName, "Type", Type)) ) {
  774. //dprintf("%08p: Could not read Irp\n", IrpToDump);
  775. return E_INVALIDARG;
  776. }
  777. if (Type != IO_TYPE_IRP) {
  778. return E_INVALIDARG;
  779. }
  780. GetFieldValue(Irp, TypeName, "StackCount", pIrp->StackCount);
  781. GetFieldValue(Irp, TypeName, "CurrentLocation", pIrp->CurrentLocation);
  782. GetFieldValue(Irp, TypeName, "MdlAddress", pIrp->MdlAddress);
  783. GetFieldValue(Irp, TypeName, "CancelRoutine", pIrp->CancelRoutine);
  784. GetFieldValue(Irp, TypeName, "Tail.Overlay.Thread", pIrp->Thread);
  785. for (irpStackIndex = pIrp->StackCount,
  786. irpStackAddress = Irp + GetTypeSize("nt!_IRP") + (pIrp->StackCount - 1)* GetTypeSize("nt!_IO_STACK_LOCATION");
  787. irpStackIndex >= 1;
  788. irpStackIndex++, irpStackAddress -= GetTypeSize("nt!_IO_STACK_LOCATION")) {
  789. if ( InitTypeRead(irpStackAddress, nt!_IO_STACK_LOCATION)) {
  790. return E_INVALIDARG;
  791. }
  792. pIrp->CurrentStack.DeviceObject = ReadField(DeviceObject);
  793. if (!pIrp->CurrentStack.DeviceObject) {
  794. // To be implemented later, we are only interested in current one now
  795. continue;
  796. }
  797. pIrp->CurrentStack.StackAddress = irpStackAddress;
  798. pIrp->CurrentStack.CompletionRoutine = ReadField(CompletionRoutine);
  799. pIrp->CurrentStack.FileObject = ReadField(FileObject);
  800. pIrp->CurrentStack.Major = (UCHAR) ReadField(MajorFunction);
  801. pIrp->CurrentStack.Minor = (UCHAR) ReadField(MinorFunction);
  802. break;
  803. }
  804. return S_OK;
  805. }
  806. EXTENSION_API( GetIrpInfo )(
  807. PDEBUG_CLIENT Client,
  808. ULONG64 Irp,
  809. PDEBUG_IRP_INFO pIrp
  810. )
  811. {
  812. HRESULT Hr = E_FAIL;
  813. INIT_API();
  814. if (pIrp && (pIrp->SizeOfStruct == sizeof(DEBUG_IRP_INFO))) {
  815. Hr = GetIrpInfo(Irp, pIrp);
  816. }
  817. EXIT_API();
  818. return Hr;
  819. }