Pipe Reader Thread: Process Client
| 107 | |
| 108 | // Pipe Reader Thread: Process Client |
| 109 | void DllReaderClientThread(PipeServer* pipeServer) { |
| 110 | // Use RAII to ensure cleanup |
| 111 | std::unique_ptr<PipeServer> server(pipeServer); |
| 112 | |
| 113 | if (!server) { |
| 114 | LOG_A(LOG_ERROR, "DllReaderClientThread: pipeServer is null"); |
| 115 | return; |
| 116 | } |
| 117 | |
| 118 | try { |
| 119 | // send config as first packet |
| 120 | // this is the only write for this pipe |
| 121 | char config[DLL_CONFIG_LEN]; |
| 122 | int result = sprintf_s(config, DLL_CONFIG_LEN, "callstack: %d; ", g_Config.do_dllinjection_ucallstack ? 1 : 0); |
| 123 | if (result < 0) { |
| 124 | LOG_A(LOG_ERROR, "DllReaderClientThread: Failed to format config string"); |
| 125 | return; |
| 126 | } |
| 127 | |
| 128 | if (!server->Send(config)) { |
| 129 | LOG_A(LOG_ERROR, "DllReaderClientThread: Failed to send config"); |
| 130 | return; |
| 131 | } |
| 132 | |
| 133 | // Now receive only |
| 134 | while (WaitForSingleObject(hStopEventDll, 0) != WAIT_OBJECT_0) { |
| 135 | std::vector<std::string> results = server->ReceiveBatch(); |
| 136 | if (results.empty()) { |
| 137 | break; // Client disconnected or error |
| 138 | } |
| 139 | for (const auto& result : results) { |
| 140 | if (!result.empty()) { |
| 141 | g_EventAggregator.NewEvent(result); |
| 142 | } |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | catch (const std::exception& e) { |
| 147 | LOG_A(LOG_ERROR, "DllReaderClientThread: Exception in client processing: %s", e.what()); |
| 148 | } |
| 149 | catch (...) { |
| 150 | LOG_A(LOG_ERROR, "DllReaderClientThread: Unknown exception in client processing"); |
| 151 | } |
| 152 | |
| 153 | server->Shutdown(); |
| 154 | // server automatically deleted when unique_ptr goes out of scope |
| 155 | } |
| 156 | |
| 157 | |
| 158 | // Shutdown |