ReactOS  0.4.15-dev-316-g938df97
kddll.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define KdPacketReceived   0
 
#define KdPacketTimedOut   1
 
#define KdPacketNeedsResend   2
 

Typedefs

typedef ULONG KDSTATUS
 

Functions

NTSTATUS NTAPI KdDebuggerInitialize0 (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
NTSTATUS NTAPI KdDebuggerInitialize1 (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
KDSTATUS NTAPI KdReceivePacket (IN ULONG PacketType, OUT PSTRING MessageHeader, OUT PSTRING MessageData, OUT PULONG DataLength, IN OUT PKD_CONTEXT Context)
 
NTSTATUS NTAPI KdRestore (IN BOOLEAN SleepTransition)
 
NTSTATUS NTAPI KdSave (IN BOOLEAN SleepTransition)
 
VOID NTAPI KdSendPacket (IN ULONG PacketType, IN PSTRING MessageHeader, IN PSTRING MessageData, IN OUT PKD_CONTEXT Context)
 
NTSTATUS NTAPI KdD0Transition (VOID)
 
NTSTATUS NTAPI KdD3Transition (VOID)
 

Macro Definition Documentation

◆ KdPacketNeedsResend

#define KdPacketNeedsResend   2

Definition at line 7 of file kddll.h.

◆ KdPacketReceived

#define KdPacketReceived   0

Definition at line 5 of file kddll.h.

◆ KdPacketTimedOut

#define KdPacketTimedOut   1

Definition at line 6 of file kddll.h.

Typedef Documentation

◆ KDSTATUS

typedef ULONG KDSTATUS

Definition at line 4 of file kddll.h.

Function Documentation

◆ KdD0Transition()

NTSTATUS NTAPI KdD0Transition ( VOID  )

Definition at line 99 of file kdcom.c.

100 {
101  return STATUS_SUCCESS;
102 }
return STATUS_SUCCESS
Definition: btrfs.c:3014

◆ KdD3Transition()

NTSTATUS NTAPI KdD3Transition ( VOID  )

Definition at line 106 of file kdcom.c.

107 {
108  return STATUS_SUCCESS;
109 }
return STATUS_SUCCESS
Definition: btrfs.c:3014

◆ KdDebuggerInitialize0()

NTSTATUS NTAPI KdDebuggerInitialize0 ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 158 of file kdcom.c.

159 {
160  ULONG ComPortNumber = DEFAULT_DEBUG_PORT;
161  ULONG ComPortBaudRate = DEFAULT_DEBUG_BAUD_RATE;
162 
163  PCHAR CommandLine, PortString, BaudString, IrqString;
164  ULONG Value;
165 
166  /* Check if we have a LoaderBlock */
167  if (LoaderBlock)
168  {
169  /* Get the Command Line */
170  CommandLine = LoaderBlock->LoadOptions;
171 
172  /* Upcase it */
173  _strupr(CommandLine);
174 
175  /* Get the port and baud rate */
176  PortString = strstr(CommandLine, "DEBUGPORT");
177  BaudString = strstr(CommandLine, "BAUDRATE");
178  IrqString = strstr(CommandLine, "IRQ");
179 
180  /* Check if we got the /DEBUGPORT parameter */
181  if (PortString)
182  {
183  /* Move past the actual string, to reach the port*/
184  PortString += strlen("DEBUGPORT");
185 
186  /* Now get past any spaces and skip the equal sign */
187  while (*PortString == ' ') PortString++;
188  PortString++;
189 
190  /* Do we have a serial port? */
191  if (strncmp(PortString, "COM", 3) != 0)
192  {
194  }
195 
196  /* Check for a valid Serial Port */
197  PortString += 3;
198  Value = atol(PortString);
199  if (Value >= sizeof(BaseArray) / sizeof(BaseArray[0]))
200  {
202  }
203 
204  /* Set the port to use */
205  ComPortNumber = Value;
206  }
207 
208  /* Check if we got a baud rate */
209  if (BaudString)
210  {
211  /* Move past the actual string, to reach the rate */
212  BaudString += strlen("BAUDRATE");
213 
214  /* Now get past any spaces */
215  while (*BaudString == ' ') BaudString++;
216 
217  /* And make sure we have a rate */
218  if (*BaudString)
219  {
220  /* Read and set it */
221  Value = atol(BaudString + 1);
222  if (Value) ComPortBaudRate = Value;
223  }
224  }
225 
226  /* Check Serial Port Settings [IRQ] */
227  if (IrqString)
228  {
229  /* Move past the actual string, to reach the rate */
230  IrqString += strlen("IRQ");
231 
232  /* Now get past any spaces */
233  while (*IrqString == ' ') IrqString++;
234 
235  /* And make sure we have an IRQ */
236  if (*IrqString)
237  {
238  /* Read and set it */
239  Value = atol(IrqString + 1);
240  if (Value) KdComPortIrq = Value;
241  }
242  }
243  }
244 
245 #ifdef KDDEBUG
246  /*
247  * Try to find a free COM port and use it as the KD debugging port.
248  * NOTE: Inspired by reactos/boot/freeldr/freeldr/comm/rs232.c, Rs232PortInitialize(...)
249  */
250  {
251  /*
252  * Start enumerating COM ports from the last one to the first one,
253  * and break when we find a valid port.
254  * If we reach the first element of the list, the invalid COM port,
255  * then it means that no valid port was found.
256  */
257  ULONG ComPort;
258  for (ComPort = MAX_COM_PORTS; ComPort > 0; ComPort--)
259  {
260  /* Check if the port exist; skip the KD port */
261  if ((ComPort != ComPortNumber) && CpDoesPortExist(UlongToPtr(BaseArray[ComPort])))
262  break;
263  }
264  if (ComPort != 0)
265  CpInitialize(&KdDebugComPort, UlongToPtr(BaseArray[ComPort]), DEFAULT_BAUD_RATE);
266  }
267 #endif
268 
269  KDDBGPRINT("KdDebuggerInitialize0\n");
270 
271  /* Initialize the port */
272  return KdpPortInitialize(ComPortNumber, ComPortBaudRate);
273 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2373
signed char * PCHAR
Definition: retypes.h:7
#define KDDBGPRINT(...)
Definition: kddll.h:19
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
BOOLEAN NTAPI CpDoesPortExist(IN PUCHAR Address)
Definition: cport.c:227
#define DEFAULT_DEBUG_PORT
Definition: kdcom.c:25
#define UlongToPtr(u)
Definition: config.h:106
#define DEFAULT_DEBUG_BAUD_RATE
Definition: kdcom.c:28
ULONG KdComPortIrq
Definition: kdcom.c:53
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
NTSTATUS NTAPI CpInitialize(IN PCPPORT Port, IN PUCHAR Address, IN ULONG BaudRate)
Definition: cport.c:88
_CRTIMP char *__cdecl _strupr(_Inout_z_ char *_String)
#define MAX_COM_PORTS
Definition: kdcom.c:48
static const ULONG BaseArray[]
Definition: hwide.c:41
#define DEFAULT_BAUD_RATE
Definition: kdcom.c:29
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI KdpPortInitialize(IN ULONG ComPortNumber, IN ULONG ComPortBaudRate)
Definition: kdcom.c:129

Referenced by KdInitSystem().

◆ KdDebuggerInitialize1()

NTSTATUS NTAPI KdDebuggerInitialize1 ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 283 of file kdcom.c.

284 {
285  return STATUS_SUCCESS;
286 }
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by Phase1InitializationDiscard().

◆ KdReceivePacket()

KDSTATUS NTAPI KdReceivePacket ( IN ULONG  PacketType,
OUT PSTRING  MessageHeader,
OUT PSTRING  MessageData,
OUT PULONG  DataLength,
IN OUT PKD_CONTEXT  Context 
)

Definition at line 80 of file kddll.c.

86 {
87  UCHAR Byte = 0;
88  KDP_STATUS KdStatus;
90  ULONG Checksum;
91 
92  /* Special handling for breakin packet */
93  if (PacketType == PACKET_TYPE_KD_POLL_BREAKIN)
94  {
95  return KdpPollBreakIn();
96  }
97 
98  for (;;)
99  {
100  /* Step 1 - Read PacketLeader */
101  KdStatus = KdpReceivePacketLeader(&Packet.PacketLeader);
102  if (KdStatus != KDP_PACKET_RECEIVED)
103  {
104  /* Check if we got a breakin */
105  if (KdStatus == KDP_PACKET_RESEND)
106  {
107  KdContext->KdpControlCPending = TRUE;
108  }
109  return KdStatus;
110  }
111 
112  /* Step 2 - Read PacketType */
113  KdStatus = KdpReceiveBuffer(&Packet.PacketType, sizeof(USHORT));
114  if (KdStatus != KDP_PACKET_RECEIVED)
115  {
116  /* Didn't receive a PacketType. */
117  return KdStatus;
118  }
119 
120  /* Check if we got a resend packet */
121  if (Packet.PacketLeader == CONTROL_PACKET_LEADER &&
122  Packet.PacketType == PACKET_TYPE_KD_RESEND)
123  {
124  return KDP_PACKET_RESEND;
125  }
126 
127  /* Step 3 - Read ByteCount */
128  KdStatus = KdpReceiveBuffer(&Packet.ByteCount, sizeof(USHORT));
129  if (KdStatus != KDP_PACKET_RECEIVED)
130  {
131  /* Didn't receive ByteCount. */
132  return KdStatus;
133  }
134 
135  /* Step 4 - Read PacketId */
136  KdStatus = KdpReceiveBuffer(&Packet.PacketId, sizeof(ULONG));
137  if (KdStatus != KDP_PACKET_RECEIVED)
138  {
139  /* Didn't receive PacketId. */
140  return KdStatus;
141  }
142 
143 /*
144  if (Packet.PacketId != ExpectedPacketId)
145  {
146  // Ask for a resend!
147  continue;
148  }
149 */
150 
151  /* Step 5 - Read Checksum */
152  KdStatus = KdpReceiveBuffer(&Packet.Checksum, sizeof(ULONG));
153  if (KdStatus != KDP_PACKET_RECEIVED)
154  {
155  /* Didn't receive Checksum. */
156  return KdStatus;
157  }
158 
159  /* Step 6 - Handle control packets */
160  if (Packet.PacketLeader == CONTROL_PACKET_LEADER)
161  {
162  switch (Packet.PacketType)
163  {
165  /* Are we waiting for an ACK packet? */
166  if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE &&
167  Packet.PacketId == (CurrentPacketId & ~SYNC_PACKET_ID))
168  {
169  /* Remote acknowledges the last packet */
170  CurrentPacketId ^= 1;
171  return KDP_PACKET_RECEIVED;
172  }
173  /* That's not what we were waiting for, start over */
174  continue;
175 
177  KDDBGPRINT("KdReceivePacket - got PACKET_TYPE_KD_RESET\n");
181  /* Fall through */
182 
184  KDDBGPRINT("KdReceivePacket - got PACKET_TYPE_KD_RESEND\n");
185  /* Remote wants us to resend the last packet */
186  return KDP_PACKET_RESEND;
187 
188  default:
189  KDDBGPRINT("KdReceivePacket - got unknown control packet\n");
190  /* We got an invalid packet, ignore it and start over */
191  continue;
192  }
193  }
194 
195  /* Did we wait for an ack packet? */
196  if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE)
197  {
198  /* We received something different */
200  CurrentPacketId ^= 1;
201  return KDP_PACKET_RECEIVED;
202  }
203 
204  /* Get size of the message header */
205  MessageHeader->Length = MessageHeader->MaximumLength;
206 
207  /* Packet smaller than expected or too big? */
208  if (Packet.ByteCount < MessageHeader->Length ||
209  Packet.ByteCount > PACKET_MAX_SIZE)
210  {
211  KDDBGPRINT("KdReceivePacket - too few data (%d) for type %d\n",
212  Packet.ByteCount, MessageHeader->Length);
213  MessageHeader->Length = Packet.ByteCount;
215  continue;
216  }
217 
218  //KDDBGPRINT("KdReceivePacket - got normal PacketType, Buffer = %p\n", MessageHeader->Buffer);
219 
220  /* Receive the message header data */
221  KdStatus = KdpReceiveBuffer(MessageHeader->Buffer,
222  MessageHeader->Length);
223  if (KdStatus != KDP_PACKET_RECEIVED)
224  {
225  /* Didn't receive data. Packet needs to be resent. */
226  KDDBGPRINT("KdReceivePacket - Didn't receive message header data.\n");
228  continue;
229  }
230 
231  //KDDBGPRINT("KdReceivePacket - got normal PacketType 3\n");
232 
233  /* Calculate checksum for the header data */
234  Checksum = KdpCalculateChecksum(MessageHeader->Buffer,
235  MessageHeader->Length);
236 
237  /* Calculate the length of the message data */
238  *DataLength = Packet.ByteCount - MessageHeader->Length;
239 
240  /* Shall we receive message data? */
241  if (MessageData)
242  {
243  /* Set the length of the message data */
244  MessageData->Length = (USHORT)*DataLength;
245 
246  /* Do we have data? */
247  if (MessageData->Length)
248  {
249  KDDBGPRINT("KdReceivePacket - got data\n");
250 
251  /* Receive the message data */
252  KdStatus = KdpReceiveBuffer(MessageData->Buffer,
253  MessageData->Length);
254  if (KdStatus != KDP_PACKET_RECEIVED)
255  {
256  /* Didn't receive data. Start over. */
257  KDDBGPRINT("KdReceivePacket - Didn't receive message data.\n");
259  continue;
260  }
261 
262  /* Add cheksum for message data */
263  Checksum += KdpCalculateChecksum(MessageData->Buffer,
264  MessageData->Length);
265  }
266  }
267 
268  /* We must receive a PACKET_TRAILING_BYTE now */
269  KdStatus = KdpReceiveBuffer(&Byte, sizeof(UCHAR));
270  if (KdStatus != KDP_PACKET_RECEIVED || Byte != PACKET_TRAILING_BYTE)
271  {
272  KDDBGPRINT("KdReceivePacket - wrong trailing byte (0x%x), status 0x%x\n", Byte, KdStatus);
274  continue;
275  }
276 
277  /* Compare checksum */
278  if (Packet.Checksum != Checksum)
279  {
280  KDDBGPRINT("KdReceivePacket - wrong cheksum, got %x, calculated %x\n",
281  Packet.Checksum, Checksum);
283  continue;
284  }
285 
286  /* Acknowledge the received packet */
288 
289  /* Check if the received PacketId is ok */
290  if (Packet.PacketId != RemotePacketId)
291  {
292  /* Continue with next packet */
293  continue;
294  }
295 
296  /* Did we get the right packet type? */
297  if (PacketType == Packet.PacketType)
298  {
299  /* Yes, return success */
300  //KDDBGPRINT("KdReceivePacket - all ok\n");
301  RemotePacketId ^= 1;
302  return KDP_PACKET_RECEIVED;
303  }
304 
305  /* We received something different, ignore it. */
306  KDDBGPRINT("KdReceivePacket - wrong PacketType\n");
307  }
308 
309  return KDP_PACKET_RECEIVED;
310 }
#define SYNC_PACKET_ID
Definition: windbgkd.h:25
#define TRUE
Definition: types.h:120
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1548
#define INITIAL_PACKET_ID
Definition: windbgkd.h:24
#define KDDBGPRINT(...)
Definition: kddll.h:19
unsigned char Byte
Definition: zconf.h:391
KDP_STATUS
Definition: kddll.h:25
ULONG CurrentPacketId
Definition: kddll.c:13
KDP_STATUS NTAPI KdpReceiveBuffer(OUT PVOID Buffer, IN ULONG Size)
Definition: kdserial.c:43
KDP_STATUS NTAPI KdpReceivePacketLeader(OUT PULONG PacketLeader)
Definition: kdserial.c:75
#define PACKET_MAX_SIZE
Definition: windbgkd.h:18
#define PACKET_TYPE_KD_ACKNOWLEDGE
Definition: windbgkd.h:45
KDP_STATUS NTAPI KdpPollBreakIn(VOID)
Definition: kdcom.c:343
#define PACKET_TYPE_KD_RESET
Definition: windbgkd.h:47
#define PACKET_TRAILING_BYTE
Definition: windbgkd.h:36
ULONG NTAPI KdpCalculateChecksum(IN PVOID Buffer, IN ULONG Length)
Definition: kddll.c:29
VOID NTAPI KdpSendControlPacket(IN USHORT PacketType, IN ULONG PacketId OPTIONAL)
Definition: kddll.c:45
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned short USHORT
Definition: pedump.c:61
ULONG RemotePacketId
Definition: kddll.c:14
#define PACKET_TYPE_KD_RESEND
Definition: windbgkd.h:46
unsigned int ULONG
Definition: retypes.h:1
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG DataLength
Definition: hidpi.h:333
#define CONTROL_PACKET_LEADER
Definition: windbgkd.h:34
#define PACKET_TYPE_KD_POLL_BREAKIN
Definition: windbgkd.h:49

Referenced by KdPollBreakIn(), KdpPollBreakInWithPortLock(), and KdSendPacket().

◆ KdRestore()

NTSTATUS NTAPI KdRestore ( IN BOOLEAN  SleepTransition)

Definition at line 121 of file kdcom.c.

122 {
123  /* Nothing to do on COM ports */
124  return STATUS_SUCCESS;
125 }
return STATUS_SUCCESS
Definition: btrfs.c:3014

◆ KdSave()

NTSTATUS NTAPI KdSave ( IN BOOLEAN  SleepTransition)

Definition at line 113 of file kdcom.c.

114 {
115  /* Nothing to do on COM ports */
116  return STATUS_SUCCESS;
117 }
return STATUS_SUCCESS
Definition: btrfs.c:3014

◆ KdSendPacket()

VOID NTAPI KdSendPacket ( IN ULONG  PacketType,
IN PSTRING  MessageHeader,
IN PSTRING  MessageData,
IN OUT PKD_CONTEXT  Context 
)

Definition at line 314 of file kddll.c.

319 {
321  KDP_STATUS KdStatus;
322  ULONG Retries;
323 
324  /* Initialize a KD_PACKET */
325  Packet.PacketLeader = PACKET_LEADER;
326  Packet.PacketType = (USHORT)PacketType;
327  Packet.ByteCount = MessageHeader->Length;
328  Packet.Checksum = KdpCalculateChecksum(MessageHeader->Buffer,
329  MessageHeader->Length);
330 
331  /* If we have message data, add it to the packet */
332  if (MessageData)
333  {
334  Packet.ByteCount += MessageData->Length;
335  Packet.Checksum += KdpCalculateChecksum(MessageData->Buffer,
336  MessageData->Length);
337  }
338 
339  Retries = KdContext->KdpDefaultRetries;
340 
341  for (;;)
342  {
343  /* Set the packet id */
344  Packet.PacketId = CurrentPacketId;
345 
346  /* Send the packet header to the KD port */
347  KdpSendBuffer(&Packet, sizeof(KD_PACKET));
348 
349  /* Send the message header */
350  KdpSendBuffer(MessageHeader->Buffer, MessageHeader->Length);
351 
352  /* If we have message data, also send it */
353  if (MessageData)
354  {
355  KdpSendBuffer(MessageData->Buffer, MessageData->Length);
356  }
357 
358  /* Finalize with a trailing byte */
360 
361  /* Wait for acknowledge */
363  NULL,
364  NULL,
365  NULL,
366  KdContext);
367 
368  /* Did we succeed? */
369  if (KdStatus == KDP_PACKET_RECEIVED)
370  {
371  /* Packet received, we can quit the loop */
373  Retries = KdContext->KdpDefaultRetries;
374  break;
375  }
376  else if (KdStatus == KDP_PACKET_TIMEOUT)
377  {
378  /* Timeout, decrement the retry count */
379  if (Retries > 0)
380  Retries--;
381 
382  /*
383  * If the retry count reaches zero, bail out
384  * for packet types allowed to timeout.
385  */
386  if (Retries == 0)
387  {
388  ULONG MessageId = *(PULONG)MessageHeader->Buffer;
389  switch (PacketType)
390  {
392  {
393  if (MessageId != DbgKdPrintStringApi) continue;
394  break;
395  }
396 
399  {
400  if (MessageId != DbgKdLoadSymbolsStateChange) continue;
401  break;
402  }
403 
405  {
406  if (MessageId != DbgKdCreateFileApi) continue;
407  break;
408  }
409  }
410 
411  /* Reset debugger state */
413  SharedUserData->KdDebuggerEnabled &= ~0x00000002;
416 
417  return;
418  }
419  }
420  // else (KdStatus == KDP_PACKET_RESEND) /* Resend the packet */
421 
422  /* Packet timed out, send it again */
423  KDDBGPRINT("KdSendPacket got KdStatus 0x%x\n", KdStatus);
424  }
425 }
#define SYNC_PACKET_ID
Definition: windbgkd.h:25
#define TRUE
Definition: types.h:120
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1548
VOID NTAPI KdpSendBuffer(IN PVOID Buffer, IN ULONG Size)
Definition: kdserial.c:21
#define INITIAL_PACKET_ID
Definition: windbgkd.h:24
#define KDDBGPRINT(...)
Definition: kddll.h:19
KDP_STATUS
Definition: kddll.h:25
ULONG CurrentPacketId
Definition: kddll.c:13
KDP_STATUS NTAPI KdReceivePacket(IN ULONG PacketType, OUT PSTRING MessageHeader, OUT PSTRING MessageData, OUT PULONG DataLength, IN OUT PKD_CONTEXT KdContext)
Definition: kddll.c:80
#define KD_DEBUGGER_NOT_PRESENT
Definition: kdfuncs.h:133
#define PACKET_TYPE_KD_ACKNOWLEDGE
Definition: windbgkd.h:45
#define DbgKdPrintStringApi
Definition: windbgkd.h:122
smooth NULL
Definition: ftsmooth.c:416
#define PACKET_TYPE_KD_FILE_IO
Definition: windbgkd.h:52
switch(r->id)
Definition: btrfs.c:2980
#define PACKET_TRAILING_BYTE
Definition: windbgkd.h:36
ULONG NTAPI KdpCalculateChecksum(IN PVOID Buffer, IN ULONG Length)
Definition: kddll.c:29
#define DbgKdLoadSymbolsStateChange
Definition: windbgkd.h:60
#define PACKET_TYPE_KD_STATE_CHANGE32
Definition: windbgkd.h:42
VOID NTAPI KdpSendByte(IN UCHAR Byte)
Definition: kdcom.c:291
#define SharedUserData
#define PACKET_TYPE_KD_STATE_CHANGE64
Definition: windbgkd.h:48
unsigned short USHORT
Definition: pedump.c:61
ULONG RemotePacketId
Definition: kddll.c:14
#define PACKET_TYPE_KD_DEBUG_IO
Definition: windbgkd.h:44
unsigned int * PULONG
Definition: retypes.h:1
#define DbgKdCreateFileApi
Definition: windbgkd.h:139
unsigned int ULONG
Definition: retypes.h:1
#define PACKET_LEADER
Definition: windbgkd.h:32