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

Side by Side Diff: remoting/host/win/wts_session_process_delegate.cc

Issue 2568983004: Fixing CRD curtain mode connection failures on Win8+ official builds (Closed)
Patch Set: Created 4 years 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
« no previous file with comments | « remoting/host/win/BUILD.gn ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // This file implements the Windows service controlling Me2Me host processes 5 // This file implements the Windows service controlling Me2Me host processes
6 // running within user sessions. 6 // running within user sessions.
7 7
8 #include "remoting/host/win/wts_session_process_delegate.h" 8 #include "remoting/host/win/wts_session_process_delegate.h"
9 9
10 #include <utility> 10 #include <utility>
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 // The handle of the worker process, if launched. 148 // The handle of the worker process, if launched.
149 base::win::ScopedHandle worker_process_; 149 base::win::ScopedHandle worker_process_;
150 150
151 // If launching elevated, this holds the server handle after launch, until 151 // If launching elevated, this holds the server handle after launch, until
152 // the final process launches. 152 // the final process launches.
153 mojo::edk::ScopedPlatformHandle elevated_server_handle_; 153 mojo::edk::ScopedPlatformHandle elevated_server_handle_;
154 154
155 // If launching elevated, this is the pid of the launcher process. 155 // If launching elevated, this is the pid of the launcher process.
156 base::ProcessId elevated_launcher_pid_ = base::kNullProcessId; 156 base::ProcessId elevated_launcher_pid_ = base::kNullProcessId;
157 157
158 // Tracks the id of the worker process.
159 base::ProcessId worker_process_pid_ = base::kNullProcessId;
160
158 // The mojo child token for the process being launched. 161 // The mojo child token for the process being launched.
159 std::string mojo_child_token_; 162 std::string mojo_child_token_;
160 163
161 DISALLOW_COPY_AND_ASSIGN(Core); 164 DISALLOW_COPY_AND_ASSIGN(Core);
162 }; 165 };
163 166
164 WtsSessionProcessDelegate::Core::Core( 167 WtsSessionProcessDelegate::Core::Core(
165 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, 168 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
166 std::unique_ptr<base::CommandLine> target_command, 169 std::unique_ptr<base::CommandLine> target_command,
167 bool launch_elevated, 170 bool launch_elevated,
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 if (channel_) { 248 if (channel_) {
246 channel_->Send(message); 249 channel_->Send(message);
247 } else { 250 } else {
248 delete message; 251 delete message;
249 } 252 }
250 } 253 }
251 254
252 void WtsSessionProcessDelegate::Core::CloseChannel() { 255 void WtsSessionProcessDelegate::Core::CloseChannel() {
253 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 256 DCHECK(caller_task_runner_->BelongsToCurrentThread());
254 257
255 if (!channel_) 258 if (!channel_) {
256 return; 259 return;
260 }
257 261
258 channel_.reset(); 262 channel_.reset();
259 elevated_server_handle_.reset(); 263 elevated_server_handle_.reset();
260 elevated_launcher_pid_ = base::kNullProcessId; 264 elevated_launcher_pid_ = base::kNullProcessId;
261 if (!mojo_child_token_.empty()) { 265 if (!mojo_child_token_.empty()) {
262 mojo::edk::ChildProcessLaunchFailed(mojo_child_token_); 266 mojo::edk::ChildProcessLaunchFailed(mojo_child_token_);
263 mojo_child_token_.clear(); 267 mojo_child_token_.clear();
264 } 268 }
265 } 269 }
266 270
267 void WtsSessionProcessDelegate::Core::KillProcess() { 271 void WtsSessionProcessDelegate::Core::KillProcess() {
268 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 272 DCHECK(caller_task_runner_->BelongsToCurrentThread());
269 273
270 CloseChannel(); 274 CloseChannel();
271 275
272 event_handler_ = nullptr; 276 event_handler_ = nullptr;
273 launch_pending_ = false; 277 launch_pending_ = false;
274 278
275 if (launch_elevated_) { 279 if (launch_elevated_) {
276 if (job_.IsValid()) 280 if (job_.IsValid()) {
277 TerminateJobObject(job_.Get(), CONTROL_C_EXIT); 281 TerminateJobObject(job_.Get(), CONTROL_C_EXIT);
282 }
278 } else { 283 } else {
279 if (worker_process_.IsValid()) 284 if (worker_process_.IsValid()) {
280 TerminateProcess(worker_process_.Get(), CONTROL_C_EXIT); 285 TerminateProcess(worker_process_.Get(), CONTROL_C_EXIT);
286 }
281 } 287 }
282 288
283 worker_process_.Close(); 289 worker_process_.Close();
284 } 290 }
285 291
286 WtsSessionProcessDelegate::Core::~Core() { 292 WtsSessionProcessDelegate::Core::~Core() {
287 DCHECK(!channel_); 293 DCHECK(!channel_);
288 DCHECK(!event_handler_); 294 DCHECK(!event_handler_);
289 DCHECK(!worker_process_.IsValid()); 295 DCHECK(!worker_process_.IsValid());
290 } 296 }
291 297
292 void WtsSessionProcessDelegate::Core::OnIOCompleted( 298 void WtsSessionProcessDelegate::Core::OnIOCompleted(
293 base::MessagePumpForIO::IOContext* context, 299 base::MessagePumpForIO::IOContext* context,
294 DWORD bytes_transferred, 300 DWORD bytes_transferred,
295 DWORD error) { 301 DWORD error) {
296 DCHECK(io_task_runner_->BelongsToCurrentThread()); 302 DCHECK(io_task_runner_->BelongsToCurrentThread());
297 303
298 // |bytes_transferred| is used in job object notifications to supply 304 // |bytes_transferred| is used in job object notifications to supply
299 // the message ID; |context| carries process ID. 305 // the message ID; |context| carries process ID.
300 switch (bytes_transferred) { 306 switch (bytes_transferred) {
301 case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO: { 307 case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO: {
302 caller_task_runner_->PostTask( 308 caller_task_runner_->PostTask(
303 FROM_HERE, base::Bind(&Core::OnActiveProcessZero, this)); 309 FROM_HERE, base::Bind(&Core::OnActiveProcessZero, this));
304 break; 310 break;
305 } 311 }
306 case JOB_OBJECT_MSG_NEW_PROCESS: { 312 case JOB_OBJECT_MSG_NEW_PROCESS: {
307 caller_task_runner_->PostTask( 313 base::ProcessId new_process_id =
308 FROM_HERE, base::Bind(&Core::OnProcessLaunchDetected, this, 314 static_cast<base::ProcessId>(reinterpret_cast<uintptr_t>(context));
Sergey Ulanov 2016/12/13 01:10:37 nit: move this above the switch statement and rena
joedow 2016/12/13 03:52:42 Done. The cast dance seems to be required, I get
309 static_cast<base::ProcessId>( 315 if (elevated_launcher_pid_ == base::kNullProcessId) {
310 reinterpret_cast<uintptr_t>(context)))); 316 // Ignore process launch events when we don't have a valid launcher pid.
317 return;
318 }
319
320 if (new_process_id != elevated_launcher_pid_) {
321 DCHECK_EQ(worker_process_pid_, base::kNullProcessId);
322 worker_process_pid_ = new_process_id;
323 }
324 break;
325 }
326 case JOB_OBJECT_MSG_EXIT_PROCESS: {
327 base::ProcessId exiting_process_id =
328 static_cast<base::ProcessId>(reinterpret_cast<uintptr_t>(context));
329 if (exiting_process_id == worker_process_pid_) {
330 // In official builds the first launch of a UiAccess enabled binary
331 // will fail due to 'STATUS_ELEVATION_REQUIRED'. In that scenario, we
332 // will clear out the previously stored value for |worker_process_pid_|
333 // and retry after the subsequent relaunch of the worker process.
Sergey Ulanov 2016/12/13 01:10:37 It's not clear from this comment who relaunches th
joedow 2016/12/13 03:52:42 Done.
334 worker_process_pid_ = base::kNullProcessId;
335 } else if (exiting_process_id == elevated_launcher_pid_) {
336 if (worker_process_pid_ == base::kNullProcessId) {
337 // The elevated launcher process can fail to launch without attemping
338 // to launch the worker. In this scenario, the failure will be
339 // detected outside this method and the elevated launcher will be
340 // launched again.
341 return;
342 }
343
344 caller_task_runner_->PostTask(
345 FROM_HERE, base::Bind(&Core::OnProcessLaunchDetected, this,
346 worker_process_pid_));
347 }
311 break; 348 break;
312 } 349 }
313 } 350 }
314 } 351 }
315 352
316 bool WtsSessionProcessDelegate::Core::OnMessageReceived( 353 bool WtsSessionProcessDelegate::Core::OnMessageReceived(
317 const IPC::Message& message) { 354 const IPC::Message& message) {
318 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 355 DCHECK(caller_task_runner_->BelongsToCurrentThread());
319 356
320 return event_handler_->OnMessageReceived(message); 357 return event_handler_->OnMessageReceived(message);
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 caller_task_runner_->PostTask(FROM_HERE, base::Bind( 519 caller_task_runner_->PostTask(FROM_HERE, base::Bind(
483 &Core::InitializeJobCompleted, this, base::Passed(&job))); 520 &Core::InitializeJobCompleted, this, base::Passed(&job)));
484 } 521 }
485 522
486 void WtsSessionProcessDelegate::Core::InitializeJobCompleted(ScopedHandle job) { 523 void WtsSessionProcessDelegate::Core::InitializeJobCompleted(ScopedHandle job) {
487 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 524 DCHECK(caller_task_runner_->BelongsToCurrentThread());
488 DCHECK(!job_.IsValid()); 525 DCHECK(!job_.IsValid());
489 526
490 job_ = std::move(job); 527 job_ = std::move(job);
491 528
492 if (launch_pending_) 529 if (launch_pending_) {
493 DoLaunchProcess(); 530 DoLaunchProcess();
531 }
494 } 532 }
495 533
496 void WtsSessionProcessDelegate::Core::OnActiveProcessZero() { 534 void WtsSessionProcessDelegate::Core::OnActiveProcessZero() {
497 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 535 DCHECK(caller_task_runner_->BelongsToCurrentThread());
498 536
499 if (launch_pending_) { 537 if (launch_pending_) {
500 LOG(ERROR) << "The worker process exited before connecting via IPC."; 538 LOG(ERROR) << "The worker process exited before connecting via IPC.";
501 launch_pending_ = false; 539 launch_pending_ = false;
502 ReportFatalError(); 540 ReportFatalError();
503 } 541 }
504 } 542 }
505 543
506 void WtsSessionProcessDelegate::Core::OnProcessLaunchDetected( 544 void WtsSessionProcessDelegate::Core::OnProcessLaunchDetected(
507 base::ProcessId pid) { 545 base::ProcessId pid) {
508 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 546 DCHECK(caller_task_runner_->BelongsToCurrentThread());
509 if (!elevated_server_handle_.is_valid()) 547 DCHECK_NE(pid, elevated_launcher_pid_);
548
549 if (!elevated_server_handle_.is_valid()) {
510 return; 550 return;
511 551 }
512 if (pid == elevated_launcher_pid_)
513 return;
514 552
515 DWORD desired_access = 553 DWORD desired_access =
516 SYNCHRONIZE | PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION; 554 SYNCHRONIZE | PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION;
517 base::win::ScopedHandle worker_process( 555 base::win::ScopedHandle worker_process(
518 OpenProcess(desired_access, false, pid)); 556 OpenProcess(desired_access, false, pid));
519 if (!worker_process.IsValid()) { 557 if (!worker_process.IsValid()) {
520 PLOG(ERROR) << "Failed to open process " << pid; 558 PLOG(ERROR) << "Failed to open process " << pid;
521 ReportFatalError(); 559 ReportFatalError();
522 return; 560 return;
523 } 561 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 632
595 void WtsSessionProcessDelegate::CloseChannel() { 633 void WtsSessionProcessDelegate::CloseChannel() {
596 core_->CloseChannel(); 634 core_->CloseChannel();
597 } 635 }
598 636
599 void WtsSessionProcessDelegate::KillProcess() { 637 void WtsSessionProcessDelegate::KillProcess() {
600 core_->KillProcess(); 638 core_->KillProcess();
601 } 639 }
602 640
603 } // namespace remoting 641 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/win/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698