00001 
00007 #include "stdafx.h"
00008 #include "kdcomdisp.h"
00009 #include "reporter.h"
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 KD_RECV_CODE KdComDispatcher::KdCompReceivePacketLeader(ULONG ,
00019                                                                                                             ULONG *pSignature,
00020                                                                                                             PKD_CONTEXT pContext)
00021 {
00022         ASSERT(pContext && pSignature);
00023         unsigned repeatCount = 0;
00024         char ch = 0, lastCh = 0;
00025         bool BreakInRequested = false;
00026         for (;;)
00027         {
00028                 if (m_Pipe.Receive(&ch, 1) != 1)
00029                 {
00030                         if (BreakInRequested)
00031                         {
00032                                 pContext->BreakInRequested = TRUE;
00033                                 return KD_RECV_CODE_FAILED;
00034                         }
00035                         else
00036                         {
00037                                 unsigned err = m_Pipe.GetLastOperationError();
00038                                 switch (err)
00039                                 {
00040                                 case ERROR_PIPE_LISTENING:
00041                                 case ERROR_PIPE_NOT_CONNECTED:
00042                                 case ERROR_NO_DATA:
00043                                         Sleep(10);
00044                                         break;
00045                                 }
00046                                 return KD_RECV_CODE_TIMEOUT;
00047                         }
00048                 }
00049                 switch (ch)
00050                 {
00051                 case '0':
00052                 case 'i':
00053                         break;
00054                 case 'b':
00055                         BreakInRequested = true;
00056                         
00057                 default:
00058                         g_pReporter->GetStatusPointer()->BytesDropped++;
00059                         repeatCount = 0;
00060                         continue;
00061                 }
00062 
00063                 if (!repeatCount)
00064                 {
00065                         lastCh = ch;
00066                         repeatCount++;
00067                         continue;
00068                 }
00069 
00070                 if (ch != lastCh)
00071                         repeatCount = 1, lastCh = ch;
00072                 else
00073                 {
00074                         if (++repeatCount >= 4)
00075                         {
00076                                 if (BreakInRequested)
00077                                         pContext->BreakInRequested = TRUE;
00078                                 *pSignature = (ch == '0') ? '0000' : 'iiii';
00079                                 KD_DEBUGGER_NOT_PRESENT = false;
00080                                 return KD_RECV_CODE_OK;
00081                         }
00082                 }
00083         }
00084 }
00085 
00086 void KdComDispatcher::KdpSendControlPacket(ULONG PacketType, ULONG NextPacketId)
00087 {
00088         static char __unused[sizeof(KD_PACKET_HEADER) == 16];
00089         static unsigned LastSentID = 0;
00090         KD_PACKET_HEADER hdr;
00091         hdr.Signature = 'iiii';
00092         hdr.PacketType = (USHORT)PacketType;
00093         hdr.TotalDataLength = 0;
00094         if (NextPacketId)
00095                 hdr.PacketID = LastSentID = NextPacketId;
00096         else
00097                 hdr.PacketID = LastSentID;
00098         hdr.Checksum = 0;
00099         if (KdTraceEnabled && (g_pReporter->GetStatusPointer()->DebugLevel >= DebugLevelTraceKdCom))
00100         {
00101                         TCHAR tsz[512];
00102                         _sntprintf(tsz, __countof(tsz), _T("Sending control packet (type = %d, id = %08X)... "),
00103                                         hdr.PacketType,
00104                                         hdr.PacketID);
00105                         g_pReporter->LogLineIfEnabled(tsz);
00106         }
00107         m_Pipe.Send(&hdr, sizeof(hdr));
00108         if (KdTraceEnabled && (g_pReporter->GetStatusPointer()->DebugLevel >= DebugLevelTraceKdCom))
00109         {
00110                 g_pReporter->LogLineIfEnabled(_T("ok\r\n"));
00111         }
00112 }
00113         
00114 KD_RECV_CODE __stdcall KdComDispatcher::KdReceivePacket(ULONG PacketType,
00115                                                                                                                 PKD_BUFFER FirstBuffer,
00116                                                                                                                 PKD_BUFFER SecondBuffer,
00117                                                                                                                 PULONG PayloadBytes,
00118                                                                                                                 PKD_CONTEXT KdContext)
00119 {
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131         if (0)
00132                 SimulateWindowsTermination();
00133 
00134         ASSERT(KdContext);
00135 #ifdef KDCLIENT_REPORT_PERFORMANCE_INFORMATION
00136         g_pReporter->GetStatusPointer()->OSDetected = true;
00137 #endif
00138 
00139         if (KdTraceEnabled)
00140         {
00141                 TCHAR tsz[512];
00142                 switch (PacketType)
00143                 {
00144                 case KdPacketAcknowledge:
00145                         if (g_pReporter->GetStatusPointer()->DebugLevel >= DebugLevelTraceKdCom)
00146                         {
00147                                 _sntprintf(tsz, __countof(tsz), _T("KdReceivePacket(%d)\r\n"),
00148                                                         PacketType);
00149                                 g_pReporter->LogLineIfEnabled(tsz);
00150                         }
00151                         break;
00152                 case KdCheckForAnyPacket:
00153                         if (g_pReporter->GetStatusPointer()->DebugLevel >= DebugLevelTraceKdComAll)
00154                                 g_pReporter->LogLineIfEnabled(_T("KdReceivePacket(): checking for new packets\r\n"));
00155                         break;
00156                 }
00157         }
00158 
00159 
00160         if (PacketType == KdCheckForAnyPacket)
00161         {
00162                 bool hasData = m_Pipe.HasDataInBuffer();
00163 #ifdef KDCLIENT_REPORT_PERFORMANCE_INFORMATION
00164                 g_pReporter->GetStatusPointer()->DebuggerConnected = m_Pipe.IsClientConnected();
00165 #endif
00166                 if (!hasData)
00167                         return KD_RECV_CODE_TIMEOUT;
00168                 char ch = 0;
00169                 if (!m_Pipe.Receive(&ch, 1))
00170                         return KD_RECV_CODE_TIMEOUT;
00171                 if (ch != 'b')
00172                         return KD_RECV_CODE_TIMEOUT;
00173                 return KD_RECV_CODE_OK;
00174         }
00175 
00176         if (FirstBuffer)
00177                 FirstBuffer->Length = 0;
00178         if (SecondBuffer)
00179                 SecondBuffer->Length = 0;
00180         
00181         for (;;)
00182         {
00183                 KD_PACKET_HEADER header = {0,};
00184                 KD_RECV_CODE status = KdCompReceivePacketLeader(PacketType, &header.Signature, KdContext);
00185 #ifdef KDCLIENT_REPORT_PERFORMANCE_INFORMATION
00186                 g_pReporter->GetStatusPointer()->DebuggerConnected = m_Pipe.IsClientConnected();
00187 #endif
00188                 if (status != KD_RECV_CODE_TIMEOUT)
00189                         KdCompNumberRetries = KdCompRetryCount;
00190                 if (status != KD_RECV_CODE_OK)
00191                 {
00192                         if (KdTraceEnabled && (g_pReporter->GetStatusPointer()->DebugLevel >= DebugLevelTraceKdComAll))
00193                         {
00194                                 TCHAR tsz[512];
00195                                 _sntprintf(tsz, __countof(tsz), _T("KdCompReceivePacketLeader(): %s\r\n"), (status == KD_RECV_CODE_TIMEOUT) ? _T("timeout") : _T("error"));
00196                                 g_pReporter->LogLineIfEnabled(tsz);
00197                         }
00198                         return status;
00199                 }
00200                 size_t size = sizeof(header) - sizeof(header.Signature);
00201                 
00202                 if (m_Pipe.Receive(&header.PacketType, size, false) != size)
00203                         return KD_RECV_CODE_TIMEOUT;
00204 
00205                 if (KdTraceEnabled && (g_pReporter->GetStatusPointer()->DebugLevel >= DebugLevelTraceKdCom))
00206                 {
00207                         TCHAR tsz[512];
00208                         _sntprintf(tsz, __countof(tsz), _T("Got packet (expected %d) (signature = %08X, id = %08X, type = %d, data = %d, checksum = %d)\r\n"),
00209                                                 PacketType,
00210                                                 header.Signature,
00211                                                 header.PacketID,
00212                                                 header.PacketType,
00213                                                 header.TotalDataLength,
00214                                                 header.Checksum);
00215                         g_pReporter->LogLineIfEnabled(tsz);
00216                 }
00217 
00218                 
00219                 if ((header.Signature == 'iiii') && (header.PacketType == KdPacketRetryRequest))
00220                         return KD_RECV_CODE_FAILED;
00221                 
00222                 if (header.Signature == 'iiii')
00223                 {
00224                         switch (header.PacketType)
00225                         {
00226                         case KdPacketAcknowledge:
00227                                 if ((PacketType == 4) && (header.PacketID == (KdCompNextPacketIdToSend & 0xFFFFF7FF)))
00228                                 {
00229                                         KdCompNextPacketIdToSend ^= 1;
00230                                         return KD_RECV_CODE_OK;
00231                                 }
00232                                 break;
00233                         case KdPacketResynchronize:
00234                                 if (KdTraceEnabled && (g_pReporter->GetStatusPointer()->DebugLevel >= DebugLevelTraceKdCom))
00235                                 {
00236                                         TCHAR tsz[512];
00237                                         _sntprintf(tsz, __countof(tsz), _T("Resync (got %d, sent %d, seq cnt %d)\r\n"),
00238                                                         m_PacketsGotFromLastReset,
00239                                                         m_PacketsSentFromLastReset,
00240                                                         m_SequentialResetCount);
00241                                         g_pReporter->LogLineIfEnabled(tsz);
00242                                 }
00243                                 if ((m_PacketsGotFromLastReset <= KdMinPacketCountForSuccessfulLink) && (m_PacketsSentFromLastReset <= KdMinPacketCountForSuccessfulLink))
00244                                         m_SequentialResetCount++;
00245                                 KdResetPacketNumbering(false);
00246                                 
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260 
00261 
00262 
00263 
00264 
00265                                 m_Pipe.DiscardBufferedData();
00266                                 KdpSendControlPacket(KdPacketResynchronize, 0);
00267 #ifdef KDCLIENT_REPORT_PERFORMANCE_INFORMATION
00268                                 g_pReporter->GetStatusPointer()->ResyncCount++;
00269 #endif
00270                                 return KD_RECV_CODE_FAILED;
00271                         case KdPacketRetryRequest:
00272                                 return KD_RECV_CODE_FAILED;
00273                         }
00274                 }
00275                 else    
00276                 {
00277                         if (PacketType != KdPacketAcknowledge)
00278                         {
00279                                 if (header.TotalDataLength <= KdMaxBufferSize)
00280                                 {
00281                                         if (header.TotalDataLength >= FirstBuffer->MaxLength)
00282                                         {
00283                                                 *PayloadBytes = header.TotalDataLength - FirstBuffer->MaxLength;
00284                                                 if (m_Pipe.Receive(FirstBuffer->pData, FirstBuffer->MaxLength, false) == FirstBuffer->MaxLength)
00285                                                 {
00286                                                         FirstBuffer->Length = FirstBuffer->MaxLength;
00287                                                         if (!(*PayloadBytes) || (m_Pipe.Receive(SecondBuffer->pData, *PayloadBytes, false) == *PayloadBytes))
00288                                                         {
00289                                                                 SecondBuffer->Length = (USHORT)*PayloadBytes;
00290                                                                 unsigned char ch = 0;
00291                                                                 if (m_Pipe.Receive(&ch, 1) && (ch == 0xAA))
00292                                                                 {
00293                                                                         if (PacketType != header.PacketType)
00294                                                                         {
00295                                                                                 KdpSendControlPacket(KdPacketAcknowledge, header.PacketID);
00296                                                                                 continue;
00297                                                                         }
00298                                                                         else if ((header.PacketID == 0x80800000) || (header.PacketID == 0x80800001))
00299                                                                         {
00300                                                                                 if (header.PacketID != KdCompPacketIdExpected)
00301                                                                                 {
00302                                                                                         KdpSendControlPacket(KdPacketAcknowledge, header.PacketID);
00303                                                                                         continue;
00304                                                                                 }
00305                                                                         }
00306                                                                         int checksum = KdpComputeChecksum(FirstBuffer->pData, FirstBuffer->Length);
00307                                                                         checksum += KdpComputeChecksum(SecondBuffer->pData, SecondBuffer->Length);
00308                                                                         if (checksum == header.Checksum)
00309                                                                         {
00310                                                                                 KdpSendControlPacket(KdPacketAcknowledge, header.PacketID);
00311                                                                                 KdCompPacketIdExpected ^= 1;
00312                                                                                 if (++m_PacketsGotFromLastReset >= KdMinPacketCountForSuccessfulLink)
00313                                                                                         m_SequentialResetCount = 0;
00314 #ifdef KDCLIENT_REPORT_PERFORMANCE_INFORMATION
00315                                                                                 g_pReporter->GetStatusPointer()->BytesReceived += header.TotalDataLength + sizeof(KD_PACKET_HEADER) + 1;
00316                                                                                 g_pReporter->GetStatusPointer()->PacketsReceived++;
00317 #endif
00318                                                                                 m_PacketLogger.OnSendReceivePacket(g_pReporter->GetStatusPointer()->LogAllPackets != 0,
00319                                                                                         false,
00320                                                                                         PacketType,
00321                                                                                         FirstBuffer,
00322                                                                                         SecondBuffer,
00323                                                                                         KdContext);
00324 
00325                                                                                 return KD_RECV_CODE_OK;
00326                                                                         }
00327                                                                 }
00328                                                         }
00329 
00330                                                 }
00331                                         }
00332                                 }
00333                                 KdpSendControlPacket(KdPacketRetryRequest, 0);
00334                                 continue;
00335                         }
00336                         if (header.PacketID == KdCompPacketIdExpected)
00337                         {
00338                                 KdpSendControlPacket(KdPacketRetryRequest, 0);
00339                                 KdCompNextPacketIdToSend ^= 1;
00340                                 return KD_RECV_CODE_OK;
00341                         }
00342                         else
00343                         {
00344                                 KdpSendControlPacket(KdPacketAcknowledge, header.PacketID);
00345                                 continue;
00346                         }
00347                 }
00348         }
00349 
00350         return KD_RECV_CODE_TIMEOUT;
00351 }
00352 
00353 static bool FixVerifierUnicodeReport(PKD_BUFFER pDataBuffer)
00354 {
00355         char *pText = (char *)pDataBuffer->pData;
00356         char *pZero = NULL;
00357         char *pEnd = pText + pDataBuffer->Length;
00358         for (int i = 0; i < pDataBuffer->Length; i++)
00359                 if (!pText[i])
00360                 {
00361                         pZero = &pText[i];
00362                         break;
00363                 }
00364         if (!pZero)
00365                 return false;
00366         if (!strstr(pText, "Driver Verifier:"))
00367                 return false;
00368 
00369         char *pSrc = pZero + 1;
00370         while (pSrc < pEnd)
00371         {
00372                 if (!pSrc[0])
00373                 {
00374                         pSrc++;
00375                         continue;
00376                 }
00377                 *pZero = *pSrc;
00378 
00379                 pZero++;
00380                 pSrc++;
00381         }
00382         
00383         
00384         if (pZero < pEnd)
00385                 *pZero = 0;     
00386         return true;
00387 }
00388 
00389 bool __stdcall KdComDispatcher::KdSendPacket(ULONG PacketType,
00390                                                                                          PKD_BUFFER FirstBuffer,
00391                                                                                          PKD_BUFFER SecondBuffer,
00392                                                                                          PKD_CONTEXT KdContext)
00393 {
00394         m_PacketLogger.OnSendReceivePacket(g_pReporter->GetStatusPointer()->LogAllPackets != 0,
00395                                                                            true,
00396                                                                            PacketType,
00397                                                                            FirstBuffer,
00398                                                                            SecondBuffer,
00399                                                                            KdContext);
00400 
00401 #ifdef KDCLIENT_REPORT_PERFORMANCE_INFORMATION
00402         g_pReporter->GetStatusPointer()->OSDetected = true;
00403 #endif
00404 #ifdef KDCLIENT_ENABLE_TRACE_ASSIST
00405         switch (PacketType)
00406         {
00407         case KdPacketType3:
00408                 if (FirstBuffer && SecondBuffer && (*((ULONG *)FirstBuffer->pData) == 0x3230))
00409                 {
00410                         FixVerifierUnicodeReport(SecondBuffer);
00411                         if (g_pReporter->GetStatusPointer()->TraceAssistUpdatePending)
00412                         {
00413                                 m_TraceAssistant.ReloadParams();
00414                                 g_pReporter->GetStatusPointer()->TraceAssistUpdatePending = false;                              
00415                         }
00416                         if (m_TraceAssistant.TraceLine((char *)SecondBuffer->pData, SecondBuffer->Length))
00417                         {
00418 #ifdef KDCLIENT_REPORT_PERFORMANCE_INFORMATION
00419                                 g_pReporter->GetStatusPointer()->BytesSent += (FirstBuffer->Length + SecondBuffer->Length + sizeof(KD_PACKET_HEADER) + 1);
00420                                 g_pReporter->GetStatusPointer()->PacketsSent++;
00421 #endif
00422                                 return true;
00423                         }
00424                 }
00425                 break;
00426         }
00427 #endif
00428 
00429         ASSERT(FirstBuffer);
00430         KD_PACKET_HEADER header;
00431         unsigned checksum = KdpComputeChecksum(FirstBuffer->pData, FirstBuffer->Length);
00432         unsigned totalLength = FirstBuffer->Length;
00433         if (SecondBuffer)
00434         {
00435                 totalLength += SecondBuffer->Length;
00436                 checksum += KdpComputeChecksum(SecondBuffer->pData, SecondBuffer->Length);
00437         }
00438         
00439         header.Signature = '0000';
00440         header.PacketType = (USHORT)PacketType;
00441         header.Checksum = checksum;
00442         header.TotalDataLength = totalLength;
00443         KdCompNumberRetries = KdCompRetryCount;
00444 
00445         if (KdTraceEnabled && (g_pReporter->GetStatusPointer()->DebugLevel >= DebugLevelTraceKdCom))
00446         {
00447                         TCHAR tsz[512];
00448                         _sntprintf(tsz, __countof(tsz), _T("Sending normal packet (type = %d, id = %08X, len = %d)...\r\n"),
00449                                         header.PacketType,
00450                                         KdCompNextPacketIdToSend,
00451                                         header.TotalDataLength);
00452                         g_pReporter->LogLineIfEnabled(tsz);
00453         }
00454 
00455         unsigned RetryNumber = 0;
00456 
00457         for (;;)
00458         {
00459                 
00460                 
00461                 
00462                 if (RetryNumber)
00463                 {
00464                         
00465 
00466 
00467 
00468 
00469 
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478                         {
00479                                 
00480                                 
00481                                 KD_DEBUGGER_NOT_PRESENT = TRUE;
00482                                 KdResetPacketNumbering(true);
00483                                 if (KdTraceEnabled && (g_pReporter->GetStatusPointer()->DebugLevel >= DebugLevelTraceKdCom))
00484                                         g_pReporter->LogLineIfEnabled(_T("Acknowledgment timeout\r\n"));
00485                                 return false;
00486                         }
00487                 }
00488 
00489                 if (KdTraceEnabled && (g_pReporter->GetStatusPointer()->DebugLevel >= DebugLevelTraceKdComAll))
00490                 {
00491                                 TCHAR tsz[512];
00492                                 _sntprintf(tsz, __countof(tsz), _T("KdSendPacket(): sending (%d)\r\n"),
00493                                                 header.PacketType);
00494                                 g_pReporter->LogLineIfEnabled(tsz);
00495                 }
00496 
00497                 header.PacketID = KdCompNextPacketIdToSend;
00498                 m_Pipe.Send(&header, sizeof(header));
00499                 m_Pipe.Send(FirstBuffer->pData, FirstBuffer->Length);
00500                 if (SecondBuffer && SecondBuffer->Length)
00501                         m_Pipe.Send(SecondBuffer->pData, SecondBuffer->Length);
00502                 unsigned char ch = 0xAA;
00503                 m_Pipe.Send(&ch, 1);
00504 #ifdef KDCLIENT_REPORT_PERFORMANCE_INFORMATION
00505                 g_pReporter->GetStatusPointer()->DebuggerConnected = m_Pipe.IsClientConnected();
00506 #endif
00507                 switch (KdReceivePacket(KdPacketAcknowledge, NULL, NULL, NULL, KdContext))
00508                 {
00509                 case KD_RECV_CODE_TIMEOUT:
00510                         KdCompNumberRetries--;
00511                         RetryNumber++;
00512                         break;
00513                 case KD_RECV_CODE_OK:
00514                         KdCompNextPacketIdToSend &= 0xFFFFFFF7;
00515                     KdCompRetryCount = KdContext->RetryCount;
00516                         if (++m_PacketsSentFromLastReset >= KdMinPacketCountForSuccessfulLink)
00517                                 m_SequentialResetCount = 0;
00518                         if (KdTraceEnabled && (g_pReporter->GetStatusPointer()->DebugLevel >= DebugLevelTraceKdCom))
00519                                 g_pReporter->LogLineIfEnabled(_T("Packet acknowledged\r\n"));
00520 #ifdef KDCLIENT_REPORT_PERFORMANCE_INFORMATION
00521                         g_pReporter->GetStatusPointer()->BytesSent += (header.TotalDataLength + sizeof(KD_PACKET_HEADER) + 1);
00522                         g_pReporter->GetStatusPointer()->PacketsSent++;
00523 #endif
00524                         return true;
00525                 }
00526         }
00527 }
00528 
00529 void KdComDispatcher::ReportProtocolVersionError(int GuestVersion, int HostVersion)
00530 {
00531         g_pReporter->GetStatusPointer()->ProtocolMismatchStatus = MAKELONG(GuestVersion, HostVersion);
00532 }
00533 
00534 
00535 
00536 typedef unsigned SystemTerminationPacket[60];
00537 
00538 typedef struct _DBGKD_LOAD_SYMBOLS64
00539 {
00540         ULONG PathNameLength;
00541         ULONG64 BaseOfDll;
00542         ULONG64 ProcessId;
00543         ULONG CheckSum;
00544         ULONG SizeOfImage;
00545         BOOLEAN UnloadSymbols;
00546 } DBGKD_LOAD_SYMBOLS64, *PDBGKD_LOAD_SYMBOLS64;
00547 
00548 static void InitializeSystemTerminationPacket(SystemTerminationPacket Packet)
00549 {
00550         memset(Packet, -1, sizeof(SystemTerminationPacket));
00551         Packet[0] = 0x00003031; 
00552         Packet[1] = 6;                  
00553         Packet[2] = 1;                  
00554 
00555         
00556 
00557         const int kDbgkdLoadSymbols64Offset = 8;
00558 
00559         PDBGKD_LOAD_SYMBOLS64 pSym = (PDBGKD_LOAD_SYMBOLS64)&Packet[kDbgkdLoadSymbols64Offset];
00560 
00561         pSym->PathNameLength = 0;
00562         pSym->BaseOfDll = -1;
00563         pSym->ProcessId = 0;
00564         pSym->CheckSum = 0;
00565         pSym->SizeOfImage = 0;
00566         pSym->UnloadSymbols = TRUE;     
00567 }
00568 
00569 #define DbgKdContinueApi                    0x00003136
00570 #define DbgKdContinueApi2                   0x0000313C
00571 
00572 
00573 
00574 
00575 
00576 
00577 void KdComDispatcher::SimulateWindowsTermination()
00578 {
00579         SystemTerminationPacket packet;
00580         InitializeSystemTerminationPacket(packet);
00581 
00582         m_PacketLogger.OnWindowsTerminationSimulated();
00583         
00584         KD_BUFFER first = {0,}, second = {0,};
00585         first.Length = sizeof(packet);
00586         first.pData = (PUCHAR)packet;
00587         KD_CONTEXT ctx = {0,};
00588 
00589         bool RequireAdditionalTerminationPacket = false;
00590 
00591         while (!KdSendPacket(7, &first, &second, &ctx))
00592         {
00593                 if (!m_Pipe.IsClientConnected())
00594                 {
00595                         m_PacketLogger.OnWindowsTerminationSimDone("debugger disconnected");
00596                         return;
00597                 }
00598                 RequireAdditionalTerminationPacket = true;      
00599         }
00600 
00601         
00602         static char szBuf1[0x38], szBuf2[KdMaxBufferSize];
00603 
00604         ULONG unused = 0;
00605 
00606         for (;;)
00607         {
00608                 if (!m_Pipe.IsClientConnected())
00609                 {
00610                         m_PacketLogger.OnWindowsTerminationSimDone("debugger disconnected");
00611                         return;
00612                 }
00613 
00614                 first.MaxLength = sizeof(szBuf1);
00615                 first.pData = (PUCHAR)szBuf1;
00616                 second.MaxLength = sizeof(szBuf2);
00617                 second.pData = (PUCHAR)szBuf2;
00618 
00619                 KD_RECV_CODE code = KdReceivePacket(2, &first, &second, &unused, &ctx);
00620                 if (!m_Pipe.IsClientConnected())
00621                 {
00622                         m_PacketLogger.OnWindowsTerminationSimDone("debugger disconnected");
00623                         return;
00624                 }
00625 
00626                 if (code == KD_RECV_CODE_TIMEOUT)
00627                 {
00628                         m_PacketLogger.OnWindowsTerminationSimDone("timeout");
00629                         return;
00630                 }
00631                 if (code != KD_RECV_CODE_OK)
00632                         continue;
00633 
00634                 if ((*((unsigned *)szBuf1) == DbgKdContinueApi2) || (*((unsigned *)szBuf1) == DbgKdContinueApi))
00635                 {
00636                         if (RequireAdditionalTerminationPacket)
00637                         {
00638                                 first.Length = sizeof(packet);
00639                                 first.pData = (PUCHAR)packet;
00640                                 if (!KdSendPacket(7, &first, &second, &ctx))
00641                                 {
00642                                         m_PacketLogger.OnWindowsTerminationSimDone("type 7 packet not acknowledged");
00643                                         return;
00644                                 }
00645                                 RequireAdditionalTerminationPacket = false;
00646                                 continue;
00647                         }
00648                         m_PacketLogger.OnWindowsTerminationSimDone("continue command received");
00649                         return;
00650                 }
00651 
00652                 
00653                 
00654                 
00655                 
00656                 KdSendPacket(2, &first, &second, &ctx);
00657                 RequireAdditionalTerminationPacket = true;
00658         }
00659         m_PacketLogger.OnWindowsTerminationSimDone("unexpected");
00660 }