13d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org/* 23d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 33d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org * 43d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org * Use of this source code is governed by a BSD-style license 53d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org * that can be found in the LICENSE file in the root of the source 63d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org * tree. An additional intellectual property rights grant can be found 73d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org * in the file PATENTS. All contributing project authors may 83d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org * be found in the AUTHORS file in the root of the source tree. 93d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org */ 103d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 113d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org#include "webrtc/modules/desktop_capture/win/desktop.h" 123d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 133d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org#include <vector> 143d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 1598f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/logging.h" 163d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 173d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgnamespace webrtc { 183d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 193d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgDesktop::Desktop(HDESK desktop, bool own) : desktop_(desktop), own_(own) { 203d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org} 213d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 223d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgDesktop::~Desktop() { 233d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org if (own_ && desktop_ != NULL) { 243d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org if (!::CloseDesktop(desktop_)) { 253d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org LOG(LS_ERROR) << "Failed to close the owned desktop handle: " 263d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org << GetLastError(); 273d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org } 283d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org } 293d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org} 303d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 313d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgbool Desktop::GetName(std::wstring* desktop_name_out) const { 323d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org if (desktop_ == NULL) 333d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org return false; 343d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 353d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org DWORD length = 0; 363d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org int rv = GetUserObjectInformationW(desktop_, UOI_NAME, NULL, 0, &length); 373d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org if (rv || GetLastError() != ERROR_INSUFFICIENT_BUFFER) 383d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org abort(); 393d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 403d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org length /= sizeof(WCHAR); 413d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org std::vector<WCHAR> buffer(length); 423d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org if (!GetUserObjectInformationW(desktop_, UOI_NAME, &buffer[0], 433d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org length * sizeof(WCHAR), &length)) { 443d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org LOG(LS_ERROR) << "Failed to query the desktop name: " << GetLastError(); 453d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org return false; 463d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org } 473d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 483d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org desktop_name_out->assign(&buffer[0], length / sizeof(WCHAR)); 493d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org return true; 503d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org} 513d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 523d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgbool Desktop::IsSame(const Desktop& other) const { 533d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org std::wstring name; 543d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org if (!GetName(&name)) 553d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org return false; 563d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 573d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org std::wstring other_name; 583d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org if (!other.GetName(&other_name)) 593d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org return false; 603d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 613d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org return name == other_name; 623d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org} 633d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 643d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgbool Desktop::SetThreadDesktop() const { 653d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org if (!::SetThreadDesktop(desktop_)) { 663d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org LOG(LS_ERROR) << "Failed to assign the desktop to the current thread: " 673d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org << GetLastError(); 683d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org return false; 693d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org } 703d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 713d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org return true; 723d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org} 733d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 743d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgDesktop* Desktop::GetDesktop(const WCHAR* desktop_name) { 753d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org ACCESS_MASK desired_access = 763d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | 773d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | 783d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org DESKTOP_SWITCHDESKTOP | GENERIC_WRITE; 793d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org HDESK desktop = OpenDesktop(desktop_name, 0, FALSE, desired_access); 803d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org if (desktop == NULL) { 813d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org LOG(LS_ERROR) << "Failed to open the desktop '" << desktop_name << "': " 823d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org << GetLastError(); 833d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org return NULL; 843d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org } 853d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 863d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org return new Desktop(desktop, true); 873d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org} 883d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 893d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgDesktop* Desktop::GetInputDesktop() { 903d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org HDESK desktop = OpenInputDesktop( 913d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 0, FALSE, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE); 923d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org if (desktop == NULL) 933d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org return NULL; 943d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 953d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org return new Desktop(desktop, true); 963d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org} 973d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 983d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgDesktop* Desktop::GetThreadDesktop() { 993d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org HDESK desktop = ::GetThreadDesktop(GetCurrentThreadId()); 1003d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org if (desktop == NULL) { 1013d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org LOG(LS_ERROR) << "Failed to retrieve the handle of the desktop assigned to " 1023d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org "the current thread: " 1033d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org << GetLastError(); 1043d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org return NULL; 1053d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org } 1063d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 1073d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org return new Desktop(desktop, false); 1083d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org} 1093d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org 1103d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org} // namespace webrtc 111