| Index: remoting/host/sas_injector_win.cc
|
| diff --git a/remoting/host/sas_injector_win.cc b/remoting/host/sas_injector_win.cc
|
| index 0bf453f6a69c63f6d8f7e0e7d00eceb55346561a..3e5bea80aea92cbe8ec4de0d81605ae8d416e827 100644
|
| --- a/remoting/host/sas_injector_win.cc
|
| +++ b/remoting/host/sas_injector_win.cc
|
| @@ -14,14 +14,15 @@
|
| #include "base/utf_string_conversions.h"
|
| #include "base/win/registry.h"
|
| #include "base/win/windows_version.h"
|
| +#include "remoting/host/win/desktop.h"
|
| +#include "remoting/host/win/scoped_thread_desktop.h"
|
|
|
| namespace remoting {
|
|
|
| namespace {
|
|
|
| // Names of the API and library implementing software SAS generation.
|
| -const FilePath::CharType kSasDllFileName[] =
|
| - FILE_PATH_LITERAL("sas.dll");
|
| +const FilePath::CharType kSasDllFileName[] = FILE_PATH_LITERAL("sas.dll");
|
| const char kSendSasName[] = "SendSAS";
|
|
|
| // The prototype of SendSAS().
|
| @@ -33,10 +34,10 @@ const wchar_t kSystemPolicyKeyName[] =
|
| L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
|
| const wchar_t kSoftwareSasValueName[] = L"SoftwareSASGeneration";
|
|
|
| -const DWORD kEnableSoftwareSasByServices = 1;
|
| +const DWORD kEnableSoftwareSasByApps = 2;
|
|
|
| // Toggles the default software SAS generation policy to enable SAS generation
|
| -// by services. Non-default policy is not changed.
|
| +// by applications. Non-default policy is not changed.
|
| class ScopedSoftwareSasPolicy {
|
| public:
|
| ScopedSoftwareSasPolicy();
|
| @@ -88,7 +89,7 @@ bool ScopedSoftwareSasPolicy::Apply() {
|
| // Override the default policy (i.e. there is no value in the registry) only.
|
| if (!custom_policy) {
|
| result = system_policy_.WriteValue(kSoftwareSasValueName,
|
| - kEnableSoftwareSasByServices);
|
| + kEnableSoftwareSasByApps);
|
| if (result != ERROR_SUCCESS) {
|
| SetLastError(result);
|
| LOG_GETLASTERROR(ERROR)
|
| @@ -121,6 +122,18 @@ class SasInjectorWin : public SasInjector {
|
| SendSasFunc send_sas_;
|
| };
|
|
|
| +// Emulates Secure Attention Sequence (Ctrl+Alt+Del) by switching to
|
| +// the Winlogon desktop and injecting Ctrl+Alt+Del as a hot key.
|
| +// N.B. Windows XP/W2K3 only.
|
| +class SasInjectorXp : public SasInjector {
|
| + public:
|
| + SasInjectorXp();
|
| + virtual ~SasInjectorXp();
|
| +
|
| + // SasInjector implementation.
|
| + virtual bool InjectSas() OVERRIDE;
|
| +};
|
| +
|
| SasInjectorWin::SasInjectorWin() : send_sas_(NULL) {
|
| }
|
|
|
| @@ -157,7 +170,7 @@ bool SasInjectorWin::InjectSas() {
|
| }
|
|
|
| // Enable software SAS generation by services and send SAS. SAS can still fail
|
| - // if the policy does not allow services to generate software SAS.
|
| + // if the policy does not allow applications to generate software SAS.
|
| ScopedSoftwareSasPolicy enable_sas;
|
| if (!enable_sas.Apply())
|
| return false;
|
| @@ -166,12 +179,43 @@ bool SasInjectorWin::InjectSas() {
|
| 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<remoting::Desktop> winlogon_desktop(
|
| + remoting::Desktop::GetDesktop(kWinlogonDesktopName));
|
| + if (!winlogon_desktop.get())
|
| + return false;
|
| +
|
| + remoting::ScopedThreadDesktop desktop;
|
| + if (!desktop.SetThreadDesktop(winlogon_desktop.Pass()))
|
| + return false;
|
| +
|
| + HWND window = FindWindow(kSasWindowClassName, kSasWindowTitle);
|
| + if (!window)
|
| + return false;
|
| +
|
| + PostMessage(window,
|
| + WM_HOTKEY,
|
| + 0,
|
| + MAKELONG(MOD_ALT | MOD_CONTROL, VK_DELETE));
|
| + return true;
|
| +}
|
| +
|
| scoped_ptr<SasInjector> SasInjector::Create() {
|
| - if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
|
| + if (base::win::GetVersion() < base::win::VERSION_VISTA) {
|
| + return scoped_ptr<SasInjector>(new SasInjectorXp());
|
| + } else {
|
| return scoped_ptr<SasInjector>(new SasInjectorWin());
|
| }
|
| -
|
| - return scoped_ptr<SasInjector>();
|
| }
|
|
|
| } // namespace remoting
|
|
|