/* * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "webrtc/modules/desktop_capture/win/desktop.h" #include #include "webrtc/system_wrappers/interface/logging.h" namespace webrtc { Desktop::Desktop(HDESK desktop, bool own) : desktop_(desktop), own_(own) { } Desktop::~Desktop() { if (own_ && desktop_ != NULL) { if (!::CloseDesktop(desktop_)) { LOG(LS_ERROR) << "Failed to close the owned desktop handle: " << GetLastError(); } } } bool Desktop::GetName(std::wstring* desktop_name_out) const { if (desktop_ == NULL) return false; DWORD length = 0; int rv = GetUserObjectInformationW(desktop_, UOI_NAME, NULL, 0, &length); if (rv || GetLastError() != ERROR_INSUFFICIENT_BUFFER) abort(); length /= sizeof(WCHAR); std::vector buffer(length); if (!GetUserObjectInformationW(desktop_, UOI_NAME, &buffer[0], length * sizeof(WCHAR), &length)) { LOG(LS_ERROR) << "Failed to query the desktop name: " << GetLastError(); return false; } desktop_name_out->assign(&buffer[0], length / sizeof(WCHAR)); return true; } bool Desktop::IsSame(const Desktop& other) const { std::wstring name; if (!GetName(&name)) return false; std::wstring other_name; if (!other.GetName(&other_name)) return false; return name == other_name; } bool Desktop::SetThreadDesktop() const { if (!::SetThreadDesktop(desktop_)) { LOG(LS_ERROR) << "Failed to assign the desktop to the current thread: " << GetLastError(); return false; } return true; } Desktop* Desktop::GetDesktop(const WCHAR* desktop_name) { ACCESS_MASK desired_access = DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE; HDESK desktop = OpenDesktop(desktop_name, 0, FALSE, desired_access); if (desktop == NULL) { LOG(LS_ERROR) << "Failed to open the desktop '" << desktop_name << "': " << GetLastError(); return NULL; } return new Desktop(desktop, true); } Desktop* Desktop::GetInputDesktop() { HDESK desktop = OpenInputDesktop( 0, FALSE, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE); if (desktop == NULL) return NULL; return new Desktop(desktop, true); } Desktop* Desktop::GetThreadDesktop() { HDESK desktop = ::GetThreadDesktop(GetCurrentThreadId()); if (desktop == NULL) { LOG(LS_ERROR) << "Failed to retrieve the handle of the desktop assigned to " "the current thread: " << GetLastError(); return NULL; } return new Desktop(desktop, false); } } // namespace webrtc