|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.