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