xref: /reactos/ntoskrnl/kd64/kdlock.c (revision 845faec4)
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
19 KdpPortLock(VOID)
20 {
21     /* Acquire the lock */
22     KiAcquireSpinLock(&KdpDebuggerLock);
23 }
24 
25 VOID
26 NTAPI
27 KdpPortUnlock(VOID)
28 {
29     /* Release the lock */
30     KiReleaseSpinLock(&KdpDebuggerLock);
31 }
32 
33 BOOLEAN
34 NTAPI
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
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             /* Try to acquire the lock */
96             if (KeTryToAcquireSpinLockAtDpcLevel(&KdpDebuggerLock))
97             {
98                 /* Now get a packet */
99                 if (KdReceivePacket(PACKET_TYPE_KD_POLL_BREAKIN,
100                                     NULL,
101                                     NULL,
102                                     NULL,
103                                     NULL) == KdPacketReceived)
104                 {
105                     /* Successful breakin */
106                     DoBreak = TRUE;
107                     KdpControlCPressed = TRUE;
108                 }
109 
110                 /* Let go of the port */
111                 KdpPortUnlock();
112             }
113         }
114 
115         /* Re-enable interrupts if they were enabled previously */
116         if (Enable) _enable();
117     }
118 
119     /* Tell the caller to do a break */
120     return DoBreak;
121 }
122