15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/host/sas_injector.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/scoped_native_library.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/registry.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/webrtc/modules/desktop_capture/win/desktop.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/webrtc/modules/desktop_capture/win/scoped_thread_desktop.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Names of the API and library implementing software SAS generation.
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType kSasDllFileName[] = FILE_PATH_LITERAL("sas.dll");
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSendSasName[] = "SendSAS";
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The prototype of SendSAS().
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef VOID (WINAPI *SendSasFunc)(BOOL);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The registry key and value holding the policy controlling software SAS
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// generation.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kSystemPolicyKeyName[] =
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kSoftwareSasValueName[] = L"SoftwareSASGeneration";
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const DWORD kEnableSoftwareSasByServices = 1;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Toggles the default software SAS generation policy to enable SAS generation
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// by services. Non-default policy is not changed.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ScopedSoftwareSasPolicy {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedSoftwareSasPolicy();
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ScopedSoftwareSasPolicy();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Apply();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The handle of the registry key were SoftwareSASGeneration policy is stored.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::RegKey system_policy_;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if the policy needs to be restored.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool restore_policy_;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedSoftwareSasPolicy);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedSoftwareSasPolicy::ScopedSoftwareSasPolicy()
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : restore_policy_(false) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedSoftwareSasPolicy::~ScopedSoftwareSasPolicy() {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restore the default policy by deleting the value that we have set.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (restore_policy_) {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LONG result = system_policy_.DeleteValue(kSoftwareSasValueName);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (result != ERROR_SUCCESS) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetLastError(result);
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      PLOG(ERROR) << "Failed to restore the software SAS generation policy";
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ScopedSoftwareSasPolicy::Apply() {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Query the currently set SoftwareSASGeneration policy.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LONG result = system_policy_.Open(HKEY_LOCAL_MACHINE,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    kSystemPolicyKeyName,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    KEY_QUERY_VALUE | KEY_SET_VALUE |
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        KEY_WOW64_64KEY);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result != ERROR_SUCCESS) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetLastError(result);
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PLOG(ERROR) << "Failed to open 'HKLM\\" << kSystemPolicyKeyName << "'";
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool custom_policy = system_policy_.HasValue(kSoftwareSasValueName);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Override the default policy (i.e. there is no value in the registry) only.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!custom_policy) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = system_policy_.WriteValue(kSoftwareSasValueName,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       kEnableSoftwareSasByServices);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (result != ERROR_SUCCESS) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetLastError(result);
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      PLOG(ERROR) << "Failed to enable software SAS generation by services";
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      restore_policy_ = true;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sends Secure Attention Sequence using the SendSAS() function from sas.dll.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This library is shipped starting from Win7/W2K8 R2 only. However Win7 SDK
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// includes a redistributable verion of the same library that works on
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Vista/W2K8. We install the latter along with our binaries.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SasInjectorWin : public SasInjector {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SasInjectorWin();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SasInjectorWin();
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SasInjector implementation.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool InjectSas() OVERRIDE;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ScopedNativeLibrary sas_dll_;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendSasFunc send_sas_;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Emulates Secure Attention Sequence (Ctrl+Alt+Del) by switching to
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the Winlogon desktop and injecting Ctrl+Alt+Del as a hot key.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// N.B. Windows XP/W2K3 only.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SasInjectorXp : public SasInjector {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SasInjectorXp();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SasInjectorXp();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SasInjector implementation.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool InjectSas() OVERRIDE;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SasInjectorWin::SasInjectorWin() : send_sas_(NULL) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SasInjectorWin::~SasInjectorWin() {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SasInjectorWin::InjectSas() {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load sas.dll. The library is expected to be in the same folder as this
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // binary.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!sas_dll_.is_valid()) {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath dir_path;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!PathService::Get(base::DIR_EXE, &dir_path)) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to get the executable file name.";
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sas_dll_.Reset(base::LoadNativeLibrary(dir_path.Append(kSasDllFileName),
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           NULL));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!sas_dll_.is_valid()) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to load '" << kSasDllFileName << "'";
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the pointer to sas!SendSAS().
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (send_sas_ == NULL) {
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    send_sas_ = reinterpret_cast<SendSasFunc>(
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sas_dll_.GetFunctionPointer(kSendSasName));
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (send_sas_ == NULL) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to retrieve the address of '" << kSendSasName
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << "()'";
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable software SAS generation by services and send SAS. SAS can still fail
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // if the policy does not allow services to generate software SAS.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedSoftwareSasPolicy enable_sas;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!enable_sas.Apply())
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*send_sas_)(FALSE);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SasInjectorXp::SasInjectorXp() {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SasInjectorXp::~SasInjectorXp() {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SasInjectorXp::InjectSas() {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t kWinlogonDesktopName[] = L"Winlogon";
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t kSasWindowClassName[] = L"SAS window class";
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t kSasWindowTitle[] = L"SAS window";
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<webrtc::Desktop> winlogon_desktop(
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      webrtc::Desktop::GetDesktop(kWinlogonDesktopName));
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!winlogon_desktop.get()) {
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PLOG(ERROR) << "Failed to open '" << kWinlogonDesktopName << "' desktop";
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  webrtc::ScopedThreadDesktop desktop;
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!desktop.SetThreadDesktop(winlogon_desktop.release())) {
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PLOG(ERROR) << "Failed to switch to '" << kWinlogonDesktopName
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                << "' desktop";
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HWND window = FindWindow(kSasWindowClassName, kSasWindowTitle);
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!window) {
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PLOG(ERROR) << "Failed to find '" << kSasWindowTitle << "' window";
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (PostMessage(window,
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  WM_HOTKEY,
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  0,
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  MAKELONG(MOD_ALT | MOD_CONTROL, VK_DELETE)) == 0) {
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PLOG(ERROR) << "Failed to post WM_HOTKEY message";
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<SasInjector> SasInjector::Create() {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::win::GetVersion() < base::win::VERSION_VISTA) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return scoped_ptr<SasInjector>(new SasInjectorXp());
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return scoped_ptr<SasInjector>(new SasInjectorWin());
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting
230