desktop.cc (3254B)
1 /* 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "modules/desktop_capture/win/desktop.h" 12 13 #include <cstddef> 14 #include <string> 15 #include <vector> 16 17 #include "rtc_base/logging.h" 18 #include "rtc_base/string_utils.h" 19 20 namespace webrtc { 21 22 Desktop::Desktop(HDESK desktop, bool own) : desktop_(desktop), own_(own) {} 23 24 Desktop::~Desktop() { 25 if (own_ && desktop_ != NULL) { 26 if (!::CloseDesktop(desktop_)) { 27 RTC_LOG(LS_ERROR) << "Failed to close the owned desktop handle: " 28 << GetLastError(); 29 } 30 } 31 } 32 33 bool Desktop::GetName(std::wstring* desktop_name_out) const { 34 if (desktop_ == NULL) 35 return false; 36 37 DWORD length = 0; 38 int rv = GetUserObjectInformationW(desktop_, UOI_NAME, NULL, 0, &length); 39 if (rv || GetLastError() != ERROR_INSUFFICIENT_BUFFER) 40 abort(); 41 42 length /= sizeof(WCHAR); 43 std::vector<WCHAR> buffer(length); 44 if (!GetUserObjectInformationW(desktop_, UOI_NAME, &buffer[0], 45 length * sizeof(WCHAR), &length)) { 46 RTC_LOG(LS_ERROR) << "Failed to query the desktop name: " << GetLastError(); 47 return false; 48 } 49 50 desktop_name_out->assign(&buffer[0], length / sizeof(WCHAR)); 51 return true; 52 } 53 54 bool Desktop::IsSame(const Desktop& other) const { 55 std::wstring name; 56 if (!GetName(&name)) 57 return false; 58 59 std::wstring other_name; 60 if (!other.GetName(&other_name)) 61 return false; 62 63 return name == other_name; 64 } 65 66 bool Desktop::SetThreadDesktop() const { 67 if (!::SetThreadDesktop(desktop_)) { 68 RTC_LOG(LS_ERROR) << "Failed to assign the desktop to the current thread: " 69 << GetLastError(); 70 return false; 71 } 72 73 return true; 74 } 75 76 Desktop* Desktop::GetDesktop(const WCHAR* desktop_name) { 77 ACCESS_MASK desired_access = DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | 78 DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | 79 DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | 80 DESKTOP_SWITCHDESKTOP | GENERIC_WRITE; 81 HDESK desktop = OpenDesktopW(desktop_name, 0, FALSE, desired_access); 82 if (desktop == NULL) { 83 RTC_LOG(LS_ERROR) << "Failed to open the desktop '" << ToUtf8(desktop_name) 84 << "': " << GetLastError(); 85 return NULL; 86 } 87 88 return new Desktop(desktop, true); 89 } 90 91 Desktop* Desktop::GetInputDesktop() { 92 HDESK desktop = OpenInputDesktop( 93 0, FALSE, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE); 94 if (desktop == NULL) 95 return NULL; 96 97 return new Desktop(desktop, true); 98 } 99 100 Desktop* Desktop::GetThreadDesktop() { 101 HDESK desktop = ::GetThreadDesktop(GetCurrentThreadId()); 102 if (desktop == NULL) { 103 RTC_LOG(LS_ERROR) 104 << "Failed to retrieve the handle of the desktop assigned to " 105 "the current thread: " 106 << GetLastError(); 107 return NULL; 108 } 109 110 return new Desktop(desktop, false); 111 } 112 113 } // namespace webrtc