| 563 | } |
| 564 | |
| 565 | Service::Status getServiceStatus(SC_HANDLE s, const QString& name) |
| 566 | { |
| 567 | DWORD needed = 0; |
| 568 | |
| 569 | if (!QueryServiceStatusEx(s, SC_STATUS_PROCESS_INFO, NULL, 0, &needed)) { |
| 570 | const auto e = GetLastError(); |
| 571 | |
| 572 | if (e != ERROR_INSUFFICIENT_BUFFER) { |
| 573 | log::error("QueryServiceStatusEx() for size for '{}' failed, {}", name, |
| 574 | GetLastError()); |
| 575 | |
| 576 | return Service::Status::None; |
| 577 | } |
| 578 | } |
| 579 | |
| 580 | const auto size = needed; |
| 581 | MallocPtr<SERVICE_STATUS_PROCESS> status( |
| 582 | static_cast<SERVICE_STATUS_PROCESS*>(std::malloc(size))); |
| 583 | |
| 584 | const auto r = QueryServiceStatusEx( |
| 585 | s, SC_STATUS_PROCESS_INFO, reinterpret_cast<BYTE*>(status.get()), size, &needed); |
| 586 | |
| 587 | if (!r) { |
| 588 | const auto e = GetLastError(); |
| 589 | |
| 590 | log::error("QueryServiceStatusEx() failed for '{}', {}", name, |
| 591 | formatSystemMessage(e)); |
| 592 | |
| 593 | return Service::Status::None; |
| 594 | } |
| 595 | |
| 596 | switch (status->dwCurrentState) { |
| 597 | case SERVICE_START_PENDING: // fall-through |
| 598 | case SERVICE_CONTINUE_PENDING: |
| 599 | case SERVICE_RUNNING: { |
| 600 | return Service::Status::Running; |
| 601 | } |
| 602 | |
| 603 | case SERVICE_STOPPED: // fall-through |
| 604 | case SERVICE_STOP_PENDING: |
| 605 | case SERVICE_PAUSE_PENDING: |
| 606 | case SERVICE_PAUSED: { |
| 607 | return Service::Status::Stopped; |
| 608 | } |
| 609 | |
| 610 | default: { |
| 611 | log::error("unknown service status {} for '{}'", status->dwCurrentState, name); |
| 612 | |
| 613 | return Service::Status::None; |
| 614 | } |
| 615 | } |
| 616 | } |
| 617 | |
| 618 | Service getService(const QString& name) |
| 619 | { |