| 94 | } |
| 95 | |
| 96 | void DbgviewReader::Loop() |
| 97 | { |
| 98 | SetDescription(wstringbuilder() << "Dbgview Agent at " << m_hostname); |
| 99 | m_iostream.connect(m_hostname, SysinternalsDebugViewAgentPort); |
| 100 | const std::string processName("[tcp]"); |
| 101 | |
| 102 | Write<DWORD>(m_iostream, Magic::RequestQueryPerformanceFrequency); |
| 103 | auto qpFrequency = Read<DWORD>(m_iostream); |
| 104 | long long t0 = 0; |
| 105 | bool first = true; |
| 106 | |
| 107 | if (!m_iostream || qpFrequency == 0) |
| 108 | { |
| 109 | LogSource::Add(stringbuilder() << "Unable to connect to " << GetDescription() << ", " << m_iostream.error().message()); |
| 110 | Signal(); |
| 111 | return; |
| 112 | } |
| 113 | |
| 114 | Write<DWORD>(m_iostream, Magic::CaptureKernelEnable); |
| 115 | Write<DWORD>(m_iostream, Magic::VerboseKernelMessagesEnable); |
| 116 | Write<DWORD>(m_iostream, Magic::CaptureWin32Enable); |
| 117 | Write<DWORD>(m_iostream, Magic::PassThroughEnable); |
| 118 | |
| 119 | if (GetAutoNewLine()) |
| 120 | { |
| 121 | Write<DWORD>(m_iostream, Magic::ForceCarriageReturnsEnable); |
| 122 | } |
| 123 | else |
| 124 | { |
| 125 | Write<DWORD>(m_iostream, Magic::ForceCarriageReturnsDisable); |
| 126 | } |
| 127 | |
| 128 | double timerUnit = 1. / qpFrequency; |
| 129 | AddMessage(stringbuilder() << "Connected to " << GetDescription()); |
| 130 | Signal(); |
| 131 | |
| 132 | while (!AtEnd()) |
| 133 | { |
| 134 | m_iostream.clear(); |
| 135 | auto messageLength = Read<DWORD>(m_iostream); |
| 136 | |
| 137 | if (m_iostream.eof()) |
| 138 | { |
| 139 | AddMessage(stringbuilder() << "Connection to " << GetDescription() << " closed."); |
| 140 | LogSource::Abort(); |
| 141 | Signal(); |
| 142 | break; |
| 143 | } |
| 144 | |
| 145 | if (!m_iostream || messageLength >= 0x7fffffff) |
| 146 | { |
| 147 | AddMessage(0, processName, "<error parsing messageLength>"); |
| 148 | Signal(); |
| 149 | break; |
| 150 | } |
| 151 | |
| 152 | if (messageLength == 0) // keep alive |
| 153 | continue; |