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.

530 lines
12 KiB

  1. /*++
  2. Copyright (c) 1997-2000 Microsoft Corporation
  3. Module Name:
  4. debug.c
  5. Abstract:
  6. This module provides debugging support.
  7. Author:
  8. Andy Thornton (andrewth) 20-Oct-97
  9. Revision History:
  10. --*/
  11. #include "mfp.h"
  12. //
  13. // Get mappings from status codes to strings
  14. //
  15. #include <ntstatus.dbg>
  16. #undef MAP
  17. #define MAP(_Value) { (_Value), #_Value }
  18. #define END_STRING_MAP { 0xFFFFFFFF, NULL }
  19. #if DBG
  20. LONG MfDebug = -1;
  21. PMF_STRING_MAP MfDbgStatusStringMap = (PMF_STRING_MAP) ntstatusSymbolicNames;
  22. MF_STRING_MAP MfDbgPnpIrpStringMap[] = {
  23. MAP(IRP_MN_START_DEVICE),
  24. MAP(IRP_MN_QUERY_REMOVE_DEVICE),
  25. MAP(IRP_MN_REMOVE_DEVICE),
  26. MAP(IRP_MN_CANCEL_REMOVE_DEVICE),
  27. MAP(IRP_MN_STOP_DEVICE),
  28. MAP(IRP_MN_QUERY_STOP_DEVICE),
  29. MAP(IRP_MN_CANCEL_STOP_DEVICE),
  30. MAP(IRP_MN_QUERY_DEVICE_RELATIONS),
  31. MAP(IRP_MN_QUERY_INTERFACE),
  32. MAP(IRP_MN_QUERY_CAPABILITIES),
  33. MAP(IRP_MN_QUERY_RESOURCES),
  34. MAP(IRP_MN_QUERY_RESOURCE_REQUIREMENTS),
  35. MAP(IRP_MN_QUERY_DEVICE_TEXT),
  36. MAP(IRP_MN_FILTER_RESOURCE_REQUIREMENTS),
  37. MAP(IRP_MN_READ_CONFIG),
  38. MAP(IRP_MN_WRITE_CONFIG),
  39. MAP(IRP_MN_EJECT),
  40. MAP(IRP_MN_SET_LOCK),
  41. MAP(IRP_MN_QUERY_ID),
  42. MAP(IRP_MN_QUERY_PNP_DEVICE_STATE),
  43. MAP(IRP_MN_QUERY_BUS_INFORMATION),
  44. MAP(IRP_MN_DEVICE_USAGE_NOTIFICATION),
  45. MAP(IRP_MN_SURPRISE_REMOVAL),
  46. MAP(IRP_MN_QUERY_LEGACY_BUS_INFORMATION),
  47. END_STRING_MAP
  48. };
  49. MF_STRING_MAP MfDbgPoIrpStringMap[] = {
  50. MAP(IRP_MN_WAIT_WAKE),
  51. MAP(IRP_MN_POWER_SEQUENCE),
  52. MAP(IRP_MN_SET_POWER),
  53. MAP(IRP_MN_QUERY_POWER),
  54. END_STRING_MAP
  55. };
  56. MF_STRING_MAP MfDbgDeviceRelationStringMap[] = {
  57. MAP(BusRelations),
  58. MAP(EjectionRelations),
  59. MAP(PowerRelations),
  60. MAP(RemovalRelations),
  61. MAP(TargetDeviceRelation),
  62. END_STRING_MAP
  63. };
  64. MF_STRING_MAP MfDbgSystemPowerStringMap[] = {
  65. MAP(PowerSystemUnspecified),
  66. MAP(PowerSystemWorking),
  67. MAP(PowerSystemSleeping1),
  68. MAP(PowerSystemSleeping2),
  69. MAP(PowerSystemSleeping3),
  70. MAP(PowerSystemHibernate),
  71. MAP(PowerSystemShutdown),
  72. MAP(PowerSystemMaximum),
  73. END_STRING_MAP
  74. };
  75. MF_STRING_MAP MfDbgDevicePowerStringMap[] = {
  76. MAP(PowerDeviceUnspecified),
  77. MAP(PowerDeviceD0),
  78. MAP(PowerDeviceD1),
  79. MAP(PowerDeviceD2),
  80. MAP(PowerDeviceD3),
  81. MAP(PowerDeviceMaximum),
  82. END_STRING_MAP
  83. };
  84. PCHAR
  85. MfDbgLookupString(
  86. IN PMF_STRING_MAP Map,
  87. IN ULONG Id
  88. )
  89. /*++
  90. Routine Description:
  91. Looks up the string associated with Id in string map Map
  92. Arguments:
  93. Map - The string map
  94. Id - The id to lookup
  95. Return Value:
  96. The string
  97. --*/
  98. {
  99. PMF_STRING_MAP current = Map;
  100. while(current->Id != 0xFFFFFFFF) {
  101. if (current->Id == Id) {
  102. return current->String;
  103. }
  104. current++;
  105. }
  106. return "** UNKNOWN **";
  107. }
  108. VOID
  109. MfDbgPrintMultiSz(
  110. LONG DebugLevel,
  111. PWSTR MultiSz
  112. )
  113. /*++
  114. Routine Description:
  115. Prints a registry style REG_MULTI_SZ
  116. Arguments:
  117. DebugLevel - The debug level at which or above the data should be displayed.
  118. MultiSz - The string to print
  119. Return Value:
  120. None
  121. --*/
  122. {
  123. PWSTR current = MultiSz;
  124. if (DebugLevel <= MfDebug) {
  125. if (MultiSz) {
  126. while(*current) {
  127. DbgPrint("%S", current);
  128. current += wcslen(current) + 1; // include the NULL
  129. DbgPrint(*current ? ", " : "\n");
  130. }
  131. } else {
  132. DbgPrint("*** None ***\n");
  133. }
  134. }
  135. }
  136. VOID
  137. MfDbgPrintResourceMap(
  138. LONG DebugLevel,
  139. PMF_RESOURCE_MAP Map
  140. )
  141. /*++
  142. Routine Description:
  143. Prints a resource map
  144. Arguments:
  145. DebugLevel - The debug level at which or above the data should be displayed.
  146. Map - The map to be displayed
  147. Return Value:
  148. None
  149. --*/
  150. {
  151. PCHAR current;
  152. if (DebugLevel <= MfDebug) {
  153. if (Map) {
  154. FOR_ALL_IN_ARRAY(Map->Resources, Map->Count, current) {
  155. DbgPrint("%i ", *current);
  156. }
  157. DbgPrint("\n");
  158. } else {
  159. DbgPrint("*** None ***\n");
  160. }
  161. }
  162. }
  163. VOID
  164. MfDbgPrintVaryingResourceMap(
  165. LONG DebugLevel,
  166. PMF_VARYING_RESOURCE_MAP Map
  167. )
  168. /*++
  169. Routine Description:
  170. Prints a varying resource map
  171. Arguments:
  172. DebugLevel - The debug level at which or above the data should be displayed.
  173. Map - The map to be displayed
  174. Return Value:
  175. None
  176. --*/
  177. {
  178. PMF_VARYING_RESOURCE_ENTRY current;
  179. if (DebugLevel <= MfDebug) {
  180. if (Map) {
  181. DbgPrint("\n");
  182. FOR_ALL_IN_ARRAY(Map->Resources, Map->Count, current) {
  183. DbgPrint("\t\tIndex %i for %x bytes at offset %x\n",
  184. current->ResourceIndex,
  185. current->Size,
  186. current->Offset
  187. );
  188. }
  189. } else {
  190. DbgPrint("*** None ***\n");
  191. }
  192. }
  193. }
  194. //
  195. // Printing resource descriptors and resource lists (stolen from PCI)
  196. //
  197. PUCHAR
  198. MfDbgCmResourceTypeToText(
  199. UCHAR Type
  200. )
  201. {
  202. switch (Type) {
  203. case CmResourceTypePort:
  204. return "CmResourceTypePort";
  205. case CmResourceTypeInterrupt:
  206. return "CmResourceTypeInterrupt";
  207. case CmResourceTypeMemory:
  208. return "CmResourceTypeMemory";
  209. case CmResourceTypeDma:
  210. return "CmResourceTypeDma";
  211. case CmResourceTypeDeviceSpecific:
  212. return "CmResourceTypeDeviceSpecific";
  213. case CmResourceTypeBusNumber:
  214. return "CmResourceTypeBusNumber";
  215. case CmResourceTypeConfigData:
  216. return "CmResourceTypeConfigData";
  217. case CmResourceTypeDevicePrivate:
  218. return "CmResourceTypeDevicePrivate";
  219. case CmResourceTypePcCardConfig:
  220. return "CmResourceTypePcCardConfig";
  221. default:
  222. return "*** INVALID RESOURCE TYPE ***";
  223. }
  224. }
  225. VOID
  226. MfDbgPrintIoResource(
  227. IN LONG Level,
  228. IN PIO_RESOURCE_DESCRIPTOR D
  229. )
  230. {
  231. ULONG i;
  232. PUCHAR t;
  233. if (Level <= MfDebug) {
  234. t = MfDbgCmResourceTypeToText(D->Type);
  235. DbgPrint(" IoResource Descriptor dump: Descriptor @0x%x\n", D);
  236. DbgPrint(" Option = 0x%x\n", D->Option);
  237. DbgPrint(" Type = %d (%s)\n", D->Type, t);
  238. DbgPrint(" ShareDisposition = %d\n", D->ShareDisposition);
  239. DbgPrint(" Flags = 0x%04X\n", D->Flags);
  240. for ( i = 0; i < 6 ; i+=3 ) {
  241. DbgPrint(" Data[%d] = %08x %08x %08x\n",
  242. i,
  243. D->u.DevicePrivate.Data[i],
  244. D->u.DevicePrivate.Data[i+1],
  245. D->u.DevicePrivate.Data[i+2]);
  246. }
  247. }
  248. }
  249. VOID
  250. MfDbgPrintIoResReqList(
  251. IN LONG Level,
  252. IN PIO_RESOURCE_REQUIREMENTS_LIST IoResReqList
  253. )
  254. {
  255. ULONG numlists;
  256. PIO_RESOURCE_LIST list;
  257. if (Level <= MfDebug) {
  258. if (IoResReqList) {
  259. numlists = IoResReqList->AlternativeLists;
  260. list = IoResReqList->List;
  261. DbgPrint(" IO_RESOURCE_REQUIREMENTS_LIST\n");
  262. DbgPrint(" InterfaceType %d\n", IoResReqList->InterfaceType);
  263. DbgPrint(" BusNumber %d\n", IoResReqList->BusNumber );
  264. DbgPrint(" SlotNumber %d\n", IoResReqList->SlotNumber );
  265. DbgPrint(" AlternativeLists %d\n", numlists );
  266. while (numlists--) {
  267. PIO_RESOURCE_DESCRIPTOR resource = list->Descriptors;
  268. ULONG count = list->Count;
  269. DbgPrint("\n List[%d].Count = %d\n", numlists, count);
  270. while (count--) {
  271. MfDbgPrintIoResource(Level, resource++);
  272. }
  273. list = (PIO_RESOURCE_LIST)resource;
  274. }
  275. DbgPrint("\n");
  276. } else {
  277. DbgPrint(" IO_RESOURCE_REQUIREMENTS_LIST\n");
  278. DbgPrint(" *** EMPTY ***\n");
  279. }
  280. }
  281. }
  282. VOID
  283. MfDbgPrintPartialResource(
  284. IN LONG Level,
  285. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR D
  286. )
  287. {
  288. ULONG i;
  289. PUCHAR t;
  290. if (Level <= MfDebug) {
  291. if (D) {
  292. t = MfDbgCmResourceTypeToText(D->Type);
  293. DbgPrint(" Partial Resource Descriptor @0x%x\n", D);
  294. DbgPrint(" Type = %d (%s)\n", D->Type, t);
  295. DbgPrint(" ShareDisposition = %d\n", D->ShareDisposition);
  296. DbgPrint(" Flags = 0x%04X\n", D->Flags);
  297. for ( i = 0; i < 3 ; i+=3 ) {
  298. DbgPrint(" Data[%d] = %08x %08x %08x\n",
  299. i,
  300. D->u.DevicePrivate.Data[i],
  301. D->u.DevicePrivate.Data[i+1],
  302. D->u.DevicePrivate.Data[i+2]);
  303. }
  304. } else {
  305. DbgPrint(" Partial Resource Descriptor EMPTY!!\n");
  306. }
  307. }
  308. }
  309. PCM_PARTIAL_RESOURCE_DESCRIPTOR
  310. MfNextPartialDescriptor(
  311. PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
  312. )
  313. /*++
  314. Routine Description:
  315. Given a pointer to a CmPartialResourceDescriptor, return a pointer
  316. to the next descriptor in the same list.
  317. This is only done in a routine (rather than a simple descriptor++)
  318. because if the variable length resource CmResourceTypeDeviceSpecific.
  319. Arguments:
  320. Descriptor - Pointer to the descriptor being advanced over.
  321. Return Value:
  322. Pointer to the next descriptor in the same list (or byte beyond
  323. end of list).
  324. --*/
  325. {
  326. PCM_PARTIAL_RESOURCE_DESCRIPTOR nextDescriptor;
  327. nextDescriptor = Descriptor + 1;
  328. if (Descriptor->Type == CmResourceTypeDeviceSpecific) {
  329. //
  330. // This (old) descriptor is followed by DataSize bytes
  331. // of device specific data, ie, not immediatelly by the
  332. // next descriptor. Adjust nextDescriptor by this amount.
  333. //
  334. nextDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
  335. ((PCHAR)nextDescriptor + Descriptor->u.DeviceSpecificData.DataSize);
  336. }
  337. return nextDescriptor;
  338. }
  339. VOID
  340. MfDbgPrintCmResList(
  341. IN LONG Level,
  342. IN PCM_RESOURCE_LIST ResourceList
  343. )
  344. {
  345. ULONG numlists;
  346. PCM_FULL_RESOURCE_DESCRIPTOR full;
  347. PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor;
  348. if (Level <= MfDebug) {
  349. if (ResourceList) {
  350. numlists = ResourceList->Count;
  351. full = ResourceList->List;
  352. DbgPrint(" CM_RESOURCE_LIST (List Count = %d)\n",
  353. numlists);
  354. while (numlists--) {
  355. PCM_PARTIAL_RESOURCE_LIST partial = &full->PartialResourceList;
  356. ULONG count = partial->Count;
  357. DbgPrint(" InterfaceType %d\n", full->InterfaceType);
  358. DbgPrint(" BusNumber %d\n", full->BusNumber );
  359. descriptor = partial->PartialDescriptors;
  360. while (count--) {
  361. MfDbgPrintPartialResource(Level, descriptor);
  362. descriptor = MfNextPartialDescriptor(descriptor);
  363. }
  364. full = (PCM_FULL_RESOURCE_DESCRIPTOR)descriptor;
  365. }
  366. DbgPrint("\n");
  367. } else {
  368. DbgPrint(" CM_RESOURCE_LIST EMPTY!!!\n");
  369. }
  370. }
  371. }
  372. #endif