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.

407 lines
10 KiB

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