This source file includes following definitions.
- Apply
- InjectSas
- InjectSas
- Create
#include "remoting/host/sas_injector.h"
#include <windows.h>
#include <string>
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/scoped_native_library.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/registry.h"
#include "base/win/windows_version.h"
#include "third_party/webrtc/modules/desktop_capture/win/desktop.h"
#include "third_party/webrtc/modules/desktop_capture/win/scoped_thread_desktop.h"
namespace remoting {
namespace {
const base::FilePath::CharType kSasDllFileName[] = FILE_PATH_LITERAL("sas.dll");
const char kSendSasName[] = "SendSAS";
typedef VOID (WINAPI *SendSasFunc)(BOOL);
const wchar_t kSystemPolicyKeyName[] =
L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
const wchar_t kSoftwareSasValueName[] = L"SoftwareSASGeneration";
const DWORD kEnableSoftwareSasByServices = 1;
class ScopedSoftwareSasPolicy {
public:
ScopedSoftwareSasPolicy();
~ScopedSoftwareSasPolicy();
bool Apply();
private:
base::win::RegKey system_policy_;
bool restore_policy_;
DISALLOW_COPY_AND_ASSIGN(ScopedSoftwareSasPolicy);
};
ScopedSoftwareSasPolicy::ScopedSoftwareSasPolicy()
: restore_policy_(false) {
}
ScopedSoftwareSasPolicy::~ScopedSoftwareSasPolicy() {
if (restore_policy_) {
LONG result = system_policy_.DeleteValue(kSoftwareSasValueName);
if (result != ERROR_SUCCESS) {
SetLastError(result);
LOG_GETLASTERROR(ERROR)
<< "Failed to restore the software SAS generation policy";
}
}
}
bool ScopedSoftwareSasPolicy::Apply() {
LONG result = system_policy_.Open(HKEY_LOCAL_MACHINE,
kSystemPolicyKeyName,
KEY_QUERY_VALUE | KEY_SET_VALUE |
KEY_WOW64_64KEY);
if (result != ERROR_SUCCESS) {
SetLastError(result);
LOG_GETLASTERROR(ERROR) << "Failed to open 'HKLM\\"
<< kSystemPolicyKeyName << "'";
return false;
}
bool custom_policy = system_policy_.HasValue(kSoftwareSasValueName);
if (!custom_policy) {
result = system_policy_.WriteValue(kSoftwareSasValueName,
kEnableSoftwareSasByServices);
if (result != ERROR_SUCCESS) {
SetLastError(result);
LOG_GETLASTERROR(ERROR)
<< "Failed to enable software SAS generation by services";
return false;
} else {
restore_policy_ = true;
}
}
return true;
}
}
class SasInjectorWin : public SasInjector {
public:
SasInjectorWin();
virtual ~SasInjectorWin();
virtual bool InjectSas() OVERRIDE;
private:
base::ScopedNativeLibrary sas_dll_;
SendSasFunc send_sas_;
};
class SasInjectorXp : public SasInjector {
public:
SasInjectorXp();
virtual ~SasInjectorXp();
virtual bool InjectSas() OVERRIDE;
};
SasInjectorWin::SasInjectorWin() : send_sas_(NULL) {
}
SasInjectorWin::~SasInjectorWin() {
}
bool SasInjectorWin::InjectSas() {
if (!sas_dll_.is_valid()) {
base::FilePath dir_path;
if (!PathService::Get(base::DIR_EXE, &dir_path)) {
LOG(ERROR) << "Failed to get the executable file name.";
return false;
}
sas_dll_.Reset(base::LoadNativeLibrary(dir_path.Append(kSasDllFileName),
NULL));
}
if (!sas_dll_.is_valid()) {
LOG(ERROR) << "Failed to load '" << kSasDllFileName << "'";
return false;
}
if (send_sas_ == NULL) {
send_sas_ = static_cast<SendSasFunc>(
sas_dll_.GetFunctionPointer(kSendSasName));
}
if (send_sas_ == NULL) {
LOG(ERROR) << "Failed to retrieve the address of '" << kSendSasName
<< "()'";
return false;
}
ScopedSoftwareSasPolicy enable_sas;
if (!enable_sas.Apply())
return false;
(*send_sas_)(FALSE);
return true;
}
SasInjectorXp::SasInjectorXp() {
}
SasInjectorXp::~SasInjectorXp() {
}
bool SasInjectorXp::InjectSas() {
const wchar_t kWinlogonDesktopName[] = L"Winlogon";
const wchar_t kSasWindowClassName[] = L"SAS window class";
const wchar_t kSasWindowTitle[] = L"SAS window";
scoped_ptr<webrtc::Desktop> winlogon_desktop(
webrtc::Desktop::GetDesktop(kWinlogonDesktopName));
if (!winlogon_desktop.get()) {
LOG_GETLASTERROR(ERROR)
<< "Failed to open '" << kWinlogonDesktopName << "' desktop";
return false;
}
webrtc::ScopedThreadDesktop desktop;
if (!desktop.SetThreadDesktop(winlogon_desktop.release())) {
LOG_GETLASTERROR(ERROR)
<< "Failed to switch to '" << kWinlogonDesktopName << "' desktop";
return false;
}
HWND window = FindWindow(kSasWindowClassName, kSasWindowTitle);
if (!window) {
LOG_GETLASTERROR(ERROR)
<< "Failed to find '" << kSasWindowTitle << "' window";
return false;
}
if (PostMessage(window,
WM_HOTKEY,
0,
MAKELONG(MOD_ALT | MOD_CONTROL, VK_DELETE)) == 0) {
LOG_GETLASTERROR(ERROR)
<< "Failed to post WM_HOTKEY message";
return false;
}
return true;
}
scoped_ptr<SasInjector> SasInjector::Create() {
if (base::win::GetVersion() < base::win::VERSION_VISTA) {
return scoped_ptr<SasInjector>(new SasInjectorXp());
} else {
return scoped_ptr<SasInjector>(new SasInjectorWin());
}
}
}