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 <windows.h> | 7 #include <windows.h> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 waiting_connect_(mode & MODE_SERVER_FLAG), | 46 waiting_connect_(mode & MODE_SERVER_FLAG), |
47 processing_incoming_(false), | 47 processing_incoming_(false), |
48 validate_client_(false), | 48 validate_client_(false), |
49 client_secret_(0), | 49 client_secret_(0), |
50 broker_(broker), | 50 broker_(broker), |
51 weak_factory_(this) { | 51 weak_factory_(this) { |
52 CreatePipe(channel_handle, mode); | 52 CreatePipe(channel_handle, mode); |
53 } | 53 } |
54 | 54 |
55 ChannelWin::~ChannelWin() { | 55 ChannelWin::~ChannelWin() { |
| 56 CleanUp(); |
56 Close(); | 57 Close(); |
57 } | 58 } |
58 | 59 |
59 void ChannelWin::Close() { | 60 void ChannelWin::Close() { |
60 if (thread_check_.get()) | 61 if (thread_check_.get()) |
61 DCHECK(thread_check_->CalledOnValidThread()); | 62 DCHECK(thread_check_->CalledOnValidThread()); |
62 | 63 |
63 if (input_state_.is_pending || output_state_.is_pending) | 64 if (input_state_.is_pending || output_state_.is_pending) |
64 CancelIo(pipe_.Get()); | 65 CancelIo(pipe_.Get()); |
65 | 66 |
66 // Closing the handle at this point prevents us from issuing more requests | 67 // Closing the handle at this point prevents us from issuing more requests |
67 // form OnIOCompleted(). | 68 // form OnIOCompleted(). |
68 if (pipe_.IsValid()) | 69 if (pipe_.IsValid()) |
69 pipe_.Close(); | 70 pipe_.Close(); |
70 | 71 |
71 // Make sure all IO has completed. | 72 // Make sure all IO has completed. |
72 while (input_state_.is_pending || output_state_.is_pending) { | 73 while (input_state_.is_pending || output_state_.is_pending) { |
73 base::MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this); | 74 base::MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this); |
74 } | 75 } |
75 | 76 |
76 while (!output_queue_.empty()) { | 77 while (!output_queue_.empty()) { |
77 Message* m = output_queue_.front(); | 78 OutputElement* element = output_queue_.front(); |
78 output_queue_.pop(); | 79 output_queue_.pop(); |
79 delete m; | 80 delete element; |
80 } | 81 } |
81 } | 82 } |
82 | 83 |
83 bool ChannelWin::Send(Message* message) { | 84 bool ChannelWin::Send(Message* message) { |
84 DCHECK(thread_check_->CalledOnValidThread()); | 85 DCHECK(thread_check_->CalledOnValidThread()); |
85 DVLOG(2) << "sending message @" << message << " on channel @" << this | 86 DVLOG(2) << "sending message @" << message << " on channel @" << this |
86 << " with type " << message->type() | 87 << " with type " << message->type() |
87 << " (" << output_queue_.size() << " in queue)"; | 88 << " (" << output_queue_.size() << " in queue)"; |
88 | 89 |
89 if (!prelim_queue_.empty()) { | 90 if (!prelim_queue_.empty()) { |
(...skipping 26 matching lines...) Expand all Loading... |
116 } | 117 } |
117 } | 118 } |
118 | 119 |
119 #ifdef IPC_MESSAGE_LOG_ENABLED | 120 #ifdef IPC_MESSAGE_LOG_ENABLED |
120 Logging::GetInstance()->OnSendMessage(message, ""); | 121 Logging::GetInstance()->OnSendMessage(message, ""); |
121 #endif | 122 #endif |
122 | 123 |
123 message->TraceMessageBegin(); | 124 message->TraceMessageBegin(); |
124 | 125 |
125 // |output_queue_| takes ownership of |message|. | 126 // |output_queue_| takes ownership of |message|. |
126 output_queue_.push(message); | 127 OutputElement* element = new OutputElement(message); |
| 128 output_queue_.push(element); |
| 129 |
| 130 #if USE_ATTACHMENT_BROKER |
| 131 if (message->HasBrokerableAttachments()) { |
| 132 // |output_queue_| takes ownership of |ids.buffer|. |
| 133 Message::SerializedAttachmentIds ids = |
| 134 message->SerializedIdsOfBrokerableAttachments(); |
| 135 OutputElement* new_element = new OutputElement(ids.buffer, ids.size); |
| 136 output_queue_.push(new_element); |
| 137 } |
| 138 #endif |
| 139 |
127 // ensure waiting to write | 140 // ensure waiting to write |
128 if (!waiting_connect_) { | 141 if (!waiting_connect_) { |
129 if (!output_state_.is_pending) { | 142 if (!output_state_.is_pending) { |
130 if (!ProcessOutgoingMessages(NULL, 0)) | 143 if (!ProcessOutgoingMessages(NULL, 0)) |
131 return false; | 144 return false; |
132 } | 145 } |
133 } | 146 } |
134 | 147 |
135 return true; | 148 return true; |
136 } | 149 } |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 | 366 |
354 // Don't send the secret to the untrusted process, and don't send a secret | 367 // Don't send the secret to the untrusted process, and don't send a secret |
355 // if the value is zero (for IPC backwards compatability). | 368 // if the value is zero (for IPC backwards compatability). |
356 int32 secret = validate_client_ ? 0 : client_secret_; | 369 int32 secret = validate_client_ ? 0 : client_secret_; |
357 if (!m->WriteInt(GetCurrentProcessId()) || | 370 if (!m->WriteInt(GetCurrentProcessId()) || |
358 (secret && !m->WriteUInt32(secret))) { | 371 (secret && !m->WriteUInt32(secret))) { |
359 pipe_.Close(); | 372 pipe_.Close(); |
360 return false; | 373 return false; |
361 } | 374 } |
362 | 375 |
363 output_queue_.push(m.release()); | 376 OutputElement* element = new OutputElement(m.release()); |
| 377 output_queue_.push(element); |
364 return true; | 378 return true; |
365 } | 379 } |
366 | 380 |
367 bool ChannelWin::Connect() { | 381 bool ChannelWin::Connect() { |
368 DLOG_IF(WARNING, thread_check_.get()) << "Connect called more than once"; | 382 DLOG_IF(WARNING, thread_check_.get()) << "Connect called more than once"; |
369 | 383 |
370 if (!thread_check_.get()) | 384 if (!thread_check_.get()) |
371 thread_check_.reset(new base::ThreadChecker()); | 385 thread_check_.reset(new base::ThreadChecker()); |
372 | 386 |
373 if (!pipe_.IsValid()) | 387 if (!pipe_.IsValid()) |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 if (output_state_.is_pending) { | 457 if (output_state_.is_pending) { |
444 DCHECK(context); | 458 DCHECK(context); |
445 output_state_.is_pending = false; | 459 output_state_.is_pending = false; |
446 if (!context || bytes_written == 0) { | 460 if (!context || bytes_written == 0) { |
447 DWORD err = GetLastError(); | 461 DWORD err = GetLastError(); |
448 LOG(ERROR) << "pipe error: " << err; | 462 LOG(ERROR) << "pipe error: " << err; |
449 return false; | 463 return false; |
450 } | 464 } |
451 // Message was sent. | 465 // Message was sent. |
452 CHECK(!output_queue_.empty()); | 466 CHECK(!output_queue_.empty()); |
453 Message* m = output_queue_.front(); | 467 OutputElement* element = output_queue_.front(); |
454 output_queue_.pop(); | 468 output_queue_.pop(); |
455 delete m; | 469 delete element; |
456 } | 470 } |
457 | 471 |
458 if (output_queue_.empty()) | 472 if (output_queue_.empty()) |
459 return true; | 473 return true; |
460 | 474 |
461 if (!pipe_.IsValid()) | 475 if (!pipe_.IsValid()) |
462 return false; | 476 return false; |
463 | 477 |
464 // Write to pipe... | 478 // Write to pipe... |
465 Message* m = output_queue_.front(); | 479 OutputElement* element = output_queue_.front(); |
466 DCHECK(m->size() <= INT_MAX); | 480 DCHECK(element->size() <= INT_MAX); |
467 BOOL ok = WriteFile(pipe_.Get(), | 481 BOOL ok = WriteFile(pipe_.Get(), element->data(), |
468 m->data(), | 482 static_cast<uint32>(element->size()), NULL, |
469 static_cast<uint32>(m->size()), | |
470 NULL, | |
471 &output_state_.context.overlapped); | 483 &output_state_.context.overlapped); |
472 if (!ok) { | 484 if (!ok) { |
473 DWORD write_error = GetLastError(); | 485 DWORD write_error = GetLastError(); |
474 if (write_error == ERROR_IO_PENDING) { | 486 if (write_error == ERROR_IO_PENDING) { |
475 output_state_.is_pending = true; | 487 output_state_.is_pending = true; |
476 | 488 |
477 DVLOG(2) << "sent pending message @" << m << " on channel @" << this | 489 const Message* m = element->get_message(); |
478 << " with type " << m->type(); | 490 if (m) { |
| 491 DVLOG(2) << "sent pending message @" << m << " on channel @" << this |
| 492 << " with type " << m->type(); |
| 493 } |
479 | 494 |
480 return true; | 495 return true; |
481 } | 496 } |
482 LOG(ERROR) << "pipe error: " << write_error; | 497 LOG(ERROR) << "pipe error: " << write_error; |
483 return false; | 498 return false; |
484 } | 499 } |
485 | 500 |
486 DVLOG(2) << "sent message @" << m << " on channel @" << this | 501 const Message* m = element->get_message(); |
487 << " with type " << m->type(); | 502 if (m) { |
| 503 DVLOG(2) << "sent message @" << m << " on channel @" << this |
| 504 << " with type " << m->type(); |
| 505 } |
488 | 506 |
489 output_state_.is_pending = true; | 507 output_state_.is_pending = true; |
490 return true; | 508 return true; |
491 } | 509 } |
492 | 510 |
493 void ChannelWin::OnIOCompleted( | 511 void ChannelWin::OnIOCompleted( |
494 base::MessageLoopForIO::IOContext* context, | 512 base::MessageLoopForIO::IOContext* context, |
495 DWORD bytes_transfered, | 513 DWORD bytes_transfered, |
496 DWORD error) { | 514 DWORD error) { |
497 bool ok = true; | 515 bool ok = true; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 int secret; | 590 int secret; |
573 do { // Guarantee we get a non-zero value. | 591 do { // Guarantee we get a non-zero value. |
574 secret = base::RandInt(0, std::numeric_limits<int>::max()); | 592 secret = base::RandInt(0, std::numeric_limits<int>::max()); |
575 } while (secret == 0); | 593 } while (secret == 0); |
576 | 594 |
577 id.append(GenerateUniqueRandomChannelID()); | 595 id.append(GenerateUniqueRandomChannelID()); |
578 return id.append(base::StringPrintf("\\%d", secret)); | 596 return id.append(base::StringPrintf("\\%d", secret)); |
579 } | 597 } |
580 | 598 |
581 } // namespace IPC | 599 } // namespace IPC |
OLD | NEW |