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.

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