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

1.1       root        1: #include "givit.h"
                      2: 
                      3: 
                      4: extern HANDLE PipeRead;         // see DbgKdpKbdPollThread
                      5: extern HANDLE PipeWrite;
                      6: extern ULONG  NumberProcessors;
                      7: static USHORT LastProcessorToPrint = -1;
                      8: 
                      9: UCHAR DbgKdpPacketLeader[4] = {
                     10:         PACKET_LEADER_BYTE,
                     11:         PACKET_LEADER_BYTE,
                     12:         PACKET_LEADER_BYTE,
                     13:         PACKET_LEADER_BYTE
                     14:         };
                     15: 
                     16: //
                     17: // DbgKdpCmdCanceled indicates the fact that the current kd command has
                     18: // been canceled by user (using ctrl-C.)  With the Packet Id controlling
                     19: // the packet exchange, the Ctrl-C has to be handled in controlled manner.
                     20: // At each end of DbgKdpXXXX routine, we will check for this flag.  If the
                     21: // command has been canceled, a longjmp will be performed to transfer control
                     22: // back to kd prompt.
                     23: //
                     24: 
                     25: BOOLEAN DbgKdpCmdCanceled = FALSE;
                     26: 
                     27: #ifdef DBG
                     28: BOOLEAN KdDebug = FALSE;
                     29: #endif
                     30: 
                     31: BOOLEAN KdResync = FALSE;
                     32: UCHAR PrintBuf[PACKET_MAX_SIZE];
                     33: 
                     34: #define CONTROL_B   2
                     35: #define CONTROL_D   4
                     36: #define CONTROL_R   18
                     37: #define CONTROL_V   22
                     38: 
                     39: ULONG DbgKdpPacketExpected;     // ID for expected incoming packet
                     40: ULONG DbgKdpNextPacketToSend;   // ID for Next packet to send
                     41: extern VOID DbgKdpSynchronizeTarget ( VOID );
                     42: 
                     43: //++
                     44: //
                     45: // VOID
                     46: // DbgKdpWaitPacketForever (
                     47: //     IN ULONG PacketType,
                     48: //     IN PVOID Buffer
                     49: //     )
                     50: //
                     51: // Routine Description:
                     52: //
                     53: //     This macro is invoked to wait for specifi type of message without
                     54: //     timeout.
                     55: //
                     56: // Arguments:
                     57: //
                     58: //     PacketType - Type of the message we are expecting.
                     59: //
                     60: //     Buffer - Buffer to store the message.
                     61: //
                     62: // Return Value:
                     63: //
                     64: //     None.
                     65: //
                     66: //--
                     67: 
                     68: #define DbgKdpWaitPacketForever( PacketType, Buffer) {         \
                     69:         BOOLEAN rc;                                            \
                     70:         do {                                                   \
                     71:             rc = DbgKdpWaitForPacket(                          \
                     72:                          PacketType,                           \
                     73:                          Buffer                                \
                     74:                          );                                    \
                     75:         } while ( rc == FALSE);                                \
                     76: }
                     77: 
                     78: DWORD
                     79: DbgKdConnectAndInitialize(
                     80:     )
                     81: {
                     82: 
                     83:     DWORD BytesWritten;
                     84:     BOOL rc;
                     85:     USHORT Length;
                     86: 
                     87:     //
                     88:     // Initialize comport, packet queue and start the packet receiving
                     89:     // thread.
                     90:     //
                     91: 
                     92:     DbgKdpInitComPort(0L);
                     93:     DbgKdpPacketExpected = INITIAL_PACKET_ID;
                     94:     DbgKdpNextPacketToSend = INITIAL_PACKET_ID;
                     95: 
                     96:     DbgKdpStartThreads();
                     97: 
                     98:     return ERROR_SUCCESS;
                     99: }
                    100: 
                    101: VOID
                    102: DbgKdpHandlePromptString(
                    103:     IN PDBGKD_DEBUG_IO IoMessage
                    104:     )
                    105: {
                    106:     PUCHAR IoData;
                    107:     DWORD i;
                    108:     DWORD j;
                    109:     BOOL rc;
                    110:     UCHAR c;
                    111:     PUCHAR d;
                    112: 
                    113:     IoData = (PUCHAR)(IoMessage+1);
                    114: 
                    115:     DbgKdpPrint(IoMessage->Processor,
                    116:                 IoData,
                    117:                 (USHORT)IoMessage->u.GetString.LengthOfPromptString
                    118:                 );
                    119: 
                    120:     //
                    121:     // read the prompt data
                    122:     //
                    123: 
                    124:     j = 0;
                    125:     d = IoData;
                    126:     rc = DbgKdpGetConsoleByte(&c, 1, &i);
                    127: 
                    128:     while ( rc == TRUE &&
                    129:             i == 1 &&
                    130:             j < (USHORT)IoMessage->u.GetString.LengthOfStringRead) {
                    131: 
                    132:         if ( c == '\r' ) {
                    133:             *d++ = '\0';
                    134:             j++;
                    135:         } else if ( c == '\n' ) {
                    136:             *d++ = '\0';
                    137:             j++;
                    138:             break;
                    139:         } else {
                    140:             *d++ = c;
                    141:             j++;
                    142:         }
                    143:         rc = DbgKdpGetConsoleByte(&c, 1, &i);
                    144:     }
                    145: 
                    146:     LastProcessorToPrint = -1;
                    147:     if ( j < (USHORT)IoMessage->u.GetString.LengthOfStringRead ) {
                    148:         IoMessage->u.GetString.LengthOfStringRead = j;
                    149:     }
                    150: 
                    151:     //
                    152:     // Send data to the debugger-target
                    153:     //
                    154: 
                    155:     DbgKdpWritePacket(
                    156:         IoMessage,
                    157:         sizeof(*IoMessage),
                    158:         PACKET_TYPE_KD_DEBUG_IO,
                    159:         IoData,
                    160:         (USHORT)IoMessage->u.GetString.LengthOfStringRead
                    161:         );
                    162: }
                    163: 
                    164: VOID
                    165: DbgKdpPrint(
                    166:     IN USHORT Processor,
                    167:     IN PUCHAR String,
                    168:     IN USHORT StringLength
                    169:     )
                    170: {
                    171:     DWORD i;
                    172:     DWORD j;
                    173:     UCHAR c;
                    174:     PUCHAR d;
                    175:     static USHORT LastProcessor = -1;
                    176: 
                    177:     assert(StringLength < PACKET_MAX_SIZE - 2);
                    178: 
                    179:     d = PrintBuf;
                    180:     if (NumberProcessors > 1  &&  Processor != LastProcessorToPrint) {
                    181:         assert(Processor < 8);
                    182:         LastProcessorToPrint = Processor;
                    183:         *d++ = (UCHAR)((UCHAR)Processor + '0');
                    184:         *d++ = ':';
                    185:         j = 2;
                    186:     } else {
                    187:         j = 0;
                    188:     }
                    189:     for(i=0;i<StringLength;i++) {
                    190:         c = *(String+i);
                    191:         if ( c == '\n' ) {
                    192:             LastProcessorToPrint = -1;
                    193:             *d++ = '\n';
                    194:             *d++ = '\r';
                    195:             j += 2;
                    196:         } else {
                    197:             if ( c ) {
                    198:                 *d++ = c;
                    199:                 j++;
                    200:                 }
                    201:             }
                    202:         }
                    203: 
                    204:     //
                    205:     // print the string. someday this should probably
                    206:     // be a callout.
                    207: 
                    208:     WriteFile(ConsoleOutputHandle,PrintBuf,j,&i,NULL);
                    209: }
                    210: 
                    211: DWORD
                    212: DbgKdWaitStateChange(
                    213:     OUT PDBGKD_WAIT_STATE_CHANGE StateChange,
                    214:     OUT PVOID Buffer,
                    215:     IN ULONG BufferLength
                    216:     )
                    217: 
                    218: /*++
                    219: 
                    220: Routine Description:
                    221: 
                    222:     This function causes the calling user interface to wait for a state
                    223:     change to occur in the system being debugged.  Once a state change
                    224:     occurs, the user interface can either continue the system using
                    225:     DbgKdContinue, or it can manipulate system state using anyone of the
                    226:     DbgKd state manipulation APIs.
                    227: 
                    228: Arguments:
                    229: 
                    230:     StateChange - Supplies the address of state change record that
                    231:         will contain the state change information.
                    232: 
                    233:     Buffer - Supplies the address of a buffer that returns additional
                    234:         information.
                    235: 
                    236:     BufferLength - Supplies the length of Buffer.
                    237: 
                    238: Return Value:
                    239: 
                    240:     ERROR_SUCCESS - A state change occured. Valid state change information
                    241:         was returned.
                    242: 
                    243: --*/
                    244: 
                    245: {
                    246: 
                    247:     PDBGKD_WAIT_STATE_CHANGE LocalStateChange;
                    248:     DWORD st;
                    249:     UCHAR   *pt;
                    250: 
                    251:     st = ERROR_INVALID_FUNCTION;
                    252:     while ( st != ERROR_SUCCESS ) {
                    253: 
                    254:         //
                    255:         // Waiting for a state change message. Copy the message to the callers
                    256:         // buffer, and then free the packet entry.
                    257:         //
                    258: 
                    259:         DbgKdpWaitPacketForever(
                    260:                 PACKET_TYPE_KD_STATE_CHANGE,
                    261:                 &LocalStateChange
                    262:                 );
                    263:         LocalStateChange = (PDBGKD_WAIT_STATE_CHANGE)DbgKdpPacket;
                    264:         st = ERROR_SUCCESS;
                    265:         assert(StateChange);
                    266:         *StateChange = *LocalStateChange;
                    267: 
                    268:         switch ( (USHORT) StateChange->NewState ) {
                    269:             case DbgKdExceptionStateChange:
                    270:                 break;
                    271:             case DbgKdLoadSymbolsStateChange:
                    272:                 if ( BufferLength < LocalStateChange->u.LoadSymbols.PathNameLength ) {
                    273:                     st = ERROR_MORE_DATA;
                    274:                 } else {
                    275:                     pt = ((UCHAR *) LocalStateChange) + PacketHeader.ByteCount -
                    276:                          (int)LocalStateChange->u.LoadSymbols.PathNameLength;
                    277:                     memcpy(Buffer, pt,
                    278:                          (int)LocalStateChange->u.LoadSymbols.PathNameLength);
                    279:                 }
                    280:                 break;
                    281:             default:
                    282:                 assert(FALSE);
                    283:         }
                    284:         return st;
                    285:     }
                    286: }
                    287: 
                    288: DWORD
                    289: DbgKdContinue (
                    290:     IN DWORD ContinueStatus
                    291:     )
                    292: 
                    293: /*++
                    294: 
                    295: Routine Description:
                    296: 
                    297:     Continuing a system that previously reported a state change causes
                    298:     the system to continue executiontion using the context in effect at
                    299:     the time the state change was reported (of course this context could
                    300:     have been modified using the DbgKd state manipulation APIs).
                    301: 
                    302: Arguments:
                    303: 
                    304:     ContinueStatus - Supplies the continuation status to the thread
                    305:         being continued.  Valid values for this are
                    306:         DBG_EXCEPTION_HANDLED, DBG_EXCEPTION_NOT_HANDLED
                    307:         or DBG_CONTINUE.
                    308: 
                    309: Return Value:
                    310: 
                    311:     ERROR_SUCCESS - Successful call to DbgUiContinue
                    312: 
                    313:     ERROR_INVALID_PARAMETER - An invalid continue status or was
                    314:         specified.
                    315: 
                    316: --*/
                    317: 
                    318: {
                    319:     DBGKD_MANIPULATE_STATE m;
                    320:     PDBGKD_CONTINUE a = &m.u.Continue;
                    321:     DWORD st;
                    322: 
                    323:     if ( ContinueStatus == DBG_EXCEPTION_HANDLED ||
                    324:          ContinueStatus == DBG_EXCEPTION_NOT_HANDLED ||
                    325:          ContinueStatus == DBG_CONTINUE ) {
                    326: 
                    327:         m.ApiNumber = DbgKdContinueApi;
                    328:         m.ReturnStatus = ContinueStatus;
                    329: 
                    330:         a->ContinueStatus = ContinueStatus;
                    331:         DbgKdpWritePacket(&m,sizeof(m),PACKET_TYPE_KD_STATE_MANIPULATE,NULL,0);
                    332:         st = ERROR_SUCCESS;
                    333:         }
                    334:     else {
                    335:         st = ERROR_INVALID_PARAMETER;
                    336:         }
                    337: 
                    338:     return st;
                    339: }
                    340: 
                    341: 
                    342: DWORD
                    343: DbgKdContinue2 (
                    344:     IN DWORD ContinueStatus,
                    345:     IN DBGKD_CONTROL_SET ControlSet
                    346:     )
                    347: 
                    348: /*++
                    349: 
                    350: Routine Description:
                    351: 
                    352:     Continuing a system that previously reported a state change causes
                    353:     the system to continue executiontion using the context in effect at
                    354:     the time the state change was reported, modified by the values set
                    355:     in the ControlSet structure.  (And, of course, the context could have
                    356:     been modified by used the DbgKd state manipulation APIs.)
                    357: 
                    358: Arguments:
                    359: 
                    360:     ContinueStatus - Supplies the continuation status to the thread
                    361:         being continued.  Valid values for this are
                    362:         DBG_EXCEPTION_HANDLED, DBG_EXCEPTION_NOT_HANDLED
                    363:         or DBG_CONTINUE.
                    364: 
                    365:     ControlSet - Supplies a pointer to a structure containing the machine
                    366:         specific control data to set.  For the x86 this is the TraceFlag
                    367:         and Dr7.
                    368: 
                    369: Return Value:
                    370: 
                    371:     ERROR_SUCCESS - Successful call to DbgUiContinue
                    372: 
                    373:     ERROR_INVALID_PARAMETER - An invalid continue status or was
                    374:         specified.
                    375: 
                    376: --*/
                    377: 
                    378: {
                    379:     DBGKD_MANIPULATE_STATE m;
                    380:     DWORD st;
                    381: 
                    382:     if ( ContinueStatus == DBG_EXCEPTION_HANDLED ||
                    383:          ContinueStatus == DBG_EXCEPTION_NOT_HANDLED ||
                    384:          ContinueStatus == DBG_CONTINUE ) {
                    385: 
                    386:         m.ApiNumber = DbgKdContinueApi2;
                    387:         m.ReturnStatus = ContinueStatus;
                    388: 
                    389:         m.u.Continue2.ContinueStatus = ContinueStatus;
                    390:         m.u.Continue2.ControlSet = ControlSet;
                    391: 
                    392:         DbgKdpWritePacket(&m,sizeof(m),PACKET_TYPE_KD_STATE_MANIPULATE,NULL,0);
                    393:         st = ERROR_SUCCESS;
                    394: 
                    395:     } else {
                    396:         st = ERROR_INVALID_PARAMETER;
                    397:     }
                    398: 
                    399:     return st;
                    400: }
                    401: 
                    402: DWORD
                    403: DbgKdReadVirtualMemory(
                    404:     IN PVOID TargetBaseAddress,
                    405:     OUT PVOID UserInterfaceBuffer,
                    406:     IN ULONG TransferCount,
                    407:     OUT PULONG ActualBytesRead OPTIONAL
                    408:     )
                    409: 
                    410: /*++
                    411: 
                    412: Routine Description:
                    413: 
                    414:     This function reads the specified data from the system being debugged
                    415:     using the current mapping of the processor.
                    416: 
                    417: Arguments:
                    418: 
                    419:     TargetBaseAddress - Supplies the base address of the memory to read
                    420:         from the system being debugged.  The virtual address is in terms
                    421:         of the current mapping for the processor that reported the last
                    422:         state change.  Until we figure out how to do this differently,
                    423:         the virtual address must refer to a valid page (although it does
                    424:         not necesserily have to be in the TB).
                    425: 
                    426:     UserInterfaceBuffer - Supplies the address of the buffer in the user
                    427:         interface that data read is to be placed.
                    428: 
                    429:     TransferCount - Specifies the number of bytes to read.
                    430: 
                    431:     ActualBytesRead - An optional parameter that if supplied, returns
                    432:         the number of bytes actually read.
                    433: 
                    434: Return Value:
                    435: 
                    436:     ERROR_SUCCESS - The specified read occured.
                    437: 
                    438:     ERROR_MORE_DATA - A read that is to large was specified.
                    439: 
                    440:     ERROR_NO_ACCESS - The TargetBaseAddress/TransferCount
                    441:         parameters refers to invalid virtual memory.
                    442: 
                    443:     !ERROR_SUCCESS - TBD
                    444: 
                    445: --*/
                    446: 
                    447: {
                    448:     DBGKD_MANIPULATE_STATE m;
                    449:     PDBGKD_MANIPULATE_STATE Reply;
                    450:     PDBGKD_READ_MEMORY a = &m.u.ReadMemory;
                    451:     DWORD st;
                    452:     BOOLEAN rc;
                    453: 
                    454:     if ( TransferCount + sizeof(m) > PACKET_MAX_SIZE ) {
                    455:         return ERROR_MORE_DATA;
                    456:         }
                    457: 
                    458:     //
                    459:     // Format state manipulate message
                    460:     //
                    461: 
                    462:     m.ApiNumber = DbgKdReadVirtualMemoryApi;
                    463:     m.ReturnStatus = STATUS_PENDING;
                    464:     a->TargetBaseAddress = TargetBaseAddress;
                    465:     a->TransferCount = TransferCount;
                    466:     a->ActualBytesRead = 0L;
                    467: 
                    468:     //
                    469:     // Send the message and then wait for reply
                    470:     //
                    471: 
                    472:     do {
                    473:         DbgKdpWritePacket(&m,sizeof(m),PACKET_TYPE_KD_STATE_MANIPULATE,NULL,0);
                    474: 
                    475:         rc = DbgKdpWaitForPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
                    476:                                  &Reply
                    477:                                  );
                    478:     } while (rc == FALSE);
                    479: 
                    480:     //
                    481:     // If this is not a ReadMemory response than protocol is screwed up.
                    482:     // assert that protocol is ok.
                    483:     //
                    484: 
                    485:     st = Reply->ReturnStatus;
                    486:     assert(Reply->ApiNumber == DbgKdReadVirtualMemoryApi);
                    487: 
                    488:     //
                    489:     // Reset message address to reply.
                    490:     //
                    491: 
                    492:     a = &Reply->u.ReadMemory;
                    493:     assert(a->ActualBytesRead <= TransferCount);
                    494: 
                    495:     //
                    496:     // Return actual bytes read, and then transfer the bytes
                    497:     //
                    498: 
                    499:     if (ActualBytesRead) {
                    500:         *ActualBytesRead = a->ActualBytesRead;
                    501:     }
                    502:     st = Reply->ReturnStatus;
                    503: 
                    504:     //
                    505:     // Since read response data follows message, Reply+1 should point
                    506:     // at the data
                    507:     //
                    508: 
                    509:     memcpy(UserInterfaceBuffer, Reply+1, (int)a->ActualBytesRead);
                    510: 
                    511:     return st;
                    512: }
                    513: 
                    514: 
                    515: 
                    516: DWORD
                    517: DbgKdWriteVirtualMemory(
                    518:     IN PVOID TargetBaseAddress,
                    519:     OUT PVOID UserInterfaceBuffer,
                    520:     IN ULONG TransferCount,
                    521:     OUT PULONG ActualBytesWritten OPTIONAL
                    522:     )
                    523: 
                    524: /*++
                    525: 
                    526: Routine Description:
                    527: 
                    528:     This function writes the specified data to the system being debugged
                    529:     using the current mapping of the processor.
                    530: 
                    531: Arguments:
                    532: 
                    533:     TargetBaseAddress - Supplies the base address of the memory to be written
                    534:         into the system being debugged.  The virtual address is in terms
                    535:         of the current mapping for the processor that reported the last
                    536:         state change.  Until we figure out how to do this differently,
                    537:         the virtual address must refer to a valid page (although it does
                    538:         not necesserily have to be in the TB).
                    539: 
                    540:     UserInterfaceBuffer - Supplies the address of the buffer in the user
                    541:         interface that contains the data to be written.
                    542: 
                    543:     TransferCount - Specifies the number of bytes to write.
                    544: 
                    545:     ActualBytesWritten - An optional parameter that if supplied, returns
                    546:         the number of bytes actually written.
                    547: 
                    548: Return Value:
                    549: 
                    550:     ERROR_SUCCESS - The specified read occured.
                    551: 
                    552:     ERROR_MORE_DATA - A read that is to large was specified.
                    553: 
                    554:     ERROR_NO_ACCESS - The TargetBaseAddress/TransferCount
                    555:         parameters refers to invalid virtual memory.
                    556: 
                    557:     !ERROR_SUCCESS - TBD
                    558: 
                    559: --*/
                    560: 
                    561: {
                    562:     DBGKD_MANIPULATE_STATE m;
                    563:     PDBGKD_MANIPULATE_STATE Reply;
                    564:     PDBGKD_WRITE_MEMORY a = &m.u.WriteMemory;
                    565:     DWORD st;
                    566:     BOOLEAN rc;
                    567: 
                    568:     if ( TransferCount + sizeof(m) > PACKET_MAX_SIZE ) {
                    569:         return ERROR_MORE_DATA;
                    570:         }
                    571: 
                    572:     //
                    573:     // Format state manipulate message
                    574:     //
                    575: 
                    576:     m.ApiNumber = DbgKdWriteVirtualMemoryApi;
                    577:     m.ReturnStatus = STATUS_PENDING;
                    578:     a->TargetBaseAddress = TargetBaseAddress;
                    579:     a->TransferCount = TransferCount;
                    580:     a->ActualBytesWritten = 0L;
                    581: 
                    582:     //
                    583:     // Send the message and data to write and then wait for reply
                    584:     //
                    585: 
                    586:     do {
                    587:         DbgKdpWritePacket(
                    588:             &m,
                    589:             sizeof(m),
                    590:             PACKET_TYPE_KD_STATE_MANIPULATE,
                    591:             UserInterfaceBuffer,
                    592:             (USHORT)TransferCount
                    593:             );
                    594:         rc = DbgKdpWaitForPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
                    595:                                  &Reply
                    596:                                  );
                    597:     } while (rc == FALSE);
                    598: 
                    599:     //
                    600:     // If this is not a WriteMemory response than protocol is screwed up.
                    601:     // assert that protocol is ok.
                    602:     //
                    603: 
                    604:     st = Reply->ReturnStatus;
                    605:     assert(Reply->ApiNumber == DbgKdWriteVirtualMemoryApi);
                    606: 
                    607:     //
                    608:     // Reset message address to reply.
                    609:     //
                    610: 
                    611:     a = &Reply->u.WriteMemory;
                    612:     assert(a->ActualBytesWritten <= TransferCount);
                    613: 
                    614:     //
                    615:     // Return actual bytes written
                    616:     //
                    617: 
                    618:     if (ActualBytesWritten) {
                    619:         *ActualBytesWritten = a->ActualBytesWritten;
                    620:     }
                    621:     st = Reply->ReturnStatus;
                    622: 
                    623:     return st;
                    624: }
                    625: 
                    626: DWORD
                    627: DbgKdReadControlSpace(
                    628:     IN USHORT Processor,
                    629:     IN PVOID TargetBaseAddress,
                    630:     OUT PVOID UserInterfaceBuffer,
                    631:     IN ULONG TransferCount,
                    632:     OUT PULONG ActualBytesRead OPTIONAL
                    633:     )
                    634: 
                    635: /*++
                    636: 
                    637: Routine Description:
                    638: 
                    639:     This function reads the specified data from the control space of
                    640:     the system being debugged.
                    641: 
                    642:     Control space is processor dependent. TargetBaseAddress is mapped
                    643:     to control space in a processor/implementation defined manner.
                    644: 
                    645: Arguments:
                    646: 
                    647:     Processor - Supplies the processor whoes control space is desired.
                    648: 
                    649:     TargetBaseAddress - Supplies the base address in control space to
                    650:         read. This address is interpreted in an implementation defined
                    651:         manner.
                    652: 
                    653: 
                    654:         On x86, control space is a per-processor area which contains:
                    655: 
                    656:             Current Context     (CONTEXT)
                    657:             Special Registers   (KSPECIAL_REGISTERS)
                    658: 
                    659:             This means that to read the special registers:
                    660: 
                    661:                 DbgKdReadControlSpace(
                    662:                     NtsdCurrentProcessor,
                    663:                     (PVOID)sizeof(CONTEXT),
                    664:                     (PVOID)&SpecialRegContext,
                    665:                     sizeof(KSPECIAL_REGISTERS),
                    666:                     &cBytesRead
                    667:                     );
                    668: 
                    669:             The above will read the special registers of the current processor
                    670:             since the control space address is sizeof(CONTEXT)
                    671: 
                    672:         On MIPS, control space addresses are used to address the translation
                    673:         buffer.
                    674: 
                    675:     UserInterfaceBuffer - Supplies the address of the buffer in the user
                    676:         interface that data read is to be placed.
                    677: 
                    678:     TransferCount - Specifies the number of bytes to read.
                    679: 
                    680:     ActualBytesRead - An optional parameter that if supplied, returns
                    681:         the number of bytes actually read.
                    682: 
                    683: Return Value:
                    684: 
                    685:     ERROR_SUCCESS - The specified read occured.
                    686: 
                    687:     ERROR_MORE_DATA - A read that is to large was specified.
                    688: 
                    689:     !ERROR_SUCCESS - TBD
                    690: 
                    691: --*/
                    692: 
                    693: {
                    694:     DBGKD_MANIPULATE_STATE m;
                    695:     PDBGKD_MANIPULATE_STATE Reply;
                    696:     PDBGKD_READ_MEMORY a = &m.u.ReadMemory;
                    697:     DWORD st;
                    698:     BOOLEAN rc;
                    699: 
                    700:     if ( TransferCount + sizeof(m) > PACKET_MAX_SIZE ) {
                    701:         return ERROR_MORE_DATA;
                    702:         }
                    703: 
                    704:     //
                    705:     // Format state manipulate message
                    706:     //
                    707: 
                    708:     m.ApiNumber = DbgKdReadControlSpaceApi;
                    709:     m.ReturnStatus = STATUS_PENDING;
                    710:     m.Processor = Processor;
                    711:     a->TargetBaseAddress = TargetBaseAddress;
                    712:     a->TransferCount = TransferCount;
                    713:     a->ActualBytesRead = 0L;
                    714: 
                    715:     //
                    716:     // Send the message and then wait for reply
                    717:     //
                    718: 
                    719:     do {
                    720:         DbgKdpWritePacket(&m,sizeof(m),PACKET_TYPE_KD_STATE_MANIPULATE,NULL,0);
                    721: 
                    722:         rc = DbgKdpWaitForPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &Reply);
                    723: 
                    724:     } while (rc == FALSE);
                    725: 
                    726:     //
                    727:     // If this is not a ReadControl response than protocol is screwed up.
                    728:     // assert that protocol is ok.
                    729:     //
                    730: 
                    731:     st = Reply->ReturnStatus;
                    732:     assert(Reply->ApiNumber == DbgKdReadControlSpaceApi);
                    733: 
                    734:     //
                    735:     // Reset message address to reply.
                    736:     //
                    737: 
                    738:     a = &Reply->u.ReadMemory;
                    739:     assert(a->ActualBytesRead <= TransferCount);
                    740: 
                    741:     //
                    742:     // Return actual bytes read, and then transfer the bytes
                    743:     //
                    744: 
                    745:     if (ActualBytesRead) {
                    746:         *ActualBytesRead = a->ActualBytesRead;
                    747:     }
                    748:     st = Reply->ReturnStatus;
                    749: 
                    750:     //
                    751:     // Since read response data follows message, Reply+1 should point
                    752:     // at the data
                    753:     //
                    754: 
                    755:     memcpy(UserInterfaceBuffer, Reply+1, (int)a->ActualBytesRead);
                    756: 
                    757:     return st;
                    758: }
                    759: 
                    760: 
                    761: 
                    762: DWORD
                    763: DbgKdWriteControlSpace(
                    764:     IN USHORT Processor,
                    765:     IN PVOID TargetBaseAddress,
                    766:     OUT PVOID UserInterfaceBuffer,
                    767:     IN ULONG TransferCount,
                    768:     OUT PULONG ActualBytesWritten OPTIONAL
                    769:     )
                    770: 
                    771: /*++
                    772: 
                    773: Routine Description:
                    774: 
                    775:     This function writes the specified data to control space on the system
                    776:     being debugged.
                    777: 
                    778:     Control space is processor dependent. TargetBaseAddress is mapped
                    779:     to control space in a processor/implementation defined manner.
                    780: 
                    781: Arguments:
                    782: 
                    783:     Processor - Supplies the processor whoes control space is desired.
                    784: 
                    785:     TargetBaseAddress - Supplies the base address in control space to be
                    786:         written.
                    787: 
                    788:     UserInterfaceBuffer - Supplies the address of the buffer in the user
                    789:         interface that contains the data to be written.
                    790: 
                    791:     TransferCount - Specifies the number of bytes to write.
                    792: 
                    793:     ActualBytesWritten - An optional parameter that if supplied, returns
                    794:         the number of bytes actually written.
                    795: 
                    796: Return Value:
                    797: 
                    798:     ERROR_SUCCESS - The specified read occured.
                    799: 
                    800:     ERROR_MORE_DATA - A read that is to large was specified.
                    801: 
                    802:     !ERROR_SUCCESS - TBD
                    803: 
                    804: --*/
                    805: 
                    806: {
                    807:     DBGKD_MANIPULATE_STATE m;
                    808:     PDBGKD_MANIPULATE_STATE Reply;
                    809:     PDBGKD_WRITE_MEMORY a = &m.u.WriteMemory;
                    810:     DWORD st;
                    811:     BOOLEAN rc;
                    812: 
                    813:     if ( TransferCount + sizeof(m) > PACKET_MAX_SIZE ) {
                    814:         return ERROR_MORE_DATA;
                    815:         }
                    816: 
                    817:     //
                    818:     // Format state manipulate message
                    819:     //
                    820: 
                    821:     m.ApiNumber = DbgKdWriteControlSpaceApi;
                    822:     m.ReturnStatus = STATUS_PENDING;
                    823:     m.Processor = Processor;
                    824:     a->TargetBaseAddress = TargetBaseAddress;
                    825:     a->TransferCount = TransferCount;
                    826:     a->ActualBytesWritten = 0L;
                    827: 
                    828:     //
                    829:     // Send the message and data to write and then wait for reply
                    830:     //
                    831: 
                    832:     do {
                    833:         DbgKdpWritePacket(
                    834:             &m,
                    835:             sizeof(m),
                    836:             PACKET_TYPE_KD_STATE_MANIPULATE,
                    837:             UserInterfaceBuffer,
                    838:             (USHORT)TransferCount
                    839:             );
                    840: 
                    841:         rc = DbgKdpWaitForPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &Reply);
                    842:     } while (rc == FALSE);
                    843: 
                    844:     //
                    845:     // If this is not a WriteControl response than protocol is screwed up.
                    846:     // assert that protocol is ok.
                    847:     //
                    848: 
                    849:     st = Reply->ReturnStatus;
                    850:     assert(Reply->ApiNumber == DbgKdWriteControlSpaceApi);
                    851: 
                    852:     //
                    853:     // Reset message address to reply.
                    854:     //
                    855: 
                    856:     a = &Reply->u.WriteMemory;
                    857:     assert(a->ActualBytesWritten <= TransferCount);
                    858: 
                    859:     //
                    860:     // Return actual bytes written
                    861:     //
                    862: 
                    863:     *ActualBytesWritten = a->ActualBytesWritten;
                    864:     st = Reply->ReturnStatus;
                    865: 
                    866:     return st;
                    867: }
                    868: 
                    869: 
                    870: DWORD
                    871: DbgKdGetContext(
                    872:     IN USHORT Processor,
                    873:     IN OUT PCONTEXT Context
                    874:     )
                    875: 
                    876: /*++
                    877: 
                    878: Routine Description:
                    879: 
                    880:     This function reads the context from the system being debugged.
                    881:     The ContextFlags field determines how much context is read.
                    882: 
                    883: Arguments:
                    884: 
                    885:     Processor - Supplies a processor number to get context from.
                    886: 
                    887:     Context - On input, the ContextFlags field controls what portions of
                    888:         the context record the caller as interested in reading.  On
                    889:         output, the context record returns the current context for the
                    890:         processor that reported the last state change.
                    891: 
                    892: Return Value:
                    893: 
                    894:     ERROR_SUCCESS - The specified get context occured.
                    895: 
                    896:     !ERROR_SUCCESS - TBD
                    897: 
                    898: --*/
                    899: 
                    900: {
                    901:     DBGKD_MANIPULATE_STATE m;
                    902:     PDBGKD_MANIPULATE_STATE Reply;
                    903:     PDBGKD_GET_CONTEXT a = &m.u.GetContext;
                    904:     DWORD st;
                    905:     BOOLEAN rc;
                    906: 
                    907:     //
                    908:     // Format state manipulate message
                    909:     //
                    910: 
                    911:     m.ApiNumber = DbgKdGetContextApi;
                    912:     m.ReturnStatus = STATUS_PENDING;
                    913:     m.Processor = Processor;
                    914:     a->ContextFlags = Context->ContextFlags;
                    915: 
                    916:     //
                    917:     // Send the message and then wait for reply
                    918:     //
                    919: 
                    920:     do {
                    921:         DbgKdpWritePacket(&m,sizeof(m),PACKET_TYPE_KD_STATE_MANIPULATE,NULL,0);
                    922:         rc = DbgKdpWaitForPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &Reply);
                    923:     } while (rc == FALSE);
                    924: 
                    925:     //
                    926:     // If this is not a GetContext response than protocol is screwed up.
                    927:     // assert that protocol is ok.
                    928:     //
                    929: 
                    930:     st = Reply->ReturnStatus;
                    931:     assert(Reply->ApiNumber == DbgKdGetContextApi);
                    932: 
                    933:     //
                    934:     // Reset message address to reply.
                    935:     //
                    936: 
                    937:     a = &Reply->u.GetContext;
                    938:     st = Reply->ReturnStatus;
                    939: 
                    940:     //
                    941:     // Since get context response data follows message, Reply+1 should point
                    942:     // at the data
                    943:     //
                    944: 
                    945:     memcpy(Context, Reply+1, sizeof(*Context));
                    946: 
                    947:     return st;
                    948: }
                    949: 
                    950: 
                    951: 
                    952: DWORD
                    953: DbgKdSetContext(
                    954:     IN USHORT Processor,
                    955:     IN PCONTEXT Context
                    956:     )
                    957: 
                    958: /*++
                    959: 
                    960: Routine Description:
                    961: 
                    962:     This function writes the specified context to the system being debugged.
                    963: 
                    964: Arguments:
                    965: 
                    966:     Processor - Supplies a processor number to set the context to.
                    967: 
                    968:     Context - Supplies a context record used to set the context for the
                    969:         processor that reported the last state change.  Only the
                    970:         portions of the context indicated by the ContextFlags field are
                    971:         actually written.
                    972: 
                    973: 
                    974: Return Value:
                    975: 
                    976:     ERROR_SUCCESS - The specified set context occured.
                    977: 
                    978:     !ERROR_SUCCESS - TBD
                    979: 
                    980: --*/
                    981: 
                    982: {
                    983:     DBGKD_MANIPULATE_STATE m;
                    984:     PDBGKD_MANIPULATE_STATE Reply;
                    985:     PDBGKD_SET_CONTEXT a = &m.u.SetContext;
                    986:     DWORD st;
                    987:     BOOLEAN rc;
                    988: 
                    989:     //
                    990:     // Format state manipulate message
                    991:     //
                    992: 
                    993:     m.ApiNumber = DbgKdSetContextApi;
                    994:     m.ReturnStatus = STATUS_PENDING;
                    995:     m.Processor = Processor;
                    996:     a->ContextFlags = Context->ContextFlags;
                    997: 
                    998:     //
                    999:     // Send the message and context and then wait for reply
                   1000:     //
                   1001: 
                   1002:     do {
                   1003:         DbgKdpWritePacket(
                   1004:             &m,
                   1005:             sizeof(m),
                   1006:             PACKET_TYPE_KD_STATE_MANIPULATE,
                   1007:             Context,
                   1008:             sizeof(*Context)
                   1009:             );
                   1010:         rc = DbgKdpWaitForPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &Reply);
                   1011:     } while (rc == FALSE);
                   1012: 
                   1013:     //
                   1014:     // If this is not a SetContext response than protocol is screwed up.
                   1015:     // assert that protocol is ok.
                   1016:     //
                   1017: 
                   1018:     st = Reply->ReturnStatus;
                   1019:     assert(Reply->ApiNumber == DbgKdSetContextApi);
                   1020: 
                   1021:     //
                   1022:     // Reset message address to reply.
                   1023:     //
                   1024: 
                   1025:     a = &Reply->u.SetContext;
                   1026:     st = Reply->ReturnStatus;
                   1027: 
                   1028:     return st;
                   1029: }
                   1030: 
                   1031: DWORD
                   1032: DbgKdWriteBreakPoint(
                   1033:     IN PVOID BreakPointAddress,
                   1034:     OUT PULONG BreakPointHandle
                   1035:     )
                   1036: 
                   1037: /*++
                   1038: 
                   1039: Routine Description:
                   1040: 
                   1041:     This function is used to write a breakpoint at the address specified.
                   1042: 
                   1043: 
                   1044: Arguments:
                   1045: 
                   1046:     BreakPointAddress - Supplies the address that a breakpoint
                   1047:         instruction is to be written.  This address is interpreted using
                   1048:         the current mapping on the processor reporting the previous
                   1049:         state change.  If the address refers to a page that is not
                   1050:         valid, the the breakpoint is remembered by the system.  As each
                   1051:         page is made valid, the system will check for pending
                   1052:         breakpoints and install breakpoints as necessary.
                   1053: 
                   1054:     BreakPointHandle - Returns a handle to a breakpoint.  This handle
                   1055:         may be used in a subsequent call to DbgKdRestoreBreakPoint.
                   1056: 
                   1057: Return Value:
                   1058: 
                   1059:     ERROR_SUCCESS - The specified breakpoint write occured.
                   1060: 
                   1061:     !ERROR_SUCCESS - TBD
                   1062: 
                   1063: 
                   1064: --*/
                   1065: 
                   1066: {
                   1067: 
                   1068:     DBGKD_MANIPULATE_STATE m;
                   1069:     PDBGKD_MANIPULATE_STATE Reply;
                   1070:     PDBGKD_WRITE_BREAKPOINT a = &m.u.WriteBreakPoint;
                   1071:     DWORD st;
                   1072:     BOOLEAN rc;
                   1073: 
                   1074:     //
                   1075:     // Format state manipulate message
                   1076:     //
                   1077: 
                   1078:     m.ApiNumber = DbgKdWriteBreakPointApi;
                   1079:     m.ReturnStatus = STATUS_PENDING;
                   1080:     a->BreakPointAddress = BreakPointAddress;
                   1081: 
                   1082:     //
                   1083:     // Send the message and context and then wait for reply
                   1084:     //
                   1085: 
                   1086:     do {
                   1087:         DbgKdpWritePacket(
                   1088:             &m,
                   1089:             sizeof(m),
                   1090:             PACKET_TYPE_KD_STATE_MANIPULATE,
                   1091:             NULL,
                   1092:             0
                   1093:             );
                   1094: 
                   1095:         rc = DbgKdpWaitForPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &Reply);
                   1096:     } while (rc == FALSE);
                   1097: 
                   1098:     //
                   1099:     // If this is not a WriteBreakPoint response than protocol is screwed up.
                   1100:     // assert that protocol is ok.
                   1101:     //
                   1102: 
                   1103:     st = Reply->ReturnStatus;
                   1104:     assert(Reply->ApiNumber == DbgKdWriteBreakPointApi);
                   1105: 
                   1106:     //
                   1107:     // Reset message address to reply.
                   1108:     //
                   1109: 
                   1110:     a = &Reply->u.WriteBreakPoint;
                   1111:     st = Reply->ReturnStatus;
                   1112:     *BreakPointHandle = a->BreakPointHandle;
                   1113: 
                   1114:     return st;
                   1115: }
                   1116: 
                   1117: DWORD
                   1118: DbgKdRestoreBreakPoint(
                   1119:     IN ULONG BreakPointHandle
                   1120:     )
                   1121: 
                   1122: /*++
                   1123: 
                   1124: Routine Description:
                   1125: 
                   1126:     This function is used to restore a breakpoint to its original
                   1127:     value.
                   1128: 
                   1129: Arguments:
                   1130: 
                   1131:     BreakPointHandle - Supplies a handle returned by
                   1132:         DbgKdWriteBreakPoint.  This handle must refer to a valid
                   1133:         address.  The contents of the address must also be a breakpoint
                   1134:         instruction.  If both of these are true, then the original value
                   1135:         at the breakpoint address is restored.
                   1136: 
                   1137: Return Value:
                   1138: 
                   1139:     ERROR_SUCCESS - The specified breakpoint restore occured.
                   1140: 
                   1141:     !ERROR_SUCCESS - TBD
                   1142: 
                   1143: --*/
                   1144: 
                   1145: {
                   1146: 
                   1147:     DBGKD_MANIPULATE_STATE m;
                   1148:     PDBGKD_MANIPULATE_STATE Reply;
                   1149:     PDBGKD_RESTORE_BREAKPOINT a = &m.u.RestoreBreakPoint;
                   1150:     DWORD st;
                   1151:     BOOLEAN rc;
                   1152: 
                   1153:     //
                   1154:     // Format state manipulate message
                   1155:     //
                   1156: 
                   1157:     m.ApiNumber = DbgKdRestoreBreakPointApi;
                   1158:     m.ReturnStatus = STATUS_PENDING;
                   1159:     a->BreakPointHandle = BreakPointHandle;
                   1160: 
                   1161:     //
                   1162:     // Send the message and context and then wait for reply
                   1163:     //
                   1164: 
                   1165:     do {
                   1166:         DbgKdpWritePacket(
                   1167:             &m,
                   1168:             sizeof(m),
                   1169:             PACKET_TYPE_KD_STATE_MANIPULATE,
                   1170:             NULL,
                   1171:             0
                   1172:             );
                   1173: 
                   1174:         rc = DbgKdpWaitForPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &Reply);
                   1175:     } while (rc == FALSE);
                   1176: 
                   1177:     //
                   1178:     // If this is not a RestoreBreakPoint response than protocol is screwed up.
                   1179:     // assert that protocol is ok.
                   1180:     //
                   1181: 
                   1182:     st = Reply->ReturnStatus;
                   1183:     assert(Reply->ApiNumber == DbgKdRestoreBreakPointApi);
                   1184: 
                   1185:     //
                   1186:     // Reset message address to reply.
                   1187:     //
                   1188: 
                   1189:     a = &Reply->u.RestoreBreakPoint;
                   1190:     st = Reply->ReturnStatus;
                   1191: 
                   1192:     //
                   1193:     // free the packet
                   1194:     //
                   1195: 
                   1196:     return st;
                   1197: }
                   1198: 
                   1199: DWORD
                   1200: DbgKdReadIoSpace(
                   1201:     IN PVOID IoAddress,
                   1202:     OUT PVOID ReturnedData,
                   1203:     IN ULONG DataSize
                   1204:     )
                   1205: 
                   1206: /*++
                   1207: 
                   1208: Routine Description:
                   1209: 
                   1210:     This function is used read a byte, short, or long (1,2,4 bytes) from
                   1211:     the specified I/O address.
                   1212: 
                   1213: Arguments:
                   1214: 
                   1215:     IoAddress - Supplies the Io address to read from.
                   1216: 
                   1217:     ReturnedData - Supplies the value read from the I/O address.
                   1218: 
                   1219:     DataSize - Supplies the size in bytes to read. Values of 1, 2, or
                   1220:         4 are accepted.
                   1221: 
                   1222: Return Value:
                   1223: 
                   1224:     ERROR_SUCCESS - Data was successfully read from the I/O
                   1225:         address.
                   1226: 
                   1227:     ERROR_INVALID_PARAMETER - A DataSize value other than 1,2, or 4 was
                   1228:         specified.
                   1229: 
                   1230:     !ERROR_SUCCESS - TBD
                   1231: 
                   1232: --*/
                   1233: 
                   1234: {
                   1235: 
                   1236:     DBGKD_MANIPULATE_STATE m;
                   1237:     PDBGKD_MANIPULATE_STATE Reply;
                   1238:     PDBGKD_READ_WRITE_IO a = &m.u.ReadWriteIo;
                   1239:     DWORD st;
                   1240:     BOOLEAN rc;
                   1241: 
                   1242:     switch ( DataSize ) {
                   1243:         case 1:
                   1244:         case 2:
                   1245:         case 4:
                   1246:             break;
                   1247:         default:
                   1248:             return ERROR_INVALID_PARAMETER;
                   1249:         }
                   1250: 
                   1251:     //
                   1252:     // Format state manipulate message
                   1253:     //
                   1254: 
                   1255:     m.ApiNumber = DbgKdReadIoSpaceApi;
                   1256:     m.ReturnStatus = STATUS_PENDING;
                   1257: 
                   1258:     a->DataSize = DataSize;
                   1259:     a->IoAddress = IoAddress;
                   1260: 
                   1261:     //
                   1262:     // Send the message and then wait for reply
                   1263:     //
                   1264: 
                   1265:     do {
                   1266:         DbgKdpWritePacket(
                   1267:             &m,
                   1268:             sizeof(m),
                   1269:             PACKET_TYPE_KD_STATE_MANIPULATE,
                   1270:             NULL,
                   1271:             0
                   1272:             );
                   1273: 
                   1274:         rc = DbgKdpWaitForPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &Reply);
                   1275:     } while (rc == FALSE);
                   1276: 
                   1277:     //
                   1278:     // If this is not a ReadIo response than protocol is screwed up.
                   1279:     // assert that protocol is ok.
                   1280:     //
                   1281: 
                   1282:     st = Reply->ReturnStatus;
                   1283:     assert(Reply->ApiNumber == DbgKdReadIoSpaceApi);
                   1284: 
                   1285:     //
                   1286:     // Reset message address to reply.
                   1287:     //
                   1288: 
                   1289:     a = &Reply->u.ReadWriteIo;
                   1290:     st = Reply->ReturnStatus;
                   1291: 
                   1292:     switch ( DataSize ) {
                   1293:         case 1:
                   1294:             *(PUCHAR)ReturnedData = (UCHAR)a->DataValue;
                   1295:             break;
                   1296:         case 2:
                   1297:             *(PUSHORT)ReturnedData = (USHORT)a->DataValue;
                   1298:             break;
                   1299:         case 4:
                   1300:             *(PULONG)ReturnedData = a->DataValue;
                   1301:             break;
                   1302:         }
                   1303: 
                   1304:     return st;
                   1305: }
                   1306: 
                   1307: DWORD
                   1308: DbgKdWriteIoSpace(
                   1309:     IN PVOID IoAddress,
                   1310:     IN ULONG DataValue,
                   1311:     IN ULONG DataSize
                   1312:     )
                   1313: 
                   1314: /*++
                   1315: 
                   1316: Routine Description:
                   1317: 
                   1318:     This function is used write a byte, short, or long (1,2,4 bytes) to
                   1319:     the specified I/O address.
                   1320: 
                   1321: Arguments:
                   1322: 
                   1323:     IoAddress - Supplies the Io address to write to.
                   1324: 
                   1325:     DataValue - Supplies the value to write to the I/O address.
                   1326: 
                   1327:     DataSize - Supplies the size in bytes to write. Values of 1, 2, or
                   1328:         4 are accepted.
                   1329: 
                   1330: Return Value:
                   1331: 
                   1332:     ERROR_SUCCESS - Data was successfully written to the I/O
                   1333:         address.
                   1334: 
                   1335:     ERROR_INVALID_PARAMETER - A DataSize value other than 1,2, or 4 was
                   1336:         specified.
                   1337: 
                   1338:     !ERROR_SUCCESS - TBD
                   1339: 
                   1340: --*/
                   1341: 
                   1342: {
                   1343: 
                   1344:     DBGKD_MANIPULATE_STATE m;
                   1345:     PDBGKD_MANIPULATE_STATE Reply;
                   1346:     PDBGKD_READ_WRITE_IO a = &m.u.ReadWriteIo;
                   1347:     DWORD st;
                   1348:     BOOLEAN rc;
                   1349: 
                   1350:     switch ( DataSize ) {
                   1351:         case 1:
                   1352:         case 2:
                   1353:         case 4:
                   1354:             break;
                   1355:         default:
                   1356:             return ERROR_INVALID_PARAMETER;
                   1357:         }
                   1358: 
                   1359:     //
                   1360:     // Format state manipulate message
                   1361:     //
                   1362: 
                   1363:     m.ApiNumber = DbgKdWriteIoSpaceApi;
                   1364:     m.ReturnStatus = STATUS_PENDING;
                   1365: 
                   1366:     a->DataSize = DataSize;
                   1367:     a->IoAddress = IoAddress;
                   1368:     a->DataValue = DataValue;
                   1369: 
                   1370:     //
                   1371:     // Send the message and then wait for reply
                   1372:     //
                   1373: 
                   1374:     do {
                   1375:         DbgKdpWritePacket(
                   1376:             &m,
                   1377:             sizeof(m),
                   1378:             PACKET_TYPE_KD_STATE_MANIPULATE,
                   1379:             NULL,
                   1380:             0
                   1381:             );
                   1382: 
                   1383:         rc = DbgKdpWaitForPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &Reply);
                   1384:     } while (rc == FALSE);
                   1385: 
                   1386:     //
                   1387:     // If this is not a WriteIo response than protocol is screwed up.
                   1388:     // assert that protocol is ok.
                   1389:     //
                   1390: 
                   1391:     st = Reply->ReturnStatus;
                   1392:     assert(Reply->ApiNumber == DbgKdWriteIoSpaceApi);
                   1393: 
                   1394:     //
                   1395:     // Reset message address to reply.
                   1396:     //
                   1397: 
                   1398:     a = &Reply->u.ReadWriteIo;
                   1399:     st = Reply->ReturnStatus;
                   1400: 
                   1401:     //
                   1402:     // free the packet
                   1403:     //
                   1404: 
                   1405:     return st;
                   1406: }
                   1407: 
                   1408: 
                   1409: VOID far
                   1410: DbgKdpKbdPollThread(VOID)
                   1411: {
                   1412:     HANDLE StandardInputHandle;
                   1413:     DWORD i;
                   1414:     BOOLEAN rc;
                   1415:     UCHAR   c;
                   1416: 
                   1417:     //
                   1418:     // Capture all typed input immediately so that control-c,
                   1419:     // control-break, etc, get processed in a timely fashion.
                   1420:     // Stuff the characters into an anonymous pipe, from which
                   1421:     // DbgKdpGetConsole byte will read them.
                   1422:     //
                   1423:     // (WHAT??? A PIPE???  Very very simple way to get data flow
                   1424:     //  between two threads correctly synchronized, folks.)
                   1425:     //
                   1426: 
                   1427:     StandardInputHandle = GetStdHandle(STD_INPUT_HANDLE);
                   1428: 
                   1429:     while (TRUE) {
                   1430:         rc = ReadFile(StandardInputHandle,&c,1,&i,NULL);
                   1431:         if ((rc != TRUE) || (i != 1)) {
                   1432:         continue;
                   1433:         }
                   1434:         if (c == CONTROL_B) {
                   1435:             exit(0);
                   1436:         } else if (c == CONTROL_D) {
                   1437:             chLastCommand[0] = '\0';
                   1438:             if (KdDebug) {
                   1439:                 KdDebug = FALSE;
                   1440:             } else {
                   1441:                 KdDebug = TRUE;
                   1442:             }
                   1443:             continue;
                   1444:         } else if (c == CONTROL_R) {
                   1445:             KdResync = TRUE;
                   1446:             chLastCommand[0] = '\0';
                   1447:             continue;
                   1448:         }
                   1449:         rc = WriteFile(PipeWrite, &c, 1, &i, NULL);
                   1450:         if ((rc != TRUE) || (i != 1)) {
                   1451:             continue;
                   1452:         }
                   1453: //        FlushFileBuffers(PipeWrite);
                   1454:     }
                   1455: }
                   1456: 
                   1457: BOOL
                   1458: DbgKdpGetConsoleByte(
                   1459:     PVOID pBuf,
                   1460:     DWORD cbBuf,
                   1461:     LPDWORD pcbBytesRead
                   1462:     )
                   1463: {
                   1464:     return ReadFile(PipeRead,pBuf,cbBuf,pcbBytesRead,NULL);
                   1465: }
                   1466: 
                   1467: PUCHAR
                   1468: DbgKdGets(
                   1469:     PUCHAR Buffer,
                   1470:     USHORT Length
                   1471:     )
                   1472: {
                   1473:     DWORD i;
                   1474:     BOOLEAN rc;
                   1475:     USHORT j;
                   1476:     UCHAR   c;
                   1477: 
                   1478:     for (j = 0; (j+1) < Length; j++) {
                   1479: 
                   1480:         rc = DbgKdpGetConsoleByte(&c, 1, &i);
                   1481: 
                   1482:                 if ((rc != TRUE) || (i != 1)) {
                   1483:         }
                   1484: 
                   1485:         if (c == '\n') {
                   1486:             Buffer[j] = '\n';
                   1487:             Buffer[j+1] = '\0';
                   1488:             return Buffer;
                   1489:         }
                   1490: 
                   1491:         Buffer[j] = c;
                   1492: 
                   1493:     }
                   1494:     Buffer[j-1] = '\0';
                   1495:     return Buffer;
                   1496: }
                   1497: 
                   1498: 
                   1499: 
                   1500: DWORD
                   1501: DbgKdReboot(
                   1502:     VOID
                   1503:     )
                   1504: 
                   1505: /*++
                   1506: 
                   1507: Routine Description:
                   1508: 
                   1509:     This function reboots being debugged.
                   1510: 
                   1511: Arguments:
                   1512: 
                   1513:     None.
                   1514: 
                   1515: Return Value:
                   1516: 
                   1517:     None.
                   1518: 
                   1519: --*/
                   1520: 
                   1521: {
                   1522:     DBGKD_MANIPULATE_STATE m;
                   1523: 
                   1524:     //
                   1525:     // Format state manipulate message
                   1526:     //
                   1527: 
                   1528:     m.ApiNumber = DbgKdRebootApi;
                   1529:     m.ReturnStatus = STATUS_PENDING;
                   1530: 
                   1531:     //
                   1532:     // Send the message.
                   1533:     //
                   1534: 
                   1535:     DbgKdpWritePacket(&m,sizeof(m),PACKET_TYPE_KD_STATE_MANIPULATE,NULL,0);
                   1536: 
                   1537:     return ERROR_SUCCESS;
                   1538: }
                   1539: 
                   1540: 
                   1541: DWORD
                   1542: DbgKdReadPhysicalMemory(
                   1543:     IN PHYSICAL_ADDRESS TargetBaseAddress,
                   1544:     OUT PVOID UserInterfaceBuffer,
                   1545:     IN ULONG TransferCount,
                   1546:     OUT PULONG ActualBytesRead OPTIONAL
                   1547:     )
                   1548: 
                   1549: /*++
                   1550: 
                   1551: Routine Description:
                   1552: 
                   1553:     This function reads the specified data from the physical memory of
                   1554:     the system being debugged.
                   1555: 
                   1556: Arguments:
                   1557: 
                   1558:     TargetBaseAddress - Supplies the physical address of the memory to read
                   1559:         from the system being debugged.
                   1560: 
                   1561:     UserInterfaceBuffer - Supplies the address of the buffer in the user
                   1562:         interface that data read is to be placed.
                   1563: 
                   1564:     TransferCount - Specifies the number of bytes to read.
                   1565: 
                   1566:     ActualBytesRead - An optional parameter that if supplied, returns
                   1567:         the number of bytes actually read.
                   1568: 
                   1569: Return Value:
                   1570: 
                   1571:     ERROR_SUCCESS - The specified read occured.
                   1572: 
                   1573:     ERROR_MORE_DATA - A read that is too large was specified.
                   1574: 
                   1575:     ERROR_NO_ACCESS - TBD       // Can you even HAVE an access
                   1576:                                         // violation with a physical
                   1577:                                         // memory access??
                   1578: 
                   1579:     !ERROR_SUCCESS - TBD
                   1580: 
                   1581: --*/
                   1582: 
                   1583: {
                   1584:     DBGKD_MANIPULATE_STATE m;
                   1585:     PDBGKD_MANIPULATE_STATE Reply;
                   1586:     PDBGKD_READ_MEMORY a = &m.u.ReadMemory;
                   1587:     DWORD st;
                   1588:     BOOLEAN rc;
                   1589: 
                   1590:     if ( TransferCount + sizeof(m) > PACKET_MAX_SIZE ) {
                   1591:         return ERROR_MORE_DATA;
                   1592:         }
                   1593: 
                   1594:     //
                   1595:     // Format state manipulate message
                   1596:     //
                   1597: 
                   1598:     m.ApiNumber = DbgKdReadPhysicalMemoryApi;
                   1599:     m.ReturnStatus = STATUS_PENDING;
                   1600:     //
                   1601:     // BUGBUG TargetBaseAddress should be >32 bits
                   1602:     //
                   1603:     a->TargetBaseAddress = (PVOID)TargetBaseAddress.LowPart;
                   1604:     a->TransferCount = TransferCount;
                   1605:     a->ActualBytesRead = 0L;
                   1606: 
                   1607:     //
                   1608:     // Send the message and then wait for reply
                   1609:     //
                   1610: 
                   1611:     do {
                   1612:         DbgKdpWritePacket(&m,sizeof(m),PACKET_TYPE_KD_STATE_MANIPULATE,NULL,0);
                   1613: 
                   1614:         rc = DbgKdpWaitForPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &Reply);
                   1615:     } while (rc == FALSE);
                   1616: 
                   1617:     //
                   1618:     // If this is not a ReadMemory response then protocol is screwed up.
                   1619:     // assert that protocol is ok.
                   1620:     //
                   1621: 
                   1622:     st = Reply->ReturnStatus;
                   1623:     assert(Reply->ApiNumber == DbgKdReadPhysicalMemoryApi);
                   1624: 
                   1625:     //
                   1626:     // Reset message address to reply.
                   1627:     //
                   1628: 
                   1629:     a = &Reply->u.ReadMemory;
                   1630:     assert(a->ActualBytesRead <= TransferCount);
                   1631: 
                   1632:     //
                   1633:     // Return actual bytes read, and then transfer the bytes
                   1634:     //
                   1635: 
                   1636:     if (ActualBytesRead) {
                   1637:         *ActualBytesRead = a->ActualBytesRead;
                   1638:     }
                   1639:     st = Reply->ReturnStatus;
                   1640: 
                   1641:     //
                   1642:     // Since read response data follows message, Reply+1 should point
                   1643:     // at the data
                   1644:     //
                   1645: 
                   1646:     memcpy(UserInterfaceBuffer, Reply+1, (int)a->ActualBytesRead);
                   1647: 
                   1648:     return st;
                   1649: }
                   1650: 
                   1651: 
                   1652: DWORD
                   1653: DbgKdWritePhysicalMemory(
                   1654:     IN PHYSICAL_ADDRESS TargetBaseAddress,
                   1655:     OUT PVOID UserInterfaceBuffer,
                   1656:     IN ULONG TransferCount,
                   1657:     OUT PULONG ActualBytesWritten OPTIONAL
                   1658:     )
                   1659: 
                   1660: /*++
                   1661: 
                   1662: Routine Description:
                   1663: 
                   1664:     This function writes the specified data to the physical memory of the
                   1665:     system being debugged.
                   1666: 
                   1667: Arguments:
                   1668: 
                   1669:     TargetBaseAddress - Supplies the physical address of the memory to write
                   1670:         to the system being debugged.
                   1671: 
                   1672:     UserInterfaceBuffer - Supplies the address of the buffer in the user
                   1673:         interface that contains the data to be written.
                   1674: 
                   1675:     TransferCount - Specifies the number of bytes to write.
                   1676: 
                   1677:     ActualBytesWritten - An optional parameter that if supplied, returns
                   1678:         the number of bytes actually written.
                   1679: 
                   1680: Return Value:
                   1681: 
                   1682:     ERROR_SUCCESS - The specified read occured.
                   1683: 
                   1684:     ERROR_MORE_DATA - A read that is to large was specified.
                   1685: 
                   1686:     ERROR_NO_ACCESS - TBD       // Can you even HAVE an access
                   1687:                                         // violation with a physical
                   1688:                                         // memory access??
                   1689: 
                   1690:     !ERROR_SUCCESS - TBD
                   1691: 
                   1692: --*/
                   1693: 
                   1694: {
                   1695:     DBGKD_MANIPULATE_STATE m;
                   1696:     PDBGKD_MANIPULATE_STATE Reply;
                   1697:     PDBGKD_WRITE_MEMORY a = &m.u.WriteMemory;
                   1698:     DWORD st;
                   1699:     BOOLEAN rc;
                   1700: 
                   1701:     if ( TransferCount + sizeof(m) > PACKET_MAX_SIZE ) {
                   1702:         return ERROR_MORE_DATA;
                   1703:         }
                   1704: 
                   1705:     //
                   1706:     // Format state manipulate message
                   1707:     //
                   1708: 
                   1709:     m.ApiNumber = DbgKdWritePhysicalMemoryApi;
                   1710:     m.ReturnStatus = STATUS_PENDING;
                   1711:     //
                   1712:     // BUGBUG TargetBaseAddress should be >32 bits
                   1713:     //
                   1714:     a->TargetBaseAddress = (PVOID)TargetBaseAddress.LowPart;
                   1715:     a->TransferCount = TransferCount;
                   1716:     a->ActualBytesWritten = 0L;
                   1717: 
                   1718:     //
                   1719:     // Send the message and data to write and then wait for reply
                   1720:     //
                   1721: 
                   1722:     do {
                   1723:         DbgKdpWritePacket(
                   1724:             &m,
                   1725:             sizeof(m),
                   1726:             PACKET_TYPE_KD_STATE_MANIPULATE,
                   1727:             UserInterfaceBuffer,
                   1728:             (USHORT)TransferCount
                   1729:             );
                   1730: 
                   1731:         rc = DbgKdpWaitForPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &Reply);
                   1732:     } while (rc == FALSE);
                   1733: 
                   1734:     //
                   1735:     // If this is not a WriteMemory response than protocol is screwed up.
                   1736:     // assert that protocol is ok.
                   1737:     //
                   1738: 
                   1739:     st = Reply->ReturnStatus;
                   1740:     assert(Reply->ApiNumber == DbgKdWritePhysicalMemoryApi);
                   1741: 
                   1742:     //
                   1743:     // Reset message address to reply.
                   1744:     //
                   1745: 
                   1746:     a = &Reply->u.WriteMemory;
                   1747:     assert(a->ActualBytesWritten <= TransferCount);
                   1748: 
                   1749:     //
                   1750:     // Return actual bytes written
                   1751:     //
                   1752: 
                   1753:     if (ActualBytesWritten) {
                   1754:         *ActualBytesWritten = a->ActualBytesWritten;
                   1755:     }
                   1756:     st = Reply->ReturnStatus;
                   1757: 
                   1758:     return st;
                   1759: }

unix.superglobalmegacorp.com

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