Leaked source code of windows server 2003
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.

442 lines
11 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1992 - 2001
  3. Module Name:
  4. util.c
  5. Abstract:
  6. Utility library used for the various debugger extensions in this library.
  7. Author:
  8. Peter Wieland (peterwie) 16-Oct-1995
  9. ervinp
  10. Environment:
  11. User Mode.
  12. Revision History:
  13. --*/
  14. #include "pch.h"
  15. #include "ideport.h"
  16. PUCHAR devicePowerStateNames[] = {
  17. "PowerDeviceUnspecified",
  18. "PowerDeviceD0",
  19. "PowerDeviceD1",
  20. "PowerDeviceD2",
  21. "PowerDeviceD3",
  22. "PowerDeviceMaximum",
  23. "Invalid"
  24. };
  25. FLAG_NAME SrbFlags[] = {
  26. FLAG_NAME(SRB_FLAGS_QUEUE_ACTION_ENABLE),
  27. FLAG_NAME(SRB_FLAGS_DISABLE_DISCONNECT),
  28. FLAG_NAME(SRB_FLAGS_DISABLE_SYNCH_TRANSFER),
  29. FLAG_NAME(SRB_FLAGS_BYPASS_FROZEN_QUEUE),
  30. FLAG_NAME(SRB_FLAGS_DISABLE_AUTOSENSE),
  31. FLAG_NAME(SRB_FLAGS_DATA_IN),
  32. FLAG_NAME(SRB_FLAGS_DATA_OUT),
  33. FLAG_NAME(SRB_FLAGS_NO_DATA_TRANSFER),
  34. FLAG_NAME(SRB_FLAGS_UNSPECIFIED_DIRECTION),
  35. FLAG_NAME(SRB_FLAGS_NO_QUEUE_FREEZE),
  36. FLAG_NAME(SRB_FLAGS_ADAPTER_CACHE_ENABLE),
  37. FLAG_NAME(SRB_FLAGS_IS_ACTIVE),
  38. FLAG_NAME(SRB_FLAGS_ALLOCATED_FROM_ZONE),
  39. FLAG_NAME(SRB_FLAGS_SGLIST_FROM_POOL),
  40. FLAG_NAME(SRB_FLAGS_BYPASS_LOCKED_QUEUE),
  41. FLAG_NAME(SRB_FLAGS_NO_KEEP_AWAKE),
  42. {0,0}
  43. };
  44. FLAG_NAME LuFlags[] = {
  45. FLAG_NAME(PD_QUEUE_FROZEN),
  46. FLAG_NAME(PD_LOGICAL_UNIT_IS_ACTIVE),
  47. FLAG_NAME(PD_NEED_REQUEST_SENSE),
  48. FLAG_NAME(PD_LOGICAL_UNIT_IS_BUSY),
  49. FLAG_NAME(PD_QUEUE_IS_FULL),
  50. FLAG_NAME(PD_RESCAN_ACTIVE),
  51. {0, 0}
  52. };
  53. FLAG_NAME PortFlags[] = {
  54. FLAG_NAME(PD_DEVICE_IS_BUSY),
  55. FLAG_NAME(PD_NOTIFICATION_REQUIRED),
  56. FLAG_NAME(PD_READY_FOR_NEXT_REQUEST),
  57. FLAG_NAME(PD_FLUSH_ADAPTER_BUFFERS),
  58. FLAG_NAME(PD_MAP_TRANSFER),
  59. FLAG_NAME(PD_LOG_ERROR),
  60. FLAG_NAME(PD_RESET_HOLD),
  61. FLAG_NAME(PD_HELD_REQUEST),
  62. FLAG_NAME(PD_RESET_REPORTED),
  63. FLAG_NAME(PD_PENDING_DEVICE_REQUEST),
  64. FLAG_NAME(PD_DISCONNECT_RUNNING),
  65. FLAG_NAME(PD_DISABLE_CALL_REQUEST),
  66. FLAG_NAME(PD_DISABLE_INTERRUPTS),
  67. FLAG_NAME(PD_ENABLE_CALL_REQUEST),
  68. FLAG_NAME(PD_TIMER_CALL_REQUEST),
  69. FLAG_NAME(PD_ALL_DEVICE_MISSING),
  70. FLAG_NAME(PD_RESET_REQUEST),
  71. {0,0}
  72. };
  73. FLAG_NAME DevFlags[] = {
  74. FLAG_NAME(DFLAGS_DEVICE_PRESENT),
  75. FLAG_NAME(DFLAGS_ATAPI_DEVICE),
  76. FLAG_NAME(DFLAGS_TAPE_DEVICE),
  77. FLAG_NAME(DFLAGS_INT_DRQ),
  78. FLAG_NAME(DFLAGS_REMOVABLE_DRIVE),
  79. FLAG_NAME(DFLAGS_MEDIA_STATUS_ENABLED),
  80. FLAG_NAME(DFLAGS_USE_DMA),
  81. FLAG_NAME(DFLAGS_LBA),
  82. FLAG_NAME(DFLAGS_MULTI_LUN_INITED),
  83. FLAG_NAME(DFLAGS_MSN_SUPPORT),
  84. FLAG_NAME(DFLAGS_AUTO_EJECT_ZIP),
  85. FLAG_NAME(DFLAGS_WD_MODE),
  86. FLAG_NAME(DFLAGS_LS120_FORMAT),
  87. FLAG_NAME(DFLAGS_USE_UDMA),
  88. FLAG_NAME(DFLAGS_IDENTIFY_VALID),
  89. FLAG_NAME(DFLAGS_IDENTIFY_INVALID),
  90. FLAG_NAME(DFLAGS_RDP_SET),
  91. FLAG_NAME(DFLAGS_SONY_MEMORYSTICK),
  92. FLAG_NAME(DFLAGS_48BIT_LBA),
  93. {0,0}
  94. };
  95. PUCHAR
  96. DevicePowerStateToString(
  97. IN DEVICE_POWER_STATE State
  98. )
  99. {
  100. if(State > PowerDeviceMaximum) {
  101. return "Invalid";
  102. } else {
  103. return devicePowerStateNames[(UCHAR) State];
  104. }
  105. }
  106. /*
  107. * xdprintf
  108. *
  109. * Prints formatted text with leading spaces.
  110. *
  111. * WARNING: DOES NOT HANDLE ULONG64 PROPERLY.
  112. */
  113. VOID
  114. xdprintf(
  115. ULONG Depth,
  116. PCCHAR S,
  117. ...
  118. )
  119. {
  120. va_list ap;
  121. ULONG i;
  122. CCHAR DebugBuffer[256] = {0};
  123. for (i=0; i<Depth; i++) {
  124. dprintf (" ");
  125. }
  126. va_start(ap, S);
  127. _vsnprintf(DebugBuffer, sizeof(DebugBuffer)-1, S, ap);
  128. dprintf (DebugBuffer);
  129. va_end(ap);
  130. }
  131. VOID
  132. DumpFlags(
  133. ULONG Depth,
  134. PUCHAR Name,
  135. ULONG Flags,
  136. PFLAG_NAME FlagTable
  137. )
  138. {
  139. ULONG i;
  140. ULONG mask = 0;
  141. ULONG count = 0;
  142. UCHAR prolog[64] = {0};
  143. _snprintf(prolog, sizeof(prolog)-1, "%s (0x%08x): ", Name, Flags);
  144. xdprintf(Depth, "%s", prolog);
  145. if(Flags == 0) {
  146. dprintf("\n");
  147. return;
  148. }
  149. memset(prolog, ' ', strlen(prolog));
  150. for(i = 0; FlagTable[i].Name != 0; i++) {
  151. PFLAG_NAME flag = &(FlagTable[i]);
  152. mask |= flag->Flag;
  153. if((Flags & flag->Flag) == flag->Flag) {
  154. //
  155. // print trailing comma
  156. //
  157. if(count != 0) {
  158. dprintf(", ");
  159. //
  160. // Only print two flags per line.
  161. //
  162. if((count % 2) == 0) {
  163. dprintf("\n");
  164. xdprintf(Depth, "%s", prolog);
  165. }
  166. }
  167. dprintf("%s", flag->Name);
  168. count++;
  169. }
  170. }
  171. dprintf("\n");
  172. if((Flags & (~mask)) != 0) {
  173. xdprintf(Depth, "%sUnknown flags %#010lx\n", prolog, (Flags & (~mask)));
  174. }
  175. return;
  176. }
  177. /*
  178. * GetULONGField
  179. *
  180. * Return the field or -1 in case of error.
  181. * Yes, it screws up if the field is actually -1.
  182. */
  183. ULONG64 GetULONGField(ULONG64 StructAddr, LPCSTR StructType, LPCSTR FieldName)
  184. {
  185. ULONG64 result;
  186. ULONG dbgStat;
  187. dbgStat = GetFieldData(StructAddr, StructType, FieldName, sizeof(ULONG64), &result);
  188. if (dbgStat != 0){
  189. dprintf("\n GetULONGField: GetFieldData failed with %xh retrieving field '%s' of struct '%s' @ %08p, returning bogus field value %08xh.\n",
  190. dbgStat, FieldName, StructType, StructAddr, BAD_VALUE);
  191. result = BAD_VALUE;
  192. }
  193. return result;
  194. }
  195. /*
  196. * GetUSHORTField
  197. *
  198. * Return the field or -1 in case of error.
  199. * Yes, it screws up if the field is actually -1.
  200. */
  201. USHORT GetUSHORTField(ULONG64 StructAddr, LPCSTR StructType, LPCSTR FieldName)
  202. {
  203. USHORT result;
  204. ULONG dbgStat;
  205. dbgStat = GetFieldData(StructAddr, StructType, FieldName, sizeof(USHORT), &result);
  206. if (dbgStat != 0){
  207. dprintf("\n GetUSHORTField: GetFieldData failed with %xh retrieving field '%s' of struct '%s' @ %08p, returning bogus field value %08xh.\n",
  208. dbgStat, FieldName, StructType, StructAddr, BAD_VALUE);
  209. result = (USHORT)BAD_VALUE;
  210. }
  211. return result;
  212. }
  213. /*
  214. * GetUCHARField
  215. *
  216. * Return the field or -1 in case of error.
  217. * Yes, it screws up if the field is actually -1.
  218. */
  219. UCHAR GetUCHARField(ULONG64 StructAddr, LPCSTR StructType, LPCSTR FieldName)
  220. {
  221. UCHAR result;
  222. ULONG dbgStat;
  223. dbgStat = GetFieldData(StructAddr, StructType, FieldName, sizeof(UCHAR), &result);
  224. if (dbgStat != 0){
  225. dprintf("\n GetUCHARField: GetFieldData failed with %xh retrieving field '%s' of struct '%s' @ %08p, returning bogus field value %08xh.\n",
  226. dbgStat, FieldName, StructType, StructAddr, BAD_VALUE);
  227. result = (UCHAR)BAD_VALUE;
  228. }
  229. return result;
  230. }
  231. ULONG64 GetFieldAddr(ULONG64 StructAddr, LPCSTR StructType, LPCSTR FieldName)
  232. {
  233. ULONG64 result;
  234. ULONG offset;
  235. ULONG dbgStat;
  236. dbgStat = GetFieldOffset(StructType, FieldName, &offset);
  237. if (dbgStat == 0){
  238. result = StructAddr+offset;
  239. }
  240. else {
  241. dprintf("\n GetFieldAddr: GetFieldOffset failed with %xh retrieving offset of struct '%s' (@ %08p) field '%s'.\n",
  242. dbgStat, StructType, StructAddr, FieldName);
  243. result = BAD_VALUE;
  244. }
  245. return result;
  246. }
  247. ULONG64 GetContainingRecord(ULONG64 FieldAddr, LPCSTR StructType, LPCSTR FieldName)
  248. {
  249. ULONG64 result;
  250. ULONG offset;
  251. ULONG dbgStat;
  252. dbgStat = GetFieldOffset(StructType, FieldName, &offset);
  253. if (dbgStat == 0){
  254. result = FieldAddr-offset;
  255. }
  256. else {
  257. dprintf("\n GetContainingRecord: GetFieldOffset failed with %xh retrieving offset of struct '%s' field '%s', returning bogus address %08xh.\n", dbgStat, StructType, FieldName, BAD_VALUE);
  258. result = BAD_VALUE;
  259. }
  260. return result;
  261. }
  262. /*
  263. * DumpObjListQueue
  264. *
  265. * Dump a list of objects queued by LIST_ENTRY's.
  266. * Returns length of list.
  267. */
  268. ULONG DumpObjListQueue(ULONG Depth, PCHAR Title, PCHAR StructName, PCHAR ListEntryFieldName, ULONG64 ListHeadAddr)
  269. {
  270. ULONG64 listEntryAddr;
  271. ULONG numObjs= 0;
  272. if (Title){
  273. xdprintf(Depth, ""), dprintf("%s:\n", Title);
  274. }
  275. listEntryAddr = GetULONGField(ListHeadAddr, "nt!_LIST_ENTRY", "Flink");
  276. while ((listEntryAddr != ListHeadAddr) && (listEntryAddr != BAD_VALUE)){
  277. ULONG64 objAddr;
  278. objAddr = GetContainingRecord(listEntryAddr, StructName, ListEntryFieldName);
  279. if (objAddr == BAD_VALUE){
  280. break;
  281. }
  282. else {
  283. /*
  284. * Dump this irp
  285. */
  286. xdprintf(Depth+1, ""), dprintf("%08p\n", objAddr);
  287. /*
  288. * Go to the next irp
  289. */
  290. numObjs++;
  291. listEntryAddr = GetULONGField(listEntryAddr, "nt!_LIST_ENTRY", "Flink");
  292. }
  293. }
  294. dprintf("\n");
  295. return numObjs;
  296. }
  297. /*
  298. * DumpIrpQueue
  299. *
  300. * Dump Irp queue linked by Irp->Tail.Overlay.ListEntry
  301. */
  302. ULONG DumpIrpQueue(ULONG Depth, PCHAR Title, ULONG64 ListHeadAddr)
  303. {
  304. return DumpObjListQueue(Depth, Title, "nt!_IRP", "Tail.Overlay.ListEntry", ListHeadAddr);
  305. }
  306. /*
  307. * DumpIrpDeviceQueue
  308. *
  309. * Dump Irp queue linked by Irp->Tail.Overlay.DeviceQueueEntry
  310. */
  311. ULONG DumpIrpDeviceQueue(ULONG Depth, PCHAR Title, ULONG64 ListHeadAddr)
  312. {
  313. return DumpObjListQueue(Depth, Title, "nt!_IRP", "Tail.Overlay.DeviceQueueEntry", ListHeadAddr);
  314. }
  315. /*
  316. * FindObjInListQueue
  317. *
  318. * Searches a list of objects queued by LIST_ENTRY's.
  319. * Returns TRUE iff the given object is found.
  320. */
  321. BOOLEAN FindObjInListQueue(ULONG64 ListHeadAddr, ULONG64 SpecificObjAddr, PCHAR StructName, PCHAR ListEntryFieldName)
  322. {
  323. ULONG64 listEntryAddr;
  324. BOOLEAN found = FALSE;
  325. listEntryAddr = GetULONGField(ListHeadAddr, "nt!_LIST_ENTRY", "Flink");
  326. while ((listEntryAddr != ListHeadAddr) && (listEntryAddr != BAD_VALUE)){
  327. ULONG64 objAddr = GetContainingRecord(listEntryAddr, StructName, ListEntryFieldName);
  328. if (objAddr == BAD_VALUE){
  329. break;
  330. }
  331. else if (objAddr == SpecificObjAddr){
  332. found = TRUE;
  333. break;
  334. }
  335. else {
  336. listEntryAddr = GetULONGField(listEntryAddr, "nt!_LIST_ENTRY", "Flink");
  337. }
  338. }
  339. return found;
  340. }
  341. /*
  342. * FindIrpInQueue
  343. *
  344. * Find Irp in Irp queue linked by Irp->Tail.Overlay.ListEntry
  345. */
  346. BOOLEAN FindIrpInQueue(ULONG64 ListHeadAddr, ULONG64 IrpAddr)
  347. {
  348. return FindObjInListQueue(ListHeadAddr, IrpAddr, "nt!_IRP", "Tail.Overlay.ListEntry");
  349. }
  350. /*
  351. * FindIrpInDeviceQueue
  352. *
  353. * Find Irp in Irp queue linked by Irp->Tail.Overlay.DeviceQueueEntry
  354. */
  355. BOOLEAN FindIrpInDeviceQueue(ULONG64 ListHeadAddr, ULONG64 IrpAddr)
  356. {
  357. return FindObjInListQueue(ListHeadAddr, IrpAddr, "nt!_IRP", "Tail.Overlay.DeviceQueueEntry");
  358. }