Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(408)

Side by Side Diff: remoting/host/session_event_executor_win.cc

Issue 10836224: [Chromoting] Call SendSAS() directly from the host. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased and made it work. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/session_event_executor_win.h" 5 #include "remoting/host/session_event_executor_win.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/compiler_specific.h" 11 #include "base/compiler_specific.h"
12 #include "base/single_thread_task_runner.h" 12 #include "base/single_thread_task_runner.h"
13 #include "base/win/windows_version.h" 13 #include "base/win/windows_version.h"
14 #include "ipc/ipc_channel.h" 14 #include "ipc/ipc_channel.h"
15 #include "ipc/ipc_channel_proxy.h" 15 #include "ipc/ipc_channel_proxy.h"
16 #include "remoting/host/chromoting_messages.h" 16 #include "remoting/host/chromoting_messages.h"
17 #include "remoting/host/sas_injector.h"
17 #include "remoting/host/win/desktop.h" 18 #include "remoting/host/win/desktop.h"
18 #include "remoting/host/win/scoped_thread_desktop.h"
19 #include "remoting/proto/event.pb.h" 19 #include "remoting/proto/event.pb.h"
20 20
21 namespace { 21 namespace {
22 22
23 // The command line switch specifying the name of the Chromoting IPC channel.
24 const char kProcessChannelId[] = "chromoting-ipc";
25
26 const uint32 kUsbLeftControl = 0x0700e0; 23 const uint32 kUsbLeftControl = 0x0700e0;
27 const uint32 kUsbRightControl = 0x0700e4; 24 const uint32 kUsbRightControl = 0x0700e4;
28 const uint32 kUsbLeftAlt = 0x0700e2; 25 const uint32 kUsbLeftAlt = 0x0700e2;
29 const uint32 kUsbRightAlt = 0x0700e6; 26 const uint32 kUsbRightAlt = 0x0700e6;
30 const uint32 kUsbDelete = 0x07004c; 27 const uint32 kUsbDelete = 0x07004c;
31 28
32 bool CheckCtrlAndAltArePressed(const std::set<uint32>& pressed_keys) { 29 bool CheckCtrlAndAltArePressed(const std::set<uint32>& pressed_keys) {
33 size_t ctrl_keys = pressed_keys.count(kUsbLeftControl) + 30 size_t ctrl_keys = pressed_keys.count(kUsbLeftControl) +
34 pressed_keys.count(kUsbRightControl); 31 pressed_keys.count(kUsbRightControl);
35 size_t alt_keys = pressed_keys.count(kUsbLeftAlt) + 32 size_t alt_keys = pressed_keys.count(kUsbLeftAlt) +
36 pressed_keys.count(kUsbRightAlt); 33 pressed_keys.count(kUsbRightAlt);
37 return ctrl_keys != 0 && alt_keys != 0 && 34 return ctrl_keys != 0 && alt_keys != 0 &&
38 (ctrl_keys + alt_keys == pressed_keys.size()); 35 (ctrl_keys + alt_keys == pressed_keys.size());
39 } 36 }
40 37
41 // Emulates Secure Attention Sequence (Ctrl+Alt+Del) by switching to
42 // the Winlogon desktop and injecting Ctrl+Alt+Del as a hot key.
43 // N.B. Windows XP/W2K3 only.
44 void EmulateSecureAttentionSequence() {
45 const wchar_t kWinlogonDesktopName[] = L"Winlogon";
46 const wchar_t kSasWindowClassName[] = L"SAS window class";
47 const wchar_t kSasWindowTitle[] = L"SAS window";
48
49 scoped_ptr<remoting::Desktop> winlogon_desktop(
50 remoting::Desktop::GetDesktop(kWinlogonDesktopName));
51 if (!winlogon_desktop.get())
52 return;
53
54 remoting::ScopedThreadDesktop desktop;
55 if (!desktop.SetThreadDesktop(winlogon_desktop.Pass()))
56 return;
57
58 HWND window = FindWindow(kSasWindowClassName, kSasWindowTitle);
59 if (!window)
60 return;
61
62 PostMessage(window,
63 WM_HOTKEY,
64 0,
65 MAKELONG(MOD_ALT | MOD_CONTROL, VK_DELETE));
66 }
67
68 } // namespace 38 } // namespace
69 39
70 namespace remoting { 40 namespace remoting {
71 41
72 using protocol::ClipboardEvent; 42 using protocol::ClipboardEvent;
73 using protocol::MouseEvent; 43 using protocol::MouseEvent;
74 using protocol::KeyEvent; 44 using protocol::KeyEvent;
75 45
76 SessionEventExecutorWin::SessionEventExecutorWin( 46 SessionEventExecutorWin::SessionEventExecutorWin(
77 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, 47 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
78 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, 48 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
79 scoped_ptr<EventExecutor> nested_executor) 49 scoped_ptr<EventExecutor> nested_executor)
80 : nested_executor_(nested_executor.Pass()), 50 : nested_executor_(nested_executor.Pass()),
81 task_runner_(main_task_runner), 51 task_runner_(main_task_runner),
82 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), 52 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
83 weak_ptr_(weak_ptr_factory_.GetWeakPtr()) { 53 weak_ptr_(weak_ptr_factory_.GetWeakPtr()) {
84 // Let |weak_ptr_| be used on the |task_runner_| thread. 54 // Let |weak_ptr_| be used on the |task_runner_| thread.
85 // |weak_ptr_| and |weak_ptr_factory_| share a ThreadChecker, so the 55 // |weak_ptr_| and |weak_ptr_factory_| share a ThreadChecker, so the
86 // following line affects both of them. 56 // following line affects both of them.
87 weak_ptr_factory_.DetachFromThread(); 57 weak_ptr_factory_.DetachFromThread();
88
89 std::string channel_name =
90 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(kProcessChannelId);
91
92 // Connect to the Chromoting IPC channel if the name was passed in the command
93 // line.
94 if (!channel_name.empty()) {
95 chromoting_channel_.reset(new IPC::ChannelProxy(
96 channel_name, IPC::Channel::MODE_CLIENT, this, io_task_runner));
97 }
98 } 58 }
99 59
100 SessionEventExecutorWin::~SessionEventExecutorWin() { 60 SessionEventExecutorWin::~SessionEventExecutorWin() {
101 } 61 }
102 62
103 void SessionEventExecutorWin::OnSessionStarted( 63 void SessionEventExecutorWin::OnSessionStarted(
104 scoped_ptr<protocol::ClipboardStub> client_clipboard) { 64 scoped_ptr<protocol::ClipboardStub> client_clipboard) {
105 if (!task_runner_->BelongsToCurrentThread()) { 65 if (!task_runner_->BelongsToCurrentThread()) {
106 task_runner_->PostTask( 66 task_runner_->PostTask(
107 FROM_HERE, 67 FROM_HERE,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 // HostEventDispatcher should drop events lacking the pressed field. 110 // HostEventDispatcher should drop events lacking the pressed field.
151 DCHECK(event.has_pressed()); 111 DCHECK(event.has_pressed());
152 112
153 if (event.has_usb_keycode()) { 113 if (event.has_usb_keycode()) {
154 if (event.pressed()) { 114 if (event.pressed()) {
155 // Simulate secure attention sequence if Ctrl-Alt-Del was just pressed. 115 // Simulate secure attention sequence if Ctrl-Alt-Del was just pressed.
156 if (event.usb_keycode() == kUsbDelete && 116 if (event.usb_keycode() == kUsbDelete &&
157 CheckCtrlAndAltArePressed(pressed_keys_)) { 117 CheckCtrlAndAltArePressed(pressed_keys_)) {
158 VLOG(3) << "Sending Secure Attention Sequence to console"; 118 VLOG(3) << "Sending Secure Attention Sequence to console";
159 119
160 if (base::win::GetVersion() == base::win::VERSION_XP) { 120 if (sas_injector_.get() == NULL)
161 EmulateSecureAttentionSequence(); 121 sas_injector_ = SasInjector::Create();
162 } else if (chromoting_channel_.get()) { 122 sas_injector_->InjectSas();
163 chromoting_channel_->Send(new ChromotingHostMsg_SendSasToConsole());
164 }
165 } 123 }
166 124
167 pressed_keys_.insert(event.usb_keycode()); 125 pressed_keys_.insert(event.usb_keycode());
168 } else { 126 } else {
169 pressed_keys_.erase(event.usb_keycode()); 127 pressed_keys_.erase(event.usb_keycode());
170 } 128 }
171 } 129 }
172 130
173 SwitchToInputDesktop(); 131 SwitchToInputDesktop();
174 nested_executor_->InjectKeyEvent(event); 132 nested_executor_->InjectKeyEvent(event);
175 } 133 }
176 134
177 void SessionEventExecutorWin::InjectMouseEvent(const MouseEvent& event) { 135 void SessionEventExecutorWin::InjectMouseEvent(const MouseEvent& event) {
178 if (!task_runner_->BelongsToCurrentThread()) { 136 if (!task_runner_->BelongsToCurrentThread()) {
179 task_runner_->PostTask( 137 task_runner_->PostTask(
180 FROM_HERE, 138 FROM_HERE,
181 base::Bind(&SessionEventExecutorWin::InjectMouseEvent, 139 base::Bind(&SessionEventExecutorWin::InjectMouseEvent,
182 weak_ptr_, event)); 140 weak_ptr_, event));
183 return; 141 return;
184 } 142 }
185 143
186 SwitchToInputDesktop(); 144 SwitchToInputDesktop();
187 nested_executor_->InjectMouseEvent(event); 145 nested_executor_->InjectMouseEvent(event);
188 } 146 }
189 147
190 bool SessionEventExecutorWin::OnMessageReceived(const IPC::Message& message) {
191 return false;
192 }
193
194 void SessionEventExecutorWin::SwitchToInputDesktop() { 148 void SessionEventExecutorWin::SwitchToInputDesktop() {
195 // Switch to the desktop receiving user input if different from the current 149 // Switch to the desktop receiving user input if different from the current
196 // one. 150 // one.
197 scoped_ptr<Desktop> input_desktop = Desktop::GetInputDesktop(); 151 scoped_ptr<Desktop> input_desktop = Desktop::GetInputDesktop();
198 if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) { 152 if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) {
199 // If SetThreadDesktop() fails, the thread is still assigned a desktop. 153 // If SetThreadDesktop() fails, the thread is still assigned a desktop.
200 // So we can continue capture screen bits, just from a diffected desktop. 154 // So we can continue capture screen bits, just from a diffected desktop.
201 desktop_.SetThreadDesktop(input_desktop.Pass()); 155 desktop_.SetThreadDesktop(input_desktop.Pass());
202 } 156 }
203 } 157 }
204 158
205 } // namespace remoting 159 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/session_event_executor_win.h ('k') | remoting/host/win/wts_session_process_launcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698