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.

411 lines
9.7 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1999 - 1999
  3. Module Name:
  4. debug.c
  5. Abstract:
  6. Common code for debugging.
  7. Author:
  8. Keisuke Tsuchida (KeisukeT)
  9. Environment:
  10. kernel mode only
  11. Notes:
  12. Revision History:
  13. --*/
  14. //
  15. // Includes
  16. //
  17. #include "stddef.h"
  18. #include "wdm.h"
  19. #include "debug.h"
  20. //
  21. // Globals
  22. //
  23. ULONG DebugTraceLevel = MIN_TRACE | DEBUG_FLAG_DISABLE;
  24. // ULONG DebugTraceLevel = MAX_TRACE | DEBUG_FLAG_DISABLE | TRACE_PROC_ENTER | TRACE_PROC_LEAVE;
  25. LONG AllocateCount = 0;
  26. ULONG DebugDumpMax = MAX_DUMPSIZE;
  27. PVOID
  28. MyAllocatePool(
  29. IN POOL_TYPE PoolType,
  30. IN ULONG ulNumberOfBytes
  31. )
  32. /*++
  33. Routine Description:
  34. Wrapper for pool allocation. Use tag to avoid heap corruption.
  35. Arguments:
  36. PoolType - type of pool memory to allocate
  37. ulNumberOfBytes - number of bytes to allocate
  38. Return Value:
  39. Pointer to the allocated memory
  40. --*/
  41. {
  42. PVOID pvRet;
  43. DebugTrace(TRACE_PROC_ENTER,("MyAllocatePool: Enter.. Size = %d\n", ulNumberOfBytes));
  44. pvRet = ExAllocatePoolWithTag(PoolType,
  45. ulNumberOfBytes,
  46. NAME_POOLTAG);
  47. #if DBG
  48. if(NULL == pvRet){
  49. DebugTrace(TRACE_ERROR,("MyAllocatePool: ERROR!! Cannot allocate pool.\n"));
  50. } else {
  51. if(++AllocateCount > MAXNUM_POOL){
  52. DebugTrace(TRACE_WARNING,("MyAllocatePool: WARNING!! Allocate called %dtimes more than Free\n", MAXNUM_POOL));
  53. }
  54. DebugTrace(TRACE_STATUS,("MyAllocatePool: Count = %d\n", AllocateCount));
  55. }
  56. #endif // DBG
  57. DebugTrace(TRACE_PROC_LEAVE,("MyAllocatePool: Leaving.. pvRet = %x\n", pvRet));
  58. return pvRet;
  59. }
  60. VOID
  61. MyFreePool(
  62. IN PVOID pvAddress
  63. )
  64. /*++
  65. Routine Description:
  66. Wrapper for pool free. Check tag to avoid heap corruption
  67. Arguments:
  68. pvAddress - Pointer to the allocated memory
  69. Return Value:
  70. none.
  71. --*/
  72. {
  73. DebugTrace(TRACE_PROC_ENTER,("USFreePool: Enter..\n"));
  74. #if DBG
  75. {
  76. ULONG ulTag;
  77. ulTag = *((PULONG)pvAddress-1);
  78. // if( (NAME_POOLTAG == ulTag) || (DebugTraceLevel & TRACE_IGNORE_TAG) ){
  79. if(NAME_POOLTAG == ulTag){
  80. if(--AllocateCount < 0){
  81. DebugTrace(TRACE_WARNING,("MyFreePool: Warning!! Free called more than Allocate.\n"));
  82. }
  83. } else {
  84. DebugTrace(TRACE_WARNING,("MyFreePool: WARNING!! tag = %c%c%c%c\n",
  85. ((PUCHAR)&ulTag)[0],
  86. ((PUCHAR)&ulTag)[1],
  87. ((PUCHAR)&ulTag)[2],
  88. ((PUCHAR)&ulTag)[3] ));
  89. }
  90. }
  91. #endif
  92. ExFreePool(pvAddress);
  93. DebugTrace(TRACE_PROC_LEAVE,("MyFreePool: Leaving.. Return = NONE\n"));
  94. }
  95. #if DBG
  96. VOID
  97. MyDebugInit(
  98. IN PUNICODE_STRING pRegistryPath
  99. )
  100. /*++
  101. Routine Description:
  102. Read DebugTraceLevel key from driver's registry if exists.
  103. Arguments:
  104. pRegistryPath - pointer to a unicode string representing the path
  105. to driver-specific key in the registry
  106. Return Value:
  107. none.
  108. --*/
  109. {
  110. HANDLE hDriverRegistry;
  111. OBJECT_ATTRIBUTES ObjectAttributes;
  112. UNICODE_STRING unicodeKeyName;
  113. ULONG DataSize;
  114. PKEY_VALUE_PARTIAL_INFORMATION pValueInfo;
  115. NTSTATUS Status;
  116. DebugTrace(TRACE_PROC_ENTER,("MyDebugInit: Enter... \n"));
  117. //
  118. // Initialize local variables.
  119. //
  120. Status = STATUS_SUCCESS;
  121. hDriverRegistry = NULL;
  122. pValueInfo = NULL;
  123. DataSize = 0;
  124. //
  125. // Initialize object attribute and open registry key.
  126. //
  127. RtlZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
  128. InitializeObjectAttributes(&ObjectAttributes,
  129. pRegistryPath,
  130. OBJ_CASE_INSENSITIVE,
  131. NULL,
  132. NULL);
  133. Status = ZwOpenKey(&hDriverRegistry,
  134. KEY_READ,
  135. &ObjectAttributes);
  136. if(!NT_SUCCESS(Status)){
  137. DebugTrace(TRACE_ERROR,("MyDebugInit: ERROR!! Can't open driver registry key.\n"));
  138. goto MyDebugInit_return;
  139. }
  140. //
  141. // Read "DebugTraceLevel" key.
  142. //
  143. DebugTrace(TRACE_CRITICAL,("MyDebugInit: Query %wZ\\%ws.\n", pRegistryPath, REG_DEBUGLEVEL));
  144. //
  145. // Query required size.
  146. //
  147. RtlInitUnicodeString(&unicodeKeyName, REG_DEBUGLEVEL);
  148. Status = ZwQueryValueKey(hDriverRegistry,
  149. &unicodeKeyName,
  150. KeyValuePartialInformation,
  151. NULL,
  152. 0,
  153. &DataSize);
  154. if( (Status != STATUS_BUFFER_OVERFLOW)
  155. && (Status != STATUS_BUFFER_TOO_SMALL)
  156. && (Status != STATUS_SUCCESS) )
  157. {
  158. if(Status == STATUS_OBJECT_NAME_NOT_FOUND){
  159. DebugTrace(TRACE_STATUS,("MyDebugInit: DebugTraceLevel doesn't exist. Use default(0x%x).\n", DebugTraceLevel));
  160. } else {
  161. DebugTrace(TRACE_ERROR,("MyDebugInit: ERROR!! ZwQueryValueKey failed. Status=0x%x\n", Status));
  162. }
  163. goto MyDebugInit_return;
  164. }
  165. //
  166. // Check size of data.
  167. //
  168. if (MAX_TEMPBUF < DataSize) {
  169. DebugTrace(TRACE_ERROR, ("MyDebugInit: ERROR!! DataSize (0x%x) is too big.\n", DataSize));
  170. goto MyDebugInit_return;
  171. }
  172. if (0 == DataSize) {
  173. DebugTrace(TRACE_ERROR, ("MyDebugInit: ERROR!! Cannot retrieve required data size.\n"));
  174. goto MyDebugInit_return;
  175. }
  176. //
  177. // Allocate memory for temp buffer. size +2 for NULL.
  178. //
  179. pValueInfo = MyAllocatePool(NonPagedPool, DataSize+2);
  180. if(NULL == pValueInfo){
  181. DebugTrace(TRACE_CRITICAL, ("MyDebugInit: ERROR!! Buffer allocate failed.\n"));
  182. Status = STATUS_INSUFFICIENT_RESOURCES;
  183. goto MyDebugInit_return;
  184. }
  185. RtlZeroMemory(pValueInfo, DataSize+2);
  186. //
  187. // Query specified value.
  188. //
  189. Status = ZwQueryValueKey(hDriverRegistry,
  190. &unicodeKeyName,
  191. KeyValuePartialInformation,
  192. pValueInfo,
  193. DataSize,
  194. &DataSize);
  195. if(!NT_SUCCESS(Status)){
  196. DebugTrace(TRACE_ERROR, ("MyDebugInit: ERROR!! ZwQueryValueKey failed.\n"));
  197. goto MyDebugInit_return;
  198. }
  199. //
  200. // Set DebugTraceLevel.
  201. //
  202. DebugTraceLevel = *((PULONG)pValueInfo->Data);
  203. DebugTrace(TRACE_CRITICAL, ("MyDebugInit: Reg-key found. DebugTraceLevel=0x%x.\n", *((PULONG)pValueInfo->Data)));
  204. MyDebugInit_return:
  205. //
  206. // Clean up.
  207. //
  208. if(pValueInfo){
  209. MyFreePool(pValueInfo);
  210. }
  211. if(NULL != hDriverRegistry){
  212. ZwClose(hDriverRegistry);
  213. }
  214. DebugTrace(TRACE_PROC_LEAVE,("MyDebugInit: Leaving... Status=0x%x, Ret=VOID.\n", Status));
  215. return;
  216. }
  217. VOID
  218. MyDumpMemory(
  219. PUCHAR pDumpBuffer,
  220. ULONG dwSize,
  221. BOOLEAN bRead
  222. )
  223. {
  224. NTSTATUS Status;
  225. ULONG ulCounter;
  226. ULONG ulMaxSize;
  227. //
  228. // Check the flag first.
  229. //
  230. if(bRead){
  231. if(!(DebugTraceLevel & TRACE_FLAG_DUMP_READ)){
  232. return;
  233. }
  234. } else { // if(bRead)
  235. if(!(DebugTraceLevel & TRACE_FLAG_DUMP_WRITE)){
  236. return;
  237. }
  238. } // if(bRead)
  239. DebugTrace(TRACE_PROC_ENTER,("MyDebugDump: Enter... \n"));
  240. //
  241. // Initialize local.
  242. //
  243. Status = STATUS_SUCCESS;
  244. ulCounter = 0;
  245. ulMaxSize = DebugDumpMax;
  246. //
  247. // Check the arguments.
  248. //
  249. if(NULL == pDumpBuffer){
  250. DebugTrace(TRACE_WARNING,("MyDebugDump: WARNING!! pDumpBuffer = NULL \n"));
  251. Status = STATUS_INVALID_PARAMETER_1;
  252. goto MyDumpMemory_return;
  253. }
  254. if(0 == dwSize){
  255. DebugTrace(TRACE_STATUS,("MyDebugDump: WARNING!! dwSize = 0 \n"));
  256. Status = STATUS_INVALID_PARAMETER_2;
  257. goto MyDumpMemory_return;
  258. }
  259. if(bRead){
  260. DebugTrace(TRACE_ERROR,("MyDebugDump: Received buffer. Size=0x%x.\n", dwSize));
  261. } else {
  262. DebugTrace(TRACE_ERROR,("MyDebugDump: Passing buffer. Size=0x%x.\n", dwSize));
  263. }
  264. /*
  265. //
  266. // Probe the buffer.
  267. //
  268. try {
  269. ProbeForRead(pDumpBuffer,
  270. dwSize,
  271. sizeof(UCHAR));
  272. } except(EXCEPTION_EXECUTE_HANDLER) {
  273. Status = GetExceptionCode();
  274. DebugTrace(TRACE_ERROR,("MyDebugDump: Buffer pointer (0x%x) is invalid. Status=0x%x\n", pDumpBuffer, Status));
  275. goto MyDumpMemory_return;
  276. } // except
  277. */
  278. //
  279. // Max dump size = 1k;
  280. //
  281. ulMaxSize = min(ulMaxSize , dwSize);
  282. //
  283. // Dump the buffer.
  284. //
  285. for(ulCounter = 0; ulCounter < ulMaxSize; ulCounter++){
  286. if(0 == (ulCounter & 0xfF)){
  287. DbgPrint("\n");
  288. DbgPrint(NAME_DRIVER);
  289. DbgPrint(" +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f\n");
  290. DbgPrint(NAME_DRIVER);
  291. DbgPrint("------------------------------------------------------------\n");
  292. }
  293. if(0 == (ulCounter & 0xf)){
  294. DbgPrint(NAME_DRIVER);
  295. DbgPrint("%p :", pDumpBuffer+ulCounter);
  296. }
  297. DbgPrint(" %02x", *(pDumpBuffer+ulCounter));
  298. if(0x7 == (ulCounter & 0xf)){
  299. DbgPrint(" -");
  300. }
  301. if(0xf == (ulCounter & 0xf)){
  302. DbgPrint("\n");
  303. }
  304. }
  305. DbgPrint("\n");
  306. DbgPrint(NAME_DRIVER);
  307. DbgPrint("------------------------------------------------------------\n\n");
  308. MyDumpMemory_return:
  309. DebugTrace(TRACE_PROC_LEAVE,("MyDebugDump: Leaving... Status=0x%x, Ret=VOID.\n", Status));
  310. return;
  311. } // MyDumpMemory(
  312. #endif // DBG