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 "webrtc/modules/desktop_capture/win/desktop.h" 12 13 #include <vector> 14 15 #include "webrtc/system_wrappers/include/logging.h" 16 17 namespace webrtc { 18 19 Desktop::Desktop(HDESK desktop, bool own) : desktop_(desktop), own_(own) { 20 } 21 22 Desktop::~Desktop() { 23 if (own_ && desktop_ != NULL) { 24 if (!::CloseDesktop(desktop_)) { 25 LOG(LS_ERROR) << "Failed to close the owned desktop handle: " 26 << GetLastError(); 27 } 28 } 29 } 30 31 bool Desktop::GetName(std::wstring* desktop_name_out) const { 32 if (desktop_ == NULL) 33 return false; 34 35 DWORD length = 0; 36 int rv = GetUserObjectInformationW(desktop_, UOI_NAME, NULL, 0, &length); 37 if (rv || GetLastError() != ERROR_INSUFFICIENT_BUFFER) 38 abort(); 39 40 length /= sizeof(WCHAR); 41 std::vector<WCHAR> buffer(length); 42 if (!GetUserObjectInformationW(desktop_, UOI_NAME, &buffer[0], 43 length * sizeof(WCHAR), &length)) { 44 LOG(LS_ERROR) << "Failed to query the desktop name: " << GetLastError(); 45 return false; 46 } 47 48 desktop_name_out->assign(&buffer[0], length / sizeof(WCHAR)); 49 return true; 50 } 51 52 bool Desktop::IsSame(const Desktop& other) const { 53 std::wstring name; 54 if (!GetName(&name)) 55 return false; 56 57 std::wstring other_name; 58 if (!other.GetName(&other_name)) 59 return false; 60 61 return name == other_name; 62 } 63 64 bool Desktop::SetThreadDesktop() const { 65 if (!::SetThreadDesktop(desktop_)) { 66 LOG(LS_ERROR) << "Failed to assign the desktop to the current thread: " 67 << GetLastError(); 68 return false; 69 } 70 71 return true; 72 } 73 74 Desktop* Desktop::GetDesktop(const WCHAR* desktop_name) { 75 ACCESS_MASK desired_access = 76 DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | 77 DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | 78 DESKTOP_SWITCHDESKTOP | GENERIC_WRITE; 79 HDESK desktop = OpenDesktop(desktop_name, 0, FALSE, desired_access); 80 if (desktop == NULL) { 81 LOG(LS_ERROR) << "Failed to open the desktop '" << desktop_name << "': " 82 << GetLastError(); 83 return NULL; 84 } 85 86 return new Desktop(desktop, true); 87 } 88 89 Desktop* Desktop::GetInputDesktop() { 90 HDESK desktop = OpenInputDesktop( 91 0, FALSE, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE); 92 if (desktop == NULL) 93 return NULL; 94 95 return new Desktop(desktop, true); 96 } 97 98 Desktop* Desktop::GetThreadDesktop() { 99 HDESK desktop = ::GetThreadDesktop(GetCurrentThreadId()); 100 if (desktop == NULL) { 101 LOG(LS_ERROR) << "Failed to retrieve the handle of the desktop assigned to " 102 "the current thread: " 103 << GetLastError(); 104 return NULL; 105 } 106 107 return new Desktop(desktop, false); 108 } 109 110 } // namespace webrtc 111