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.

290 lines
6.8 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. devstack.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Author:
  8. Adrian Oney (adriao) 29-Sep-1998
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. /*
  16. #define FLAG_NAME(flag) {flag, #flag}
  17. FLAG_NAME DeviceObjectExtensionFlags[] = {
  18. FLAG_NAME(DOE_UNLOAD_PENDING), // 00000001
  19. FLAG_NAME(DOE_DELETE_PENDING), // 00000002
  20. FLAG_NAME(DOE_REMOVE_PENDING), // 00000004
  21. FLAG_NAME(DOE_REMOVE_PROCESSED), // 00000008
  22. FLAG_NAME(DOE_RAW_FDO), // 20000000
  23. FLAG_NAME(DOE_BOTTOM_OF_FDO_STACK), // 40000000
  24. FLAG_NAME(DOE_DESIGNATED_FDO), // 80000000
  25. { 0, 0 }
  26. };
  27. */
  28. VOID
  29. DumpDeviceStack(
  30. ULONG64 DeviceAddress
  31. );
  32. DECLARE_API( devstack )
  33. /*++
  34. Routine Description:
  35. Dump a device object.
  36. Arguments:
  37. args - the location of the device object to dump.
  38. Return Value:
  39. None
  40. --*/
  41. {
  42. ULONG64 deviceToDump ;
  43. char deviceExprBuf[256] ;
  44. char *deviceExpr ;
  45. //
  46. // !devstack DeviceAddress DumpLevel
  47. // where DeviceAddress can be an expression or device name
  48. // and DumpLevel is a hex mask
  49. //
  50. strcpy(deviceExprBuf, "\\Device\\") ;
  51. deviceExpr = deviceExprBuf+strlen(deviceExprBuf) ;
  52. deviceToDump = 0 ;
  53. strcpy(deviceExpr, args) ;
  54. //
  55. // sscanf(args, "%s %lx", deviceExpr, &Flags);
  56. //
  57. //
  58. // The debugger will treat C0000000 as a symbol first, then a number if
  59. // no match comes up. We sanely reverse this ordering.
  60. //
  61. if (IsHexNumber(deviceExpr)) {
  62. deviceToDump = GetExpression (deviceExpr) ;
  63. } else if (deviceExpr[0] == '\\') {
  64. deviceToDump = FindObjectByName( deviceExpr, 0);
  65. } else if (isalpha(deviceExpr[0])) {
  66. //
  67. // Perhaps it's an object. Try with \\Device\\ prepended...
  68. //
  69. deviceToDump = FindObjectByName((PUCHAR) deviceExprBuf, 0);
  70. }
  71. if (deviceToDump == 0) {
  72. //
  73. // Last try, is it an expression to evaluate?
  74. //
  75. deviceToDump = GetExpression( deviceExpr ) ;
  76. }
  77. if(deviceToDump == 0) {
  78. dprintf("Device object %s not found\n", args);
  79. return E_INVALIDARG;
  80. }
  81. DumpDeviceStack(deviceToDump);
  82. return S_OK;
  83. }
  84. VOID
  85. DumpDeviceStack(
  86. ULONG64 DeviceAddress
  87. )
  88. /*++
  89. Routine Description:
  90. Displays the driver name for the device object .
  91. Otherwise displays more information about the device and the device queue.
  92. Arguments:
  93. DeviceAddress - address of device object to dump.
  94. Return Value:
  95. None
  96. --*/
  97. {
  98. ULONG result;
  99. ULONG i;
  100. ULONG64 nextEntry;
  101. BOOLEAN devObjExtRead;
  102. ULONG64 currentDeviceObject ;
  103. ULONG64 DeviceNode=0 ;
  104. ULONG64 AttachedDevice;
  105. ULONG64 DeviceObjectExtension;
  106. ULONG Type;
  107. if (!IsPtr64()) {
  108. DeviceAddress = (ULONG64) (LONG64) (LONG) DeviceAddress;
  109. }
  110. //
  111. // Find top of stack...
  112. //
  113. currentDeviceObject = DeviceAddress;
  114. dprintf(" !DevObj !DrvObj !DevExt ObjectName\n") ;
  115. while(1) {
  116. if (GetFieldValue(currentDeviceObject,"nt!_DEVICE_OBJECT","Type",Type)) {
  117. dprintf("%08p: Could not read device object\n", currentDeviceObject);
  118. return;
  119. }
  120. if (Type != IO_TYPE_DEVICE) {
  121. dprintf("%08p: is not a device object\n", currentDeviceObject);
  122. return;
  123. }
  124. GetFieldValue(currentDeviceObject,"nt!_DEVICE_OBJECT",
  125. "AttachedDevice", AttachedDevice);
  126. if ((!AttachedDevice)||CheckControlC()) {
  127. break;
  128. }
  129. currentDeviceObject = AttachedDevice ;
  130. }
  131. //
  132. // Crawl back down...
  133. //
  134. while(1) {
  135. ULONG64 DeviceExtension, AttachedTo;
  136. InitTypeRead(currentDeviceObject, nt!_DEVICE_OBJECT);
  137. dprintf("%c %08p ",
  138. (currentDeviceObject == DeviceAddress) ? '>' : ' ',
  139. currentDeviceObject
  140. ) ;
  141. DumpDevice(currentDeviceObject, 20, FALSE) ;
  142. InitTypeRead(currentDeviceObject, nt!_DEVICE_OBJECT);
  143. dprintf("%08p ", (DeviceExtension = ReadField(DeviceExtension)));
  144. //
  145. // Dump the device name if present.
  146. //
  147. DumpObjectName(currentDeviceObject) ;
  148. InitTypeRead(currentDeviceObject, nt!_DEVICE_OBJECT);
  149. devObjExtRead = FALSE ;
  150. if (DeviceObjectExtension = ReadField(DeviceObjectExtension)) {
  151. //
  152. // grab a copy of the device object extension as well
  153. //
  154. if(!GetFieldValue(DeviceObjectExtension,"nt!_DEVOBJ_EXTENSION",
  155. "AttachedTo",AttachedTo)) {
  156. devObjExtRead = TRUE ;
  157. }
  158. GetFieldValue(DeviceObjectExtension,"nt!_DEVOBJ_EXTENSION",
  159. "DeviceNode", DeviceNode);
  160. }
  161. if (!devObjExtRead) {
  162. dprintf("\n%#08p: Could not read device object extension\n",
  163. currentDeviceObject);
  164. return ;
  165. }
  166. dprintf("\n");
  167. /*
  168. DumpFlags(0,
  169. "ExtensionFlags",
  170. deviceObjectExtension.ExtensionFlags,
  171. DeviceObjectExtensionFlags);
  172. }
  173. */
  174. currentDeviceObject = AttachedTo ;
  175. if ((!currentDeviceObject)||CheckControlC()) {
  176. break;
  177. }
  178. if (GetFieldValue(currentDeviceObject,"nt!_DEVICE_OBJECT","Type",Type)) {
  179. dprintf("%08p: Could not read device object\n", currentDeviceObject);
  180. return;
  181. }
  182. }
  183. if(DeviceNode) {
  184. UNICODE_STRING64 InstancePath, ServiceName;
  185. dprintf("!DevNode %08p :\n", DeviceNode);
  186. if (GetFieldValue(DeviceNode,
  187. "nt!_DEVICE_NODE",
  188. "InstancePath.Length",
  189. InstancePath.Length)) {
  190. dprintf(
  191. "%08p: Could not read device node\n",
  192. DeviceNode
  193. );
  194. return;
  195. }
  196. InitTypeRead(DeviceNode, nt!_DEVICE_NODE);
  197. InstancePath.MaximumLength = (USHORT) ReadField(InstancePath.MaximumLength);
  198. InstancePath.Buffer = ReadField(InstancePath.Buffer);
  199. ServiceName.Length = (USHORT) ReadField(ServiceName.Length);
  200. ServiceName.MaximumLength = (USHORT) ReadField(ServiceName.MaximumLength);
  201. ServiceName.Buffer = ReadField(ServiceName.Buffer);
  202. if (InstancePath.Buffer != 0) {
  203. dprintf(" DeviceInst is \"");
  204. DumpUnicode64(InstancePath);
  205. dprintf("\"\n");
  206. }
  207. if (ServiceName.Buffer != 0) {
  208. dprintf(" ServiceName is \"");
  209. DumpUnicode64(ServiceName);
  210. dprintf("\"\n");
  211. }
  212. }
  213. }