Annotation of ntddk/src/krnldbg/kdapis/packet.c, revision 1.1.1.1

1.1       root        1: 
                      2: #include "givit.h"
                      3: 
                      4: 
                      5: //
                      6: // These two globals are used to contain the values
                      7: // passed back from ClearCommError.  They are trash
                      8: // because we really don't care what went wrong.  We
                      9: // just want the debugger to go on.
                     10: //
                     11: DWORD TrashErr;
                     12: COMSTAT TrashStat;
                     13: 
                     14: ULONG DbgKdpPacketExpected;     // ID for expected incoming packet
                     15: ULONG DbgKdpNextPacketToSend;   // ID for Next packet to send
                     16: 
                     17: //
                     18: // ValidUnaccessedPacket is used to control if the DbgKdpPacket
                     19: // contains valid but unaccessed packet.
                     20: //
                     21: 
                     22: BOOLEAN ValidUnaccessedPacket = FALSE;
                     23: UCHAR DbgKdpPacket[PACKET_MAX_SIZE];
                     24: KD_PACKET PacketHeader;
                     25: 
                     26: #define CONTROL_C 3
                     27: 
                     28: 
                     29: extern BOOLEAN KdResync;
                     30: 
                     31: //
                     32: // Private prototypes to allow printing error messages without tripping
                     33: // over the 'C' runtimes.
                     34: //
                     35: 
                     36: VOID
                     37: StartupCtrlCHandler(
                     38:         ULONG
                     39:         );
                     40: 
                     41: VOID
                     42: PrintErrorMessage(
                     43:     IN  PUCHAR  Message,
                     44:     IN  USHORT  Value1,
                     45:     IN  USHORT  Value2,
                     46:     IN  USHORT  Value3
                     47:     );
                     48: 
                     49: VOID
                     50: PrivateUstoa(
                     51:     IN  PUCHAR  Buffer,
                     52:     IN  USHORT  Value
                     53:     );
                     54: 
                     55: VOID
                     56: PutString(
                     57:     IN  PUCHAR  Message
                     58:     );
                     59: 
                     60: UCHAR DbgKdpBreakinPacket[1] = {
                     61:         BREAKIN_PACKET_BYTE
                     62:         };
                     63: 
                     64: UCHAR DbgKdpPacketTrailingByte[1] = {
                     65:         PACKET_TRAILING_BYTE
                     66:         };
                     67: 
                     68: VOID
                     69: DbgKdpWriteControlPacket(
                     70:     IN USHORT PacketType,
                     71:     IN ULONG PacketId OPTIONAL
                     72:     )
                     73: 
                     74: /*++
                     75: 
                     76: Routine Description:
                     77: 
                     78:     This function writes a control packet to target machine.
                     79: 
                     80:     N.B. a CONTROL Packet header is sent with the following information:
                     81:          PacketLeader - indicates it's a control packet
                     82:          PacketType - indicates the type of the control packet
                     83:          ByteCount - aways zero to indicate no data following the header
                     84:          PacketId - Valid ONLY for PACKET_TYPE_KD_ACKNOWLEDGE to indicate
                     85:                     which packet is acknowledged.
                     86: 
                     87: Arguments:
                     88: 
                     89:     PacketType - Supplies the type of the control packet.
                     90: 
                     91:     PacketId - Supplies the PacketId.  Used by Acknowledge packet only.
                     92: 
                     93: Return Value:
                     94: 
                     95:     None.
                     96: 
                     97: --*/
                     98: {
                     99: 
                    100:     DWORD BytesWritten;
                    101:     BOOL rc;
                    102:     KD_PACKET Packet;
                    103: 
                    104:     assert( PacketType < PACKET_TYPE_MAX );
                    105: 
                    106:     Packet.PacketLeader = CONTROL_PACKET_LEADER;
                    107:     Packet.ByteCount = 0;
                    108:     Packet.PacketType = PacketType;
                    109:     if ( PacketId ) {
                    110:         Packet.PacketId = PacketId;
                    111:     }
                    112: 
                    113:     do {
                    114: 
                    115:         //
                    116:         // Write the control packet header
                    117:         //
                    118: 
                    119:         rc = WriteFile(
                    120:                  DbgKdpComPort,
                    121:                  &Packet,
                    122:                  sizeof(Packet),
                    123:                  &BytesWritten,
                    124:                  &WriteOverlapped
                    125:                  );
                    126: 
                    127:         if (!rc) {
                    128: 
                    129:            if (GetLastError() == ERROR_IO_PENDING) {
                    130: 
                    131:                rc = GetOverlappedResult(
                    132:                         DbgKdpComPort,
                    133:                         &WriteOverlapped,
                    134:                         &BytesWritten,
                    135:                         TRUE
                    136:                         );
                    137: 
                    138:             } else {
                    139: 
                    140:                 //
                    141:                 // Device could be locked up.  Clear it just in case.
                    142:                 //
                    143: 
                    144:                 ClearCommError(
                    145:                     DbgKdpComPort,
                    146:                     &TrashErr,
                    147:                     &TrashStat
                    148:                     );
                    149: 
                    150:             }
                    151: 
                    152:         }
                    153: 
                    154:     } while ( (!rc) || BytesWritten != sizeof(Packet) );
                    155: }
                    156: 
                    157: ULONG
                    158: DbgKdpComputeChecksum (
                    159:     IN PUCHAR Buffer,
                    160:     IN ULONG Length
                    161:     )
                    162: 
                    163: /*++
                    164: 
                    165: Routine Description:
                    166: 
                    167:     This routine computes the checksum for the string passed in.
                    168: 
                    169: Arguments:
                    170: 
                    171:     Buffer - Supplies a pointer to the string.
                    172: 
                    173:     Length - Supplies the length of the string.
                    174: 
                    175: Return Value:
                    176: 
                    177:     A ULONG is return as the checksum for the input string.
                    178: 
                    179: --*/
                    180: 
                    181: {
                    182: 
                    183:     ULONG Checksum = 0;
                    184: 
                    185:     while (Length > 0) {
                    186:         Checksum = Checksum + (ULONG)*Buffer++;
                    187:         Length--;
                    188:     }
                    189:     return Checksum;
                    190: }
                    191: 
                    192: VOID
                    193: DbgKdpSynchronizeTarget (
                    194:     VOID
                    195:     )
                    196: 
                    197: /*++
                    198: 
                    199: Routine Description:
                    200: 
                    201:     This routine keeps on sending reset packet to target until reset packet
                    202:     is acknowledged by a reset packet from target.
                    203: 
                    204:     N.B. This routine is intended to be used by kernel debugger at startup
                    205:          time (ONLY) to get packet control variables on both target and host
                    206:          back in synchronization.  Also, reset request will cause kernel to
                    207:          reset its control variables AND resend us its previous packet (with
                    208:          the new packet id).
                    209: 
                    210: Arguments:
                    211: 
                    212:     None.
                    213: 
                    214: Return Value:
                    215: 
                    216:     None.
                    217: 
                    218: --*/
                    219: 
                    220: {
                    221: 
                    222:     USHORT Index;
                    223:     UCHAR DataByte, PreviousDataByte;
                    224:     USHORT PacketType = 0;
                    225:     ULONG TimeoutCount = 0;
                    226:     COMMTIMEOUTS CommTimeouts;
                    227:     COMMTIMEOUTS OldTimeouts;
                    228:     DWORD BytesRead;
                    229:     BOOL rc;
                    230: 
                    231:     //
                    232:     // Get the old time out values and hold them.
                    233:     // We then set a new total timeout value of
                    234:     // five seconds on the read.  (In millisecond intervals.
                    235:     //
                    236: 
                    237:     GetCommTimeouts(
                    238:         DbgKdpComPort,
                    239:         &OldTimeouts
                    240:         );
                    241: 
                    242:     CommTimeouts = OldTimeouts;
                    243:     CommTimeouts.ReadIntervalTimeout = 0;
                    244:     CommTimeouts.ReadTotalTimeoutMultiplier = 0;
                    245:     CommTimeouts.ReadTotalTimeoutConstant = 500;
                    246: 
                    247:     SetCommTimeouts(
                    248:         DbgKdpComPort,
                    249:         &CommTimeouts
                    250:         );
                    251: 
                    252:     while (TRUE) {
                    253: Timeout:
                    254:         DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESET, 0L);
                    255: 
                    256:         //
                    257:         // Read packet leader
                    258:         //
                    259: 
                    260:         Index = 0;
                    261:         do {
                    262: 
                    263:             //
                    264:             // Check user input for control_c.  If user types control_c,
                    265:             // we will send a breakin packet to the target.  Hopefully,
                    266:             // target will send us a StateChange packet and
                    267:             //
                    268: 
                    269: 
                    270:             //
                    271:             // if we don't get response from kernel in 3 seconds we
                    272:             // will resend the reset packet if user does not type ctrl_c.
                    273:             // Otherwise, we send breakin character and wait for data again.
                    274:             //
                    275: 
                    276:             rc = ReadFile(
                    277:                     DbgKdpComPort,
                    278:                     &DataByte,
                    279:                     1,
                    280:                     &BytesRead,
                    281:                     &ReadOverlapped
                    282:                     );
                    283: 
                    284:             if (!rc) {
                    285: 
                    286:                if (GetLastError() == ERROR_IO_PENDING) {
                    287: 
                    288:                    rc = GetOverlappedResult(
                    289:                             DbgKdpComPort,
                    290:                             &ReadOverlapped,
                    291:                             &BytesRead,
                    292:                             TRUE
                    293:                             );
                    294: 
                    295:                 } else {
                    296: 
                    297:                     //
                    298:                     // Device could be locked up.  Clear it just in case.
                    299:                     //
                    300: 
                    301:                     ClearCommError(
                    302:                         DbgKdpComPort,
                    303:                         &TrashErr,
                    304:                         &TrashStat
                    305:                         );
                    306: 
                    307:                 }
                    308: 
                    309:             }
                    310: 
                    311:             if ((!rc) || (BytesRead != 1)) {
                    312:                 TimeoutCount++;
                    313: 
                    314:                 //
                    315:                 // if we have been waiting for 3 seconds, resend RESYNC packet
                    316:                 //
                    317: 
                    318:                 if (TimeoutCount != 6) {
                    319:                     continue;
                    320:                 }
                    321:                 TimeoutCount = 0;
                    322:                 goto Timeout;
                    323:             }
                    324: 
                    325:             if (rc && BytesRead == 1 &&
                    326:                 ( DataByte == PACKET_LEADER_BYTE ||
                    327:                   DataByte == CONTROL_PACKET_LEADER_BYTE)
                    328:                 ) {
                    329:                 if ( Index == 0 ) {
                    330:                     PreviousDataByte = DataByte;
                    331:                     Index++;
                    332:                 } else if ( DataByte == PreviousDataByte ) {
                    333:                     Index++;
                    334:                 } else {
                    335:                     PreviousDataByte = DataByte;
                    336:                     Index = 1;
                    337:                 }
                    338:             } else {
                    339:                 Index = 0;
                    340:             }
                    341:         } while ( Index < 4 );
                    342: 
                    343:         if (DataByte == CONTROL_PACKET_LEADER_BYTE) {
                    344: 
                    345:             //
                    346:             // Read 2 byte Packet type
                    347:             //
                    348: 
                    349:             rc = ReadFile(
                    350:                      DbgKdpComPort,
                    351:                      &PacketType,
                    352:                      sizeof(PacketType),
                    353:                      &BytesRead,
                    354:                      &ReadOverlapped
                    355:                      );
                    356: 
                    357:             if (!rc) {
                    358: 
                    359:                if (GetLastError() == ERROR_IO_PENDING) {
                    360: 
                    361:                    rc = GetOverlappedResult(
                    362:                             DbgKdpComPort,
                    363:                             &ReadOverlapped,
                    364:                             &BytesRead,
                    365:                             TRUE
                    366:                             );
                    367: 
                    368:                 } else {
                    369: 
                    370:                     //
                    371:                     // Device could be locked up.  Clear it just in case.
                    372:                     //
                    373: 
                    374:                     ClearCommError(
                    375:                         DbgKdpComPort,
                    376:                         &TrashErr,
                    377:                         &TrashStat
                    378:                         );
                    379: 
                    380:                 }
                    381: 
                    382:             }
                    383: 
                    384:             if (rc && BytesRead == sizeof(PacketType) &&
                    385:                 PacketType == PACKET_TYPE_KD_RESET ) {
                    386:                 DbgKdpPacketExpected = INITIAL_PACKET_ID;
                    387:                 DbgKdpNextPacketToSend = INITIAL_PACKET_ID;
                    388:                 SetCommTimeouts(
                    389:                     DbgKdpComPort,
                    390:                     &OldTimeouts
                    391:                     );
                    392:                 return;
                    393:             }
                    394:         }
                    395: 
                    396:         //
                    397:         // If we receive Data Packet leader, it means target has not
                    398:         // receive our reset packet. So we loop back and send it again.
                    399:         // N.B. We need to wait until target finishes sending the packet.
                    400:         // Otherwise, we may be sending the reset packet while the target
                    401:         // is sending the packet. This might cause target loss the reset
                    402:         // packet.
                    403:         //
                    404: 
                    405:         while (DataByte != PACKET_TRAILING_BYTE) {
                    406: 
                    407:             rc = ReadFile(
                    408:                     DbgKdpComPort,
                    409:                     &DataByte,
                    410:                     1,
                    411:                     &BytesRead,
                    412:                     &ReadOverlapped
                    413:                     );
                    414: 
                    415:             if (!rc) {
                    416: 
                    417:                if (GetLastError() == ERROR_IO_PENDING) {
                    418: 
                    419:                    rc = GetOverlappedResult(
                    420:                             DbgKdpComPort,
                    421:                             &ReadOverlapped,
                    422:                             &BytesRead,
                    423:                             TRUE
                    424:                             );
                    425: 
                    426:                 } else {
                    427: 
                    428:                     //
                    429:                     // Device could be locked up.  Clear it just in case.
                    430:                     //
                    431: 
                    432:                     ClearCommError(
                    433:                         DbgKdpComPort,
                    434:                         &TrashErr,
                    435:                         &TrashStat
                    436:                         );
                    437: 
                    438:                 }
                    439: 
                    440:             }
                    441: 
                    442:             if (BytesRead != 1) {
                    443:                 break;
                    444:             }
                    445:         }
                    446:     }
                    447: }
                    448: 
                    449: 
                    450: VOID
                    451: DbgKdSendBreakIn(
                    452:     VOID
                    453:     )
                    454: 
                    455: /*++
                    456: 
                    457:     Routine Description:
                    458: 
                    459:     Send a breakin packet to the target, unless some other packet
                    460:     is already being transmitted, in which case do nothing.
                    461: 
                    462: --*/
                    463: 
                    464: {
                    465:     DWORD BytesWritten;
                    466:     BOOL rc;
                    467: 
                    468:     do {
                    469:         rc = WriteFile(
                    470:                  DbgKdpComPort,
                    471:                  &DbgKdpBreakinPacket[0],
                    472:                  sizeof(DbgKdpBreakinPacket),
                    473:                  &BytesWritten,
                    474:                  &WriteOverlapped
                    475:                  );
                    476: 
                    477:         if (!rc) {
                    478: 
                    479:            if (GetLastError() == ERROR_IO_PENDING) {
                    480: 
                    481:                rc = GetOverlappedResult(
                    482:                         DbgKdpComPort,
                    483:                         &WriteOverlapped,
                    484:                         &BytesWritten,
                    485:                         TRUE
                    486:                         );
                    487: 
                    488:             } else {
                    489: 
                    490:                 //
                    491:                 // Device could be locked up.  Clear it just in case.
                    492:                 //
                    493: 
                    494:                 ClearCommError(
                    495:                     DbgKdpComPort,
                    496:                     &TrashErr,
                    497:                     &TrashStat
                    498:                     );
                    499: 
                    500:             }
                    501: 
                    502:         }
                    503: 
                    504:     } while ((!rc) || (BytesWritten != sizeof(DbgKdpBreakinPacket)));
                    505: }
                    506: VOID
                    507: DbgKdpWritePacket(
                    508:     IN PVOID PacketData,
                    509:     IN USHORT PacketDataLength,
                    510:     IN USHORT PacketType,
                    511:     IN PVOID MorePacketData OPTIONAL,
                    512:     IN USHORT MorePacketDataLength OPTIONAL
                    513:     )
                    514: {
                    515:     DWORD BytesWritten;
                    516:     BOOL rc;
                    517:     KD_PACKET Packet;
                    518:     USHORT TotalBytesToWrite;
                    519:     BOOLEAN Received;
                    520: 
                    521:     assert( PacketType < PACKET_TYPE_MAX );
                    522:     if ( MorePacketData ) {
                    523:         TotalBytesToWrite = PacketDataLength + MorePacketDataLength;
                    524:         Packet.Checksum = DbgKdpComputeChecksum(
                    525:                                         MorePacketData,
                    526:                                         MorePacketDataLength
                    527:                                         );
                    528:         }
                    529:     else {
                    530:         TotalBytesToWrite = PacketDataLength;
                    531:         Packet.Checksum = 0;
                    532:         }
                    533:     Packet.Checksum += DbgKdpComputeChecksum(
                    534:                                     PacketData,
                    535:                                     PacketDataLength
                    536:                                     );
                    537:     Packet.PacketLeader = PACKET_LEADER;
                    538:     Packet.ByteCount = TotalBytesToWrite;
                    539:     Packet.PacketType = PacketType;
                    540: ResendPacket:
                    541:     Packet.PacketId = DbgKdpNextPacketToSend;
                    542: 
                    543:     //
                    544:     // Write the packet header
                    545:     //
                    546: 
                    547:     rc = WriteFile(
                    548:             DbgKdpComPort,
                    549:             &Packet,
                    550:             sizeof(Packet),
                    551:             &BytesWritten,
                    552:             &WriteOverlapped
                    553:             );
                    554: 
                    555:     if (!rc) {
                    556: 
                    557:        if (GetLastError() == ERROR_IO_PENDING) {
                    558: 
                    559:            rc = GetOverlappedResult(
                    560:                     DbgKdpComPort,
                    561:                     &WriteOverlapped,
                    562:                     &BytesWritten,
                    563:                     TRUE
                    564:                     );
                    565: 
                    566:         } else {
                    567: 
                    568:             //
                    569:             // Device could be locked up.  Clear it just in case.
                    570:             //
                    571: 
                    572:             ClearCommError(
                    573:                 DbgKdpComPort,
                    574:                 &TrashErr,
                    575:                 &TrashStat
                    576:                 );
                    577: 
                    578:         }
                    579: 
                    580:     }
                    581: 
                    582:     if ( (!rc) || BytesWritten != sizeof(Packet) ){
                    583: 
                    584:         //
                    585:         // an error occured writing the header, so write it again
                    586:         //
                    587: 
                    588:         goto ResendPacket;
                    589:     }
                    590: 
                    591:     //
                    592:     // Write the primary packet data
                    593:     //
                    594: 
                    595:     rc = WriteFile(
                    596:             DbgKdpComPort,
                    597:             PacketData,
                    598:             PacketDataLength,
                    599:             &BytesWritten,
                    600:             &WriteOverlapped
                    601:             );
                    602: 
                    603:     if (!rc) {
                    604: 
                    605:        if (GetLastError() == ERROR_IO_PENDING) {
                    606: 
                    607:            rc = GetOverlappedResult(
                    608:                     DbgKdpComPort,
                    609:                     &WriteOverlapped,
                    610:                     &BytesWritten,
                    611:                     TRUE
                    612:                     );
                    613: 
                    614:         } else {
                    615: 
                    616:             //
                    617:             // Device could be locked up.  Clear it just in case.
                    618:             //
                    619: 
                    620:             ClearCommError(
                    621:                 DbgKdpComPort,
                    622:                 &TrashErr,
                    623:                 &TrashStat
                    624:                 );
                    625: 
                    626:         }
                    627: 
                    628:     }
                    629: 
                    630:     if ( (!rc) || BytesWritten != PacketDataLength ){
                    631: 
                    632:         //
                    633:         // an error occured writing the primary packet data,
                    634:         // so write it again
                    635:         //
                    636: 
                    637:         goto ResendPacket;
                    638:     }
                    639: 
                    640:     //
                    641:     // If secondary packet data was specified (WriteMemory, SetContext...)
                    642:     // then write it as well.
                    643:     //
                    644: 
                    645:     if ( MorePacketData ) {
                    646: 
                    647:     rc = WriteFile(
                    648:                 DbgKdpComPort,
                    649:                 MorePacketData,
                    650:                 MorePacketDataLength,
                    651:                 &BytesWritten,
                    652:                 &WriteOverlapped
                    653:                 );
                    654:     if (!rc) {
                    655: 
                    656:        if (GetLastError() == ERROR_IO_PENDING) {
                    657: 
                    658:            rc = GetOverlappedResult(
                    659:                     DbgKdpComPort,
                    660:                     &WriteOverlapped,
                    661:                     &BytesWritten,
                    662:                     TRUE
                    663:                     );
                    664: 
                    665:         } else {
                    666: 
                    667:             //
                    668:             // Device could be locked up.  Clear it just in case.
                    669:             //
                    670: 
                    671:             ClearCommError(
                    672:                 DbgKdpComPort,
                    673:                 &TrashErr,
                    674:                 &TrashStat
                    675:                 );
                    676: 
                    677:         }
                    678: 
                    679:     }
                    680: 
                    681:         if ( (!rc) || BytesWritten != MorePacketDataLength ){
                    682: 
                    683:             //
                    684:             // an error occured writing the secondary packet data,
                    685:             // so write it again
                    686:             //
                    687: 
                    688:             goto ResendPacket;
                    689:         }
                    690:     }
                    691: 
                    692:     //
                    693:     // Output a packet trailing byte
                    694:     //
                    695: 
                    696:     do {
                    697:         rc = WriteFile(
                    698:                  DbgKdpComPort,
                    699:                  &DbgKdpPacketTrailingByte[0],
                    700:                  sizeof(DbgKdpPacketTrailingByte),
                    701:                  &BytesWritten,
                    702:                  &WriteOverlapped
                    703:                  );
                    704: 
                    705:         if (!rc) {
                    706: 
                    707:            if (GetLastError() == ERROR_IO_PENDING) {
                    708: 
                    709:                rc = GetOverlappedResult(
                    710:                         DbgKdpComPort,
                    711:                         &WriteOverlapped,
                    712:                         &BytesWritten,
                    713:                         TRUE
                    714:                         );
                    715: 
                    716:             } else {
                    717: 
                    718:                 //
                    719:                 // Device could be locked up.  Clear it just in case.
                    720:                 //
                    721: 
                    722:                 ClearCommError(
                    723:                     DbgKdpComPort,
                    724:                     &TrashErr,
                    725:                     &TrashStat
                    726:                     );
                    727: 
                    728:             }
                    729: 
                    730:         }
                    731: 
                    732:     } while ((!rc) || (BytesWritten != sizeof(DbgKdpPacketTrailingByte)));
                    733: 
                    734:     //
                    735:     // Wait for ACK
                    736:     //
                    737: 
                    738:     Received = DbgKdpWaitForPacket(
                    739:                    PACKET_TYPE_KD_ACKNOWLEDGE,
                    740:                    NULL
                    741:                    );
                    742: 
                    743:     if ( Received == FALSE ) {
                    744:         goto ResendPacket;
                    745:     }
                    746: }
                    747: 
                    748: BOOLEAN
                    749: DbgKdpReadPacketLeader(
                    750:     IN ULONG PacketType,
                    751:     OUT PULONG PacketLeader
                    752:     )
                    753: {
                    754:     DWORD BytesRead;
                    755:     BOOL rc;
                    756:     USHORT Index;
                    757:     UCHAR DataByte, PreviousDataByte;
                    758: 
                    759:     Index = 0;
                    760:     do {
                    761:         if (KdResync) {
                    762:             KdResync = FALSE;
                    763:             DbgKdpSynchronizeTarget();
                    764:         }
                    765:         rc = ReadFile(
                    766:                  DbgKdpComPort,
                    767:                  &DataByte,
                    768:                  1,
                    769:                  &BytesRead,
                    770:                  &ReadOverlapped
                    771:                  );
                    772: 
                    773:         if (!rc) {
                    774: 
                    775:            if (GetLastError() == ERROR_IO_PENDING) {
                    776: 
                    777:                rc = GetOverlappedResult(
                    778:                         DbgKdpComPort,
                    779:                         &ReadOverlapped,
                    780:                         &BytesRead,
                    781:                         TRUE
                    782:                         );
                    783: 
                    784:             } else {
                    785: 
                    786:                 //
                    787:                 // Device could be locked up.  Clear it just in case.
                    788:                 //
                    789: 
                    790:                 ClearCommError(
                    791:                     DbgKdpComPort,
                    792:                     &TrashErr,
                    793:                     &TrashStat
                    794:                     );
                    795: 
                    796:             }
                    797: 
                    798:         }
                    799: 
                    800:         if (rc && BytesRead == 1 &&
                    801:             ( DataByte == PACKET_LEADER_BYTE ||
                    802:               DataByte == CONTROL_PACKET_LEADER_BYTE)
                    803:            ) {
                    804:             if ( Index == 0 ) {
                    805:                 PreviousDataByte = DataByte;
                    806:                 Index++;
                    807:             } else if ( DataByte == PreviousDataByte ) {
                    808:                 Index++;
                    809:             } else {
                    810:                 PreviousDataByte = DataByte;
                    811:                 Index = 1;
                    812:             }
                    813:         } else {
                    814:             Index = 0;
                    815:             if (BytesRead == 0) {
                    816:                 return(FALSE);
                    817:             }
                    818:         }
                    819:     } while ( Index < 2 );
                    820: 
                    821:     if ( DataByte != CONTROL_PACKET_LEADER_BYTE ) {
                    822:         *PacketLeader = PACKET_LEADER;
                    823:     } else {
                    824:         *PacketLeader = CONTROL_PACKET_LEADER;
                    825:     }
                    826:     return TRUE;
                    827: }
                    828: BOOLEAN
                    829: DbgKdpWaitForPacket(
                    830:     IN USHORT PacketType,
                    831:     OUT PVOID Packet
                    832:     )
                    833: {
                    834:     PDBGKD_DEBUG_IO IoMessage;
                    835:     DWORD BytesRead;
                    836:     BOOL rc;
                    837:     UCHAR DataByte;
                    838:     ULONG Checksum;
                    839:     ULONG SyncBit;
                    840: 
                    841: 
                    842:     if (PacketType != PACKET_TYPE_KD_ACKNOWLEDGE) {
                    843:         if (ValidUnaccessedPacket) {
                    844:             goto ReadBuffered;
                    845:         }
                    846:     }
                    847: 
                    848:     //
                    849:     // First read a packet leader
                    850:     //
                    851: 
                    852: WaitForPacketLeader:
                    853: 
                    854:     ValidUnaccessedPacket = FALSE;
                    855: 
                    856:     if (!DbgKdpReadPacketLeader(PacketType, &PacketHeader.PacketLeader)) {
                    857:         return FALSE;
                    858:     }
                    859: 
                    860:     //
                    861:     // Read packetLeader ONLY read two Packet Leader bytes.  This do loop
                    862:     // filters out the remaining leader byte.
                    863:     //
                    864: 
                    865:     do {
                    866:         rc = ReadFile(
                    867:                  DbgKdpComPort,
                    868:                  &DataByte,
                    869:                  1,
                    870:                  &BytesRead,
                    871:                  &ReadOverlapped
                    872:                  );
                    873: 
                    874:         if (!rc) {
                    875: 
                    876:            if (GetLastError() == ERROR_IO_PENDING) {
                    877: 
                    878:                rc = GetOverlappedResult(
                    879:                         DbgKdpComPort,
                    880:                         &ReadOverlapped,
                    881:                         &BytesRead,
                    882:                         TRUE
                    883:                         );
                    884: 
                    885:             } else {
                    886: 
                    887:                 //
                    888:                 // Device could be locked up.  Clear it just in case.
                    889:                 //
                    890: 
                    891:                 ClearCommError(
                    892:                     DbgKdpComPort,
                    893:                     &TrashErr,
                    894:                     &TrashStat
                    895:                     );
                    896: 
                    897:             }
                    898: 
                    899:         }
                    900: 
                    901:         if ((rc) && BytesRead == 1) {
                    902:             if (DataByte == PACKET_LEADER_BYTE ||
                    903:                 DataByte == CONTROL_PACKET_LEADER_BYTE) {
                    904:                 continue;
                    905:             } else {
                    906:                 *(PUCHAR)&PacketHeader.PacketType = DataByte;
                    907:                 break;
                    908:             }
                    909:         } else {
                    910:             goto WaitForPacketLeader;
                    911:         }
                    912:     }while (TRUE);
                    913: 
                    914:     //
                    915:     // Now we have valid packet leader. Read rest of the packet type.
                    916:     //
                    917: 
                    918:     rc = ReadFile(
                    919:                  DbgKdpComPort,
                    920:                  ((PUCHAR)&PacketHeader.PacketType) + 1,
                    921:                  sizeof(PacketHeader.PacketType) - 1,
                    922:                  &BytesRead,
                    923:                  &ReadOverlapped
                    924:                  );
                    925: 
                    926:     if (!rc) {
                    927: 
                    928:        if (GetLastError() == ERROR_IO_PENDING) {
                    929: 
                    930:            rc = GetOverlappedResult(
                    931:                     DbgKdpComPort,
                    932:                     &ReadOverlapped,
                    933:                     &BytesRead,
                    934:                     TRUE
                    935:                     );
                    936: 
                    937:         } else {
                    938: 
                    939:             //
                    940:             // Device could be locked up.  Clear it just in case.
                    941:             //
                    942: 
                    943:             ClearCommError(
                    944:                 DbgKdpComPort,
                    945:                 &TrashErr,
                    946:                 &TrashStat
                    947:                 );
                    948: 
                    949:         }
                    950: 
                    951:     }
                    952: 
                    953:     if ((!rc) || BytesRead != sizeof(PacketHeader.PacketType) - 1) {
                    954:         //
                    955:         // If we cannot read the packet type and if the packet leader
                    956:         // indicates this is a data packet, we need to ask for resend.
                    957:         // Otherwise we simply ignore the incomplete packet.
                    958:         //
                    959: 
                    960:         if (PacketHeader.PacketLeader == PACKET_LEADER) {
                    961:             DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
                    962:         }
                    963:         goto WaitForPacketLeader;
                    964:     }
                    965: 
                    966:     //
                    967:     // Check the Packet type.
                    968:     //
                    969: 
                    970:     if (PacketHeader.PacketType >= PACKET_TYPE_MAX ) {
                    971:         if (PacketHeader.PacketLeader == PACKET_LEADER) {
                    972:             DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
                    973:         }
                    974:         goto WaitForPacketLeader;
                    975:     }
                    976: 
                    977:     //
                    978:     // Read ByteCount
                    979:     //
                    980: 
                    981:     rc = ReadFile(
                    982:                  DbgKdpComPort,
                    983:                  &PacketHeader.ByteCount,
                    984:                  sizeof(PacketHeader.ByteCount),
                    985:                  &BytesRead,
                    986:                  &ReadOverlapped
                    987:                  );
                    988: 
                    989:     if (!rc) {
                    990: 
                    991:        if (GetLastError() == ERROR_IO_PENDING) {
                    992: 
                    993:            rc = GetOverlappedResult(
                    994:                     DbgKdpComPort,
                    995:                     &ReadOverlapped,
                    996:                     &BytesRead,
                    997:                     TRUE
                    998:                     );
                    999: 
                   1000:         } else {
                   1001: 
                   1002:             //
                   1003:             // Device could be locked up.  Clear it just in case.
                   1004:             //
                   1005: 
                   1006:             ClearCommError(
                   1007:                 DbgKdpComPort,
                   1008:                 &TrashErr,
                   1009:                 &TrashStat
                   1010:                 );
                   1011: 
                   1012:         }
                   1013: 
                   1014:     }
                   1015: 
                   1016:     if ((!rc) || BytesRead != sizeof(PacketHeader.ByteCount)) {
                   1017:         //
                   1018:         // If we cannot read the packet type and if the packet leader
                   1019:         // indicates this is a data packet, we need to ask for resend.
                   1020:         // Otherwise we simply ignore the incomplete packet.
                   1021:         //
                   1022: 
                   1023:         if (PacketHeader.PacketLeader == PACKET_LEADER) {
                   1024:             DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
                   1025:         }
                   1026:         goto WaitForPacketLeader;
                   1027:     }
                   1028: 
                   1029:     //
                   1030:     // Check ByteCount
                   1031:     //
                   1032: 
                   1033:     if (PacketHeader.ByteCount > PACKET_MAX_SIZE ) {
                   1034:         if (PacketHeader.PacketLeader == PACKET_LEADER) {
                   1035:             DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
                   1036:         }
                   1037:         goto WaitForPacketLeader;
                   1038:     }
                   1039: 
                   1040:     //
                   1041:     // Read Packet Id
                   1042:     //
                   1043: 
                   1044:     rc = ReadFile(
                   1045:                  DbgKdpComPort,
                   1046:                  &PacketHeader.PacketId,
                   1047:                  sizeof(PacketHeader.PacketId),
                   1048:                  &BytesRead,
                   1049:                  &ReadOverlapped
                   1050:                  );
                   1051: 
                   1052:     if (!rc) {
                   1053: 
                   1054:        if (GetLastError() == ERROR_IO_PENDING) {
                   1055: 
                   1056:            rc = GetOverlappedResult(
                   1057:                     DbgKdpComPort,
                   1058:                     &ReadOverlapped,
                   1059:                     &BytesRead,
                   1060:                     TRUE
                   1061:                     );
                   1062: 
                   1063:         } else {
                   1064: 
                   1065:             //
                   1066:             // Device could be locked up.  Clear it just in case.
                   1067:             //
                   1068: 
                   1069:             ClearCommError(
                   1070:                 DbgKdpComPort,
                   1071:                 &TrashErr,
                   1072:                 &TrashStat
                   1073:                 );
                   1074: 
                   1075:         }
                   1076: 
                   1077:     }
                   1078: 
                   1079:     if ((!rc) || BytesRead != sizeof(PacketHeader.PacketId)) {
                   1080:         //
                   1081:         // If we cannot read the packet Id and if the packet leader
                   1082:         // indicates this is a data packet, we need to ask for resend.
                   1083:         // Otherwise we simply ignore the incomplete packet.
                   1084:         //
                   1085: 
                   1086:         if (PacketHeader.PacketLeader == PACKET_LEADER) {
                   1087:             DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
                   1088:         }
                   1089:         goto WaitForPacketLeader;
                   1090:     }
                   1091: 
                   1092:     if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER ) {
                   1093:         if (PacketHeader.PacketType == PACKET_TYPE_KD_ACKNOWLEDGE ) {
                   1094: 
                   1095:             //
                   1096:             // If we received an expected ACK packet and we are not
                   1097:             // waiting for any new packet, update outgoing packet id
                   1098:             // and return.  If we are NOT waiting for ACK packet
                   1099:             // we will keep on waiting.  If the ACK packet
                   1100:             // is not for the packet we send, ignore it and keep on waiting.
                   1101:             //
                   1102: 
                   1103:             if (PacketHeader.PacketId != DbgKdpNextPacketToSend) {
                   1104:                 goto WaitForPacketLeader;
                   1105:             } else if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) {
                   1106:                 DbgKdpNextPacketToSend ^= 1;
                   1107:                 return TRUE;
                   1108:             } else {
                   1109:                 goto WaitForPacketLeader;
                   1110:             }
                   1111:         } else if (PacketHeader.PacketType == PACKET_TYPE_KD_RESET) {
                   1112: 
                   1113:             //
                   1114:             // if we received Reset packet, reset the packet control variables
                   1115:             // and resend earlier packet.
                   1116:             //
                   1117: 
                   1118:             DbgKdpNextPacketToSend = INITIAL_PACKET_ID;
                   1119:             DbgKdpPacketExpected = INITIAL_PACKET_ID;
                   1120:             DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESET, 0L);
                   1121:             return FALSE;
                   1122:         } else if (PacketHeader.PacketType == PACKET_TYPE_KD_RESEND) {
                   1123:             return FALSE;
                   1124:         } else {
                   1125: 
                   1126:             //
                   1127:             // Invalid packet header, ignore it.
                   1128:             //
                   1129: 
                   1130:             goto WaitForPacketLeader;
                   1131:         }
                   1132: 
                   1133:     //
                   1134:     // The packet header is for data packet (not control packet).
                   1135:     //
                   1136: 
                   1137:     } else {
                   1138: 
                   1139:         //
                   1140:         // Read Packet Checksum. (for Data Packet Only).
                   1141:         //
                   1142: 
                   1143:         rc = ReadFile(
                   1144:                  DbgKdpComPort,
                   1145:                  &PacketHeader.Checksum,
                   1146:                  sizeof(PacketHeader.Checksum),
                   1147:                  &BytesRead,
                   1148:                  &ReadOverlapped
                   1149:                  );
                   1150: 
                   1151:         if (!rc) {
                   1152: 
                   1153:            if (GetLastError() == ERROR_IO_PENDING) {
                   1154: 
                   1155:                rc = GetOverlappedResult(
                   1156:                         DbgKdpComPort,
                   1157:                         &ReadOverlapped,
                   1158:                         &BytesRead,
                   1159:                         TRUE
                   1160:                         );
                   1161: 
                   1162:             } else {
                   1163: 
                   1164:                 //
                   1165:                 // Device could be locked up.  Clear it just in case.
                   1166:                 //
                   1167: 
                   1168:                 ClearCommError(
                   1169:                     DbgKdpComPort,
                   1170:                     &TrashErr,
                   1171:                     &TrashStat
                   1172:                     );
                   1173: 
                   1174:             }
                   1175: 
                   1176:         }
                   1177: 
                   1178:         if ((!rc) || BytesRead != sizeof(PacketHeader.Checksum)) {
                   1179:             DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
                   1180:             goto WaitForPacketLeader;
                   1181:         }
                   1182: 
                   1183:         if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) {
                   1184: 
                   1185:         //
                   1186:         // if we are waiting for ACK packet ONLY
                   1187:         // and we receive a data packet header, check if the packet id
                   1188:         // is what we expected.  If yes, assume the acknowledge is lost (but
                   1189:         // sent), ask sender to resend and return with PACKET_RECEIVED.
                   1190:         //
                   1191: 
                   1192:             if (PacketHeader.PacketId == DbgKdpPacketExpected) {
                   1193:                 DbgKdpNextPacketToSend ^= 1;
                   1194:             } else {
                   1195:                 DbgKdpWriteControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE,
                   1196:                                      PacketHeader.PacketId
                   1197:                                      );
                   1198:                 goto WaitForPacketLeader;
                   1199:             }
                   1200:         }
                   1201:     }
                   1202: 
                   1203:     //
                   1204:     // we are waiting for data packet and we received the packet header
                   1205:     // for data packet. Perform the following checkings to make sure
                   1206:     // it is the packet we are waiting for.
                   1207:     //
                   1208: 
                   1209:     if ((PacketHeader.PacketId & ~SYNC_PACKET_ID) != INITIAL_PACKET_ID &&
                   1210:         (PacketHeader.PacketId & ~SYNC_PACKET_ID) != (INITIAL_PACKET_ID ^ 1)) {
                   1211:         goto AskForResend;
                   1212:     }
                   1213: 
                   1214:     rc = ReadFile(
                   1215:             DbgKdpComPort,
                   1216:             DbgKdpPacket,
                   1217:             PacketHeader.ByteCount,
                   1218:             &BytesRead,
                   1219:             &ReadOverlapped
                   1220:             );
                   1221: 
                   1222:     if (!rc) {
                   1223: 
                   1224:        if (GetLastError() == ERROR_IO_PENDING) {
                   1225: 
                   1226:            rc = GetOverlappedResult(
                   1227:                     DbgKdpComPort,
                   1228:                     &ReadOverlapped,
                   1229:                     &BytesRead,
                   1230:                     TRUE
                   1231:                     );
                   1232: 
                   1233:         } else {
                   1234: 
                   1235:             //
                   1236:             // Device could be locked up.  Clear it just in case.
                   1237:             //
                   1238: 
                   1239:             ClearCommError(
                   1240:                 DbgKdpComPort,
                   1241:                 &TrashErr,
                   1242:                 &TrashStat
                   1243:                 );
                   1244: 
                   1245:         }
                   1246: 
                   1247:     }
                   1248: 
                   1249:     if ( (!rc) || BytesRead != PacketHeader.ByteCount ) {
                   1250:         goto AskForResend;
                   1251:     }
                   1252: 
                   1253:     //
                   1254:     // Make sure the next byte is packet trailing byte
                   1255:     //
                   1256: 
                   1257:     rc = ReadFile(
                   1258:             DbgKdpComPort,
                   1259:             &DataByte,
                   1260:             sizeof(DataByte),
                   1261:             &BytesRead,
                   1262:             &ReadOverlapped
                   1263:             );
                   1264: 
                   1265:     if (!rc) {
                   1266: 
                   1267:        if (GetLastError() == ERROR_IO_PENDING) {
                   1268: 
                   1269:            rc = GetOverlappedResult(
                   1270:                     DbgKdpComPort,
                   1271:                     &ReadOverlapped,
                   1272:                     &BytesRead,
                   1273:                     TRUE
                   1274:                     );
                   1275: 
                   1276:         } else {
                   1277: 
                   1278:             //
                   1279:             // Device could be locked up.  Clear it just in case.
                   1280:             //
                   1281: 
                   1282:             ClearCommError(
                   1283:                 DbgKdpComPort,
                   1284:                 &TrashErr,
                   1285:                 &TrashStat
                   1286:                 );
                   1287: 
                   1288:         }
                   1289: 
                   1290:     }
                   1291: 
                   1292:     if ( (!rc) || BytesRead != sizeof(DataByte) ||
                   1293:          DataByte != PACKET_TRAILING_BYTE ) {
                   1294:         goto AskForResend;
                   1295:     }
                   1296: 
                   1297:     //
                   1298:     // Make sure the checksum is valid.
                   1299:     //
                   1300: 
                   1301:     Checksum = DbgKdpComputeChecksum(DbgKdpPacket, PacketHeader.ByteCount);
                   1302:     if (Checksum != PacketHeader.Checksum) {
                   1303:         goto AskForResend;
                   1304:     }
                   1305: 
                   1306:     //
                   1307:     // We have a valid data packet.  If the packetid is bad, we just
                   1308:     // ack the packet to the sender will step ahead.  If packetid is bad
                   1309:     // but SYNC_PACKET_ID bit is set, we sync up.  If packetid is good,
                   1310:     // or SYNC_PACKET_ID is set, we take the packet.
                   1311:     //
                   1312: 
                   1313: 
                   1314:     SyncBit = PacketHeader.PacketId & SYNC_PACKET_ID;
                   1315:     PacketHeader.PacketId = PacketHeader.PacketId & ~SYNC_PACKET_ID;
                   1316: 
                   1317:     //
                   1318:     // Ack the packet.  SYNC_PACKET_ID bit will ALWAYS be OFF.
                   1319:     //
                   1320: 
                   1321:     DbgKdpWriteControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE,
                   1322:                              PacketHeader.PacketId
                   1323:                              );
                   1324: 
                   1325:     //
                   1326:     // Check the incoming packet Id.
                   1327:     //
                   1328: 
                   1329:     if ((PacketHeader.PacketId != DbgKdpPacketExpected) &&
                   1330:         (SyncBit != SYNC_PACKET_ID)) {
                   1331: 
                   1332:         goto WaitForPacketLeader;
                   1333: 
                   1334:     } else {
                   1335: 
                   1336:         if (SyncBit == SYNC_PACKET_ID) {
                   1337: 
                   1338:             //
                   1339:             // We know SyncBit is set, so reset Expected Ids
                   1340:             //
                   1341: 
                   1342: 
                   1343:             DbgKdpPacketExpected = PacketHeader.PacketId;
                   1344:             DbgKdpNextPacketToSend = INITIAL_PACKET_ID;
                   1345: 
                   1346:         }
                   1347:         DbgKdpPacketExpected ^= 1;
                   1348: 
                   1349:     }
                   1350: 
                   1351:     //
                   1352:     // If this is an internal packet. IO, or Resend, then
                   1353:     // handle it.
                   1354:     //
                   1355: 
                   1356:     if (PacketHeader.PacketType == PACKET_TYPE_KD_DEBUG_IO) {
                   1357:         IoMessage = (PDBGKD_DEBUG_IO)DbgKdpPacket;
                   1358: 
                   1359:         if (IoMessage->ApiNumber == DbgKdPrintStringApi) {
                   1360:             DbgKdpPrint(
                   1361:                   IoMessage->Processor,
                   1362:                   (PUCHAR)(IoMessage+1),
                   1363:                   (SHORT)IoMessage->u.PrintString.LengthOfString
                   1364:                   );
                   1365:         } else {
                   1366:             DbgKdpHandlePromptString(IoMessage);
                   1367:         }
                   1368:         if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) {
                   1369:             return TRUE;
                   1370:         }
                   1371:         goto WaitForPacketLeader;
                   1372:     }
                   1373: 
                   1374:     if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) {
                   1375:         ValidUnaccessedPacket = TRUE;
                   1376:         return TRUE;
                   1377:     }
                   1378: ReadBuffered:
                   1379: 
                   1380:     //
                   1381:     // Check PacketType is what we are waiting for.
                   1382:     //
                   1383: 
                   1384:     if (PacketType != PacketHeader.PacketType) {
                   1385:         goto WaitForPacketLeader;
                   1386:     }
                   1387:     *(PVOID *)Packet = &DbgKdpPacket;
                   1388:     ValidUnaccessedPacket = FALSE;
                   1389:     return TRUE;
                   1390: 
                   1391: AskForResend:
                   1392: 
                   1393:     DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
                   1394:     if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) {
                   1395:         return TRUE;
                   1396:     }
                   1397:     goto WaitForPacketLeader;
                   1398: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.