Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3260 lines
79 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // KD hard-line communication support.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999-2001.
  6. //
  7. //----------------------------------------------------------------------------
  8. #include "ntsdp.hpp"
  9. #include <portio.h>
  10. #define THROTTLE_WRITES 0
  11. #define DBG_KD_READ 0
  12. #define DBG_KD_WRITE 0
  13. #define DBG_SYNCH 0
  14. #define KD_FILE_SIGNATURE 'lFdK'
  15. struct KD_FILE
  16. {
  17. LIST_ENTRY List;
  18. HANDLE Handle;
  19. ULONG Signature;
  20. };
  21. struct KD_FILE_ASSOC
  22. {
  23. LIST_ENTRY List;
  24. PWSTR From;
  25. PSTR To;
  26. };
  27. LIST_ENTRY g_KdFiles;
  28. char g_KdFileAssocSource[MAX_PATH];
  29. LIST_ENTRY g_KdFileAssoc;
  30. ULONG g_LastProcessorToPrint = (ULONG) -1;
  31. CHAR g_PrintBuf[PACKET_MAX_SIZE];
  32. PCSTR g_DbgKdTransportNames[] =
  33. {
  34. "com", "1394"
  35. };
  36. DbgKdTransport* g_DbgKdTransport;
  37. DbgKdComTransport g_DbgKdComTransport;
  38. DbgKd1394Transport g_DbgKd1394Transport;
  39. // This log is for debugging the protocol so leave it
  40. // a simple global for easy examination.
  41. ULONG g_PacketLogIndex;
  42. ULONG64 g_PacketLog[16];
  43. #define PACKET_LOG_SIZE (sizeof(g_PacketLog) / sizeof(g_PacketLog[0]))
  44. UCHAR DbgKdTransport::s_BreakinPacket[1] =
  45. {
  46. BREAKIN_PACKET_BYTE
  47. };
  48. UCHAR DbgKdTransport::s_PacketTrailingByte[1] =
  49. {
  50. PACKET_TRAILING_BYTE
  51. };
  52. UCHAR DbgKdTransport::s_PacketLeader[4] =
  53. {
  54. PACKET_LEADER_BYTE,
  55. PACKET_LEADER_BYTE,
  56. PACKET_LEADER_BYTE,
  57. PACKET_LEADER_BYTE
  58. };
  59. UCHAR DbgKdTransport::s_Packet[PACKET_MAX_MANIP_SIZE];
  60. KD_PACKET DbgKdTransport::s_PacketHeader;
  61. UCHAR DbgKdTransport::s_SavedPacket[PACKET_MAX_MANIP_SIZE];
  62. KD_PACKET DbgKdTransport::s_SavedPacketHeader;
  63. #define COPYSE(p64,p32,f) p64->f = (ULONG64)(LONG64)(LONG)p32->f
  64. __inline
  65. void
  66. DbgkdGetVersion32To64(
  67. IN PDBGKD_GET_VERSION32 vs32,
  68. OUT PDBGKD_GET_VERSION64 vs64,
  69. OUT PKDDEBUGGER_DATA64 dd64
  70. )
  71. {
  72. vs64->MajorVersion = vs32->MajorVersion;
  73. vs64->MinorVersion = vs32->MinorVersion;
  74. vs64->ProtocolVersion = vs32->ProtocolVersion;
  75. vs64->Flags = vs32->Flags;
  76. vs64->MachineType = vs32->MachineType;
  77. COPYSE(vs64,vs32,PsLoadedModuleList);
  78. COPYSE(vs64,vs32,DebuggerDataList);
  79. COPYSE(vs64,vs32,KernBase);
  80. COPYSE(dd64,vs32,KernBase);
  81. COPYSE(dd64,vs32,PsLoadedModuleList);
  82. dd64->ThCallbackStack = vs32->ThCallbackStack;
  83. dd64->NextCallback = vs32->NextCallback;
  84. dd64->FramePointer = vs32->FramePointer;
  85. COPYSE(dd64,vs32,KiCallUserMode);
  86. COPYSE(dd64,vs32,KeUserCallbackDispatcher);
  87. COPYSE(dd64,vs32,BreakpointWithStatus);
  88. }
  89. void
  90. OutputIo(PSTR Format, PVOID _Buffer, ULONG Request, ULONG Done)
  91. {
  92. ULONG i, Chunk;
  93. PUCHAR Buffer = (PUCHAR)_Buffer;
  94. dprintf(Format, Done, Request);
  95. while (Done > 0)
  96. {
  97. Chunk = min(Done, 16);
  98. Done -= Chunk;
  99. dprintf(" ");
  100. for (i = 0; i < Chunk; i++)
  101. {
  102. dprintf(" %02X", *Buffer++);
  103. }
  104. dprintf("\n");
  105. }
  106. }
  107. KD_FILE_ASSOC*
  108. FindKdFileAssoc(PWSTR From)
  109. {
  110. PLIST_ENTRY Entry;
  111. KD_FILE_ASSOC* Assoc;
  112. for (Entry = g_KdFileAssoc.Flink;
  113. Entry != &g_KdFileAssoc;
  114. Entry = Entry->Flink)
  115. {
  116. Assoc = CONTAINING_RECORD(Entry, KD_FILE_ASSOC, List);
  117. if (!_wcsicmp(From, Assoc->From))
  118. {
  119. return Assoc;
  120. }
  121. }
  122. return NULL;
  123. }
  124. void
  125. ClearKdFileAssoc(void)
  126. {
  127. while (!IsListEmpty(&g_KdFileAssoc))
  128. {
  129. KD_FILE_ASSOC* Assoc;
  130. Assoc = CONTAINING_RECORD(g_KdFileAssoc.Flink, KD_FILE_ASSOC, List);
  131. RemoveEntryList(&Assoc->List);
  132. free(Assoc);
  133. }
  134. g_KdFileAssocSource[0] = 0;
  135. }
  136. HRESULT
  137. LoadKdFileAssoc(PSTR FileName)
  138. {
  139. HRESULT Status;
  140. FILE* File;
  141. char Op[32], From[MAX_PATH], To[MAX_PATH];
  142. File = fopen(FileName, "r");
  143. if (File == NULL)
  144. {
  145. return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  146. }
  147. ClearKdFileAssoc();
  148. Status = S_OK;
  149. for (;;)
  150. {
  151. if (fgets(Op, sizeof(Op), File) == NULL)
  152. {
  153. break;
  154. }
  155. // Remove newline.
  156. Op[strlen(Op) - 1] = 0;
  157. if (_stricmp(Op, "map") != 0)
  158. {
  159. Status = E_INVALIDARG;
  160. break;
  161. }
  162. if (fgets(From, sizeof(From), File) == NULL ||
  163. fgets(To, sizeof(To), File) == NULL)
  164. {
  165. Status = E_INVALIDARG;
  166. break;
  167. }
  168. // Remove newlines.
  169. From[strlen(From) - 1] = 0;
  170. To[strlen(To) - 1] = 0;
  171. KD_FILE_ASSOC* Assoc;
  172. Assoc = (KD_FILE_ASSOC*)malloc(sizeof(KD_FILE_ASSOC) +
  173. (strlen(From) + 1) * sizeof(WCHAR) +
  174. strlen(To) + 1);
  175. if (Assoc == NULL)
  176. {
  177. Status = E_OUTOFMEMORY;
  178. break;
  179. }
  180. Assoc->From = (PWSTR)(Assoc + 1);
  181. if (MultiByteToWideChar(CP_ACP, 0, From, -1, Assoc->From,
  182. sizeof(From) / sizeof(WCHAR)) == 0)
  183. {
  184. Status = WIN32_LAST_STATUS();
  185. break;
  186. }
  187. Assoc->To = (PSTR)(Assoc->From + strlen(From) + 1);
  188. strcpy(Assoc->To, To);
  189. InsertHeadList(&g_KdFileAssoc, &Assoc->List);
  190. }
  191. fclose(File);
  192. if (Status == S_OK)
  193. {
  194. strncat(g_KdFileAssocSource, FileName,
  195. sizeof(g_KdFileAssocSource) - 1);
  196. }
  197. return Status;
  198. }
  199. void
  200. InitKdFileAssoc(void)
  201. {
  202. PSTR Env;
  203. InitializeListHead(&g_KdFileAssoc);
  204. Env = getenv("_NT_KD_FILES");
  205. if (Env != NULL)
  206. {
  207. LoadKdFileAssoc(Env);
  208. }
  209. }
  210. void
  211. ParseKdFileAssoc(void)
  212. {
  213. if (PeekChar() == ';' || *g_CurCmd == 0)
  214. {
  215. if (g_KdFileAssocSource[0])
  216. {
  217. dprintf("KD file assocations loaded from '%s'\n",
  218. g_KdFileAssocSource);
  219. }
  220. else
  221. {
  222. dprintf("No KD file associations set\n");
  223. }
  224. return;
  225. }
  226. while (PeekChar() == '-' || *g_CurCmd == '/')
  227. {
  228. g_CurCmd++;
  229. switch(*g_CurCmd++)
  230. {
  231. case 'c':
  232. ClearKdFileAssoc();
  233. dprintf("KD file associations cleared\n");
  234. return;
  235. default:
  236. ErrOut("Unknown option '%c'\n", *(g_CurCmd - 1));
  237. break;
  238. }
  239. }
  240. PSTR FileName;
  241. CHAR Save;
  242. FileName = StringValue(STRV_TRIM_TRAILING_SPACE, &Save);
  243. if (LoadKdFileAssoc(FileName) == S_OK)
  244. {
  245. dprintf("KD file assocations loaded from '%s'\n", FileName);
  246. }
  247. else
  248. {
  249. dprintf("Unable to load KD file associations from '%s'\n", FileName);
  250. }
  251. *g_CurCmd = Save;
  252. }
  253. NTSTATUS
  254. CreateKdFile(PWSTR FileName,
  255. ULONG DesiredAccess, ULONG FileAttributes,
  256. ULONG ShareAccess, ULONG CreateDisposition,
  257. ULONG CreateOptions,
  258. KD_FILE** FileEntry, PULONG64 Length)
  259. {
  260. ULONG Access, Create;
  261. KD_FILE* File;
  262. KD_FILE_ASSOC* Assoc;
  263. Assoc = FindKdFileAssoc(FileName);
  264. if (Assoc == NULL)
  265. {
  266. return STATUS_NO_SUCH_FILE;
  267. }
  268. File = new KD_FILE;
  269. if (File == NULL)
  270. {
  271. return STATUS_NO_MEMORY;
  272. }
  273. Access = 0;
  274. if (DesiredAccess & FILE_GENERIC_READ)
  275. {
  276. Access |= GENERIC_READ;
  277. }
  278. if (DesiredAccess & FILE_GENERIC_WRITE)
  279. {
  280. Access |= GENERIC_WRITE;
  281. }
  282. switch(CreateDisposition)
  283. {
  284. case FILE_OPEN:
  285. Create = OPEN_EXISTING;
  286. break;
  287. case FILE_CREATE:
  288. Create = CREATE_NEW;
  289. break;
  290. case FILE_OPEN_IF:
  291. Create = OPEN_ALWAYS;
  292. break;
  293. case FILE_OVERWRITE_IF:
  294. Create = CREATE_ALWAYS;
  295. break;
  296. default:
  297. delete File;
  298. return STATUS_INVALID_PARAMETER;
  299. }
  300. // No interesting CreateOptions at this point.
  301. File->Handle = CreateFile(Assoc->To, Access, ShareAccess, NULL,
  302. Create, FileAttributes, NULL);
  303. if (File->Handle == NULL || File->Handle == INVALID_HANDLE_VALUE)
  304. {
  305. delete File;
  306. switch(GetLastError())
  307. {
  308. case ERROR_FILE_NOT_FOUND:
  309. return STATUS_NO_SUCH_FILE;
  310. case ERROR_ACCESS_DENIED:
  311. return STATUS_ACCESS_DENIED;
  312. default:
  313. return STATUS_UNSUCCESSFUL;
  314. }
  315. }
  316. ULONG SizeLow;
  317. LONG SizeHigh = 0;
  318. SizeLow = SetFilePointer(File->Handle, 0, &SizeHigh, FILE_END);
  319. if (SizeLow == INVALID_SET_FILE_POINTER && GetLastError())
  320. {
  321. CloseHandle(File->Handle);
  322. delete File;
  323. return STATUS_UNSUCCESSFUL;
  324. }
  325. *Length = ((ULONG64)SizeHigh << 32) | SizeLow;
  326. dprintf("KD: Accessing '%s' (%ws)\n ", Assoc->To, FileName);
  327. if (*Length > 0)
  328. {
  329. dprintf("File size %dK", KBYTES(*Length));
  330. }
  331. // Progress dots will be printed for each read/write.
  332. File->Signature = KD_FILE_SIGNATURE;
  333. InsertHeadList(&g_KdFiles, &File->List);
  334. *FileEntry = File;
  335. return STATUS_SUCCESS;
  336. }
  337. void
  338. CloseKdFile(KD_FILE* File)
  339. {
  340. RemoveEntryList(&File->List);
  341. CloseHandle(File->Handle);
  342. File->Signature = 0;
  343. delete File;
  344. }
  345. KD_FILE*
  346. TranslateKdFileHandle(ULONG64 Handle)
  347. {
  348. KD_FILE* File = (KD_FILE*)(ULONG_PTR)Handle;
  349. if (IsBadWritePtr(File, sizeof(*File)) ||
  350. File->Signature != KD_FILE_SIGNATURE)
  351. {
  352. return NULL;
  353. }
  354. return File;
  355. }
  356. //----------------------------------------------------------------------------
  357. //
  358. // DbgKdTransport.
  359. //
  360. //----------------------------------------------------------------------------
  361. void
  362. DbgKdTransport::Restart(void)
  363. {
  364. //
  365. // Reinitialize per-connection values.
  366. //
  367. while (!IsListEmpty(&g_KdFiles))
  368. {
  369. CloseKdFile(CONTAINING_RECORD(g_KdFiles.Flink, KD_FILE, List));
  370. }
  371. m_PacketsRead = 0;
  372. m_BytesRead = 0;
  373. m_PacketsWritten = 0;
  374. m_BytesWritten = 0;
  375. m_PacketExpected = INITIAL_PACKET_ID;
  376. m_NextPacketToSend = INITIAL_PACKET_ID;
  377. m_WaitingThread = 0;
  378. m_AllowInitialBreak = TRUE;
  379. m_Resync = TRUE;
  380. m_BreakIn = FALSE;
  381. m_SyncBreakIn = FALSE;
  382. m_ValidUnaccessedPacket = FALSE;
  383. }
  384. void
  385. DbgKdTransport::OutputInfo(void)
  386. {
  387. char Params[2 * (MAX_PARAM_NAME + MAX_PARAM_VALUE)];
  388. g_DbgKdTransport->GetParameters(Params, sizeof(Params));
  389. dprintf("Transport %s\n", Params);
  390. dprintf("Packets read: %u, bytes read %I64u\n",
  391. m_PacketsRead, m_BytesRead);
  392. dprintf("Packets written: %u, bytes written %I64u\n",
  393. m_PacketsWritten, m_BytesWritten);
  394. }
  395. HRESULT
  396. DbgKdTransport::Initialize(void)
  397. {
  398. HRESULT Status;
  399. //
  400. // Create the events used by the overlapped structures for the
  401. // read and write.
  402. //
  403. if ((Status = CreateOverlappedPair(&m_ReadOverlapped,
  404. &m_WriteOverlapped)) != S_OK)
  405. {
  406. ErrOut("Unable to create overlapped info, 0x%X\n", Status);
  407. }
  408. InitializeListHead(&g_KdFiles);
  409. return Status;
  410. }
  411. void
  412. DbgKdTransport::Uninitialize(void)
  413. {
  414. if (m_ReadOverlapped.hEvent != NULL)
  415. {
  416. CloseHandle(m_ReadOverlapped.hEvent);
  417. m_ReadOverlapped.hEvent = NULL;
  418. }
  419. if (m_WriteOverlapped.hEvent != NULL)
  420. {
  421. CloseHandle(m_WriteOverlapped.hEvent);
  422. m_WriteOverlapped.hEvent = NULL;
  423. }
  424. }
  425. void
  426. DbgKdTransport::CycleSpeed(void)
  427. {
  428. WarnOut("KD transport cannot change speeds\n");
  429. }
  430. HRESULT
  431. DbgKdTransport::ReadTargetPhysicalMemory(
  432. IN ULONG64 MemoryOffset,
  433. IN PVOID Buffer,
  434. IN ULONG SizeofBuffer,
  435. IN PULONG BytesRead
  436. )
  437. {
  438. WarnOut("Not valid KD transport operation\n");
  439. return E_UNEXPECTED;
  440. }
  441. ULONG
  442. DbgKdTransport::HandleDebugIo(PDBGKD_DEBUG_IO Packet)
  443. {
  444. ULONG ReadStatus = DBGKD_WAIT_AGAIN;
  445. switch(Packet->ApiNumber)
  446. {
  447. case DbgKdPrintStringApi:
  448. DbgKdpPrint(Packet->Processor,
  449. (PSTR)(Packet + 1),
  450. (SHORT)Packet->u.PrintString.LengthOfString,
  451. DEBUG_OUTPUT_DEBUGGEE);
  452. break;
  453. case DbgKdGetStringApi:
  454. DbgKdpHandlePromptString(Packet);
  455. break;
  456. default:
  457. KdOut("READ: Received INVALID DEBUG_IO packet type %x.\n",
  458. Packet->ApiNumber);
  459. ReadStatus = DBGKD_WAIT_RESEND;
  460. break;
  461. }
  462. return ReadStatus;
  463. }
  464. ULONG
  465. DbgKdTransport::HandleTraceIo(PDBGKD_TRACE_IO Packet)
  466. {
  467. ULONG ReadStatus = DBGKD_WAIT_AGAIN;
  468. switch(Packet->ApiNumber)
  469. {
  470. case DbgKdPrintTraceApi:
  471. DbgKdpPrintTrace(Packet->Processor,
  472. (PUCHAR)(Packet + 1),
  473. (USHORT)Packet->u.PrintTrace.LengthOfData,
  474. DEBUG_OUTPUT_DEBUGGEE);
  475. break;
  476. default:
  477. KdOut("READ: Received INVALID TRACE_IO packet type %x.\n",
  478. Packet->ApiNumber);
  479. ReadStatus = DBGKD_WAIT_RESEND;
  480. break;
  481. }
  482. return ReadStatus;
  483. }
  484. ULONG
  485. DbgKdTransport::HandleControlRequest(PDBGKD_CONTROL_REQUEST Packet)
  486. {
  487. ULONG ReadStatus = DBGKD_WAIT_AGAIN;
  488. switch(Packet->ApiNumber)
  489. {
  490. case DbgKdRequestHardwareBp:
  491. DbgKdpAcquireHardwareBp(Packet);
  492. break;
  493. case DbgKdReleaseHardwareBp:
  494. DbgKdpReleaseHardwareBp(Packet);
  495. break;
  496. default:
  497. KdOut("READ: Received INVALID CONTROL_REQUEST packet type %x.\n",
  498. Packet->ApiNumber);
  499. ReadStatus = DBGKD_WAIT_RESEND;
  500. break;
  501. }
  502. return ReadStatus;
  503. }
  504. ULONG
  505. DbgKdTransport::HandleFileIo(PDBGKD_FILE_IO Packet)
  506. {
  507. KD_FILE* File;
  508. PVOID ExtraData = NULL;
  509. USHORT ExtraDataLength = 0;
  510. LARGE_INTEGER FilePtr;
  511. // Reenter the engine lock to protect the file list.
  512. RESUME_ENGINE();
  513. switch(Packet->ApiNumber)
  514. {
  515. case DbgKdCreateFileApi:
  516. Packet->Status = CreateKdFile((PWSTR)(Packet + 1),
  517. Packet->u.CreateFile.DesiredAccess,
  518. Packet->u.CreateFile.FileAttributes,
  519. Packet->u.CreateFile.ShareAccess,
  520. Packet->u.CreateFile.CreateDisposition,
  521. Packet->u.CreateFile.CreateOptions,
  522. &File,
  523. &Packet->u.CreateFile.Length);
  524. Packet->u.CreateFile.Handle = (ULONG_PTR)File;
  525. KdOut("KdFile request for '%ws' returns %08X\n",
  526. (PWSTR)(Packet + 1), Packet->Status);
  527. break;
  528. case DbgKdReadFileApi:
  529. File = TranslateKdFileHandle(Packet->u.ReadFile.Handle);
  530. if (File == NULL ||
  531. Packet->u.ReadFile.Length > PACKET_MAX_SIZE - sizeof(*Packet))
  532. {
  533. Packet->Status = STATUS_INVALID_PARAMETER;
  534. break;
  535. }
  536. FilePtr.QuadPart = Packet->u.ReadFile.Offset;
  537. if (SetFilePointer(File->Handle, FilePtr.LowPart, &FilePtr.HighPart,
  538. FILE_BEGIN) == INVALID_SET_FILE_POINTER &&
  539. GetLastError())
  540. {
  541. Packet->Status = STATUS_END_OF_FILE;
  542. break;
  543. }
  544. if (!ReadFile(File->Handle, Packet + 1, Packet->u.ReadFile.Length,
  545. &Packet->u.ReadFile.Length, NULL))
  546. {
  547. Packet->Status = STATUS_UNSUCCESSFUL;
  548. }
  549. else
  550. {
  551. dprintf(".");
  552. Packet->Status = STATUS_SUCCESS;
  553. ExtraData = Packet + 1;
  554. ExtraDataLength = (USHORT)Packet->u.ReadFile.Length;
  555. }
  556. break;
  557. case DbgKdWriteFileApi:
  558. File = TranslateKdFileHandle(Packet->u.WriteFile.Handle);
  559. if (File == NULL ||
  560. Packet->u.WriteFile.Length > PACKET_MAX_SIZE - sizeof(*Packet))
  561. {
  562. Packet->Status = STATUS_INVALID_PARAMETER;
  563. break;
  564. }
  565. FilePtr.QuadPart = Packet->u.WriteFile.Offset;
  566. if (SetFilePointer(File->Handle, FilePtr.LowPart, &FilePtr.HighPart,
  567. FILE_BEGIN) == INVALID_SET_FILE_POINTER &&
  568. GetLastError())
  569. {
  570. Packet->Status = STATUS_END_OF_FILE;
  571. break;
  572. }
  573. if (!WriteFile(File->Handle, Packet + 1, Packet->u.WriteFile.Length,
  574. &Packet->u.WriteFile.Length, NULL))
  575. {
  576. Packet->Status = STATUS_UNSUCCESSFUL;
  577. }
  578. else
  579. {
  580. dprintf(".");
  581. Packet->Status = STATUS_SUCCESS;
  582. }
  583. break;
  584. case DbgKdCloseFileApi:
  585. File = TranslateKdFileHandle(Packet->u.CloseFile.Handle);
  586. if (File != NULL)
  587. {
  588. // Finish line of progress dots.
  589. dprintf("\n");
  590. CloseKdFile(File);
  591. Packet->Status = STATUS_SUCCESS;
  592. }
  593. else
  594. {
  595. Packet->Status = STATUS_INVALID_PARAMETER;
  596. }
  597. break;
  598. default:
  599. KdOut("READ: Received INVALID FILE_IO packet type %x.\n",
  600. Packet->ApiNumber);
  601. SUSPEND_ENGINE();
  602. return DBGKD_WAIT_RESEND;
  603. }
  604. //
  605. // Send response data.
  606. //
  607. g_DbgKdTransport->WritePacket(Packet, sizeof(*Packet),
  608. PACKET_TYPE_KD_FILE_IO,
  609. ExtraData, ExtraDataLength);
  610. SUSPEND_ENGINE();
  611. return DBGKD_WAIT_AGAIN;
  612. }
  613. ULONG
  614. DbgKdTransport::WaitForPacket(
  615. IN USHORT PacketType,
  616. OUT PVOID Packet
  617. )
  618. {
  619. ULONG InvPacketRetry = 0;
  620. // Packets can only be read when the kernel transport
  621. // is not in use.
  622. if (m_WaitingThread != 0 &&
  623. m_WaitingThread != GetCurrentThreadId())
  624. {
  625. ErrOut("Kernel transport in use, packet read failed\n");
  626. return DBGKD_WAIT_FAILED;
  627. }
  628. if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE)
  629. {
  630. KdOut("READ: Wait for ACK packet with id = %lx\n",
  631. m_NextPacketToSend);
  632. }
  633. else
  634. {
  635. KdOut("READ: Wait for type %x packet exp id = %lx\n",
  636. PacketType, m_PacketExpected);
  637. }
  638. g_PacketLog[g_PacketLogIndex++ & (PACKET_LOG_SIZE - 1)] =
  639. ((ULONG64)PacketType << 32);
  640. if (PacketType != PACKET_TYPE_KD_ACKNOWLEDGE)
  641. {
  642. if (m_ValidUnaccessedPacket)
  643. {
  644. KdOut("READ: Grab packet from buffer.\n");
  645. goto ReadBuffered;
  646. }
  647. }
  648. ReadContents:
  649. for (;;)
  650. {
  651. ULONG ReadStatus = ReadPacketContents(PacketType);
  652. //
  653. // If we read an internal packet such as IO or Resend, then
  654. // handle it and continue waiting.
  655. //
  656. if (ReadStatus == DBGKD_WAIT_PACKET)
  657. {
  658. m_PacketsRead++;
  659. switch(s_PacketHeader.PacketType)
  660. {
  661. case PACKET_TYPE_KD_DEBUG_IO:
  662. ReadStatus = HandleDebugIo((PDBGKD_DEBUG_IO)s_Packet);
  663. break;
  664. case PACKET_TYPE_KD_TRACE_IO:
  665. ReadStatus = HandleTraceIo((PDBGKD_TRACE_IO)s_Packet);
  666. break;
  667. case PACKET_TYPE_KD_CONTROL_REQUEST:
  668. ReadStatus =
  669. HandleControlRequest((PDBGKD_CONTROL_REQUEST)s_Packet);
  670. break;
  671. case PACKET_TYPE_KD_FILE_IO:
  672. ReadStatus = HandleFileIo((PDBGKD_FILE_IO)s_Packet);
  673. break;
  674. }
  675. }
  676. else if (ReadStatus == DBGKD_WAIT_ACK)
  677. {
  678. m_PacketsRead++;
  679. // If we're waiting for an ack we're done,
  680. // otherwise the communication is confused
  681. // so ask for a resend.
  682. if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE)
  683. {
  684. return DBGKD_WAIT_ACK;
  685. }
  686. else
  687. {
  688. KdOut("READ: Received ACK while waiting for type %d\n",
  689. PacketType);
  690. ReadStatus = DBGKD_WAIT_RESEND;
  691. }
  692. }
  693. if (ReadStatus == DBGKD_WAIT_PACKET)
  694. {
  695. // If we're waiting for an ack and received
  696. // a normal packet leave it in the buffer
  697. // and record the fact that we have one
  698. // stored. Consider it an ack and return.
  699. if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE)
  700. {
  701. m_ValidUnaccessedPacket = TRUE;
  702. KdOut("READ: Packet Read ahead.\n");
  703. FlushCallbacks();
  704. return DBGKD_WAIT_ACK;
  705. }
  706. // We're waiting for a data packet and we
  707. // just got one so process it.
  708. break;
  709. }
  710. else if (ReadStatus == DBGKD_WAIT_RESEND)
  711. {
  712. // If the other end didn't wait for an
  713. // ack then we can't ask for a resend.
  714. if (!m_AckWrites)
  715. {
  716. return DBGKD_WAIT_FAILED;
  717. }
  718. WriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
  719. if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE)
  720. {
  721. return DBGKD_WAIT_ACK;
  722. }
  723. KdOut("READ: Ask for resend.\n");
  724. }
  725. else if (ReadStatus == DBGKD_WAIT_AGAIN)
  726. {
  727. // Internal packets count as acknowledgements,
  728. // so if we processed one while waiting for an
  729. // ack consider things done.
  730. if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE)
  731. {
  732. return DBGKD_WAIT_ACK;
  733. }
  734. }
  735. else
  736. {
  737. return ReadStatus;
  738. }
  739. }
  740. ReadBuffered:
  741. //
  742. // Check PacketType is what we are waiting for.
  743. //
  744. if (PacketType == PACKET_TYPE_KD_STATE_CHANGE64)
  745. {
  746. if (s_PacketHeader.PacketType == PACKET_TYPE_KD_STATE_CHANGE64)
  747. {
  748. DbgKdApi64 = TRUE;
  749. }
  750. else if (s_PacketHeader.PacketType == PACKET_TYPE_KD_STATE_CHANGE32)
  751. {
  752. PacketType = PACKET_TYPE_KD_STATE_CHANGE32;
  753. DbgKdApi64 = FALSE;
  754. }
  755. KdOut("READ: Packet type = %x, DbgKdApi64 = %x\n",
  756. s_PacketHeader.PacketType, DbgKdApi64);
  757. }
  758. if (PacketType != s_PacketHeader.PacketType)
  759. {
  760. KdOut("READ: Unexpected Packet type %x (Acked). "
  761. "Expecting Packet type %x\n",
  762. s_PacketHeader.PacketType, PacketType);
  763. if (m_InvPacketRetryLimit > 0 &&
  764. ++InvPacketRetry >= m_InvPacketRetryLimit)
  765. {
  766. return DBGKD_WAIT_FAILED;
  767. }
  768. goto ReadContents;
  769. }
  770. if (!DbgKdApi64 && PacketType == PACKET_TYPE_KD_STATE_MANIPULATE)
  771. {
  772. DBGKD_MANIPULATE_STATE64 Packet64;
  773. DWORD AdditionalDataSize;
  774. DbgkdManipulateState32To64((PDBGKD_MANIPULATE_STATE32)&s_Packet,
  775. &Packet64, &AdditionalDataSize);
  776. if (Packet64.ApiNumber == DbgKdGetVersionApi)
  777. {
  778. DbgkdGetVersion32To64(&((PDBGKD_MANIPULATE_STATE32)&s_Packet)->
  779. u.GetVersion32,
  780. &Packet64.u.GetVersion64,
  781. &KdDebuggerData);
  782. }
  783. else if (AdditionalDataSize)
  784. {
  785. //
  786. // Move the trailing data to make room for the larger packet header
  787. //
  788. MoveMemory(s_Packet + sizeof(DBGKD_MANIPULATE_STATE64),
  789. s_Packet + sizeof(DBGKD_MANIPULATE_STATE32),
  790. AdditionalDataSize);
  791. }
  792. *(PDBGKD_MANIPULATE_STATE64)s_Packet = Packet64;
  793. }
  794. *(PVOID *)Packet = &s_Packet;
  795. m_ValidUnaccessedPacket = FALSE;
  796. return DBGKD_WAIT_PACKET;
  797. }
  798. VOID
  799. DbgKdTransport::WriteBreakInPacket(VOID)
  800. {
  801. DWORD BytesWritten;
  802. BOOL rc;
  803. KdOut("Send Break in ...\n");
  804. FlushCallbacks();
  805. do
  806. {
  807. rc = Write(&s_BreakinPacket[0], sizeof(s_BreakinPacket),
  808. &BytesWritten);
  809. } while ((!rc) || (BytesWritten != sizeof(s_BreakinPacket)));
  810. m_BreakIn = FALSE;
  811. m_PacketsWritten++;
  812. }
  813. VOID
  814. DbgKdTransport::WriteControlPacket(
  815. IN USHORT PacketType,
  816. IN ULONG PacketId OPTIONAL
  817. )
  818. /*++
  819. Routine Description:
  820. This function writes a control packet to target machine.
  821. N.B. a CONTROL Packet header is sent with the following information:
  822. PacketLeader - indicates it's a control packet
  823. PacketType - indicates the type of the control packet
  824. ByteCount - aways zero to indicate no data following the header
  825. PacketId - Valid ONLY for PACKET_TYPE_KD_ACKNOWLEDGE to indicate
  826. which packet is acknowledged.
  827. Arguments:
  828. PacketType - Supplies the type of the control packet.
  829. PacketId - Supplies the PacketId. Used by Acknowledge packet only.
  830. Return Value:
  831. None.
  832. --*/
  833. {
  834. DWORD BytesWritten;
  835. BOOL rc;
  836. KD_PACKET Packet;
  837. DBG_ASSERT( (g_KdMaxPacketType == 0 && PacketType < PACKET_TYPE_MAX) ||
  838. (g_KdMaxPacketType > 0 && PacketType < g_KdMaxPacketType) );
  839. Packet.PacketLeader = CONTROL_PACKET_LEADER;
  840. Packet.ByteCount = 0;
  841. Packet.PacketType = PacketType;
  842. if ( PacketId )
  843. {
  844. Packet.PacketId = PacketId;
  845. }
  846. else
  847. {
  848. Packet.PacketId = 0;
  849. }
  850. Packet.Checksum = 0;
  851. do
  852. {
  853. //
  854. // Write the control packet header
  855. //
  856. rc = Write(&Packet, sizeof(Packet), &BytesWritten);
  857. } while ( (!rc) || BytesWritten != sizeof(Packet) );
  858. m_PacketsWritten++;
  859. }
  860. VOID
  861. DbgKdTransport::WriteDataPacket(
  862. IN PVOID PacketData,
  863. IN USHORT PacketDataLength,
  864. IN USHORT PacketType,
  865. IN PVOID MorePacketData OPTIONAL,
  866. IN USHORT MorePacketDataLength OPTIONAL,
  867. IN BOOL NoAck
  868. )
  869. {
  870. KD_PACKET Packet;
  871. USHORT TotalBytesToWrite;
  872. DBGKD_MANIPULATE_STATE32 m32;
  873. PVOID ConvertedPacketData = NULL;
  874. DBG_ASSERT( (g_KdMaxPacketType == 0 && PacketType < PACKET_TYPE_MAX) ||
  875. (g_KdMaxPacketType > 0 && PacketType < g_KdMaxPacketType) );
  876. // Packets can only be written when the kernel transport
  877. // is not in use.
  878. if (m_WaitingThread != 0 &&
  879. m_WaitingThread != GetCurrentThreadId())
  880. {
  881. ErrOut("Kernel transport in use, packet write failed\n");
  882. return;
  883. }
  884. KdOut("WRITE: Write type %x packet id= %lx.\n",
  885. PacketType, m_NextPacketToSend);
  886. if (!DbgKdApi64 && PacketType == PACKET_TYPE_KD_STATE_MANIPULATE)
  887. {
  888. PacketDataLength = (USHORT)
  889. DbgkdManipulateState64To32((PDBGKD_MANIPULATE_STATE64)PacketData,
  890. &m32);
  891. PacketData = (PVOID)&m32;
  892. if (m32.ApiNumber == DbgKdWriteBreakPointExApi)
  893. {
  894. ConvertedPacketData = malloc(MorePacketDataLength / 2);
  895. if (!ConvertedPacketData)
  896. {
  897. ErrOut("Failed to allocate Packet Data\n");
  898. return;
  899. }
  900. ConvertQwordsToDwords((PULONG64)PacketData,
  901. (PULONG)ConvertedPacketData,
  902. MorePacketDataLength / 8);
  903. MorePacketData = ConvertedPacketData;
  904. MorePacketDataLength /= 2;
  905. }
  906. }
  907. if ( ARGUMENT_PRESENT(MorePacketData) )
  908. {
  909. TotalBytesToWrite = PacketDataLength + MorePacketDataLength;
  910. Packet.Checksum = ComputeChecksum((PUCHAR)MorePacketData,
  911. MorePacketDataLength);
  912. }
  913. else
  914. {
  915. TotalBytesToWrite = PacketDataLength;
  916. Packet.Checksum = 0;
  917. }
  918. Packet.Checksum += ComputeChecksum((PUCHAR)PacketData,
  919. PacketDataLength);
  920. Packet.PacketLeader = PACKET_LEADER;
  921. Packet.ByteCount = TotalBytesToWrite;
  922. Packet.PacketType = PacketType;
  923. g_PacketLog[g_PacketLogIndex++ & (PACKET_LOG_SIZE - 1)] =
  924. ((ULONG64)0xF << 60) | ((ULONG64)PacketType << 32) | TotalBytesToWrite;
  925. for (;;)
  926. {
  927. Packet.PacketId = m_NextPacketToSend;
  928. if (WritePacketContents(&Packet, PacketData, PacketDataLength,
  929. MorePacketData, MorePacketDataLength,
  930. NoAck) == DBGKD_WRITE_PACKET)
  931. {
  932. m_PacketsWritten++;
  933. break;
  934. }
  935. }
  936. if (ConvertedPacketData)
  937. {
  938. free(ConvertedPacketData);
  939. }
  940. }
  941. ULONG
  942. DbgKdTransport::ComputeChecksum(
  943. IN PUCHAR Buffer,
  944. IN ULONG Length
  945. )
  946. {
  947. ULONG Checksum = 0;
  948. while (Length > 0)
  949. {
  950. Checksum = Checksum + (ULONG)*Buffer++;
  951. Length--;
  952. }
  953. return Checksum;
  954. }
  955. //----------------------------------------------------------------------------
  956. //
  957. // DbgKdComTransport.
  958. //
  959. //----------------------------------------------------------------------------
  960. // Environment variable names.
  961. #define COM_PORT_NAME "_NT_DEBUG_PORT"
  962. #define COM_PORT_BAUD "_NT_DEBUG_BAUD_RATE"
  963. // Parameter string names.
  964. #define PARAM_COM_PORT "Port"
  965. #define PARAM_COM_BAUD "Baud"
  966. #define PARAM_COM_MODEM "Modem"
  967. #define PARAM_COM_TIMEOUT "Timeout"
  968. DbgKdComTransport::DbgKdComTransport(void)
  969. {
  970. m_Index = DBGKD_TRANSPORT_COM;
  971. m_Name = g_DbgKdTransportNames[m_Index];
  972. m_InvPacketRetryLimit = 0;
  973. m_AckWrites = TRUE;
  974. }
  975. ULONG
  976. DbgKdComTransport::GetNumberParameters(void)
  977. {
  978. return 4;
  979. }
  980. void
  981. DbgKdComTransport::GetParameter(ULONG Index, PSTR Name, PSTR Value)
  982. {
  983. switch(Index)
  984. {
  985. case 0:
  986. strcpy(Name, PARAM_COM_PORT);
  987. strcpy(Value, m_PortName);
  988. break;
  989. case 1:
  990. strcpy(Name, PARAM_COM_BAUD);
  991. sprintf(Value, "%d", m_BaudRate);
  992. break;
  993. case 2:
  994. if (m_Modem)
  995. {
  996. strcpy(Name, PARAM_COM_MODEM);
  997. }
  998. break;
  999. case 3:
  1000. strcpy(Name, PARAM_COM_TIMEOUT);
  1001. sprintf(Value, "%d", m_Timeout);
  1002. break;
  1003. }
  1004. }
  1005. void
  1006. DbgKdComTransport::ResetParameters(void)
  1007. {
  1008. PSTR Env;
  1009. if ((Env = getenv(COM_PORT_NAME)) == NULL)
  1010. {
  1011. Env = "com1";
  1012. }
  1013. SetComPortName(Env, m_PortName);
  1014. if ((Env = getenv(COM_PORT_BAUD)) != NULL)
  1015. {
  1016. m_BaudRate = atol(Env);
  1017. }
  1018. else
  1019. {
  1020. m_BaudRate = 19200;
  1021. }
  1022. m_Modem = FALSE;
  1023. m_Timeout = 4000;
  1024. }
  1025. BOOL
  1026. DbgKdComTransport::SetParameter(PCSTR Name, PCSTR Value)
  1027. {
  1028. if (!_strcmpi(Name, PARAM_COM_PORT))
  1029. {
  1030. SetComPortName(Value, m_PortName);
  1031. }
  1032. else if (!_strcmpi(Name, PARAM_COM_BAUD))
  1033. {
  1034. m_BaudRate = atol(Value);
  1035. }
  1036. else if (!_strcmpi(Name, PARAM_COM_MODEM))
  1037. {
  1038. m_Modem = TRUE;
  1039. }
  1040. else if (!_strcmpi(Name, PARAM_COM_TIMEOUT))
  1041. {
  1042. m_Timeout = atol(Value);
  1043. }
  1044. else
  1045. {
  1046. ErrOut("COM port parameters: %s is not a valid parameter\n", Name);
  1047. return FALSE;
  1048. }
  1049. return TRUE;
  1050. }
  1051. HRESULT
  1052. DbgKdComTransport::Initialize(void)
  1053. {
  1054. HRESULT Status;
  1055. if ((Status = DbgKdTransport::Initialize()) != S_OK)
  1056. {
  1057. return Status;
  1058. }
  1059. m_DirectPhysicalMemory = FALSE;
  1060. if ((Status = OpenComPort(m_PortName, m_BaudRate, m_Timeout,
  1061. &m_Handle, &m_BaudRate)) != S_OK)
  1062. {
  1063. ErrOut("Failed to open %s\n", m_PortName);
  1064. return Status;
  1065. }
  1066. dprintf("Opened %s\n", m_PortName);
  1067. m_ComEvent = 0;
  1068. if (m_Modem)
  1069. {
  1070. DWORD Mask;
  1071. //
  1072. // Debugger is being run over a modem. Set event to watch
  1073. // carrier detect.
  1074. //
  1075. GetCommMask (m_Handle, &Mask);
  1076. // set DDCD event
  1077. if (!SetCommMask (m_Handle, Mask | 0xA0))
  1078. {
  1079. ErrOut("Failed to set event for %s.\n", m_PortName);
  1080. return WIN32_LAST_STATUS();
  1081. }
  1082. m_EventOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  1083. if (!m_EventOverlapped.hEvent)
  1084. {
  1085. ErrOut("Failed to create EventOverlapped\n");
  1086. return WIN32_LAST_STATUS();
  1087. }
  1088. m_EventOverlapped.Offset = 0;
  1089. m_EventOverlapped.OffsetHigh = 0;
  1090. // Fake an event, so modem status will be checked
  1091. m_ComEvent = 1;
  1092. }
  1093. return S_OK;
  1094. }
  1095. void
  1096. DbgKdComTransport::Uninitialize(void)
  1097. {
  1098. if (m_Handle != NULL)
  1099. {
  1100. CloseHandle(m_Handle);
  1101. m_Handle = NULL;
  1102. }
  1103. if (m_EventOverlapped.hEvent != NULL)
  1104. {
  1105. CloseHandle(m_EventOverlapped.hEvent);
  1106. m_EventOverlapped.hEvent = NULL;
  1107. }
  1108. DbgKdTransport::Uninitialize();
  1109. }
  1110. BOOL
  1111. DbgKdComTransport::Read(
  1112. IN PVOID Buffer,
  1113. IN ULONG SizeOfBuffer,
  1114. IN PULONG BytesRead
  1115. )
  1116. {
  1117. if (IS_DUMP_TARGET())
  1118. {
  1119. ErrOut( "Attempted to read KD transport while "
  1120. "debugging a crash dump\n" );
  1121. DebugBreak();
  1122. }
  1123. if (m_ComEvent)
  1124. {
  1125. CheckComStatus ();
  1126. }
  1127. if (ComPortRead(m_Handle, Buffer, SizeOfBuffer, BytesRead,
  1128. &m_ReadOverlapped))
  1129. {
  1130. #if DBG_KD_READ
  1131. OutputIo("CR: Read %d bytes of %d\n",
  1132. Buffer, SizeOfBuffer, *BytesRead);
  1133. #endif
  1134. m_BytesRead += *BytesRead;
  1135. return TRUE;
  1136. }
  1137. else
  1138. {
  1139. return FALSE;
  1140. }
  1141. }
  1142. BOOL
  1143. DbgKdComTransport::Write(
  1144. IN PVOID Buffer,
  1145. IN ULONG SizeOfBuffer,
  1146. IN PULONG BytesWritten
  1147. )
  1148. {
  1149. if (IS_DUMP_TARGET())
  1150. {
  1151. ErrOut( "Attempted to write KD transport "
  1152. "while debugging a crash dump\n" );
  1153. DebugBreak();
  1154. }
  1155. if (m_ComEvent)
  1156. {
  1157. CheckComStatus ();
  1158. }
  1159. //
  1160. // Break up large writes in smaller chunks
  1161. // to try and avoid sending too much data
  1162. // to the target all at once. Sleep a bit
  1163. // between chunks to let the target retrieve
  1164. // data.
  1165. //
  1166. BOOL Succ = TRUE;
  1167. *BytesWritten = 0;
  1168. while (SizeOfBuffer > 0)
  1169. {
  1170. ULONG Request, Done;
  1171. // By default we want to encourage vendors
  1172. // to create machines with robust serial
  1173. // support so we don't actually limit
  1174. // the write size.
  1175. #if THROTTLE_WRITES
  1176. Request = 96;
  1177. #else
  1178. Request = 0xffffffff;
  1179. #endif
  1180. if (SizeOfBuffer < Request)
  1181. {
  1182. Request = SizeOfBuffer;
  1183. }
  1184. if (!ComPortWrite(m_Handle, Buffer, Request, &Done,
  1185. &m_WriteOverlapped))
  1186. {
  1187. Succ = FALSE;
  1188. break;
  1189. }
  1190. #if DBG_KD_WRITE
  1191. OutputIo("CW: Write %d bytes of %d\n",
  1192. Buffer, Request, Done);
  1193. #endif
  1194. *BytesWritten += Done;
  1195. if (Done <= Request)
  1196. {
  1197. break;
  1198. }
  1199. Buffer = (PVOID)((PUCHAR)Buffer + Done);
  1200. SizeOfBuffer -= Done;
  1201. Sleep(10);
  1202. }
  1203. m_BytesWritten += *BytesWritten;
  1204. return Succ;
  1205. }
  1206. void
  1207. DbgKdComTransport::CycleSpeed(void)
  1208. {
  1209. if (SetComPortBaud(m_Handle, 0, &m_BaudRate) != S_OK)
  1210. {
  1211. ErrOut("New Baud rate Could not be set on Com %I64x - remains %d.\n",
  1212. (ULONG64)m_Handle, m_BaudRate);
  1213. }
  1214. else
  1215. {
  1216. dprintf("Baud rate set to %d\n", m_BaudRate);
  1217. }
  1218. }
  1219. VOID
  1220. DbgKdComTransport::Synchronize(VOID)
  1221. {
  1222. USHORT Index;
  1223. UCHAR DataByte, PreviousDataByte;
  1224. USHORT PacketType = 0;
  1225. ULONG TimeoutCount = 0;
  1226. COMMTIMEOUTS CommTimeouts;
  1227. COMMTIMEOUTS OldTimeouts;
  1228. DWORD BytesRead;
  1229. BOOL rc;
  1230. //
  1231. // Get the old time out values and hold them.
  1232. // We then set a new total timeout value of
  1233. // a fraction of the base timeout.
  1234. //
  1235. GetCommTimeouts(g_DbgKdTransport->m_Handle, &OldTimeouts);
  1236. CommTimeouts = OldTimeouts;
  1237. CommTimeouts.ReadIntervalTimeout = 0;
  1238. CommTimeouts.ReadTotalTimeoutMultiplier = 0;
  1239. CommTimeouts.ReadTotalTimeoutConstant = m_Timeout / 8;
  1240. #define TIMEOUT_ITERATIONS 6
  1241. SetCommTimeouts(g_DbgKdTransport->m_Handle, &CommTimeouts);
  1242. FlushCallbacks();
  1243. while (TRUE)
  1244. {
  1245. Timeout:
  1246. WriteControlPacket(PACKET_TYPE_KD_RESET, 0L);
  1247. //
  1248. // Read packet leader
  1249. //
  1250. BOOL First = TRUE;
  1251. Index = 0;
  1252. do
  1253. {
  1254. if (g_EngStatus & ENG_STATUS_EXIT_CURRENT_WAIT)
  1255. {
  1256. KdOut("Synchronize interrupted by exit request\n");
  1257. goto Exit;
  1258. }
  1259. //
  1260. // Check user input for control_c. If user types control_c,
  1261. // we will send a breakin packet to the target. Hopefully,
  1262. // target will send us a StateChange packet and
  1263. //
  1264. //
  1265. // if we don't get response from kernel in 3 seconds we
  1266. // will resend the reset packet if user does not type ctrl_c.
  1267. // Otherwise, we send breakin character and wait for data again.
  1268. //
  1269. rc = g_DbgKdTransport->Read(&DataByte, 1, &BytesRead);
  1270. if ((!rc) || (BytesRead != 1))
  1271. {
  1272. if (m_BreakIn || m_SyncBreakIn)
  1273. {
  1274. m_SyncBreakIn = FALSE;
  1275. WriteBreakInPacket();
  1276. TimeoutCount = 0;
  1277. continue;
  1278. }
  1279. TimeoutCount++;
  1280. //
  1281. // if we have been waiting for 3 seconds, resend RESYNC packet
  1282. //
  1283. if (TimeoutCount < TIMEOUT_ITERATIONS)
  1284. {
  1285. continue;
  1286. }
  1287. TimeoutCount = 0;
  1288. KdOut("SYNCTARGET: Timeout.\n");
  1289. FlushCallbacks();
  1290. goto Timeout;
  1291. }
  1292. #if DBG_SYNCH
  1293. if (rc && BytesRead == 1 && First)
  1294. {
  1295. dprintf("First byte %X\n", DataByte);
  1296. First = FALSE;
  1297. }
  1298. #endif
  1299. if (rc && BytesRead == 1 &&
  1300. ( DataByte == PACKET_LEADER_BYTE ||
  1301. DataByte == CONTROL_PACKET_LEADER_BYTE)
  1302. )
  1303. {
  1304. if ( Index == 0 )
  1305. {
  1306. PreviousDataByte = DataByte;
  1307. Index++;
  1308. }
  1309. else if ( DataByte == PreviousDataByte )
  1310. {
  1311. Index++;
  1312. }
  1313. else
  1314. {
  1315. PreviousDataByte = DataByte;
  1316. Index = 1;
  1317. }
  1318. }
  1319. else
  1320. {
  1321. Index = 0;
  1322. if (rc && BytesRead == 1)
  1323. {
  1324. // The target machine is alive and talking but
  1325. // the received data is in the middle of
  1326. // a packet. Break out of the header byte
  1327. // loop and consume up to a trailer byte.
  1328. break;
  1329. }
  1330. }
  1331. }
  1332. while ( Index < 4 );
  1333. if (Index == 4 && DataByte == CONTROL_PACKET_LEADER_BYTE)
  1334. {
  1335. //
  1336. // Read 2 byte Packet type
  1337. //
  1338. rc = g_DbgKdTransport->Read((PUCHAR)&PacketType,
  1339. sizeof(PacketType), &BytesRead);
  1340. if (rc && BytesRead == sizeof(PacketType) &&
  1341. PacketType == PACKET_TYPE_KD_RESET)
  1342. {
  1343. KdOut("SYNCTARGET: Received KD_RESET ACK packet.\n");
  1344. m_PacketExpected = INITIAL_PACKET_ID;
  1345. m_NextPacketToSend = INITIAL_PACKET_ID;
  1346. KdOut("SYNCTARGET: Target synchronized successfully...\n");
  1347. FlushCallbacks();
  1348. goto Exit;
  1349. }
  1350. }
  1351. //
  1352. // If we receive Data Packet leader, it means target has not
  1353. // receive our reset packet. So we loop back and send it again.
  1354. // N.B. We need to wait until target finishes sending the packet.
  1355. // Otherwise, we may be sending the reset packet while the target
  1356. // is sending the packet. This might cause target loss the reset
  1357. // packet.
  1358. //
  1359. Index = 0;
  1360. while (DataByte != PACKET_TRAILING_BYTE)
  1361. {
  1362. rc = g_DbgKdTransport->Read(&DataByte, 1, &BytesRead);
  1363. if (!rc || BytesRead != 1)
  1364. {
  1365. break;
  1366. }
  1367. Index++;
  1368. }
  1369. #if DBG_SYNCH
  1370. dprintf(" ate %x bytes\n", Index);
  1371. FlushCallbacks();
  1372. #endif
  1373. }
  1374. Exit:
  1375. SetCommTimeouts(g_DbgKdTransport->m_Handle, &OldTimeouts);
  1376. }
  1377. ULONG
  1378. DbgKdComTransport::ReadPacketContents(IN USHORT PacketType)
  1379. {
  1380. DWORD BytesRead;
  1381. BOOL rc;
  1382. UCHAR DataByte;
  1383. ULONG Checksum;
  1384. ULONG SyncBit;
  1385. ULONG WaitStatus;
  1386. //
  1387. // First read a packet leader
  1388. //
  1389. WaitForPacketLeader:
  1390. WaitStatus = ReadPacketLeader(PacketType, &s_PacketHeader.PacketLeader);
  1391. if (WaitStatus != DBGKD_WAIT_PACKET)
  1392. {
  1393. return WaitStatus;
  1394. }
  1395. if (m_AllowInitialBreak && (g_EngOptions & DEBUG_ENGOPT_INITIAL_BREAK))
  1396. {
  1397. KdOut("Attempting to get initial breakpoint.\n");
  1398. WriteBreakInPacket();
  1399. }
  1400. // We've either sent the initial break or we don't want
  1401. // one. Either way we don't need to send another one.
  1402. m_AllowInitialBreak = FALSE;
  1403. //
  1404. // Read packetLeader ONLY read two Packet Leader bytes. This do loop
  1405. // filters out the remaining leader byte.
  1406. //
  1407. do
  1408. {
  1409. rc = Read(&DataByte, 1, &BytesRead);
  1410. if ((rc) && BytesRead == 1)
  1411. {
  1412. if (DataByte == PACKET_LEADER_BYTE ||
  1413. DataByte == CONTROL_PACKET_LEADER_BYTE)
  1414. {
  1415. continue;
  1416. }
  1417. else
  1418. {
  1419. *(PUCHAR)&s_PacketHeader.PacketType = DataByte;
  1420. break;
  1421. }
  1422. }
  1423. else
  1424. {
  1425. goto WaitForPacketLeader;
  1426. }
  1427. } while (TRUE);
  1428. //
  1429. // Now we have valid packet leader. Read rest of the packet type.
  1430. //
  1431. rc = Read(((PUCHAR)&s_PacketHeader.PacketType) + 1,
  1432. sizeof(s_PacketHeader.PacketType) - 1, &BytesRead);
  1433. if ((!rc) || BytesRead != sizeof(s_PacketHeader.PacketType) - 1)
  1434. {
  1435. //
  1436. // If we cannot read the packet type and if the packet leader
  1437. // indicates this is a data packet, we need to ask for resend.
  1438. // Otherwise we simply ignore the incomplete packet.
  1439. //
  1440. if (s_PacketHeader.PacketLeader == PACKET_LEADER)
  1441. {
  1442. WriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
  1443. KdOut("READ: Data packet header Type error (short read).\n");
  1444. }
  1445. goto WaitForPacketLeader;
  1446. }
  1447. //
  1448. // Check the Packet type.
  1449. //
  1450. if ((g_KdMaxPacketType == 0 &&
  1451. s_PacketHeader.PacketType >= PACKET_TYPE_MAX) ||
  1452. (g_KdMaxPacketType > 0 &&
  1453. s_PacketHeader.PacketType >= g_KdMaxPacketType))
  1454. {
  1455. KdOut("READ: Received INVALID packet type.\n");
  1456. if (s_PacketHeader.PacketLeader == PACKET_LEADER)
  1457. {
  1458. WriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
  1459. }
  1460. goto WaitForPacketLeader;
  1461. }
  1462. KdOut(" PacketType=%x, ", s_PacketHeader.PacketType);
  1463. //
  1464. // Read ByteCount
  1465. //
  1466. rc = Read(&s_PacketHeader.ByteCount, sizeof(s_PacketHeader.ByteCount),
  1467. &BytesRead);
  1468. if ((!rc) || BytesRead != sizeof(s_PacketHeader.ByteCount))
  1469. {
  1470. //
  1471. // If we cannot read the packet type and if the packet leader
  1472. // indicates this is a data packet, we need to ask for resend.
  1473. // Otherwise we simply ignore the incomplete packet.
  1474. //
  1475. if (s_PacketHeader.PacketLeader == PACKET_LEADER)
  1476. {
  1477. WriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
  1478. KdOut("READ: Data packet header ByteCount error (short read).\n");
  1479. }
  1480. goto WaitForPacketLeader;
  1481. }
  1482. //
  1483. // Check ByteCount
  1484. //
  1485. if (s_PacketHeader.ByteCount > PACKET_MAX_SIZE)
  1486. {
  1487. if (s_PacketHeader.PacketLeader == PACKET_LEADER)
  1488. {
  1489. WriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
  1490. KdOut("READ: Data packet header ByteCount error (short read).\n");
  1491. }
  1492. goto WaitForPacketLeader;
  1493. }
  1494. KdOut("ByteCount=%x, ", s_PacketHeader.ByteCount);
  1495. //
  1496. // Read Packet Id
  1497. //
  1498. rc = Read(&s_PacketHeader.PacketId, sizeof(s_PacketHeader.PacketId),
  1499. &BytesRead);
  1500. if ((!rc) || BytesRead != sizeof(s_PacketHeader.PacketId))
  1501. {
  1502. //
  1503. // If we cannot read the packet Id and if the packet leader
  1504. // indicates this is a data packet, we need to ask for resend.
  1505. // Otherwise we simply ignore the incomplete packet.
  1506. //
  1507. if (s_PacketHeader.PacketLeader == PACKET_LEADER)
  1508. {
  1509. WriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
  1510. KdOut("READ: Data packet header Id error (short read).\n");
  1511. }
  1512. goto WaitForPacketLeader;
  1513. }
  1514. KdOut("PacketId=%x,\n", s_PacketHeader.PacketId);
  1515. //
  1516. // Don't read checksum here as in some cases
  1517. // it isn't sent with control packets.
  1518. //
  1519. if (s_PacketHeader.PacketLeader == CONTROL_PACKET_LEADER )
  1520. {
  1521. if (s_PacketHeader.PacketType == PACKET_TYPE_KD_ACKNOWLEDGE )
  1522. {
  1523. //
  1524. // If we received an expected ACK packet and we are not
  1525. // waiting for any new packet, update outgoing packet id
  1526. // and return. If we are NOT waiting for ACK packet
  1527. // we will keep on waiting. If the ACK packet
  1528. // is not for the packet we send, ignore it and keep on waiting.
  1529. //
  1530. if (s_PacketHeader.PacketId != m_NextPacketToSend)
  1531. {
  1532. KdOut("READ: Received unmatched packet id = %lx, Type = %x\n",
  1533. s_PacketHeader.PacketId, s_PacketHeader.PacketType);
  1534. goto WaitForPacketLeader;
  1535. }
  1536. else if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE)
  1537. {
  1538. m_NextPacketToSend ^= 1;
  1539. KdOut("READ: Received correct ACK packet.\n");
  1540. FlushCallbacks();
  1541. return DBGKD_WAIT_ACK;
  1542. }
  1543. else
  1544. {
  1545. goto WaitForPacketLeader;
  1546. }
  1547. }
  1548. else if (s_PacketHeader.PacketType == PACKET_TYPE_KD_RESET)
  1549. {
  1550. //
  1551. // if we received Reset packet, reset the packet control variables
  1552. // and resend earlier packet.
  1553. //
  1554. m_NextPacketToSend = INITIAL_PACKET_ID;
  1555. m_PacketExpected = INITIAL_PACKET_ID;
  1556. WriteControlPacket(PACKET_TYPE_KD_RESET, 0L);
  1557. KdOut("DbgKdpWaitForPacket(): Recieved KD_RESET packet, "
  1558. "send KD_RESET ACK packet\n");
  1559. FlushCallbacks();
  1560. return DBGKD_WAIT_FAILED;
  1561. }
  1562. else if (s_PacketHeader.PacketType == PACKET_TYPE_KD_RESEND)
  1563. {
  1564. KdOut("READ: Received RESEND packet\n");
  1565. FlushCallbacks();
  1566. return DBGKD_WAIT_FAILED;
  1567. }
  1568. else
  1569. {
  1570. //
  1571. // Invalid packet header, ignore it.
  1572. //
  1573. KdOut("READ: Received Control packet with UNKNOWN type\n");
  1574. goto WaitForPacketLeader;
  1575. }
  1576. }
  1577. else
  1578. {
  1579. //
  1580. // The packet header is for data packet (not control packet).
  1581. // Read Checksum.
  1582. //
  1583. rc = Read(&s_PacketHeader.Checksum, sizeof(s_PacketHeader.Checksum),
  1584. &BytesRead);
  1585. if ((!rc) || BytesRead != sizeof(s_PacketHeader.Checksum))
  1586. {
  1587. WriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
  1588. KdOut("READ: Data packet header "
  1589. "checksum error (short read).\n");
  1590. goto WaitForPacketLeader;
  1591. }
  1592. if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE)
  1593. {
  1594. //
  1595. // If we are waiting for ACK packet ONLY
  1596. // and we receive a data packet header, check if the packet id
  1597. // is what we expected. If yes, assume the acknowledge is lost
  1598. // (but sent) and process the packet.
  1599. //
  1600. if (s_PacketHeader.PacketId == m_PacketExpected)
  1601. {
  1602. m_NextPacketToSend ^= 1;
  1603. KdOut("READ: Received VALID data packet "
  1604. "while waiting for ACK.\n");
  1605. }
  1606. else
  1607. {
  1608. KdOut("READ: Received Data packet with unmatched ID = %lx\n",
  1609. s_PacketHeader.PacketId);
  1610. WriteControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE,
  1611. s_PacketHeader.PacketId);
  1612. goto WaitForPacketLeader;
  1613. }
  1614. }
  1615. }
  1616. //
  1617. // We are waiting for data packet and we received the packet header
  1618. // for data packet. Perform the following checkings to make sure
  1619. // it is the packet we are waiting for.
  1620. //
  1621. if ((s_PacketHeader.PacketId & ~SYNC_PACKET_ID) != INITIAL_PACKET_ID &&
  1622. (s_PacketHeader.PacketId & ~SYNC_PACKET_ID) != (INITIAL_PACKET_ID ^ 1))
  1623. {
  1624. KdOut("READ: Received INVALID packet Id.\n");
  1625. return DBGKD_WAIT_RESEND;
  1626. }
  1627. rc = Read(s_Packet, s_PacketHeader.ByteCount, &BytesRead);
  1628. if ( (!rc) || BytesRead != s_PacketHeader.ByteCount )
  1629. {
  1630. KdOut("READ: Data packet error (short read).\n");
  1631. return DBGKD_WAIT_RESEND;
  1632. }
  1633. //
  1634. // Make sure the next byte is packet trailing byte
  1635. //
  1636. rc = Read(&DataByte, sizeof(DataByte), &BytesRead);
  1637. if ( (!rc) || BytesRead != sizeof(DataByte) ||
  1638. DataByte != PACKET_TRAILING_BYTE )
  1639. {
  1640. KdOut("READ: Packet trailing byte timeout.\n");
  1641. return DBGKD_WAIT_RESEND;
  1642. }
  1643. //
  1644. // Make sure the checksum is valid.
  1645. //
  1646. Checksum = ComputeChecksum(s_Packet, s_PacketHeader.ByteCount);
  1647. if (Checksum != s_PacketHeader.Checksum)
  1648. {
  1649. KdOut("READ: Checksum error.\n");
  1650. return DBGKD_WAIT_RESEND;
  1651. }
  1652. //
  1653. // We have a valid data packet. If the packetid is bad, we just
  1654. // ack the packet to the sender will step ahead. If packetid is bad
  1655. // but SYNC_PACKET_ID bit is set, we sync up. If packetid is good,
  1656. // or SYNC_PACKET_ID is set, we take the packet.
  1657. //
  1658. KdOut("READ: Received Type %x data packet with id = %lx successfully.\n\n",
  1659. s_PacketHeader.PacketType, s_PacketHeader.PacketId);
  1660. SyncBit = s_PacketHeader.PacketId & SYNC_PACKET_ID;
  1661. s_PacketHeader.PacketId = s_PacketHeader.PacketId & ~SYNC_PACKET_ID;
  1662. //
  1663. // Ack the packet. SYNC_PACKET_ID bit will ALWAYS be OFF.
  1664. //
  1665. WriteControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE,
  1666. s_PacketHeader.PacketId);
  1667. //
  1668. // Check the incoming packet Id.
  1669. //
  1670. if ((s_PacketHeader.PacketId != m_PacketExpected) &&
  1671. (SyncBit != SYNC_PACKET_ID))
  1672. {
  1673. KdOut("READ: Unexpected Packet Id (Acked).\n");
  1674. goto WaitForPacketLeader;
  1675. }
  1676. else
  1677. {
  1678. if (SyncBit == SYNC_PACKET_ID)
  1679. {
  1680. //
  1681. // We know SyncBit is set, so reset Expected Ids
  1682. //
  1683. KdOut("READ: Got Sync Id, reset PacketId.\n");
  1684. m_PacketExpected = s_PacketHeader.PacketId;
  1685. m_NextPacketToSend = INITIAL_PACKET_ID;
  1686. }
  1687. m_PacketExpected ^= 1;
  1688. }
  1689. return DBGKD_WAIT_PACKET;
  1690. }
  1691. ULONG
  1692. DbgKdComTransport::WritePacketContents(IN KD_PACKET* Packet,
  1693. IN PVOID PacketData,
  1694. IN USHORT PacketDataLength,
  1695. IN PVOID MorePacketData OPTIONAL,
  1696. IN USHORT MorePacketDataLength OPTIONAL,
  1697. IN BOOL NoAck)
  1698. {
  1699. BOOL rc;
  1700. ULONG BytesWritten;
  1701. // Lock to ensure all parts of the data are
  1702. // sequential in the stream.
  1703. RESUME_ENGINE();
  1704. //
  1705. // Write the packet header
  1706. //
  1707. rc = Write(Packet, sizeof(*Packet), &BytesWritten);
  1708. if ( (!rc) || BytesWritten != sizeof(*Packet))
  1709. {
  1710. //
  1711. // An error occured writing the header, so write it again
  1712. //
  1713. KdOut("WRITE: Packet header error.\n");
  1714. SUSPEND_ENGINE();
  1715. return DBGKD_WRITE_RESEND;
  1716. }
  1717. //
  1718. // Write the primary packet data
  1719. //
  1720. rc = Write(PacketData, PacketDataLength, &BytesWritten);
  1721. if ( (!rc) || BytesWritten != PacketDataLength )
  1722. {
  1723. //
  1724. // An error occured writing the primary packet data,
  1725. // so write it again
  1726. //
  1727. KdOut("WRITE: Message header error.\n");
  1728. SUSPEND_ENGINE();
  1729. return DBGKD_WRITE_RESEND;
  1730. }
  1731. //
  1732. // If secondary packet data was specified (WriteMemory, SetContext...)
  1733. // then write it as well.
  1734. //
  1735. if ( ARGUMENT_PRESENT(MorePacketData) )
  1736. {
  1737. rc = Write(MorePacketData, MorePacketDataLength, &BytesWritten);
  1738. if ( (!rc) || BytesWritten != MorePacketDataLength )
  1739. {
  1740. //
  1741. // An error occured writing the secondary packet data,
  1742. // so write it again
  1743. //
  1744. KdOut("WRITE: Message data error.\n");
  1745. SUSPEND_ENGINE();
  1746. return DBGKD_WRITE_RESEND;
  1747. }
  1748. }
  1749. //
  1750. // Output a packet trailing byte
  1751. //
  1752. do
  1753. {
  1754. rc = Write(&s_PacketTrailingByte[0],
  1755. sizeof(s_PacketTrailingByte),
  1756. &BytesWritten);
  1757. }
  1758. while ((!rc) || (BytesWritten != sizeof(s_PacketTrailingByte)));
  1759. SUSPEND_ENGINE();
  1760. if (!NoAck)
  1761. {
  1762. ULONG Received;
  1763. //
  1764. // Wait for ACK
  1765. //
  1766. Received = WaitForPacket(PACKET_TYPE_KD_ACKNOWLEDGE, NULL);
  1767. if (Received != DBGKD_WAIT_ACK)
  1768. {
  1769. KdOut("WRITE: Wait for ACK failed. Resend Packet.\n");
  1770. return DBGKD_WRITE_RESEND;
  1771. }
  1772. }
  1773. return DBGKD_WRITE_PACKET;
  1774. }
  1775. ULONG
  1776. DbgKdComTransport::ReadPacketLeader(
  1777. IN ULONG PacketType,
  1778. OUT PULONG PacketLeader
  1779. )
  1780. {
  1781. DWORD BytesRead;
  1782. BOOL rc;
  1783. USHORT Index;
  1784. UCHAR DataByte, PreviousDataByte;
  1785. Index = 0;
  1786. do
  1787. {
  1788. if (m_BreakIn)
  1789. {
  1790. if (PacketType == PACKET_TYPE_KD_STATE_CHANGE64)
  1791. {
  1792. WriteBreakInPacket();
  1793. return DBGKD_WAIT_RESYNC;
  1794. }
  1795. }
  1796. if (m_Resync)
  1797. {
  1798. m_Resync = FALSE;
  1799. KdOut(" Resync packet id ...");
  1800. Synchronize();
  1801. KdOut(" Done.\n");
  1802. FlushCallbacks();
  1803. return DBGKD_WAIT_RESYNC;
  1804. }
  1805. if (g_EngStatus & ENG_STATUS_EXIT_CURRENT_WAIT)
  1806. {
  1807. KdOut("Packet read interrupted by exit request\n");
  1808. return DBGKD_WAIT_FAILED;
  1809. }
  1810. FlushCallbacks();
  1811. rc = Read(&DataByte, 1, &BytesRead);
  1812. if (rc && BytesRead == 1 &&
  1813. ( DataByte == PACKET_LEADER_BYTE ||
  1814. DataByte == CONTROL_PACKET_LEADER_BYTE))
  1815. {
  1816. if ( Index == 0 )
  1817. {
  1818. PreviousDataByte = DataByte;
  1819. Index++;
  1820. }
  1821. else if ( DataByte == PreviousDataByte )
  1822. {
  1823. Index++;
  1824. }
  1825. else
  1826. {
  1827. PreviousDataByte = DataByte;
  1828. Index = 1;
  1829. }
  1830. }
  1831. else
  1832. {
  1833. Index = 0;
  1834. if (BytesRead == 0)
  1835. {
  1836. KdOut("READ: Timeout.\n");
  1837. FlushCallbacks();
  1838. if (m_AllowInitialBreak &&
  1839. (g_EngOptions & DEBUG_ENGOPT_INITIAL_BREAK))
  1840. {
  1841. KdOut("Attempting to get initial breakpoint.\n");
  1842. WriteBreakInPacket();
  1843. }
  1844. return DBGKD_WAIT_FAILED;
  1845. }
  1846. }
  1847. } while ( Index < 2 );
  1848. if ( DataByte != CONTROL_PACKET_LEADER_BYTE )
  1849. {
  1850. *PacketLeader = PACKET_LEADER;
  1851. }
  1852. else
  1853. {
  1854. *PacketLeader = CONTROL_PACKET_LEADER;
  1855. }
  1856. return DBGKD_WAIT_PACKET;
  1857. }
  1858. void
  1859. DbgKdComTransport::CheckComStatus(void)
  1860. /*++
  1861. Routine Description:
  1862. Called when the com port status trigger signals a change.
  1863. This function handles the change in status.
  1864. Note: status is only monitored when being used over the modem.
  1865. --*/
  1866. {
  1867. DWORD status;
  1868. BOOL rc;
  1869. ULONG br, bw;
  1870. CHAR buf[128];
  1871. DWORD CommErr;
  1872. COMSTAT CommStat;
  1873. ULONG Len;
  1874. if (!m_ComEvent)
  1875. {
  1876. //
  1877. // Not triggered, just return
  1878. //
  1879. return;
  1880. }
  1881. // This should succeed since we were just notified,
  1882. // but check the return value to keep PREfix happy.
  1883. if (!GetCommModemStatus(m_Handle, &status))
  1884. {
  1885. // Leave m_ComEvent set for another try.
  1886. return;
  1887. }
  1888. m_ComEvent = 0;
  1889. if (!(status & 0x80))
  1890. {
  1891. dprintf ("No carrier detect - in terminal mode\n");
  1892. // This routine can be called during a wait when the
  1893. // engine lock isn't held and can also be called when
  1894. // the lock is held. RESUME handles both of these
  1895. // cases so that the lock is reacquired or reentered.
  1896. RESUME_ENGINE();
  1897. //
  1898. // Loop and read any com input
  1899. //
  1900. while (!(status & 0x80))
  1901. {
  1902. //
  1903. // Get some input to send to the modem.
  1904. //
  1905. Len = GetInput("Term> ", buf, sizeof(buf));
  1906. if (Len > 0)
  1907. {
  1908. Write(buf, Len, &Len);
  1909. buf[0] = '\n';
  1910. buf[1] = '\r';
  1911. Write(buf, 2, &Len);
  1912. }
  1913. GetCommModemStatus (m_Handle, &status);
  1914. rc = Read(buf, sizeof buf, &br);
  1915. if (rc != TRUE || br == 0)
  1916. {
  1917. continue;
  1918. }
  1919. //
  1920. // print the string.
  1921. //
  1922. dprintf("%s", buf);
  1923. FlushCallbacks();
  1924. //
  1925. // if logging is on, log the output
  1926. //
  1927. if (g_LogFile != -1)
  1928. {
  1929. _write(g_LogFile, buf, br);
  1930. }
  1931. }
  1932. dprintf ("Carrier detect - returning to debugger\n");
  1933. FlushCallbacks();
  1934. ClearCommError (
  1935. m_Handle,
  1936. &CommErr,
  1937. &CommStat
  1938. );
  1939. SUSPEND_ENGINE();
  1940. }
  1941. else
  1942. {
  1943. CommErr = 0;
  1944. ClearCommError (
  1945. m_Handle,
  1946. &CommErr,
  1947. &CommStat
  1948. );
  1949. if (CommErr & CE_FRAME)
  1950. {
  1951. dprintf (" [FRAME ERR] ");
  1952. }
  1953. if (CommErr & CE_OVERRUN)
  1954. {
  1955. dprintf (" [OVERRUN ERR] ");
  1956. }
  1957. if (CommErr & CE_RXPARITY)
  1958. {
  1959. dprintf (" [PARITY ERR] ");
  1960. }
  1961. }
  1962. //
  1963. // Reset trigger
  1964. //
  1965. WaitCommEvent (m_Handle, &m_ComEvent, &m_EventOverlapped);
  1966. }
  1967. //----------------------------------------------------------------------------
  1968. //
  1969. // DbgKd1394Transport.
  1970. //
  1971. //----------------------------------------------------------------------------
  1972. #define PARAM_1394_CHANNEL "Channel"
  1973. #define ENV_1394_CHANNEL "_NT_DEBUG_1394_CHANNEL"
  1974. DbgKd1394Transport::DbgKd1394Transport(void)
  1975. {
  1976. m_Index = DBGKD_TRANSPORT_1394;
  1977. m_Name = g_DbgKdTransportNames[m_Index];
  1978. m_InvPacketRetryLimit = 3;
  1979. m_AckWrites = FALSE;
  1980. }
  1981. ULONG
  1982. DbgKd1394Transport::GetNumberParameters(void)
  1983. {
  1984. return 1;
  1985. }
  1986. void
  1987. DbgKd1394Transport::GetParameter(ULONG Index, PSTR Name, PSTR Value)
  1988. {
  1989. switch(Index)
  1990. {
  1991. case 0:
  1992. strcpy(Name, PARAM_1394_CHANNEL);
  1993. sprintf(Value, "%d", m_Channel);
  1994. break;
  1995. }
  1996. }
  1997. void
  1998. DbgKd1394Transport::ResetParameters(void)
  1999. {
  2000. PSTR Env;
  2001. if ((Env = getenv(ENV_1394_CHANNEL)) == NULL)
  2002. {
  2003. m_Channel = 0;
  2004. }
  2005. else
  2006. {
  2007. m_Channel = atol(Env);
  2008. }
  2009. }
  2010. BOOL
  2011. DbgKd1394Transport::SetParameter(PCSTR Name, PCSTR Value)
  2012. {
  2013. if (!_strcmpi(Name, PARAM_1394_CHANNEL))
  2014. {
  2015. m_Channel = atol(Value);
  2016. }
  2017. else
  2018. {
  2019. ErrOut("1394 port parameters: %s is not a valid parameter\n", Name);
  2020. return FALSE;
  2021. }
  2022. return TRUE;
  2023. }
  2024. HRESULT
  2025. DbgKd1394Transport::Initialize(void)
  2026. {
  2027. char Name[64];
  2028. HRESULT Status;
  2029. dprintf("Using 1394 for debugging\n");
  2030. if ((Status = DbgKdTransport::Initialize()) != S_OK)
  2031. {
  2032. return Status;
  2033. }
  2034. m_DirectPhysicalMemory = TRUE;
  2035. Status = Create1394Channel(m_Channel, Name, &m_Handle);
  2036. if (Status != S_OK)
  2037. {
  2038. ErrOut("Failed to open 1394 channel %d\n", m_Channel);
  2039. ErrOut("If this is the first time KD was run, this is"
  2040. " why this failed.\nVirtual 1394 "
  2041. "Debugger Driver Installation will now be attempted\n");
  2042. return Status;
  2043. }
  2044. else
  2045. {
  2046. dprintf("Opened %s\n", Name);
  2047. }
  2048. //
  2049. // put the virtual driver in the right operating mode..
  2050. //
  2051. if (!SwitchVirtualDebuggerDriverMode(V1394DBG_API_CONFIGURATION_MODE_DEBUG)) {
  2052. return FALSE;
  2053. }
  2054. return S_OK;
  2055. }
  2056. void
  2057. DbgKd1394Transport::Uninitialize(void)
  2058. {
  2059. if (m_Handle != NULL)
  2060. {
  2061. CloseHandle(m_Handle);
  2062. m_Handle = NULL;
  2063. }
  2064. DbgKdTransport::Uninitialize();
  2065. }
  2066. BOOL
  2067. DbgKd1394Transport::Read(
  2068. IN PVOID Buffer,
  2069. IN ULONG SizeOfBuffer,
  2070. IN PULONG BytesRead
  2071. )
  2072. {
  2073. BOOL rc;
  2074. DWORD TrashErr;
  2075. COMSTAT TrashStat;
  2076. if (IS_DUMP_TARGET())
  2077. {
  2078. ErrOut( "Attempted to read KD transport while "
  2079. "debugging a crash dump\n" );
  2080. DebugBreak();
  2081. }
  2082. if (!SwitchVirtualDebuggerDriverMode(V1394DBG_API_CONFIGURATION_MODE_DEBUG)) {
  2083. return FALSE;
  2084. }
  2085. rc = ReadFile(
  2086. m_Handle,
  2087. Buffer,
  2088. SizeOfBuffer,
  2089. BytesRead,
  2090. &m_ReadOverlapped
  2091. );
  2092. if (!rc)
  2093. {
  2094. if (GetLastError() == ERROR_IO_PENDING)
  2095. {
  2096. rc = GetOverlappedResult(m_Handle,
  2097. &m_ReadOverlapped,
  2098. BytesRead,
  2099. TRUE);
  2100. }
  2101. else
  2102. {
  2103. // Prevent looping on read errors from
  2104. // burning 100% of the CPU.
  2105. Sleep(50);
  2106. }
  2107. }
  2108. if (rc)
  2109. {
  2110. m_BytesRead += *BytesRead;
  2111. }
  2112. return rc;
  2113. }
  2114. BOOL
  2115. DbgKd1394Transport::Write(
  2116. IN PVOID Buffer,
  2117. IN ULONG SizeOfBuffer,
  2118. IN PULONG BytesWritten
  2119. )
  2120. {
  2121. BOOL rc;
  2122. DWORD TrashErr;
  2123. COMSTAT TrashStat;
  2124. if (IS_DUMP_TARGET())
  2125. {
  2126. ErrOut( "Attempted to write KD transport "
  2127. "while debugging a crash dump\n" );
  2128. DebugBreak();
  2129. }
  2130. if (!SwitchVirtualDebuggerDriverMode(V1394DBG_API_CONFIGURATION_MODE_DEBUG)) {
  2131. return FALSE;
  2132. }
  2133. rc = WriteFile(
  2134. m_Handle,
  2135. Buffer,
  2136. SizeOfBuffer,
  2137. BytesWritten,
  2138. &m_WriteOverlapped
  2139. );
  2140. if (!rc)
  2141. {
  2142. if (GetLastError() == ERROR_IO_PENDING)
  2143. {
  2144. rc = GetOverlappedResult(m_Handle,
  2145. &m_WriteOverlapped,
  2146. BytesWritten,
  2147. TRUE);
  2148. }
  2149. }
  2150. if (rc)
  2151. {
  2152. m_BytesWritten += *BytesWritten;
  2153. }
  2154. return rc;
  2155. }
  2156. HRESULT
  2157. DbgKd1394Transport::ReadTargetPhysicalMemory(
  2158. IN ULONG64 MemoryOffset,
  2159. IN PVOID Buffer,
  2160. IN ULONG SizeofBuffer,
  2161. IN PULONG BytesRead
  2162. )
  2163. {
  2164. DWORD dwRet, dwBytesRet;
  2165. PV1394DBG_API_REQUEST pApiReq;
  2166. if (IS_DUMP_TARGET())
  2167. {
  2168. ErrOut( "Attempted to access KD transport while "
  2169. "debugging a crash dump\n" );
  2170. DebugBreak();
  2171. }
  2172. //
  2173. // first setup the read i/o parameters in the virtual driver
  2174. //
  2175. pApiReq = (PV1394DBG_API_REQUEST)
  2176. LocalAlloc(LPTR, sizeof(V1394DBG_API_REQUEST));
  2177. if (pApiReq == NULL)
  2178. {
  2179. return E_OUTOFMEMORY;
  2180. }
  2181. //
  2182. // if the virtual driver is not set in raw access mode, we need to
  2183. // tell it to change modes..
  2184. //
  2185. if (!SwitchVirtualDebuggerDriverMode(V1394DBG_API_CONFIGURATION_MODE_RAW_MEMORY_ACCESS)) {
  2186. LocalFree(pApiReq);
  2187. return E_UNEXPECTED;
  2188. }
  2189. pApiReq->RequestNumber = V1394DBG_API_SET_IO_PARAMETERS;
  2190. pApiReq->Flags = V1394DBG_API_FLAG_READ_IO;
  2191. pApiReq->u.SetIoParameters.fulFlags = 0;
  2192. pApiReq->u.SetIoParameters.StartingMemoryOffset.QuadPart = MemoryOffset;
  2193. dwRet = DeviceIoControl( m_Handle,
  2194. IOCTL_V1394DBG_API_REQUEST,
  2195. pApiReq,
  2196. sizeof(V1394DBG_API_REQUEST),
  2197. NULL,
  2198. 0,
  2199. &dwBytesRet,
  2200. NULL
  2201. );
  2202. if (!dwRet)
  2203. {
  2204. dwRet = GetLastError();
  2205. ErrOut("Failed to send SetIoParameters 1394 "
  2206. "Virtual Driver Request, error %x\n",dwRet);
  2207. LocalFree(pApiReq);
  2208. return E_UNEXPECTED;
  2209. }
  2210. LocalFree(pApiReq);
  2211. //
  2212. // now do anormal read. The virtual driver will read SizeofBuffer bytes
  2213. // starting at the remote PCs physical address we specified above
  2214. //
  2215. dwRet = ReadFile(
  2216. m_Handle,
  2217. Buffer,
  2218. SizeofBuffer,
  2219. BytesRead,
  2220. &m_ReadOverlapped
  2221. );
  2222. if (!dwRet)
  2223. {
  2224. if (GetLastError() == ERROR_IO_PENDING)
  2225. {
  2226. dwRet = GetOverlappedResult(m_Handle,
  2227. &m_ReadOverlapped,
  2228. BytesRead,
  2229. TRUE);
  2230. }
  2231. }
  2232. return (dwRet != 0) ? S_OK : E_UNEXPECTED;
  2233. }
  2234. BOOL
  2235. DbgKd1394Transport::SwitchVirtualDebuggerDriverMode(
  2236. IN ULONG DesiredOperationMode
  2237. )
  2238. {
  2239. DWORD dwRet, dwBytesRet;
  2240. PV1394DBG_API_REQUEST pApiReq;
  2241. //
  2242. // if the virtual driver is not set in raw access mode, we need to
  2243. // tell it to change modes..
  2244. //
  2245. if (m_OperationMode != DesiredOperationMode) {
  2246. //
  2247. // first setup the read i/o parameters in the virtual driver
  2248. //
  2249. pApiReq = (PV1394DBG_API_REQUEST)
  2250. LocalAlloc(LPTR, sizeof(V1394DBG_API_REQUEST));
  2251. if (pApiReq == NULL)
  2252. {
  2253. return FALSE;
  2254. }
  2255. pApiReq->RequestNumber = V1394DBG_API_SET_CONFIGURATION;
  2256. pApiReq->Flags = 0;
  2257. pApiReq->u.SetConfiguration.OperationMode = DesiredOperationMode;
  2258. dwRet = DeviceIoControl( m_Handle,
  2259. IOCTL_V1394DBG_API_REQUEST,
  2260. pApiReq,
  2261. sizeof(V1394DBG_API_REQUEST),
  2262. NULL,
  2263. 0,
  2264. &dwBytesRet,
  2265. NULL
  2266. );
  2267. if (!dwRet)
  2268. {
  2269. dwRet = GetLastError();
  2270. ErrOut("Failed to send SetConfiguration 1394 "
  2271. "Virtual Driver Request, error %x\n", dwRet);
  2272. LocalFree(pApiReq);
  2273. return FALSE;
  2274. }
  2275. m_OperationMode = DesiredOperationMode;
  2276. LocalFree(pApiReq);
  2277. }
  2278. return TRUE;
  2279. }
  2280. VOID
  2281. DbgKd1394Transport::Synchronize(VOID)
  2282. {
  2283. ULONG Index;
  2284. ULONG BytesRead;
  2285. BOOL rc;
  2286. // XXX drewb - Why is this code disabled?
  2287. return;
  2288. Index = 3;
  2289. while (TRUE)
  2290. {
  2291. if (g_EngStatus & ENG_STATUS_EXIT_CURRENT_WAIT)
  2292. {
  2293. KdOut("Synchronize interrupted by exit request\n");
  2294. return;
  2295. }
  2296. WriteControlPacket(PACKET_TYPE_KD_RESET, 0L);
  2297. FlushCallbacks();
  2298. rc = Read(s_Packet, sizeof(s_Packet), &BytesRead);
  2299. CopyMemory(&s_PacketHeader, &s_Packet[0], sizeof(KD_PACKET));
  2300. if (rc && (BytesRead >= sizeof(s_PacketHeader)))
  2301. {
  2302. if (s_PacketHeader.PacketType == PACKET_TYPE_KD_RESET)
  2303. {
  2304. break;
  2305. }
  2306. }
  2307. if (!Index--)
  2308. {
  2309. break;
  2310. }
  2311. }
  2312. }
  2313. ULONG
  2314. DbgKd1394Transport::ReadPacketContents(IN USHORT PacketType)
  2315. {
  2316. DWORD BytesRead;
  2317. BOOL rc;
  2318. UCHAR DataByte;
  2319. ULONG Checksum;
  2320. WaitForPacket1394:
  2321. if (m_AllowInitialBreak && (g_EngOptions & DEBUG_ENGOPT_INITIAL_BREAK))
  2322. {
  2323. KdOut("Attempting to get initial breakpoint.\n");
  2324. WriteBreakInPacket();
  2325. m_AllowInitialBreak = FALSE;
  2326. }
  2327. if (m_Resync)
  2328. {
  2329. m_Resync = FALSE;
  2330. KdOut(" Resync packet id ...");
  2331. Synchronize();
  2332. KdOut(" Done.\n");
  2333. FlushCallbacks();
  2334. return DBGKD_WAIT_RESYNC;
  2335. }
  2336. if (m_BreakIn)
  2337. {
  2338. WriteBreakInPacket();
  2339. return DBGKD_WAIT_RESYNC;
  2340. }
  2341. if (g_EngStatus & ENG_STATUS_EXIT_CURRENT_WAIT)
  2342. {
  2343. KdOut("Packet read interrupted by exit request\n");
  2344. return DBGKD_WAIT_FAILED;
  2345. }
  2346. FlushCallbacks();
  2347. //
  2348. // read the whole packet at once.
  2349. // we try to read MAX_PACKET worth of data and then check how much
  2350. // we really read. Also since the packet header (KD_PACKET) is part of what
  2351. // we read, we later have to move the data packet back sizeof(KD_PACKET)
  2352. //
  2353. rc = Read(s_Packet, sizeof(s_Packet), &BytesRead);
  2354. CopyMemory(&s_PacketHeader, &s_Packet[0], sizeof(KD_PACKET));
  2355. if (!rc || (BytesRead < sizeof(s_PacketHeader)))
  2356. {
  2357. if (!rc)
  2358. {
  2359. KdOut("READ: Error %x.\n",GetLastError());
  2360. }
  2361. else
  2362. {
  2363. KdOut("READ: Data ByteCount error (short read) %x, %x.\n",
  2364. BytesRead, sizeof(s_PacketHeader));
  2365. }
  2366. if (rc && (BytesRead >= sizeof(s_PacketHeader)) )
  2367. {
  2368. if (s_PacketHeader.PacketLeader == PACKET_LEADER)
  2369. {
  2370. WriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
  2371. KdOut("READ: Data packet header "
  2372. "ByteCount error (short read).\n");
  2373. }
  2374. }
  2375. goto WaitForPacket1394;
  2376. }
  2377. //
  2378. // move data portion to start of packet.
  2379. //
  2380. MoveMemory(s_Packet, ((PUCHAR)s_Packet + sizeof(KD_PACKET)),
  2381. BytesRead - sizeof(KD_PACKET));
  2382. //
  2383. // Check the Packet type.
  2384. //
  2385. if ((g_KdMaxPacketType == 0 &&
  2386. s_PacketHeader.PacketType >= PACKET_TYPE_MAX) ||
  2387. (g_KdMaxPacketType > 0 &&
  2388. s_PacketHeader.PacketType >= g_KdMaxPacketType))
  2389. {
  2390. KdOut("READ: Received INVALID packet type.\n");
  2391. if (s_PacketHeader.PacketLeader == PACKET_LEADER)
  2392. {
  2393. return DBGKD_WAIT_RESEND;
  2394. }
  2395. return DBGKD_WAIT_FAILED;
  2396. }
  2397. KdOut(" PacketType=%x, ", s_PacketHeader.PacketType);
  2398. //
  2399. // Check ByteCount
  2400. //
  2401. if (s_PacketHeader.ByteCount > PACKET_MAX_SIZE )
  2402. {
  2403. if (s_PacketHeader.PacketLeader == PACKET_LEADER)
  2404. {
  2405. KdOut("READ: Data packet header ByteCount error (short read).\n");
  2406. return DBGKD_WAIT_RESEND;
  2407. }
  2408. return DBGKD_WAIT_FAILED;
  2409. }
  2410. KdOut("ByteCount=%x, PacketId=%x,\n",
  2411. s_PacketHeader.ByteCount,
  2412. s_PacketHeader.PacketId);
  2413. if (s_PacketHeader.ByteCount != (BytesRead - sizeof(s_PacketHeader)))
  2414. {
  2415. if (s_PacketHeader.PacketLeader == PACKET_LEADER)
  2416. {
  2417. KdOut("READ: Data packet header ByteCount error (short read).\n");
  2418. return DBGKD_WAIT_RESEND;
  2419. }
  2420. return DBGKD_WAIT_FAILED;
  2421. }
  2422. //
  2423. // Make sure the checksum is valid.
  2424. //
  2425. Checksum = ComputeChecksum(s_Packet, s_PacketHeader.ByteCount);
  2426. if (Checksum != s_PacketHeader.Checksum)
  2427. {
  2428. KdOut("READ: Checksum error.\n");
  2429. return DBGKD_WAIT_RESEND;
  2430. }
  2431. if (s_PacketHeader.PacketLeader == CONTROL_PACKET_LEADER)
  2432. {
  2433. if (s_PacketHeader.PacketType == PACKET_TYPE_KD_RESET)
  2434. {
  2435. //
  2436. // if we received Reset packet, reset the packet control variables
  2437. // and resend earlier packet.
  2438. //
  2439. m_NextPacketToSend = INITIAL_PACKET_ID;
  2440. m_PacketExpected = INITIAL_PACKET_ID;
  2441. WriteControlPacket(PACKET_TYPE_KD_RESET, 0L);
  2442. KdOut("DbgKdpWaitForPacket(): "
  2443. "Recieved KD_RESET packet, send KD_RESET ACK packet\n");
  2444. FlushCallbacks();
  2445. return DBGKD_WAIT_FAILED;
  2446. }
  2447. else if (s_PacketHeader.PacketType == PACKET_TYPE_KD_RESEND)
  2448. {
  2449. KdOut("READ: Received RESEND packet\n");
  2450. FlushCallbacks();
  2451. return DBGKD_WAIT_FAILED;
  2452. }
  2453. else
  2454. {
  2455. //
  2456. // Invalid packet header, ignore it.
  2457. //
  2458. KdOut("READ: Received Control packet with UNKNOWN type\n");
  2459. FlushCallbacks();
  2460. return DBGKD_WAIT_FAILED;
  2461. }
  2462. }
  2463. //
  2464. // we are waiting for data packet and we received the packet header
  2465. // for data packet. Perform the following checkings to make sure
  2466. // it is the packet we are waiting for.
  2467. //
  2468. KdOut("READ: Received Type %x data packet with id = %lx successfully.\n\n",
  2469. s_PacketHeader.PacketType, s_PacketHeader.PacketId);
  2470. return DBGKD_WAIT_PACKET;
  2471. }
  2472. ULONG
  2473. DbgKd1394Transport::WritePacketContents(IN KD_PACKET* Packet,
  2474. IN PVOID PacketData,
  2475. IN USHORT PacketDataLength,
  2476. IN PVOID MorePacketData OPTIONAL,
  2477. IN USHORT MorePacketDataLength OPTIONAL,
  2478. IN BOOL NoAck)
  2479. {
  2480. BOOL rc;
  2481. ULONG BytesWritten;
  2482. PUCHAR Tx;
  2483. // Lock to ensure only one thread is using
  2484. // the transmit buffer.
  2485. RESUME_ENGINE();
  2486. //
  2487. // On 1394 we double buffer all packet segments into one contigious
  2488. // buffer and write it all at once
  2489. //
  2490. Tx = m_TxPacket;
  2491. memcpy(Tx, Packet, sizeof(*Packet));
  2492. Tx += sizeof(*Packet);
  2493. memcpy(Tx, PacketData, PacketDataLength);
  2494. Tx += PacketDataLength;
  2495. if ( ARGUMENT_PRESENT(MorePacketData) )
  2496. {
  2497. memcpy(Tx, MorePacketData, MorePacketDataLength);
  2498. Tx += MorePacketDataLength;
  2499. }
  2500. //
  2501. // The 1394 Debug protocol does not use trailer bytes
  2502. //
  2503. //
  2504. // Write the whole packet out to the bus
  2505. //
  2506. do
  2507. {
  2508. rc = Write(&m_TxPacket[0], (ULONG)(Tx - m_TxPacket), &BytesWritten);
  2509. }
  2510. while ((!rc) || (BytesWritten != (ULONG)(Tx - m_TxPacket)));
  2511. SUSPEND_ENGINE();
  2512. return DBGKD_WRITE_PACKET;
  2513. }
  2514. //----------------------------------------------------------------------------
  2515. //
  2516. // Functions.
  2517. //
  2518. //----------------------------------------------------------------------------
  2519. #define BUS_TYPE "_NT_DEBUG_BUS"
  2520. #define DBG_BUS1394_NAME "1394"
  2521. HRESULT
  2522. DbgKdConnectAndInitialize(PCSTR Options)
  2523. {
  2524. DbgKdTransport* Trans = NULL;
  2525. ULONG Index;
  2526. // Try and find the transport by name.
  2527. Index = ParameterStringParser::
  2528. GetParser(Options, DBGKD_TRANSPORT_COUNT, g_DbgKdTransportNames);
  2529. if (Index < DBGKD_TRANSPORT_COUNT)
  2530. {
  2531. switch(Index)
  2532. {
  2533. case DBGKD_TRANSPORT_COM:
  2534. Trans = &g_DbgKdComTransport;
  2535. break;
  2536. case DBGKD_TRANSPORT_1394:
  2537. Trans = &g_DbgKd1394Transport;
  2538. break;
  2539. }
  2540. }
  2541. if (Trans == NULL)
  2542. {
  2543. PCHAR BusType;
  2544. // Couldn't identify the transport from options so check
  2545. // the environment.
  2546. // Default to com port.
  2547. Trans = &g_DbgKdComTransport;
  2548. if (BusType = getenv(BUS_TYPE))
  2549. {
  2550. if (strstr(BusType, DBG_BUS1394_NAME))
  2551. {
  2552. Trans = &g_DbgKd1394Transport;
  2553. }
  2554. }
  2555. }
  2556. HRESULT Status;
  2557. // Clear parameter state.
  2558. Trans->ResetParameters();
  2559. if (!Trans->ParseParameters(Options))
  2560. {
  2561. Status = E_INVALIDARG;
  2562. }
  2563. else
  2564. {
  2565. Status = Trans->Initialize();
  2566. if (Status != S_OK)
  2567. {
  2568. ErrOut("Kernel Debugger failed initialization, 0x%X\n", Status);
  2569. }
  2570. }
  2571. if (Status == S_OK)
  2572. {
  2573. g_DbgKdTransport = Trans;
  2574. Trans->Restart();
  2575. }
  2576. return Status;
  2577. }
  2578. VOID
  2579. DbgKdpPrint(
  2580. IN ULONG Processor,
  2581. IN PCSTR String,
  2582. IN USHORT StringLength,
  2583. IN ULONG Mask
  2584. )
  2585. {
  2586. DWORD i;
  2587. DWORD j;
  2588. CHAR c;
  2589. PSTR d;
  2590. DBG_ASSERT(StringLength < PACKET_MAX_SIZE - 2);
  2591. // This routine can be called during a wait when the
  2592. // engine lock isn't held and can also be called when
  2593. // the lock is held. RESUME handles both of these
  2594. // cases so that the lock is reacquired or reentered.
  2595. RESUME_ENGINE();
  2596. if (g_TargetNumberProcessors > 1 && Processor != g_LastProcessorToPrint)
  2597. {
  2598. g_LastProcessorToPrint = Processor;
  2599. MaskOut(Mask, "%d:", Processor);
  2600. }
  2601. StartOutLine(Mask, OUT_LINE_NO_PREFIX);
  2602. //
  2603. // Add the original data to the print buffer.
  2604. //
  2605. d = g_PrintBuf;
  2606. for (i = 0; i < StringLength ; i++)
  2607. {
  2608. c = *(String + i);
  2609. if ( c == '\n' )
  2610. {
  2611. g_LastProcessorToPrint = -1;
  2612. *d++ = '\n';
  2613. *d++ = '\r';
  2614. }
  2615. else
  2616. {
  2617. if ( c )
  2618. {
  2619. *d++ = c;
  2620. }
  2621. }
  2622. }
  2623. j = (DWORD)(d - g_PrintBuf);
  2624. //
  2625. // print the string.
  2626. //
  2627. MaskOut(Mask, "%*.*s", j, j, g_PrintBuf);
  2628. SUSPEND_ENGINE();
  2629. }
  2630. VOID
  2631. DbgKdpHandlePromptString(
  2632. IN PDBGKD_DEBUG_IO IoMessage
  2633. )
  2634. {
  2635. PSTR IoData;
  2636. DWORD j;
  2637. // This routine can be called during a wait when the
  2638. // engine lock isn't held and can also be called when
  2639. // the lock is held. RESUME handles both of these
  2640. // cases so that the lock is reacquired or reentered.
  2641. RESUME_ENGINE();
  2642. IoData = (PSTR)(IoMessage + 1);
  2643. DbgKdpPrint(IoMessage->Processor,
  2644. IoData,
  2645. (USHORT)IoMessage->u.GetString.LengthOfPromptString,
  2646. DEBUG_OUTPUT_DEBUGGEE_PROMPT
  2647. );
  2648. //
  2649. // read the prompt data
  2650. //
  2651. j = GetInput(NULL, IoData,
  2652. IoMessage->u.GetString.LengthOfStringRead);
  2653. if (j == 0)
  2654. {
  2655. j = IoMessage->u.GetString.LengthOfStringRead;
  2656. memset(IoData, 0, j);
  2657. }
  2658. g_LastProcessorToPrint = -1;
  2659. if ( j < (USHORT)IoMessage->u.GetString.LengthOfStringRead )
  2660. {
  2661. IoMessage->u.GetString.LengthOfStringRead = j;
  2662. }
  2663. //
  2664. // Log the user's input
  2665. //
  2666. if (g_LogFile != -1)
  2667. {
  2668. _write(g_LogFile, IoData, j);
  2669. _write(g_LogFile, "\n", 1);
  2670. }
  2671. SUSPEND_ENGINE();
  2672. //
  2673. // Send data to the debugger-target
  2674. //
  2675. g_DbgKdTransport->WritePacket(IoMessage, sizeof(*IoMessage),
  2676. PACKET_TYPE_KD_DEBUG_IO,
  2677. IoData,
  2678. (USHORT)IoMessage->
  2679. u.GetString.LengthOfStringRead);
  2680. }
  2681. VOID
  2682. DbgKdpPrintTrace(
  2683. IN ULONG Processor,
  2684. IN PUCHAR Data,
  2685. IN USHORT DataLength,
  2686. IN ULONG Mask
  2687. )
  2688. {
  2689. // This routine can be called during a wait when the
  2690. // engine lock isn't held and can also be called when
  2691. // the lock is held. RESUME handles both of these
  2692. // cases so that the lock is reacquired or reentered.
  2693. RESUME_ENGINE();
  2694. DebugClient* Client;
  2695. // Find a client with output callbacks to use for output.
  2696. for (Client = g_Clients; Client != NULL; Client = Client->m_Next)
  2697. {
  2698. if (Client->m_OutputCb != NULL)
  2699. {
  2700. break;
  2701. }
  2702. }
  2703. if (Client == NULL)
  2704. {
  2705. // No clients have output callbacks so nobody
  2706. // cares about output and we can just quit.
  2707. goto Exit;
  2708. }
  2709. // Prefix the entire output block with the processor
  2710. // number as we can't (and don't want to) get involved
  2711. // in the individual messages.
  2712. if (g_TargetNumberProcessors > 1 && Processor != g_LastProcessorToPrint)
  2713. {
  2714. g_LastProcessorToPrint = Processor;
  2715. MaskOut(Mask, "%d", Processor);
  2716. }
  2717. if (g_WmiFormatTraceData == NULL)
  2718. {
  2719. AddExtensionDll("wmikd.dll", FALSE, NULL);
  2720. }
  2721. if (g_WmiFormatTraceData == NULL)
  2722. {
  2723. ErrOut("Missing or incorrect wmikd.dll - "
  2724. "0x%X byte trace data buffer ignored\n",
  2725. DataLength);
  2726. }
  2727. else
  2728. {
  2729. g_WmiFormatTraceData((PDEBUG_CONTROL)(IDebugControlN*)Client,
  2730. Mask, DataLength, Data);
  2731. }
  2732. Exit:
  2733. SUSPEND_ENGINE();
  2734. }