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.

293 lines
5.9 KiB

  1. #if DBG
  2. #include <irda.h>
  3. #include <stdio.h>
  4. #include <stdarg.h>
  5. #include <string.h>
  6. CHAR DbgMsgs[DBG_MSG_CNT][MAX_MSG_LEN];
  7. UINT First, Last;
  8. CTETimer DbgTimer;
  9. BOOLEAN TimerRunning;
  10. CTELock DbgLock;
  11. PIRP pDbgIrp;
  12. UCHAR *IrpBuf;
  13. ULONG IrpBufLen;
  14. ULONG IrpBufWritten;
  15. VOID DbgTimerExp(CTEEvent *Event, void *Arg);
  16. VOID
  17. DbgMsgInit()
  18. {
  19. pDbgIrp = NULL;
  20. First = 0;
  21. Last = 0;
  22. TimerRunning = FALSE;
  23. CTEInitLock(&DbgLock);
  24. CTEInitTimer(&DbgTimer);
  25. }
  26. VOID
  27. DbgMsgUninit()
  28. {
  29. CTELockHandle LockHandle;
  30. KIRQL Irql;
  31. CTEGetLock(&DbgLock, &LockHandle);
  32. if (pDbgIrp)
  33. {
  34. IoAcquireCancelSpinLock(&Irql);
  35. IoSetCancelRoutine(pDbgIrp, NULL);
  36. IoReleaseCancelSpinLock(Irql);
  37. pDbgIrp->IoStatus.Information = 0;
  38. pDbgIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
  39. DbgPrint("Complete irp!\n");
  40. IoCompleteRequest(pDbgIrp, IO_NO_INCREMENT);
  41. pDbgIrp = NULL;
  42. }
  43. CTEFreeLock(&DbgLock, LockHandle);
  44. }
  45. VOID
  46. DbgMsg(CHAR *Format, ...)
  47. {
  48. va_list Args;
  49. CTELockHandle LockHandle;
  50. CHAR Temp[MAX_MSG_LEN];
  51. LARGE_INTEGER Time;
  52. ULONG UlongTime;
  53. KeQueryTickCount(&Time);
  54. //
  55. // change it milliseconds and stuff it in a dword
  56. //
  57. UlongTime=(ULONG)((Time.QuadPart * KeQueryTimeIncrement()) / 10000);
  58. sprintf(Temp,"%6d.%03d - ",UlongTime/1000, UlongTime%1000);
  59. va_start(Args, Format);
  60. vsprintf(&Temp[strlen(Temp)], Format, Args);
  61. if (DbgOutput & DBG_OUTPUT_DEBUGGER)
  62. {
  63. DbgPrint(Temp);
  64. }
  65. if (DbgOutput & DBG_OUTPUT_BUFFER)
  66. {
  67. CTEGetLock(&DbgLock, &LockHandle);
  68. strcpy(DbgMsgs[Last], Temp);
  69. Last++;
  70. if (Last == DBG_MSG_CNT)
  71. Last = 0;
  72. if (First == Last)
  73. {
  74. First++;
  75. if (First == DBG_MSG_CNT)
  76. First = 0;
  77. }
  78. if (pDbgIrp && !TimerRunning)
  79. {
  80. CTEStartTimer(&DbgTimer, DBG_TIMER_INTERVAL,
  81. DbgTimerExp, NULL);
  82. TimerRunning = TRUE;
  83. }
  84. CTEFreeLock(&DbgLock, LockHandle);
  85. }
  86. va_end(Args);
  87. }
  88. NTSTATUS
  89. FillDbgIrp(UCHAR Msg[])
  90. {
  91. NTSTATUS Status = STATUS_PENDING;
  92. UINT i;
  93. if ((IrpBufLen - IrpBufWritten) < MAX_MSG_LEN)
  94. {
  95. Status = STATUS_SUCCESS;
  96. }
  97. else
  98. {
  99. Msg[MAX_MSG_LEN - 1] = 0; // just to be sure
  100. i = 0;
  101. while (1)
  102. {
  103. IrpBuf[IrpBufWritten++] = Msg[i];
  104. if (Msg[i] == 0)
  105. break;
  106. i++;
  107. }
  108. }
  109. return Status;
  110. }
  111. VOID CancelDbgIrp(
  112. PDEVICE_OBJECT DeviceObject,
  113. PIRP pIrp)
  114. {
  115. // DbgPrint("CancelDbgIrp %x\n", pIrp);
  116. pDbgIrp = NULL;
  117. IoReleaseCancelSpinLock(pIrp->CancelIrql);
  118. pIrp->IoStatus.Status = STATUS_CANCELLED;
  119. pIrp->IoStatus.Information = 0;
  120. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  121. }
  122. NTSTATUS
  123. DbgMsgIrp(
  124. PIRP pIrp,
  125. PIO_STACK_LOCATION pIrpSp)
  126. {
  127. CTELockHandle LockHandle;
  128. NTSTATUS Status = STATUS_PENDING;
  129. if (pDbgIrp != NULL)
  130. return STATUS_DEVICE_BUSY;
  131. CTEGetLock(&DbgLock, &LockHandle);
  132. IrpBufLen = pIrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  133. IrpBufWritten = 0;
  134. if (IrpBufLen < MAX_MSG_LEN)
  135. {
  136. CTEFreeLock(&DbgLock, LockHandle);
  137. return STATUS_BUFFER_OVERFLOW;
  138. }
  139. IrpBuf = pIrp->AssociatedIrp.SystemBuffer;
  140. while (First != Last)
  141. {
  142. Status = FillDbgIrp(DbgMsgs[First]);
  143. if (Status == STATUS_SUCCESS)
  144. break;
  145. First++;
  146. if (First == DBG_MSG_CNT)
  147. First = 0;
  148. }
  149. if (Status == STATUS_SUCCESS)
  150. {
  151. pIrp->IoStatus.Information = IrpBufWritten;
  152. }
  153. else if (Status == STATUS_PENDING)
  154. {
  155. KIRQL Irql;
  156. PDRIVER_CANCEL PrevCancel;
  157. pDbgIrp = pIrp;
  158. IoMarkIrpPending(pIrp);
  159. IoAcquireCancelSpinLock(&Irql);
  160. PrevCancel = IoSetCancelRoutine(pIrp, CancelDbgIrp);
  161. CTEAssert(PrevCancel == NULL);
  162. IoReleaseCancelSpinLock(Irql);
  163. if (IrpBufWritten != 0)
  164. {
  165. CTEStartTimer(&DbgTimer, DBG_TIMER_INTERVAL,
  166. DbgTimerExp, NULL);
  167. TimerRunning = TRUE;
  168. }
  169. }
  170. CTEFreeLock(&DbgLock, LockHandle);
  171. //DbgPrint("DbgIrp status %x, bw %d, irp %x\n", Status, IrpBufWritten, pIrp);
  172. return Status;
  173. }
  174. VOID
  175. DbgTimerExp(CTEEvent *Event, void *Arg)
  176. {
  177. CTELockHandle LockHandle;
  178. PIRP pIrp;
  179. KIRQL Irql;
  180. //DbgPrint("Texp\n");
  181. if (pDbgIrp == NULL)
  182. {
  183. DbgPrint("DbgIrp is null\n");
  184. return;
  185. }
  186. IoAcquireCancelSpinLock(&Irql);
  187. IoSetCancelRoutine(pDbgIrp, NULL);
  188. IoReleaseCancelSpinLock(Irql);
  189. if (pDbgIrp->Cancel)
  190. {
  191. DbgPrint("DbgIrp is being canceled\n");
  192. pDbgIrp = NULL;
  193. return;
  194. }
  195. CTEGetLock(&DbgLock, &LockHandle);
  196. TimerRunning = FALSE;
  197. while (First != Last)
  198. {
  199. if (FillDbgIrp(DbgMsgs[First]) == STATUS_SUCCESS)
  200. break;
  201. First++;
  202. if (First == DBG_MSG_CNT)
  203. First = 0;
  204. }
  205. pIrp = pDbgIrp;
  206. pDbgIrp = NULL;
  207. CTEFreeLock(&DbgLock, LockHandle);
  208. pIrp->IoStatus.Information = IrpBufWritten;
  209. pIrp->IoStatus.Status = STATUS_SUCCESS;
  210. // DbgPrint("Comp bw %d, irp %x\n", IrpBufWritten, pIrp);
  211. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  212. }
  213. #endif