Leaked source code of windows server 2003
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.

3807 lines
100 KiB

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