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

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: Addressing CR Feedback 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 for the events we listen for.
306 base::ProcessId process_id =
307 static_cast<base::ProcessId>(reinterpret_cast<uintptr_t>(context));
300 switch (bytes_transferred) { 308 switch (bytes_transferred) {
301 case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO: { 309 case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO: {
302 caller_task_runner_->PostTask( 310 caller_task_runner_->PostTask(
303 FROM_HERE, base::Bind(&Core::OnActiveProcessZero, this)); 311 FROM_HERE, base::Bind(&Core::OnActiveProcessZero, this));
304 break; 312 break;
305 } 313 }
306 case JOB_OBJECT_MSG_NEW_PROCESS: { 314 case JOB_OBJECT_MSG_NEW_PROCESS: {
307 caller_task_runner_->PostTask( 315 if (elevated_launcher_pid_ == base::kNullProcessId) {
308 FROM_HERE, base::Bind(&Core::OnProcessLaunchDetected, this, 316 // Ignore process launch events when we don't have a valid launcher pid.
309 static_cast<base::ProcessId>( 317 return;
310 reinterpret_cast<uintptr_t>(context)))); 318 }
319
320 if (process_id != elevated_launcher_pid_) {
321 DCHECK_EQ(worker_process_pid_, base::kNullProcessId);
322 worker_process_pid_ = process_id;
323 }
324 break;
325 }
326 case JOB_OBJECT_MSG_EXIT_PROCESS: {
327 if (process_id == worker_process_pid_) {
328 // In official builds the first launch of a UiAccess enabled binary
329 // will fail due to 'STATUS_ELEVATION_REQUIRED'. This is an artifact of
330 // using ShellExecuteEx() to launch the process. In this scenario, we
331 // will clear out the previously stored value for |worker_process_pid_|
332 // and retry after the subsequent relaunch of the worker process.
333 worker_process_pid_ = base::kNullProcessId;
334 } else if (process_id == elevated_launcher_pid_) {
335 if (worker_process_pid_ == base::kNullProcessId) {
336 // The elevated launcher process can fail to launch without attemping
337 // to launch the worker. In this scenario, the failure will be
338 // detected outside this method and the elevated launcher will be
339 // launched again.
340 return;
341 }
342
343 caller_task_runner_->PostTask(
344 FROM_HERE, base::Bind(&Core::OnProcessLaunchDetected, this,
345 worker_process_pid_));
346 }
311 break; 347 break;
312 } 348 }
313 } 349 }
314 } 350 }
315 351
316 bool WtsSessionProcessDelegate::Core::OnMessageReceived( 352 bool WtsSessionProcessDelegate::Core::OnMessageReceived(
317 const IPC::Message& message) { 353 const IPC::Message& message) {
318 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 354 DCHECK(caller_task_runner_->BelongsToCurrentThread());
319 355
320 return event_handler_->OnMessageReceived(message); 356 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( 518 caller_task_runner_->PostTask(FROM_HERE, base::Bind(
483 &Core::InitializeJobCompleted, this, base::Passed(&job))); 519 &Core::InitializeJobCompleted, this, base::Passed(&job)));
484 } 520 }
485 521
486 void WtsSessionProcessDelegate::Core::InitializeJobCompleted(ScopedHandle job) { 522 void WtsSessionProcessDelegate::Core::InitializeJobCompleted(ScopedHandle job) {
487 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 523 DCHECK(caller_task_runner_->BelongsToCurrentThread());
488 DCHECK(!job_.IsValid()); 524 DCHECK(!job_.IsValid());
489 525
490 job_ = std::move(job); 526 job_ = std::move(job);
491 527
492 if (launch_pending_) 528 if (launch_pending_) {
493 DoLaunchProcess(); 529 DoLaunchProcess();
530 }
494 } 531 }
495 532
496 void WtsSessionProcessDelegate::Core::OnActiveProcessZero() { 533 void WtsSessionProcessDelegate::Core::OnActiveProcessZero() {
497 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 534 DCHECK(caller_task_runner_->BelongsToCurrentThread());
498 535
499 if (launch_pending_) { 536 if (launch_pending_) {
500 LOG(ERROR) << "The worker process exited before connecting via IPC."; 537 LOG(ERROR) << "The worker process exited before connecting via IPC.";
501 launch_pending_ = false; 538 launch_pending_ = false;
502 ReportFatalError(); 539 ReportFatalError();
503 } 540 }
504 } 541 }
505 542
506 void WtsSessionProcessDelegate::Core::OnProcessLaunchDetected( 543 void WtsSessionProcessDelegate::Core::OnProcessLaunchDetected(
507 base::ProcessId pid) { 544 base::ProcessId pid) {
508 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 545 DCHECK(caller_task_runner_->BelongsToCurrentThread());
509 if (!elevated_server_handle_.is_valid()) 546 DCHECK_NE(pid, elevated_launcher_pid_);
547
548 if (!elevated_server_handle_.is_valid()) {
510 return; 549 return;
511 550 }
512 if (pid == elevated_launcher_pid_)
513 return;
514 551
515 DWORD desired_access = 552 DWORD desired_access =
516 SYNCHRONIZE | PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION; 553 SYNCHRONIZE | PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION;
517 base::win::ScopedHandle worker_process( 554 base::win::ScopedHandle worker_process(
518 OpenProcess(desired_access, false, pid)); 555 OpenProcess(desired_access, false, pid));
519 if (!worker_process.IsValid()) { 556 if (!worker_process.IsValid()) {
520 PLOG(ERROR) << "Failed to open process " << pid; 557 PLOG(ERROR) << "Failed to open process " << pid;
521 ReportFatalError(); 558 ReportFatalError();
522 return; 559 return;
523 } 560 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 631
595 void WtsSessionProcessDelegate::CloseChannel() { 632 void WtsSessionProcessDelegate::CloseChannel() {
596 core_->CloseChannel(); 633 core_->CloseChannel();
597 } 634 }
598 635
599 void WtsSessionProcessDelegate::KillProcess() { 636 void WtsSessionProcessDelegate::KillProcess() {
600 core_->KillProcess(); 637 core_->KillProcess();
601 } 638 }
602 639
603 } // namespace remoting 640 } // 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