1 // Copyright 2016 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/public/cpp/system/platform_handle.h"
6 
7 namespace mojo {
8 
9 namespace {
10 
PlatformHandleValueFromPlatformFile(base::PlatformFile file)11 uint64_t PlatformHandleValueFromPlatformFile(base::PlatformFile file) {
12 #if defined(OS_WIN)
13   return reinterpret_cast<uint64_t>(file);
14 #else
15   return static_cast<uint64_t>(file);
16 #endif
17 }
18 
PlatformFileFromPlatformHandleValue(uint64_t value)19 base::PlatformFile PlatformFileFromPlatformHandleValue(uint64_t value) {
20 #if defined(OS_WIN)
21   return reinterpret_cast<base::PlatformFile>(value);
22 #else
23   return static_cast<base::PlatformFile>(value);
24 #endif
25 }
26 
27 }  // namespace
28 
WrapPlatformFile(base::PlatformFile platform_file)29 ScopedHandle WrapPlatformFile(base::PlatformFile platform_file) {
30   MojoPlatformHandle platform_handle;
31   platform_handle.struct_size = sizeof(MojoPlatformHandle);
32   platform_handle.type = kPlatformFileHandleType;
33   platform_handle.value = PlatformHandleValueFromPlatformFile(platform_file);
34 
35   MojoHandle mojo_handle;
36   MojoResult result = MojoWrapPlatformHandle(&platform_handle, &mojo_handle);
37   CHECK_EQ(result, MOJO_RESULT_OK);
38 
39   return ScopedHandle(Handle(mojo_handle));
40 }
41 
UnwrapPlatformFile(ScopedHandle handle,base::PlatformFile * file)42 MojoResult UnwrapPlatformFile(ScopedHandle handle, base::PlatformFile* file) {
43   MojoPlatformHandle platform_handle;
44   platform_handle.struct_size = sizeof(MojoPlatformHandle);
45   MojoResult result = MojoUnwrapPlatformHandle(handle.release().value(),
46                                                &platform_handle);
47   if (result != MOJO_RESULT_OK)
48     return result;
49 
50   if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_INVALID) {
51     *file = base::kInvalidPlatformFile;
52   } else {
53     CHECK_EQ(platform_handle.type, kPlatformFileHandleType);
54     *file = PlatformFileFromPlatformHandleValue(platform_handle.value);
55   }
56 
57   return MOJO_RESULT_OK;
58 }
59 
WrapSharedMemoryHandle(const base::SharedMemoryHandle & memory_handle,size_t size,bool read_only)60 ScopedSharedBufferHandle WrapSharedMemoryHandle(
61     const base::SharedMemoryHandle& memory_handle,
62     size_t size,
63     bool read_only) {
64   MojoPlatformHandle platform_handle;
65   platform_handle.struct_size = sizeof(MojoPlatformHandle);
66   platform_handle.type = kPlatformSharedBufferHandleType;
67 #if defined(OS_MACOSX) && !defined(OS_IOS)
68   platform_handle.value =
69       static_cast<uint64_t>(memory_handle.GetMemoryObject());
70 #elif defined(OS_POSIX)
71   platform_handle.value = PlatformHandleValueFromPlatformFile(memory_handle.fd);
72 #elif defined(OS_WIN)
73   platform_handle.value =
74       PlatformHandleValueFromPlatformFile(memory_handle.GetHandle());
75 #endif
76 
77   MojoPlatformSharedBufferHandleFlags flags =
78       MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_NONE;
79   if (read_only)
80     flags |= MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_READ_ONLY;
81 
82   MojoHandle mojo_handle;
83   MojoResult result = MojoWrapPlatformSharedBufferHandle(
84       &platform_handle, size, flags, &mojo_handle);
85   CHECK_EQ(result, MOJO_RESULT_OK);
86 
87   return ScopedSharedBufferHandle(SharedBufferHandle(mojo_handle));
88 }
89 
UnwrapSharedMemoryHandle(ScopedSharedBufferHandle handle,base::SharedMemoryHandle * memory_handle,size_t * size,bool * read_only)90 MojoResult UnwrapSharedMemoryHandle(ScopedSharedBufferHandle handle,
91                                     base::SharedMemoryHandle* memory_handle,
92                                     size_t* size,
93                                     bool* read_only) {
94   MojoPlatformHandle platform_handle;
95   platform_handle.struct_size = sizeof(MojoPlatformHandle);
96 
97   MojoPlatformSharedBufferHandleFlags flags;
98   size_t num_bytes;
99   MojoResult result = MojoUnwrapPlatformSharedBufferHandle(
100       handle.release().value(), &platform_handle, &num_bytes, &flags);
101   if (result != MOJO_RESULT_OK)
102     return result;
103 
104   if (size)
105     *size = num_bytes;
106 
107   if (read_only)
108     *read_only = flags & MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_READ_ONLY;
109 
110 #if defined(OS_MACOSX) && !defined(OS_IOS)
111   CHECK_EQ(platform_handle.type, MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT);
112   *memory_handle = base::SharedMemoryHandle(
113       static_cast<mach_port_t>(platform_handle.value), num_bytes,
114       base::GetCurrentProcId());
115 #elif defined(OS_POSIX)
116   CHECK_EQ(platform_handle.type, MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR);
117   *memory_handle = base::SharedMemoryHandle(
118       static_cast<int>(platform_handle.value), false);
119 #elif defined(OS_WIN)
120   CHECK_EQ(platform_handle.type, MOJO_PLATFORM_HANDLE_TYPE_WINDOWS_HANDLE);
121   *memory_handle = base::SharedMemoryHandle(
122       reinterpret_cast<HANDLE>(platform_handle.value),
123       base::GetCurrentProcId());
124 #endif
125 
126   return MOJO_RESULT_OK;
127 }
128 
129 }  // namespace mojo
130