| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "printing/backend/spooler_win.h" |
| |
| #include <windows.h> |
| #include <winspool.h> |
| #include <winsvc.h> |
| |
| #include "base/logging.h" |
| #include "base/win/scoped_handle.h" |
| |
| namespace printing::internal { |
| |
| namespace { |
| |
| class ScHandleTraits { |
| public: |
| typedef SC_HANDLE Handle; |
| |
| ScHandleTraits() = delete; |
| ScHandleTraits(const ScHandleTraits&) = delete; |
| ScHandleTraits& operator=(const ScHandleTraits&) = delete; |
| |
| static bool CloseHandle(SC_HANDLE handle) { |
| return ::CloseServiceHandle(handle) != FALSE; |
| } |
| |
| static bool IsHandleValid(SC_HANDLE handle) { return handle != nullptr; } |
| |
| static SC_HANDLE NullHandle() { return nullptr; } |
| }; |
| |
| typedef base::win::GenericScopedHandle<ScHandleTraits, |
| base::win::DummyVerifierTraits> |
| ScopedScHandle; |
| |
| } // namespace |
| |
| SpoolerServiceStatus IsSpoolerRunning() { |
| ScopedScHandle scm_handle( |
| ::OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT)); |
| if (!scm_handle.IsValid()) { |
| LOG(ERROR) << "Unable to connect to Windows Service Control Manager"; |
| return SpoolerServiceStatus::kUnknown; |
| } |
| |
| ScopedScHandle sc_handle( |
| ::OpenService(scm_handle.Get(), L"Spooler", SERVICE_QUERY_STATUS)); |
| if (!sc_handle.IsValid()) { |
| LOG(ERROR) << "Unable to open Windows print spooler service"; |
| return SpoolerServiceStatus::kUnknown; |
| } |
| |
| SERVICE_STATUS service_status; |
| if (!::QueryServiceStatus(sc_handle.Get(), &service_status)) { |
| LOG(ERROR) << "Unable to open Windows print spooler service"; |
| return SpoolerServiceStatus::kUnknown; |
| } |
| |
| return service_status.dwCurrentState == SERVICE_RUNNING |
| ? SpoolerServiceStatus::kRunning |
| : SpoolerServiceStatus::kNotRunning; |
| } |
| |
| } // namespace printing::internal |