ReactOS  0.4.14-dev-833-g5f692ed
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 88 of file kdcom.c.

89 {
90  return STATUS_SUCCESS;
91 }
return STATUS_SUCCESS
Definition: btrfs.c:2938

◆ KdD3Transition()

NTSTATUS NTAPI KdD3Transition ( VOID  )

Definition at line 95 of file kdcom.c.

96 {
97  return STATUS_SUCCESS;
98 }
return STATUS_SUCCESS
Definition: btrfs.c:2938

◆ KdDebuggerInitialize0()

NTSTATUS NTAPI KdDebuggerInitialize0 ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 147 of file kdcom.c.

148 {
149  ULONG ComPortNumber = DEFAULT_DEBUG_PORT;
150  ULONG ComPortBaudRate = DEFAULT_DEBUG_BAUD_RATE;
151 
152  PCHAR CommandLine, PortString, BaudString, IrqString;
153  ULONG Value;
154 
155  /* Check if we have a LoaderBlock */
156  if (LoaderBlock)
157  {
158  /* Get the Command Line */
159  CommandLine = LoaderBlock->LoadOptions;
160 
161  /* Upcase it */
162  _strupr(CommandLine);
163 
164  /* Get the port and baud rate */
165  PortString = strstr(CommandLine, "DEBUGPORT");
166  BaudString = strstr(CommandLine, "BAUDRATE");
167  IrqString = strstr(CommandLine, "IRQ");
168 
169  /* Check if we got the /DEBUGPORT parameter */
170  if (PortString)
171  {
172  /* Move past the actual string, to reach the port*/
173  PortString += strlen("DEBUGPORT");
174 
175  /* Now get past any spaces and skip the equal sign */
176  while (*PortString == ' ') PortString++;
177  PortString++;
178 
179  /* Do we have a serial port? */
180  if (strncmp(PortString, "COM", 3) != 0)
181  {
183  }
184 
185  /* Check for a valid Serial Port */
186  PortString += 3;
187  Value = atol(PortString);
188  if (Value >= sizeof(BaseArray) / sizeof(BaseArray[0]))
189  {
191  }
192 
193  /* Set the port to use */
194  ComPortNumber = Value;
195  }
196 
197  /* Check if we got a baud rate */
198  if (BaudString)
199  {
200  /* Move past the actual string, to reach the rate */
201  BaudString += strlen("BAUDRATE");
202 
203  /* Now get past any spaces */
204  while (*BaudString == ' ') BaudString++;
205 
206  /* And make sure we have a rate */
207  if (*BaudString)
208  {
209  /* Read and set it */
210  Value = atol(BaudString + 1);
211  if (Value) ComPortBaudRate = Value;
212  }
213  }
214 
215  /* Check Serial Port Settings [IRQ] */
216  if (IrqString)
217  {
218  /* Move past the actual string, to reach the rate */
219  IrqString += strlen("IRQ");
220 
221  /* Now get past any spaces */
222  while (*IrqString == ' ') IrqString++;
223 
224  /* And make sure we have an IRQ */
225  if (*IrqString)
226  {
227  /* Read and set it */
228  Value = atol(IrqString + 1);
229  if (Value) KdComPortIrq = Value;
230  }
231  }
232  }
233 
234 #ifdef KDDEBUG
235  /*
236  * Try to find a free COM port and use it as the KD debugging port.
237  * NOTE: Inspired by reactos/boot/freeldr/freeldr/comm/rs232.c, Rs232PortInitialize(...)
238  */
239  {
240  /*
241  * Start enumerating COM ports from the last one to the first one,
242  * and break when we find a valid port.
243  * If we reach the first element of the list, the invalid COM port,
244  * then it means that no valid port was found.
245  */
246  ULONG ComPort;
247  for (ComPort = MAX_COM_PORTS; ComPort > 0; ComPort--)
248  {
249  /* Check if the port exist; skip the KD port */
250  if ((ComPort != ComPortNumber) && CpDoesPortExist(UlongToPtr(BaseArray[ComPort])))
251  break;
252  }
253  if (ComPort != 0)
254  CpInitialize(&KdDebugComPort, UlongToPtr(BaseArray[ComPort]), DEFAULT_BAUD_RATE);
255  }
256 #endif
257 
258  KDDBGPRINT("KdDebuggerInitialize0\n");
259 
260  /* Initialize the port */
261  return KdpPortInitialize(ComPortNumber, ComPortBaudRate);
262 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2374
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:18
#define UlongToPtr(u)
Definition: config.h:106
#define DEFAULT_DEBUG_BAUD_RATE
Definition: kdcom.c:21
ULONG KdComPortIrq
Definition: kdcom.c:42
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:37
static const ULONG BaseArray[]
Definition: hwide.c:44
#define DEFAULT_BAUD_RATE
Definition: kdcom.c:23
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI KdpPortInitialize(IN ULONG ComPortNumber, IN ULONG ComPortBaudRate)
Definition: kdcom.c:118

Referenced by KdInitSystem().

◆ KdDebuggerInitialize1()

NTSTATUS NTAPI KdDebuggerInitialize1 ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 272 of file kdcom.c.

273 {
274  return STATUS_SUCCESS;
275 }
return STATUS_SUCCESS
Definition: btrfs.c:2938

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:332
#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 110 of file kdcom.c.

111 {
112  /* Nothing to do on COM ports */
113  return STATUS_SUCCESS;
114 }
return STATUS_SUCCESS
Definition: btrfs.c:2938

◆ KdSave()

NTSTATUS NTAPI KdSave ( IN BOOLEAN  SleepTransition)

Definition at line 102 of file kdcom.c.

103 {
104  /* Nothing to do on COM ports */
105  return STATUS_SUCCESS;
106 }
return STATUS_SUCCESS
Definition: btrfs.c:2938

◆ 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:2904
#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:280
#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