OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/sas_injector.h" | 5 #include "remoting/host/sas_injector.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/file_path.h" | 11 #include "base/file_path.h" |
12 #include "base/path_service.h" | 12 #include "base/path_service.h" |
13 #include "base/scoped_native_library.h" | 13 #include "base/scoped_native_library.h" |
14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
15 #include "base/win/registry.h" | 15 #include "base/win/registry.h" |
16 #include "base/win/windows_version.h" | 16 #include "base/win/windows_version.h" |
17 #include "remoting/host/win/desktop.h" | |
18 #include "remoting/host/win/scoped_thread_desktop.h" | |
17 | 19 |
18 namespace remoting { | 20 namespace remoting { |
19 | 21 |
20 namespace { | 22 namespace { |
21 | 23 |
22 // Names of the API and library implementing software SAS generation. | 24 // Names of the API and library implementing software SAS generation. |
23 const FilePath::CharType kSasDllFileName[] = | 25 const FilePath::CharType kSasDllFileName[] = FILE_PATH_LITERAL("sas.dll"); |
24 FILE_PATH_LITERAL("sas.dll"); | |
25 const char kSendSasName[] = "SendSAS"; | 26 const char kSendSasName[] = "SendSAS"; |
26 | 27 |
27 // The prototype of SendSAS(). | 28 // The prototype of SendSAS(). |
28 typedef VOID (WINAPI *SendSasFunc)(BOOL); | 29 typedef VOID (WINAPI *SendSasFunc)(BOOL); |
29 | 30 |
30 // The registry key and value holding the policy controlling software SAS | 31 // The registry key and value holding the policy controlling software SAS |
31 // generation. | 32 // generation. |
32 const wchar_t kSystemPolicyKeyName[] = | 33 const wchar_t kSystemPolicyKeyName[] = |
33 L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"; | 34 L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"; |
34 const wchar_t kSoftwareSasValueName[] = L"SoftwareSASGeneration"; | 35 const wchar_t kSoftwareSasValueName[] = L"SoftwareSASGeneration"; |
35 | 36 |
36 const DWORD kEnableSoftwareSasByServices = 1; | 37 const DWORD kEnableSoftwareSasByApps = 2; |
37 | 38 |
38 // Toggles the default software SAS generation policy to enable SAS generation | 39 // Toggles the default software SAS generation policy to enable SAS generation |
39 // by services. Non-default policy is not changed. | 40 // by applications. Non-default policy is not changed. |
40 class ScopedSoftwareSasPolicy { | 41 class ScopedSoftwareSasPolicy { |
41 public: | 42 public: |
42 ScopedSoftwareSasPolicy(); | 43 ScopedSoftwareSasPolicy(); |
43 ~ScopedSoftwareSasPolicy(); | 44 ~ScopedSoftwareSasPolicy(); |
44 | 45 |
45 bool Apply(); | 46 bool Apply(); |
46 | 47 |
47 private: | 48 private: |
48 // The handle of the registry key were SoftwareSASGeneration policy is stored. | 49 // The handle of the registry key were SoftwareSASGeneration policy is stored. |
49 base::win::RegKey system_policy_; | 50 base::win::RegKey system_policy_; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
81 LOG_GETLASTERROR(ERROR) << "Failed to open 'HKLM\\" | 82 LOG_GETLASTERROR(ERROR) << "Failed to open 'HKLM\\" |
82 << kSystemPolicyKeyName << "'"; | 83 << kSystemPolicyKeyName << "'"; |
83 return false; | 84 return false; |
84 } | 85 } |
85 | 86 |
86 bool custom_policy = system_policy_.HasValue(kSoftwareSasValueName); | 87 bool custom_policy = system_policy_.HasValue(kSoftwareSasValueName); |
87 | 88 |
88 // Override the default policy (i.e. there is no value in the registry) only. | 89 // Override the default policy (i.e. there is no value in the registry) only. |
89 if (!custom_policy) { | 90 if (!custom_policy) { |
90 result = system_policy_.WriteValue(kSoftwareSasValueName, | 91 result = system_policy_.WriteValue(kSoftwareSasValueName, |
91 kEnableSoftwareSasByServices); | 92 kEnableSoftwareSasByApps); |
92 if (result != ERROR_SUCCESS) { | 93 if (result != ERROR_SUCCESS) { |
93 SetLastError(result); | 94 SetLastError(result); |
94 LOG_GETLASTERROR(ERROR) | 95 LOG_GETLASTERROR(ERROR) |
95 << "Failed to enable software SAS generation by services"; | 96 << "Failed to enable software SAS generation by services"; |
96 return false; | 97 return false; |
97 } else { | 98 } else { |
98 restore_policy_ = true; | 99 restore_policy_ = true; |
99 } | 100 } |
100 } | 101 } |
101 | 102 |
(...skipping 12 matching lines...) Expand all Loading... | |
114 virtual ~SasInjectorWin(); | 115 virtual ~SasInjectorWin(); |
115 | 116 |
116 // SasInjector implementation. | 117 // SasInjector implementation. |
117 virtual bool InjectSas() OVERRIDE; | 118 virtual bool InjectSas() OVERRIDE; |
118 | 119 |
119 private: | 120 private: |
120 base::ScopedNativeLibrary sas_dll_; | 121 base::ScopedNativeLibrary sas_dll_; |
121 SendSasFunc send_sas_; | 122 SendSasFunc send_sas_; |
122 }; | 123 }; |
123 | 124 |
125 // Emulates Secure Attention Sequence (Ctrl+Alt+Del) by switching to | |
126 // the Winlogon desktop and injecting Ctrl+Alt+Del as a hot key. | |
127 // N.B. Windows XP/W2K3 only. | |
128 class SasInjectorXp : public SasInjector { | |
129 public: | |
130 SasInjectorXp(); | |
131 virtual ~SasInjectorXp(); | |
132 | |
133 // SasInjector implementation. | |
134 virtual bool InjectSas() OVERRIDE; | |
135 }; | |
136 | |
124 SasInjectorWin::SasInjectorWin() : send_sas_(NULL) { | 137 SasInjectorWin::SasInjectorWin() : send_sas_(NULL) { |
125 } | 138 } |
126 | 139 |
127 SasInjectorWin::~SasInjectorWin() { | 140 SasInjectorWin::~SasInjectorWin() { |
128 } | 141 } |
129 | 142 |
130 bool SasInjectorWin::InjectSas() { | 143 bool SasInjectorWin::InjectSas() { |
131 // Load sas.dll. The library is expected to be in the same folder as this | 144 // Load sas.dll. The library is expected to be in the same folder as this |
132 // binary. | 145 // binary. |
133 if (!sas_dll_.is_valid()) { | 146 if (!sas_dll_.is_valid()) { |
(...skipping 16 matching lines...) Expand all Loading... | |
150 send_sas_ = static_cast<SendSasFunc>( | 163 send_sas_ = static_cast<SendSasFunc>( |
151 sas_dll_.GetFunctionPointer(kSendSasName)); | 164 sas_dll_.GetFunctionPointer(kSendSasName)); |
152 } | 165 } |
153 if (send_sas_ == NULL) { | 166 if (send_sas_ == NULL) { |
154 LOG(ERROR) << "Failed to retrieve the address of '" << kSendSasName | 167 LOG(ERROR) << "Failed to retrieve the address of '" << kSendSasName |
155 << "()'"; | 168 << "()'"; |
156 return false; | 169 return false; |
157 } | 170 } |
158 | 171 |
159 // Enable software SAS generation by services and send SAS. SAS can still fail | 172 // Enable software SAS generation by services and send SAS. SAS can still fail |
160 // if the policy does not allow services to generate software SAS. | 173 // if the policy does not allow services to generate software SAS. |
simonmorris
2012/08/14 17:29:59
Does the reference to "services" need updating?
| |
161 ScopedSoftwareSasPolicy enable_sas; | 174 ScopedSoftwareSasPolicy enable_sas; |
162 if (!enable_sas.Apply()) | 175 if (!enable_sas.Apply()) |
163 return false; | 176 return false; |
164 | 177 |
165 (*send_sas_)(FALSE); | 178 (*send_sas_)(TRUE); |
179 return true; | |
180 } | |
181 | |
182 SasInjectorXp::SasInjectorXp() { | |
183 } | |
184 | |
185 SasInjectorXp::~SasInjectorXp() { | |
186 } | |
187 | |
188 bool SasInjectorXp::InjectSas() { | |
189 const wchar_t kWinlogonDesktopName[] = L"Winlogon"; | |
190 const wchar_t kSasWindowClassName[] = L"SAS window class"; | |
191 const wchar_t kSasWindowTitle[] = L"SAS window"; | |
192 | |
193 scoped_ptr<remoting::Desktop> winlogon_desktop( | |
194 remoting::Desktop::GetDesktop(kWinlogonDesktopName)); | |
195 if (!winlogon_desktop.get()) | |
196 return false; | |
197 | |
198 remoting::ScopedThreadDesktop desktop; | |
199 if (!desktop.SetThreadDesktop(winlogon_desktop.Pass())) | |
200 return false; | |
201 | |
202 HWND window = FindWindow(kSasWindowClassName, kSasWindowTitle); | |
203 if (!window) | |
204 return false; | |
205 | |
206 PostMessage(window, | |
207 WM_HOTKEY, | |
208 0, | |
209 MAKELONG(MOD_ALT | MOD_CONTROL, VK_DELETE)); | |
166 return true; | 210 return true; |
167 } | 211 } |
168 | 212 |
169 scoped_ptr<SasInjector> SasInjector::Create() { | 213 scoped_ptr<SasInjector> SasInjector::Create() { |
170 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { | 214 if (base::win::GetVersion() < base::win::VERSION_VISTA) { |
215 return scoped_ptr<SasInjector>(new SasInjectorXp()); | |
216 } else { | |
171 return scoped_ptr<SasInjector>(new SasInjectorWin()); | 217 return scoped_ptr<SasInjector>(new SasInjectorWin()); |
172 } | 218 } |
173 | |
174 return scoped_ptr<SasInjector>(); | |
175 } | 219 } |
176 | 220 |
177 } // namespace remoting | 221 } // namespace remoting |
OLD | NEW |