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 "ipc/ipc_channel_win.h" | 5 #include "ipc/ipc_channel_win.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 #include <windows.h> | 8 #include <windows.h> |
9 | 9 |
10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 // form OnIOCompleted(). | 68 // form OnIOCompleted(). |
69 if (pipe_.IsValid()) | 69 if (pipe_.IsValid()) |
70 pipe_.Close(); | 70 pipe_.Close(); |
71 | 71 |
72 // Make sure all IO has completed. | 72 // Make sure all IO has completed. |
73 while (input_state_.is_pending || output_state_.is_pending) { | 73 while (input_state_.is_pending || output_state_.is_pending) { |
74 base::MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this); | 74 base::MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this); |
75 } | 75 } |
76 | 76 |
77 while (!output_queue_.empty()) { | 77 while (!output_queue_.empty()) { |
78 Message* m = output_queue_.front(); | 78 OutputElement* element = output_queue_.front(); |
79 output_queue_.pop(); | 79 output_queue_.pop(); |
80 delete m; | 80 delete element; |
81 } | 81 } |
82 } | 82 } |
83 | 83 |
84 bool ChannelWin::Send(Message* message) { | 84 bool ChannelWin::Send(Message* message) { |
85 DCHECK(thread_check_->CalledOnValidThread()); | 85 DCHECK(thread_check_->CalledOnValidThread()); |
86 DVLOG(2) << "sending message @" << message << " on channel @" << this | 86 DVLOG(2) << "sending message @" << message << " on channel @" << this |
87 << " with type " << message->type() | 87 << " with type " << message->type() |
88 << " (" << output_queue_.size() << " in queue)"; | 88 << " (" << output_queue_.size() << " in queue)"; |
89 | 89 |
90 if (!prelim_queue_.empty()) { | 90 if (!prelim_queue_.empty()) { |
(...skipping 29 matching lines...) Expand all Loading... |
120 #ifdef IPC_MESSAGE_LOG_ENABLED | 120 #ifdef IPC_MESSAGE_LOG_ENABLED |
121 Logging::GetInstance()->OnSendMessage(message, ""); | 121 Logging::GetInstance()->OnSendMessage(message, ""); |
122 #endif | 122 #endif |
123 | 123 |
124 TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"), | 124 TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"), |
125 "ChannelWin::ProcessMessageForDelivery", | 125 "ChannelWin::ProcessMessageForDelivery", |
126 message->flags(), | 126 message->flags(), |
127 TRACE_EVENT_FLAG_FLOW_OUT); | 127 TRACE_EVENT_FLAG_FLOW_OUT); |
128 | 128 |
129 // |output_queue_| takes ownership of |message|. | 129 // |output_queue_| takes ownership of |message|. |
130 output_queue_.push(message); | 130 OutputElement* element = new OutputElement(message); |
| 131 output_queue_.push(element); |
| 132 |
| 133 // TODO(erikchen): Serialize the brokerable attachments and add them to the |
| 134 // output_queue_. http://crbug.com/493414. |
| 135 |
131 // ensure waiting to write | 136 // ensure waiting to write |
132 if (!waiting_connect_) { | 137 if (!waiting_connect_) { |
133 if (!output_state_.is_pending) { | 138 if (!output_state_.is_pending) { |
134 if (!ProcessOutgoingMessages(NULL, 0)) | 139 if (!ProcessOutgoingMessages(NULL, 0)) |
135 return false; | 140 return false; |
136 } | 141 } |
137 } | 142 } |
138 | 143 |
139 return true; | 144 return true; |
140 } | 145 } |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 | 362 |
358 // Don't send the secret to the untrusted process, and don't send a secret | 363 // Don't send the secret to the untrusted process, and don't send a secret |
359 // if the value is zero (for IPC backwards compatability). | 364 // if the value is zero (for IPC backwards compatability). |
360 int32_t secret = validate_client_ ? 0 : client_secret_; | 365 int32_t secret = validate_client_ ? 0 : client_secret_; |
361 if (!m->WriteInt(GetCurrentProcessId()) || | 366 if (!m->WriteInt(GetCurrentProcessId()) || |
362 (secret && !m->WriteUInt32(secret))) { | 367 (secret && !m->WriteUInt32(secret))) { |
363 pipe_.Close(); | 368 pipe_.Close(); |
364 return false; | 369 return false; |
365 } | 370 } |
366 | 371 |
367 output_queue_.push(m.release()); | 372 OutputElement* element = new OutputElement(m.release()); |
| 373 output_queue_.push(element); |
368 return true; | 374 return true; |
369 } | 375 } |
370 | 376 |
371 bool ChannelWin::Connect() { | 377 bool ChannelWin::Connect() { |
372 DLOG_IF(WARNING, thread_check_.get()) << "Connect called more than once"; | 378 DLOG_IF(WARNING, thread_check_.get()) << "Connect called more than once"; |
373 | 379 |
374 if (!thread_check_.get()) | 380 if (!thread_check_.get()) |
375 thread_check_.reset(new base::ThreadChecker()); | 381 thread_check_.reset(new base::ThreadChecker()); |
376 | 382 |
377 if (!pipe_.IsValid()) | 383 if (!pipe_.IsValid()) |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 if (output_state_.is_pending) { | 453 if (output_state_.is_pending) { |
448 DCHECK(context); | 454 DCHECK(context); |
449 output_state_.is_pending = false; | 455 output_state_.is_pending = false; |
450 if (!context || bytes_written == 0) { | 456 if (!context || bytes_written == 0) { |
451 DWORD err = GetLastError(); | 457 DWORD err = GetLastError(); |
452 LOG(ERROR) << "pipe error: " << err; | 458 LOG(ERROR) << "pipe error: " << err; |
453 return false; | 459 return false; |
454 } | 460 } |
455 // Message was sent. | 461 // Message was sent. |
456 CHECK(!output_queue_.empty()); | 462 CHECK(!output_queue_.empty()); |
457 Message* m = output_queue_.front(); | 463 OutputElement* element = output_queue_.front(); |
458 output_queue_.pop(); | 464 output_queue_.pop(); |
459 delete m; | 465 delete element; |
460 } | 466 } |
461 | 467 |
462 if (output_queue_.empty()) | 468 if (output_queue_.empty()) |
463 return true; | 469 return true; |
464 | 470 |
465 if (!pipe_.IsValid()) | 471 if (!pipe_.IsValid()) |
466 return false; | 472 return false; |
467 | 473 |
468 // Write to pipe... | 474 // Write to pipe... |
469 Message* m = output_queue_.front(); | 475 OutputElement* element = output_queue_.front(); |
470 DCHECK(m->size() <= INT_MAX); | 476 DCHECK(element->size() <= INT_MAX); |
471 BOOL ok = WriteFile(pipe_.Get(), | 477 BOOL ok = WriteFile(pipe_.Get(), |
472 m->data(), | 478 element->data(), |
473 static_cast<uint32_t>(m->size()), | 479 static_cast<uint32_t>(element->size()), |
474 NULL, | 480 NULL, |
475 &output_state_.context.overlapped); | 481 &output_state_.context.overlapped); |
476 if (!ok) { | 482 if (!ok) { |
477 DWORD write_error = GetLastError(); | 483 DWORD write_error = GetLastError(); |
478 if (write_error == ERROR_IO_PENDING) { | 484 if (write_error == ERROR_IO_PENDING) { |
479 output_state_.is_pending = true; | 485 output_state_.is_pending = true; |
480 | 486 |
481 DVLOG(2) << "sent pending message @" << m << " on channel @" << this | 487 const Message* m = element->get_message(); |
482 << " with type " << m->type(); | 488 if (m) { |
| 489 DVLOG(2) << "sent pending message @" << m << " on channel @" << this |
| 490 << " with type " << m->type(); |
| 491 } |
483 | 492 |
484 return true; | 493 return true; |
485 } | 494 } |
486 LOG(ERROR) << "pipe error: " << write_error; | 495 LOG(ERROR) << "pipe error: " << write_error; |
487 return false; | 496 return false; |
488 } | 497 } |
489 | 498 |
490 DVLOG(2) << "sent message @" << m << " on channel @" << this | 499 const Message* m = element->get_message(); |
491 << " with type " << m->type(); | 500 if (m) { |
| 501 DVLOG(2) << "sent message @" << m << " on channel @" << this |
| 502 << " with type " << m->type(); |
| 503 } |
492 | 504 |
493 output_state_.is_pending = true; | 505 output_state_.is_pending = true; |
494 return true; | 506 return true; |
495 } | 507 } |
496 | 508 |
497 void ChannelWin::OnIOCompleted( | 509 void ChannelWin::OnIOCompleted( |
498 base::MessageLoopForIO::IOContext* context, | 510 base::MessageLoopForIO::IOContext* context, |
499 DWORD bytes_transfered, | 511 DWORD bytes_transfered, |
500 DWORD error) { | 512 DWORD error) { |
501 bool ok = true; | 513 bool ok = true; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 int secret; | 588 int secret; |
577 do { // Guarantee we get a non-zero value. | 589 do { // Guarantee we get a non-zero value. |
578 secret = base::RandInt(0, std::numeric_limits<int>::max()); | 590 secret = base::RandInt(0, std::numeric_limits<int>::max()); |
579 } while (secret == 0); | 591 } while (secret == 0); |
580 | 592 |
581 id.append(GenerateUniqueRandomChannelID()); | 593 id.append(GenerateUniqueRandomChannelID()); |
582 return id.append(base::StringPrintf("\\%d", secret)); | 594 return id.append(base::StringPrintf("\\%d", secret)); |
583 } | 595 } |
584 | 596 |
585 } // namespace IPC | 597 } // namespace IPC |
OLD | NEW |