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.

380 lines
7.0 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. DBGSRVIC.C
  5. Abstract:
  6. Devug services exported by USBD
  7. Environment:
  8. kernel mode only
  9. Notes:
  10. Revision History:
  11. 09-29-95 : created
  12. --*/
  13. #include "wdm.h"
  14. #include "stdarg.h"
  15. #include "stdio.h"
  16. #include "usbdi.h" //public data structures
  17. #include "hcdi.h"
  18. #include "usbd.h" //private data strutures
  19. #if DBG
  20. // default debug trace level is 0
  21. #ifdef DEBUG1
  22. ULONG USBD_Debug_Trace_Level = 1;
  23. #else
  24. #ifdef DEBUG2
  25. ULONG USBD_Debug_Trace_Level = 2;
  26. #else
  27. #ifdef DEBUG3
  28. ULONG USBD_Debug_Trace_Level = 3;
  29. #else
  30. ULONG USBD_Debug_Trace_Level = 0;
  31. #endif /* DEBUG3 */
  32. #endif /* DEBUG2 */
  33. #endif /* DEBUG1 */
  34. LONG USBDTotalHeapAllocated = 0;
  35. #endif /* DBG */
  36. #ifdef DEBUG_LOG
  37. struct USBD_LOG_ENTRY {
  38. CHAR le_name[4]; // Identifying string
  39. ULONG_PTR le_info1; // entry specific info
  40. ULONG_PTR le_info2; // entry specific info
  41. ULONG_PTR le_info3; // entry specific info
  42. }; /* USBD_LOG_ENTRY */
  43. struct USBD_LOG_ENTRY *LStart = 0; // No log yet
  44. struct USBD_LOG_ENTRY *LPtr;
  45. struct USBD_LOG_ENTRY *LEnd;
  46. #endif /* DEBUG_LOG */
  47. VOID
  48. USBD_Debug_LogEntry(
  49. IN CHAR *Name,
  50. IN ULONG_PTR Info1,
  51. IN ULONG_PTR Info2,
  52. IN ULONG_PTR Info3
  53. )
  54. /*++
  55. Routine Description:
  56. Adds an Entry to USBD log.
  57. Arguments:
  58. Return Value:
  59. None.
  60. --*/
  61. {
  62. #ifdef DEBUG_LOG
  63. if (LStart == 0)
  64. return;
  65. if (LPtr > LStart)
  66. LPtr -= 1; // Decrement to next entry
  67. else
  68. LPtr = LEnd;
  69. RtlCopyMemory(LPtr->le_name, Name, 4);
  70. // LPtr->le_ret = (stk[1] & 0x00ffffff) | (CurVMID()<<24);
  71. LPtr->le_info1 = Info1;
  72. LPtr->le_info2 = Info2;
  73. LPtr->le_info3 = Info3;
  74. #endif /* DEBUG_LOG */
  75. return;
  76. }
  77. #ifdef DEBUG_LOG
  78. VOID
  79. USBD_LogInit(
  80. )
  81. /*++
  82. Routine Description:
  83. Init the debug log - remember interesting information in a circular buffer
  84. Arguments:
  85. LogSize - maximum size of log in pages
  86. Return Value:
  87. None.
  88. --*/
  89. {
  90. ULONG LogSize = 4096; //1 page of log entries
  91. LStart = ExAllocatePool(NonPagedPool,
  92. LogSize);
  93. if (LStart) {
  94. LPtr = LStart;
  95. // Point the end (and first entry) 1 entry from the end of the segment
  96. LEnd = LStart + (LogSize / sizeof(struct USBD_LOG_ENTRY)) - 1;
  97. }
  98. return;
  99. }
  100. #endif /* DEBUG_LOG */
  101. //
  102. // tag buffer we use to mark heap blocks we allocate
  103. //
  104. typedef struct _HEAP_TAG_BUFFER {
  105. ULONG Sig;
  106. ULONG Length;
  107. } HEAP_TAG_BUFFER, *PHEAP_TAG_BUFFER;
  108. PVOID
  109. USBD_Debug_GetHeap(
  110. IN POOL_TYPE PoolType,
  111. IN ULONG NumberOfBytes,
  112. IN ULONG Signature,
  113. IN PLONG TotalAllocatedHeapSpace
  114. )
  115. /*++
  116. Routine Description:
  117. Debug routine, used to debug heap problems. We are using this since
  118. most NT debug functions are not supported by NTKERN.
  119. Arguments:
  120. PoolType - pool type passed to ExAllocatePool
  121. NumberOfBytes - number of bytes for item
  122. Signature - four byte signature supplied by caller
  123. TotalAllocatedHeapSpace - pointer to variable where client stores
  124. the total accumulated heap space allocated.
  125. Return Value:
  126. pointer to allocated memory
  127. --*/
  128. {
  129. PUCHAR p;
  130. #ifdef DEBUG_HEAP
  131. ULONG *stk = NULL;
  132. PHEAP_TAG_BUFFER tagBuffer;
  133. // we call ExAllocatePoolWithTag but no tag will be added
  134. // when running under NTKERN
  135. #ifdef _M_IX86
  136. _asm mov stk, ebp
  137. #endif
  138. p = (PUCHAR) ExAllocatePoolWithTag(PoolType,
  139. NumberOfBytes + sizeof(HEAP_TAG_BUFFER),
  140. Signature);
  141. if (p) {
  142. tagBuffer = (PHEAP_TAG_BUFFER) p;
  143. tagBuffer->Sig = Signature;
  144. tagBuffer->Length = NumberOfBytes;
  145. p += sizeof(HEAP_TAG_BUFFER);
  146. *TotalAllocatedHeapSpace += NumberOfBytes;
  147. }
  148. LOGENTRY((PUCHAR) &Signature, 0, 0, 0);
  149. #ifdef _M_IX86
  150. LOGENTRY("GetH", p, NumberOfBytes, stk[1] & 0x00FFFFFF);
  151. #else
  152. LOGENTRY("GetH", p, NumberOfBytes, 0);
  153. #endif
  154. #else
  155. p = (PUCHAR) ExAllocatePoolWithTag(PoolType,
  156. NumberOfBytes,
  157. Signature);
  158. #endif /* DEBUG_HEAP */
  159. return p;
  160. }
  161. VOID
  162. USBD_Debug_RetHeap(
  163. IN PVOID P,
  164. IN ULONG Signature,
  165. IN PLONG TotalAllocatedHeapSpace
  166. )
  167. /*++
  168. Routine Description:
  169. Debug routine, used to debug heap problems. We are using this since
  170. most NT debug functions are not supported by NTKERN.
  171. Arguments:
  172. P - pointer to free
  173. Return Value:
  174. none.
  175. --*/
  176. {
  177. #ifdef DEBUG_HEAP
  178. PHEAP_TAG_BUFFER tagBuffer;
  179. ULONG *stk = NULL ;
  180. USBD_ASSERT(P != 0);
  181. #ifdef _M_IX86
  182. _asm mov stk, ebp
  183. #endif
  184. tagBuffer = (PHEAP_TAG_BUFFER) ((PUCHAR)P - sizeof(HEAP_TAG_BUFFER));
  185. *TotalAllocatedHeapSpace -= tagBuffer->Length;
  186. LOGENTRY((PUCHAR) &Signature, 0, 0, 0);
  187. #ifdef _M_IX86
  188. LOGENTRY("RetH", P, tagBuffer->Length, stk[1] & 0x00FFFFFF);
  189. #else
  190. LOGENTRY("RetH", P, tagBuffer->Length, 0);
  191. #endif
  192. USBD_ASSERT(*TotalAllocatedHeapSpace >= 0);
  193. USBD_ASSERT(tagBuffer->Sig == Signature);
  194. // fill the buffer with bad data
  195. RtlFillMemory(P, tagBuffer->Length, 0xff);
  196. tagBuffer->Sig = USBD_FREE_TAG;
  197. // free the original block
  198. ExFreePool(tagBuffer);
  199. #else
  200. ExFreePool(P);
  201. #endif /* DEBUG_HEAP */
  202. }
  203. #if DBG
  204. ULONG
  205. _cdecl
  206. USBD_KdPrintX(
  207. PCH Format,
  208. ...
  209. )
  210. {
  211. va_list list;
  212. int i;
  213. int arg[5];
  214. va_start(list, Format);
  215. for (i=0; i<4; i++)
  216. arg[i] = va_arg(list, int);
  217. DbgPrint(Format, arg[0], arg[1], arg[2], arg[3]);
  218. return 0;
  219. }
  220. VOID
  221. USBD_Warning(
  222. PUSBD_DEVICE_DATA DeviceData,
  223. PUCHAR Message,
  224. BOOLEAN DebugBreak
  225. )
  226. {
  227. DbgPrint("USBD: Warning ****************************************************************\n");
  228. if (DeviceData) {
  229. DbgPrint("Device PID %04.4x, VID %04.4x\n",
  230. DeviceData->DeviceDescriptor.idProduct,
  231. DeviceData->DeviceDescriptor.idVendor);
  232. }
  233. DbgPrint("%s", Message);
  234. DbgPrint("******************************************************************************\n");
  235. if (DebugBreak) {
  236. DBGBREAK();
  237. }
  238. }
  239. VOID
  240. USBD_Assert(
  241. IN PVOID FailedAssertion,
  242. IN PVOID FileName,
  243. IN ULONG LineNumber,
  244. IN PCHAR Message
  245. )
  246. /*++
  247. Routine Description:
  248. Debug Assert function.
  249. Arguments:
  250. DeviceObject - pointer to a device object
  251. Irp - pointer to an I/O Request Packet
  252. Return Value:
  253. --*/
  254. {
  255. #ifdef NTKERN
  256. // this makes the compiler generate a ret
  257. ULONG stop = 1;
  258. assert_loop:
  259. #endif
  260. // just call the NT assert function and stop
  261. // in the debugger.
  262. RtlAssert( FailedAssertion, FileName, LineNumber, Message );
  263. // loop here to prevent users from going past
  264. // are assert before we can look at it
  265. #ifdef NTKERN
  266. DBGBREAK();
  267. if (stop) {
  268. goto assert_loop;
  269. }
  270. #endif
  271. return;
  272. }
  273. #endif /* DBG */