* @brief Windows implementation of the named-pipe read loop. */
| 576 | * @brief Windows implementation of the named-pipe read loop. |
| 577 | */ |
| 578 | void IO::Drivers::Process::pipeReadLoopWindows() |
| 579 | { |
| 580 | #ifdef Q_OS_WIN |
| 581 | const QString dosPath = QDir::toNativeSeparators(m_pipePath); |
| 582 | HANDLE hPipe = CreateNamedPipeW(reinterpret_cast<LPCWSTR>(dosPath.utf16()), |
| 583 | PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, |
| 584 | PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, |
| 585 | 1, |
| 586 | 0, |
| 587 | 4096, |
| 588 | 0, |
| 589 | nullptr); |
| 590 | |
| 591 | if (hPipe == INVALID_HANDLE_VALUE) { |
| 592 | QMetaObject::invokeMethod(this, "onPipeError", Qt::QueuedConnection); |
| 593 | return; |
| 594 | } |
| 595 | |
| 596 | OVERLAPPED ov{}; |
| 597 | ov.hEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr); |
| 598 | ConnectNamedPipe(hPipe, &ov); |
| 599 | |
| 600 | bool connected = (GetLastError() == ERROR_PIPE_CONNECTED); |
| 601 | while (!connected && m_pipeRunning.load()) { |
| 602 | const DWORD rc = WaitForSingleObject(ov.hEvent, 100); |
| 603 | if (rc == WAIT_OBJECT_0) { |
| 604 | connected = true; |
| 605 | break; |
| 606 | } |
| 607 | } |
| 608 | |
| 609 | CloseHandle(ov.hEvent); |
| 610 | |
| 611 | if (!connected) { |
| 612 | CloseHandle(hPipe); |
| 613 | return; |
| 614 | } |
| 615 | |
| 616 | char buf[4096]; |
| 617 | while (m_pipeRunning.load()) { |
| 618 | DWORD avail = 0; |
| 619 | if (!PeekNamedPipe(hPipe, nullptr, 0, nullptr, &avail, nullptr)) |
| 620 | break; |
| 621 | |
| 622 | if (avail == 0) { |
| 623 | ::Sleep(10); |
| 624 | continue; |
| 625 | } |
| 626 | |
| 627 | DWORD bytesRead = 0; |
| 628 | const BOOL ok = ReadFile(hPipe, buf, sizeof(buf), &bytesRead, nullptr); |
| 629 | if (!ok || bytesRead == 0) |
| 630 | break; |
| 631 | |
| 632 | publishReceivedData(QByteArray(buf, static_cast<int>(bytesRead))); |
| 633 | } |
| 634 | |
| 635 | CloseHandle(hPipe); |