📄 kdcomio.c
字号:
} } // // if the packet we received is a resend request, we return true and // let caller resend the packet. // if ( PacketHeader.PacketLeader == CONTROL_PACKET_LEADER && PacketHeader.PacketType == PACKET_TYPE_KD_RESEND ) { DBGPRT("Got Packet Resend"); return KDP_PACKET_RESEND; } // // Read data length. // ReturnCode = KdpReceiveString((PCHAR)&PacketHeader.ByteCount, sizeof(PacketHeader.ByteCount)); if (ReturnCode == CP_GET_NODATA) { DBGPRT("Did not receive data length"); return KDP_PACKET_TIMEOUT; } else if (ReturnCode == CP_GET_ERROR) { KdClearCommError(); if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) { goto WaitForPacketLeader; } else { DBGPRT("Failed to get ByteCount"); goto SendResendPacket; } } // // Read Packet Id. // ReturnCode = KdpReceiveString((PCHAR)&PacketHeader.PacketId, sizeof(PacketHeader.PacketId)); if (ReturnCode == CP_GET_NODATA) { DBGPRT("Did not receive packet ID"); return KDP_PACKET_TIMEOUT; } else if (ReturnCode == CP_GET_ERROR) { KdClearCommError(); if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) { goto WaitForPacketLeader; } else { DBGPRT("Failed to get PacketId"); goto SendResendPacket; } } // // Read packet checksum. // ReturnCode = KdpReceiveString((PCHAR)&PacketHeader.Checksum, sizeof(PacketHeader.Checksum)); if (ReturnCode == CP_GET_NODATA) { DBGPRT("Did not receive packet checksum"); return KDP_PACKET_TIMEOUT; } else if (ReturnCode == CP_GET_ERROR) { KdClearCommError(); if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) { goto WaitForPacketLeader; } else { DBGPRT("Failed to get Checksum"); goto SendResendPacket; } } // // A complete packet header is received. Check its validity and // perform appropriate action depending on packet type. // if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER ) { if (PacketHeader.PacketType == PACKET_TYPE_KD_ACKNOWLEDGE ) { // // If we received an expected ACK packet and we are not // waiting for any new packet, update outgoing packet id // and return. If we are NOT waiting for ACK packet // we will keep on waiting. If the ACK packet // is not for the packet we send, ignore it and keep on waiting. // if (PacketHeader.PacketId != (KdpNextPacketIdToSend & ~SYNC_PACKET_ID)) { goto WaitForPacketLeader; } else if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) { KdpNextPacketIdToSend ^= 1; return KDP_PACKET_RECEIVED; } else { goto WaitForPacketLeader; } } else if (PacketHeader.PacketType == PACKET_TYPE_KD_RESET) { DBGPRT("Got reset packet"); // // if we received Reset packet, reset the packet control variables // and resend earlier packet. // KdpNextPacketIdToSend = INITIAL_PACKET_ID; KdpPacketIdExpected = INITIAL_PACKET_ID; KdpSendControlPacket(PACKET_TYPE_KD_RESET, 0L); return KDP_PACKET_RESEND; } else if (PacketHeader.PacketType == PACKET_TYPE_KD_RESEND) { DBGPRT("Got packet Resend 2"); return KDP_PACKET_RESEND; } else { // // Invalid packet header, ignore it. // goto WaitForPacketLeader; } // // The packet header is for data packet (not control packet). // } else if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) { // // if we are waiting for ACK packet ONLY // and we receive a data packet header, check if the packet id // is what we expected. If yes, assume the acknowledge is lost (but // sent), ask sender to resend and return with PACKET_RECEIVED. // if (PacketHeader.PacketId == KdpPacketIdExpected) { KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0L); KdpNextPacketIdToSend ^= 1; return KDP_PACKET_RECEIVED; } else { KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, PacketHeader.PacketId ); goto WaitForPacketLeader; } } // // we are waiting for data packet and we received the packet header // for data packet. Perform the following checkings to make sure // it is the packet we are waiting for. // // // Check ByteCount received is valid // MessageLength = MessageHeader->MaximumLength; if ((PacketHeader.ByteCount > (USHORT)PACKET_MAX_SIZE) || (PacketHeader.ByteCount < (USHORT)MessageLength)) { DBGPRT("Invalid ByteCount"); goto SendResendPacket; } *DataLength = PacketHeader.ByteCount - MessageLength; // // Read the message header. // ReturnCode = KdpReceiveString(MessageHeader->Buffer, MessageLength); if (ReturnCode != CP_GET_SUCCESS) { DBGPRT("Invalid MessageLength"); goto SendResendPacket; } MessageHeader->Length = (USHORT)MessageLength; // // Read the message data. // ReturnCode = KdpReceiveString(MessageData->Buffer, *DataLength); if (ReturnCode != CP_GET_SUCCESS) { goto SendResendPacket; } MessageData->Length = (USHORT)*DataLength; // // Read packet trailing byte // ReturnCode = KdPortGetByte(&Input); if (ReturnCode != CP_GET_SUCCESS || Input != PACKET_TRAILING_BYTE) { DBGPRT("Invalid Trailing Byte"); goto SendResendPacket; } // // Check PacketType is what we are waiting for. // if (PacketType != PacketHeader.PacketType) { if (!KdpUseTCPSockets) { KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, PacketHeader.PacketId ); } goto WaitForPacketLeader; } // // Check PacketId is valid. // if (PacketHeader.PacketId == INITIAL_PACKET_ID || PacketHeader.PacketId == (INITIAL_PACKET_ID ^ 1)) { if (PacketHeader.PacketId != KdpPacketIdExpected) { if (!KdpUseTCPSockets) { KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, PacketHeader.PacketId ); } goto WaitForPacketLeader; } } else { DBGPRT("Invalid Packet ID"); goto SendResendPacket; } // // Check checksum is valid. // Checksum = KdpComputeChecksum( MessageHeader->Buffer, MessageHeader->Length ); Checksum += KdpComputeChecksum( MessageData->Buffer, MessageData->Length ); if (Checksum != PacketHeader.Checksum) { DBGPRT("Invalid CheckSum"); goto SendResendPacket; } if (!KdpUseTCPSockets) { // // Send Acknowledge byte and the Id of the packet received. // Then, update the ExpectId for next incoming packet. // KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, PacketHeader.PacketId ); } // // We have successfully received the packet so update the // packet control variables and return sucess. // KdpPacketIdExpected ^= 1; return KDP_PACKET_RECEIVED;SendResendPacket: KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0L); goto WaitForPacketLeader;}VOID KdpSendPacket(IN ULONG PacketType, IN PSTRING MessageHeader, IN PSTRING MessageData OPTIONAL)/*++Routine Description: This routine sends a packet to the host machine that is running the kernel debugger and waits for an ACK.Arguments: PacketType - Supplies the type of packet to send. MessageHeader - Supplies a pointer to a string descriptor that describes the message information. MessageData - Supplies a pointer to a string descriptor that describes the optional message data.Return Value: None.--*/{ KD_PACKET PacketHeader; ULONG MessageDataLength; USHORT ReturnCode; PDBGKD_DEBUG_IO DebugIo; PDBGKD_WAIT_STATE_CHANGE StateChange; if ( ARGUMENT_PRESENT(MessageData) ) { MessageDataLength = MessageData->Length; PacketHeader.Checksum = KdpComputeChecksum( MessageData->Buffer, MessageData->Length ); } else { MessageDataLength = 0; PacketHeader.Checksum = 0; } PacketHeader.Checksum += KdpComputeChecksum ( MessageHeader->Buffer, MessageHeader->Length ); // // Initialize and send the packet header. // PacketHeader.PacketLeader = PACKET_LEADER; PacketHeader.ByteCount = (USHORT)(MessageHeader->Length + MessageDataLength); PacketHeader.PacketType = (USHORT)PacketType; KdpNumberRetries = KdpRetryCount; do { if (KdpNumberRetries == 0) { // // If the packet is not for reporting exception, we give up // and declare debugger not present. // if (PacketType == PACKET_TYPE_KD_DEBUG_IO) { DebugIo = (PDBGKD_DEBUG_IO)MessageHeader->Buffer; if (DebugIo->ApiNumber == DbgKdPrintStringApi) { KdDebuggerNotPresent = TRUE; KdpNextPacketIdToSend = INITIAL_PACKET_ID | SYNC_PACKET_ID; KdpPacketIdExpected = INITIAL_PACKET_ID; return; } } else if (PacketType == PACKET_TYPE_KD_STATE_CHANGE) { StateChange = (PDBGKD_WAIT_STATE_CHANGE)MessageHeader->Buffer; if (StateChange->NewState == DbgKdLoadSymbolsStateChange) { KdDebuggerNotPresent = TRUE; KdpNextPacketIdToSend = INITIAL_PACKET_ID | SYNC_PACKET_ID; KdpPacketIdExpected = INITIAL_PACKET_ID; return; } } } // // Setting PacketId has to be in the do loop in case Packet Id was // reset. // PacketHeader.PacketId = KdpNextPacketIdToSend; KdpSendString((PCHAR)&PacketHeader, sizeof(KD_PACKET)); // // Output message header. // KdpSendString(MessageHeader->Buffer, MessageHeader->Length); // // Output message data. // if ( MessageDataLength ) { KdpSendString(MessageData->Buffer, MessageData->Length); } // // Output a packet trailing byte // KdPortPutByte(PACKET_TRAILING_BYTE); // If we're using EDBG services, flush write buffer to net if (KdpUseEdbg) WriteEdbgBuffer(); // Don't need acks over reliable transports if (!KdpUseTCPSockets) { // // Wait for the Ack Packet. // ReturnCode = KdpReceivePacket( PACKET_TYPE_KD_ACKNOWLEDGE, NULL, NULL, NULL ); if (ReturnCode == KDP_PACKET_TIMEOUT) { KdpNumberRetries--; } } else { // Since we don't wait for an ack with TCP, toggle the send id // here. KdpNextPacketIdToSend ^= 1; ReturnCode = KDP_PACKET_RECEIVED; } } while (ReturnCode != KDP_PACKET_RECEIVED); // // Reset Sync bit in packet id. The packet we sent may have Sync bit set // KdpNextPacketIdToSend &= ~SYNC_PACKET_ID; // // Since we are able to talk to debugger, the retrycount is set to // maximum value. // KdpRetryCount = MAXIMUM_RETRIES;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -