1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/kd64/kdlock.c
5 * PURPOSE: KD64 Port Lock and Breakin Support
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 /* PRIVATE FUNCTIONS *********************************************************/
16
17 VOID
18 NTAPI
KdpPortLock(VOID)19 KdpPortLock(VOID)
20 {
21 /* Acquire the lock */
22 KiAcquireSpinLock(&KdpDebuggerLock);
23 }
24
25 VOID
26 NTAPI
KdpPortUnlock(VOID)27 KdpPortUnlock(VOID)
28 {
29 /* Release the lock */
30 KiReleaseSpinLock(&KdpDebuggerLock);
31 }
32
33 BOOLEAN
34 NTAPI
KdpPollBreakInWithPortLock(VOID)35 KdpPollBreakInWithPortLock(VOID)
36 {
37 BOOLEAN DoBreak = FALSE;
38
39 /* First make sure that KD is enabled */
40 if (KdDebuggerEnabled)
41 {
42 /* Check if a CTRL-C is in the queue */
43 if (KdpContext.KdpControlCPending)
44 {
45 /* Set it and prepare for break */
46 DoBreak = TRUE;
47 KdpContext.KdpControlCPending = FALSE;
48 }
49 else
50 {
51 /* Now get a packet */
52 if (KdReceivePacket(PACKET_TYPE_KD_POLL_BREAKIN,
53 NULL,
54 NULL,
55 NULL,
56 NULL) == KdPacketReceived)
57 {
58 /* Successful breakin */
59 DoBreak = TRUE;
60 }
61 }
62 }
63
64 /* Tell the caller to do a break */
65 return DoBreak;
66 }
67
68 /* PUBLIC FUNCTIONS **********************************************************/
69
70 /*
71 * @implemented
72 */
73 BOOLEAN
74 NTAPI
KdPollBreakIn(VOID)75 KdPollBreakIn(VOID)
76 {
77 BOOLEAN DoBreak = FALSE, Enable;
78
79 /* First make sure that KD is enabled */
80 if (KdDebuggerEnabled)
81 {
82 /* Disable interrupts */
83 Enable = KeDisableInterrupts();
84
85 /* Check if a CTRL-C is in the queue */
86 if (KdpContext.KdpControlCPending)
87 {
88 /* Set it and prepare for break */
89 KdpControlCPressed = TRUE;
90 DoBreak = TRUE;
91 KdpContext.KdpControlCPending = FALSE;
92 }
93 else
94 {
95 KIRQL OldIrql;
96 /* Try to acquire the lock */
97 KeRaiseIrql(HIGH_LEVEL, &OldIrql);
98 if (KeTryToAcquireSpinLockAtDpcLevel(&KdpDebuggerLock))
99 {
100 /* Now get a packet */
101 if (KdReceivePacket(PACKET_TYPE_KD_POLL_BREAKIN,
102 NULL,
103 NULL,
104 NULL,
105 NULL) == KdPacketReceived)
106 {
107 /* Successful breakin */
108 DoBreak = TRUE;
109 KdpControlCPressed = TRUE;
110 }
111
112 /* Let go of the port */
113 KdpPortUnlock();
114 }
115 KeLowerIrql(OldIrql);
116 }
117
118 /* Re-enable interrupts */
119 KeRestoreInterrupts(Enable);
120 }
121
122 /* Tell the caller to do a break */
123 return DoBreak;
124 }
125