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.

428 lines
10 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 "SpSim.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 SpSimDebug = -1;
  21. PSPSIM_STRING_MAP SpSimDbgStatusStringMap = (PSPSIM_STRING_MAP) ntstatusSymbolicNames;
  22. SPSIM_STRING_MAP SpSimDbgPnpIrpStringMap[] = {
  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. END_STRING_MAP
  47. };
  48. SPSIM_STRING_MAP SpSimDbgPoIrpStringMap[] = {
  49. MAP(IRP_MN_WAIT_WAKE),
  50. MAP(IRP_MN_POWER_SEQUENCE),
  51. MAP(IRP_MN_SET_POWER),
  52. MAP(IRP_MN_QUERY_POWER),
  53. END_STRING_MAP
  54. };
  55. SPSIM_STRING_MAP SpSimDbgDeviceRelationStringMap[] = {
  56. MAP(BusRelations),
  57. MAP(EjectionRelations),
  58. MAP(PowerRelations),
  59. MAP(RemovalRelations),
  60. MAP(TargetDeviceRelation),
  61. END_STRING_MAP
  62. };
  63. SPSIM_STRING_MAP SpSimDbgSystemPowerStringMap[] = {
  64. MAP(PowerSystemUnspecified),
  65. MAP(PowerSystemWorking),
  66. MAP(PowerSystemSleeping1),
  67. MAP(PowerSystemSleeping2),
  68. MAP(PowerSystemSleeping3),
  69. MAP(PowerSystemHibernate),
  70. MAP(PowerSystemShutdown),
  71. MAP(PowerSystemMaximum),
  72. END_STRING_MAP
  73. };
  74. SPSIM_STRING_MAP SpSimDbgDevicePowerStringMap[] = {
  75. MAP(PowerDeviceUnspecified),
  76. MAP(PowerDeviceD0),
  77. MAP(PowerDeviceD1),
  78. MAP(PowerDeviceD2),
  79. MAP(PowerDeviceD3),
  80. MAP(PowerDeviceMaximum),
  81. END_STRING_MAP
  82. };
  83. PCHAR
  84. SpSimDbgLookupString(
  85. IN PSPSIM_STRING_MAP Map,
  86. IN ULONG Id
  87. )
  88. /*++
  89. Routine Description:
  90. Looks up the string associated with Id in string map Map
  91. Arguments:
  92. Map - The string map
  93. Id - The id to lookup
  94. Return Value:
  95. The string
  96. --*/
  97. {
  98. PSPSIM_STRING_MAP current = Map;
  99. while(current->Id != 0xFFFFFFFF) {
  100. if (current->Id == Id) {
  101. return current->String;
  102. }
  103. current++;
  104. }
  105. return "** UNKNOWN **";
  106. }
  107. VOID
  108. SpSimDbgPrintMultiSz(
  109. LONG DebugLevel,
  110. PWSTR MultiSz
  111. )
  112. /*++
  113. Routine Description:
  114. Prints a registry style REG_MULTI_SZ
  115. Arguments:
  116. DebugLevel - The debug level at which or above the data should be displayed.
  117. MultiSz - The string to print
  118. Return Value:
  119. None
  120. --*/
  121. {
  122. PWSTR current = MultiSz;
  123. if (DebugLevel <= SpSimDebug) {
  124. if (MultiSz) {
  125. while(*current) {
  126. DbgPrint("%S", current);
  127. current += wcslen(current) + 1; // include the NULL
  128. DbgPrint(*current ? ", " : "\n");
  129. }
  130. } else {
  131. DbgPrint("*** None ***\n");
  132. }
  133. }
  134. }
  135. //
  136. // Printing resource descriptors and resource lists (stolen from PCI)
  137. //
  138. PUCHAR
  139. SpSimDbgCmResourceTypeToText(
  140. UCHAR Type
  141. )
  142. {
  143. switch (Type) {
  144. case CmResourceTypePort:
  145. return "CmResourceTypePort";
  146. case CmResourceTypeInterrupt:
  147. return "CmResourceTypeInterrupt";
  148. case CmResourceTypeMemory:
  149. return "CmResourceTypeMemory";
  150. case CmResourceTypeDma:
  151. return "CmResourceTypeDma";
  152. case CmResourceTypeDeviceSpecific:
  153. return "CmResourceTypeDeviceSpecific";
  154. case CmResourceTypeBusNumber:
  155. return "CmResourceTypeBusNumber";
  156. case CmResourceTypeConfigData:
  157. return "CmResourceTypeConfigData";
  158. case CmResourceTypeDevicePrivate:
  159. return "CmResourceTypeDevicePrivate";
  160. case CmResourceTypePcCardConfig:
  161. return "CmResourceTypePcCardConfig";
  162. default:
  163. return "*** INVALID RESOURCE TYPE ***";
  164. }
  165. }
  166. VOID
  167. SpSimDbgPrintIoResource(
  168. IN LONG Level,
  169. IN PIO_RESOURCE_DESCRIPTOR D
  170. )
  171. {
  172. ULONG i;
  173. PUCHAR t;
  174. if (Level <= SpSimDebug) {
  175. t = SpSimDbgCmResourceTypeToText(D->Type);
  176. DbgPrint(" IoResource Descriptor dump: Descriptor @0x%x\n", D);
  177. DbgPrint(" Option = 0x%x\n", D->Option);
  178. DbgPrint(" Type = %d (%s)\n", D->Type, t);
  179. DbgPrint(" ShareDisposition = %d\n", D->ShareDisposition);
  180. DbgPrint(" Flags = 0x%04X\n", D->Flags);
  181. for ( i = 0; i < 6 ; i+=3 ) {
  182. DbgPrint(" Data[%d] = %08x %08x %08x\n",
  183. i,
  184. D->u.DevicePrivate.Data[i],
  185. D->u.DevicePrivate.Data[i+1],
  186. D->u.DevicePrivate.Data[i+2]);
  187. }
  188. }
  189. }
  190. VOID
  191. SpSimDbgPrintIoResReqList(
  192. IN LONG Level,
  193. IN PIO_RESOURCE_REQUIREMENTS_LIST IoResReqList
  194. )
  195. {
  196. ULONG numlists;
  197. PIO_RESOURCE_LIST list;
  198. if (Level <= SpSimDebug) {
  199. if (IoResReqList) {
  200. numlists = IoResReqList->AlternativeLists;
  201. list = IoResReqList->List;
  202. DbgPrint(" IO_RESOURCE_REQUIREMENTS_LIST\n");
  203. DbgPrint(" AlternativeLists %d\n", numlists );
  204. while (numlists--) {
  205. PIO_RESOURCE_DESCRIPTOR resource = list->Descriptors;
  206. ULONG count = list->Count;
  207. DbgPrint("\n List[%d].Count = %d\n", numlists, count);
  208. while (count--) {
  209. SpSimDbgPrintIoResource(Level, resource++);
  210. }
  211. list = (PIO_RESOURCE_LIST)resource;
  212. }
  213. DbgPrint("\n");
  214. } else {
  215. DbgPrint(" IO_RESOURCE_REQUIREMENTS_LIST\n");
  216. DbgPrint(" *** EMPTY ***\n");
  217. }
  218. }
  219. }
  220. VOID
  221. SpSimDbgPrintPartialResource(
  222. IN LONG Level,
  223. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR D
  224. )
  225. {
  226. ULONG i;
  227. PUCHAR t;
  228. if (Level <= SpSimDebug) {
  229. if (D) {
  230. t = SpSimDbgCmResourceTypeToText(D->Type);
  231. DbgPrint(" Partial Resource Descriptor @0x%x\n", D);
  232. DbgPrint(" Type = %d (%s)\n", D->Type, t);
  233. DbgPrint(" ShareDisposition = %d\n", D->ShareDisposition);
  234. DbgPrint(" Flags = 0x%04X\n", D->Flags);
  235. for ( i = 0; i < 3 ; i+=3 ) {
  236. DbgPrint(" Data[%d] = %08x %08x %08x\n",
  237. i,
  238. D->u.DevicePrivate.Data[i],
  239. D->u.DevicePrivate.Data[i+1],
  240. D->u.DevicePrivate.Data[i+2]);
  241. }
  242. } else {
  243. DbgPrint(" Partial Resource Descriptor EMPTY!!\n");
  244. }
  245. }
  246. }
  247. PCM_PARTIAL_RESOURCE_DESCRIPTOR
  248. SpSimNextPartialDescriptor(
  249. PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
  250. )
  251. /*++
  252. Routine Description:
  253. Given a pointer to a CmPartialResourceDescriptor, return a pointer
  254. to the next descriptor in the same list.
  255. This is only done in a routine (rather than a simple descriptor++)
  256. because if the variable length resource CmResourceTypeDeviceSpecific.
  257. Arguments:
  258. Descriptor - Pointer to the descriptor being advanced over.
  259. Return Value:
  260. Pointer to the next descriptor in the same list (or byte beyond
  261. end of list).
  262. --*/
  263. {
  264. PCM_PARTIAL_RESOURCE_DESCRIPTOR nextDescriptor;
  265. nextDescriptor = Descriptor + 1;
  266. if (Descriptor->Type == CmResourceTypeDeviceSpecific) {
  267. //
  268. // This (old) descriptor is followed by DataSize bytes
  269. // of device specific data, ie, not immediatelly by the
  270. // next descriptor. Adjust nextDescriptor by this amount.
  271. //
  272. nextDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
  273. ((PCHAR)nextDescriptor + Descriptor->u.DeviceSpecificData.DataSize);
  274. }
  275. return nextDescriptor;
  276. }
  277. VOID
  278. SpSimDbgPrintCmResList(
  279. IN LONG Level,
  280. IN PCM_RESOURCE_LIST ResourceList
  281. )
  282. {
  283. ULONG numlists;
  284. PCM_FULL_RESOURCE_DESCRIPTOR full;
  285. PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor;
  286. if (Level <= SpSimDebug) {
  287. if (ResourceList) {
  288. numlists = ResourceList->Count;
  289. full = ResourceList->List;
  290. DbgPrint(" CM_RESOURCE_LIST (List Count = %d)\n",
  291. numlists);
  292. while (numlists--) {
  293. PCM_PARTIAL_RESOURCE_LIST partial = &full->PartialResourceList;
  294. ULONG count = partial->Count;
  295. descriptor = partial->PartialDescriptors;
  296. while (count--) {
  297. SpSimDbgPrintPartialResource(Level, descriptor);
  298. descriptor = SpSimNextPartialDescriptor(descriptor);
  299. }
  300. full = (PCM_FULL_RESOURCE_DESCRIPTOR)descriptor;
  301. }
  302. DbgPrint("\n");
  303. } else {
  304. DbgPrint(" CM_RESOURCE_LIST EMPTY!!!\n");
  305. }
  306. }
  307. }
  308. #endif