Home | History | Annotate | Download | only in win
      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