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