xref: /reactos/ntoskrnl/kd64/kdlock.c (revision 9393fc32)
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             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