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

Side by Side Diff: mojo/edk/system/raw_channel_win.cc

Issue 1387963004: Create a broker interface for the new Mojo EDK so that the browser can create and duplicate messa... (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: presubmit whitespace error Created 5 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "mojo/edk/system/raw_channel.h" 5 #include "mojo/edk/system/raw_channel.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
11 #include "base/location.h" 11 #include "base/location.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
14 #include "base/message_loop/message_loop.h" 14 #include "base/message_loop/message_loop.h"
15 #include "base/process/process.h" 15 #include "base/process/process.h"
16 #include "base/synchronization/lock.h" 16 #include "base/synchronization/lock.h"
17 #include "base/synchronization/waitable_event.h" 17 #include "base/synchronization/waitable_event.h"
18 #include "base/win/scoped_handle.h" 18 #include "base/win/scoped_handle.h"
19 #include "base/win/windows_version.h" 19 #include "base/win/windows_version.h"
20 #include "mojo/edk/embedder/embedder_internal.h" 20 #include "mojo/edk/embedder/embedder_internal.h"
21 #include "mojo/edk/embedder/platform_handle.h" 21 #include "mojo/edk/embedder/platform_handle.h"
22 #include "mojo/edk/system/token_serializer_win.h"
22 #include "mojo/edk/system/transport_data.h" 23 #include "mojo/edk/system/transport_data.h"
23 #include "mojo/public/cpp/system/macros.h" 24 #include "mojo/public/cpp/system/macros.h"
24 25
25 #define STATUS_CANCELLED 0xC0000120 26 #define STATUS_CANCELLED 0xC0000120
26 #define STATUS_PIPE_BROKEN 0xC000014B 27 #define STATUS_PIPE_BROKEN 0xC000014B
27 28
28 namespace mojo { 29 namespace mojo {
29 namespace edk { 30 namespace edk {
30 31
31 namespace { 32 namespace {
32 33
33 struct MOJO_ALIGNAS(8) SerializedHandle {
34 DWORD handle_pid;
35 HANDLE handle;
36 };
37
38 class VistaOrHigherFunctions { 34 class VistaOrHigherFunctions {
39 public: 35 public:
40 VistaOrHigherFunctions() 36 VistaOrHigherFunctions()
41 : is_vista_or_higher_( 37 : is_vista_or_higher_(
42 base::win::GetVersion() >= base::win::VERSION_VISTA), 38 base::win::GetVersion() >= base::win::VERSION_VISTA),
43 cancel_io_ex_(nullptr), 39 cancel_io_ex_(nullptr),
44 get_file_information_by_handle_ex_(nullptr) { 40 get_file_information_by_handle_ex_(nullptr) {
45 if (!is_vista_or_higher_) 41 if (!is_vista_or_higher_)
46 return; 42 return;
47 43
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 DCHECK(io_handler_); 591 DCHECK(io_handler_);
596 DCHECK(!io_handler_->pending_read()); 592 DCHECK(!io_handler_->pending_read());
597 593
598 size_t bytes_read = 0; 594 size_t bytes_read = 0;
599 return Read(&bytes_read); 595 return Read(&bytes_read);
600 } 596 }
601 597
602 ScopedPlatformHandleVectorPtr GetReadPlatformHandles( 598 ScopedPlatformHandleVectorPtr GetReadPlatformHandles(
603 size_t num_platform_handles, 599 size_t num_platform_handles,
604 const void* platform_handle_table) override { 600 const void* platform_handle_table) override {
605 // TODO(jam): this code will have to be updated once it's used in a sandbox
606 // and the receiving process doesn't have duplicate permission for the
607 // receiver. Once there's a broker and we have a connection to it (possibly
608 // through ConnectionManager), then we can make a sync IPC to it here to get
609 // a token for this handle, and it will duplicate the handle to is process.
610 // Then we pass the token to the receiver, which will then make a sync call
611 // to the broker to get a duplicated handle. This will also allow us to
612 // avoid leaks of the handle if the receiver dies, since the broker can
613 // notice that.
614 DCHECK_GT(num_platform_handles, 0u); 601 DCHECK_GT(num_platform_handles, 0u);
615 ScopedPlatformHandleVectorPtr rv(new PlatformHandleVector()); 602 ScopedPlatformHandleVectorPtr rv(new PlatformHandleVector());
603 rv->resize(num_platform_handles);
616 604
617 const SerializedHandle* serialization_data = 605 const uint64_t* tokens =
618 static_cast<const SerializedHandle*>(platform_handle_table); 606 static_cast<const uint64_t*>(platform_handle_table);
619 for (size_t i = 0; i < num_platform_handles; i++) { 607 internal::g_token_serializer->TokenToHandle(
620 DWORD pid = serialization_data->handle_pid; 608 tokens, num_platform_handles, &rv->at(0));
621 HANDLE source_handle = serialization_data->handle;
622 serialization_data ++;
623 base::Process sender =
624 base::Process::OpenWithAccess(pid, PROCESS_DUP_HANDLE);
625 DCHECK(sender.IsValid());
626 HANDLE target_handle = NULL;
627 BOOL dup_result = DuplicateHandle(
628 sender.Handle(), source_handle,
629 base::GetCurrentProcessHandle(), &target_handle, 0,
630 FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
631 DCHECK(dup_result);
632 rv->push_back(PlatformHandle(target_handle));
633 }
634 return rv.Pass(); 609 return rv.Pass();
635 } 610 }
636 611
637 size_t SerializePlatformHandles(std::vector<int>* fds) override { 612 size_t SerializePlatformHandles(std::vector<int>* fds) override {
638 if (!write_buffer_no_lock()->HavePlatformHandlesToSend()) 613 if (!write_buffer_no_lock()->HavePlatformHandlesToSend())
639 return 0u; 614 return 0u;
640 615
641 // Since we're not sure which process might ultimately deserialize this
642 // message, we can't duplicate the handle now. Instead, write the process
643 // ID and handle now and let the receiver duplicate it.
644 PlatformHandle* platform_handles; 616 PlatformHandle* platform_handles;
645 void* serialization_data_temp; 617 void* serialization_data_temp;
646 size_t num_platform_handles; 618 size_t num_platform_handles;
647 write_buffer_no_lock()->GetPlatformHandlesToSend( 619 write_buffer_no_lock()->GetPlatformHandlesToSend(
648 &num_platform_handles, &platform_handles, &serialization_data_temp); 620 &num_platform_handles, &platform_handles, &serialization_data_temp);
649 SerializedHandle* serialization_data = 621 uint64_t* tokens = static_cast<uint64_t*>(serialization_data_temp);
650 static_cast<SerializedHandle*>(serialization_data_temp);
651 DCHECK_GT(num_platform_handles, 0u); 622 DCHECK_GT(num_platform_handles, 0u);
652 DCHECK(platform_handles); 623 DCHECK(platform_handles);
653 624
654 DWORD current_process_id = base::GetCurrentProcId(); 625 internal::g_token_serializer->HandleToToken(
655 for (size_t i = 0; i < num_platform_handles; i++) { 626 &platform_handles[0], num_platform_handles, tokens);
656 serialization_data->handle_pid = current_process_id; 627 for (size_t i = 0; i < num_platform_handles; i++)
657 serialization_data->handle = platform_handles[i].handle;
658 serialization_data++;
659 platform_handles[i] = PlatformHandle(); 628 platform_handles[i] = PlatformHandle();
660 }
661 return num_platform_handles; 629 return num_platform_handles;
662 } 630 }
663 631
664 IOResult WriteNoLock(size_t* platform_handles_written, 632 IOResult WriteNoLock(size_t* platform_handles_written,
665 size_t* bytes_written) override { 633 size_t* bytes_written) override {
666 write_lock().AssertAcquired(); 634 write_lock().AssertAcquired();
667 635
668 DCHECK(io_handler_); 636 DCHECK(io_handler_);
669 DCHECK(!io_handler_->pending_write_no_lock()); 637 DCHECK(!io_handler_->pending_write_no_lock());
670 638
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 739
772 } // namespace 740 } // namespace
773 741
774 // ----------------------------------------------------------------------------- 742 // -----------------------------------------------------------------------------
775 743
776 RawChannel* RawChannel::Create(ScopedPlatformHandle handle) { 744 RawChannel* RawChannel::Create(ScopedPlatformHandle handle) {
777 return new RawChannelWin(handle.Pass()); 745 return new RawChannelWin(handle.Pass());
778 } 746 }
779 747
780 size_t RawChannel::GetSerializedPlatformHandleSize() { 748 size_t RawChannel::GetSerializedPlatformHandleSize() {
781 return sizeof(SerializedHandle); 749 return sizeof(uint64_t);
782 } 750 }
783 751
784 bool RawChannel::IsOtherEndOf(RawChannel* other) { 752 bool RawChannel::IsOtherEndOf(RawChannel* other) {
785 DCHECK_NE(other, this); 753 DCHECK_NE(other, this);
786 PlatformHandle this_handle = static_cast<RawChannelWin*>(this)->GetHandle(); 754 PlatformHandle this_handle = static_cast<RawChannelWin*>(this)->GetHandle();
787 PlatformHandle other_handle = static_cast<RawChannelWin*>(other)->GetHandle(); 755 PlatformHandle other_handle = static_cast<RawChannelWin*>(other)->GetHandle();
788 756
789 if (g_vista_or_higher_functions.Get().is_vista_or_higher()) { 757 if (g_vista_or_higher_functions.Get().is_vista_or_higher()) {
790 WCHAR data1[_MAX_PATH + sizeof(FILE_NAME_INFO)]; 758 WCHAR data1[_MAX_PATH + sizeof(FILE_NAME_INFO)];
791 WCHAR data2[_MAX_PATH + sizeof(FILE_NAME_INFO)]; 759 WCHAR data2[_MAX_PATH + sizeof(FILE_NAME_INFO)];
792 FILE_NAME_INFO* fileinfo1 = reinterpret_cast<FILE_NAME_INFO *>(data1); 760 FILE_NAME_INFO* fileinfo1 = reinterpret_cast<FILE_NAME_INFO *>(data1);
793 FILE_NAME_INFO* fileinfo2 = reinterpret_cast<FILE_NAME_INFO *>(data2); 761 FILE_NAME_INFO* fileinfo2 = reinterpret_cast<FILE_NAME_INFO *>(data2);
794 CHECK(g_vista_or_higher_functions.Get().GetFileInformationByHandleEx( 762 CHECK(g_vista_or_higher_functions.Get().GetFileInformationByHandleEx(
795 this_handle.handle, FileNameInfo, fileinfo1, arraysize(data1))); 763 this_handle.handle, FileNameInfo, fileinfo1, arraysize(data1)));
796 CHECK(g_vista_or_higher_functions.Get().GetFileInformationByHandleEx( 764 CHECK(g_vista_or_higher_functions.Get().GetFileInformationByHandleEx(
797 other_handle.handle, FileNameInfo, fileinfo2, arraysize(data2))); 765 other_handle.handle, FileNameInfo, fileinfo2, arraysize(data2)));
798 std::wstring filepath1(fileinfo1->FileName, fileinfo1->FileNameLength / 2); 766 std::wstring filepath1(fileinfo1->FileName, fileinfo1->FileNameLength / 2);
799 std::wstring filepath2(fileinfo2->FileName, fileinfo2->FileNameLength / 2); 767 std::wstring filepath2(fileinfo2->FileName, fileinfo2->FileNameLength / 2);
800 return filepath1 == filepath2; 768 return filepath1 == filepath2;
801 } else { 769 } else {
802 // This is to catch developer errors. Let them be caught on Vista and above, 770 // This is to catch developer errors. Let them be caught on Vista and above,
803 // i.e. no point in implementing this on XP since support for it will be 771 // i.e. no point in implementing this on XP since support for it will be
804 // removed in early 2016. 772 // removed in early 2016.
805 return false; 773 return false;
806 } 774 }
807 } 775 }
808 776
809 } // namespace edk 777 } // namespace edk
810 } // namespace mojo 778 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698