⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kdcomio.c

📁 wince3.0的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
        }
    }

    //
    // 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 + -