OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "mojo/edk/system/master_impl.h" |
| 6 |
| 7 #include "base/containers/hash_tables.h" |
| 8 #include "base/lazy_instance.h" |
| 9 #include "base/logging.h" |
| 10 #include "base/rand_util.h" |
| 11 #include "mojo/edk/embedder/embedder.h" |
| 12 |
| 13 #if defined(OS_WIN) |
| 14 base::LazyInstance<base::hash_map<uint64_t, HANDLE>>::Leaky |
| 15 g_token_map = LAZY_INSTANCE_INITIALIZER; |
| 16 #endif |
| 17 |
| 18 namespace mojo { |
| 19 namespace edk { |
| 20 |
| 21 MasterImpl::MasterImpl(base::ProcessId slave_pid) |
| 22 #if defined(OS_WIN) |
| 23 : slave_process_( |
| 24 base::Process::OpenWithAccess(slave_pid, PROCESS_DUP_HANDLE)) |
| 25 #endif |
| 26 { |
| 27 #if defined(OS_WIN) |
| 28 DCHECK(slave_process_.IsValid()); |
| 29 #endif |
| 30 } |
| 31 |
| 32 MasterImpl::~MasterImpl() { |
| 33 } |
| 34 |
| 35 void MasterImpl::HandleToToken(ScopedHandle platform_handle, |
| 36 const HandleToTokenCallback& callback) { |
| 37 #if defined(OS_WIN) |
| 38 ScopedPlatformHandle sender_handle; |
| 39 MojoResult unwrap_result = PassWrappedPlatformHandle( |
| 40 platform_handle.get().value(), &sender_handle); |
| 41 if (unwrap_result != MOJO_RESULT_OK) { |
| 42 DLOG(WARNING) << "HandleToToken couldn't unwrap platform handle."; |
| 43 callback.Run(unwrap_result, 0); |
| 44 return; |
| 45 } |
| 46 |
| 47 HANDLE master_handle = NULL; |
| 48 BOOL dup_result = |
| 49 DuplicateHandle(slave_process_.Handle(), sender_handle.release().handle, |
| 50 base::GetCurrentProcessHandle(), &master_handle, 0, |
| 51 FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); |
| 52 if (!dup_result) { |
| 53 DLOG(WARNING) << "HandleToToken couldn't duplicate slave handle."; |
| 54 callback.Run(MOJO_RESULT_INVALID_ARGUMENT, 0); |
| 55 return; |
| 56 } |
| 57 |
| 58 uint64_t token = base::RandUint64(); |
| 59 g_token_map.Get()[token] = master_handle; |
| 60 callback.Run(MOJO_RESULT_OK, token); |
| 61 #else |
| 62 NOTREACHED(); |
| 63 #endif |
| 64 } |
| 65 |
| 66 void MasterImpl::TokenToHandle(uint64_t token, |
| 67 const TokenToHandleCallback& callback) { |
| 68 #if defined(OS_WIN) |
| 69 auto it = g_token_map.Get().find(token); |
| 70 if (it == g_token_map.Get().end()) { |
| 71 DLOG(WARNING) << "TokenToHandle didn't find token."; |
| 72 callback.Run(MOJO_RESULT_INVALID_ARGUMENT, ScopedHandle()); |
| 73 return; |
| 74 } |
| 75 |
| 76 HANDLE slave_handle = NULL; |
| 77 BOOL dup_result = |
| 78 DuplicateHandle(base::GetCurrentProcessHandle(), it->second, |
| 79 slave_process_.Handle(), &slave_handle, 0, |
| 80 FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); |
| 81 if (!dup_result) { |
| 82 DLOG(WARNING) << "TokenToHandle couldn't duplicate slave handle."; |
| 83 callback.Run(MOJO_RESULT_INTERNAL, ScopedHandle()); |
| 84 return; |
| 85 } |
| 86 |
| 87 ScopedPlatformHandle platform_handle; |
| 88 platform_handle.reset(PlatformHandle(slave_handle)); |
| 89 |
| 90 MojoHandle handle; |
| 91 MojoResult wrap_result = CreatePlatformHandleWrapper( |
| 92 platform_handle.Pass(), &handle); |
| 93 if (wrap_result != MOJO_RESULT_OK) { |
| 94 DLOG(WARNING) << "TokenToHandle couldn't unwrap platform handle."; |
| 95 callback.Run(wrap_result, ScopedHandle()); |
| 96 return; |
| 97 } |
| 98 |
| 99 callback.Run(MOJO_RESULT_OK, ScopedHandle(Handle(handle))); |
| 100 g_token_map.Get().erase(it); |
| 101 #else |
| 102 NOTREACHED(); |
| 103 #endif |
| 104 } |
| 105 |
| 106 } // namespace edk |
| 107 } // namespace mojo |
OLD | NEW |