1 // Copyright (c) 2013 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 #ifndef PPAPI_PROXY_SERIALIZED_HANDLES_H_ 6 #define PPAPI_PROXY_SERIALIZED_HANDLES_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "base/logging.h" 13 #include "base/memory/shared_memory.h" 14 #include "build/build_config.h" 15 #include "ipc/ipc_platform_file.h" 16 #include "ppapi/proxy/ppapi_proxy_export.h" 17 18 class Pickle; 19 20 namespace ppapi { 21 namespace proxy { 22 23 // SerializedHandle is a unified structure for holding a handle (e.g., a shared 24 // memory handle, socket descriptor, etc). This is useful for passing handles in 25 // resource messages and also makes it easier to translate handles in 26 // NaClIPCAdapter for use in NaCl. 27 class PPAPI_PROXY_EXPORT SerializedHandle { 28 public: 29 enum Type { INVALID, SHARED_MEMORY, SOCKET, CHANNEL_HANDLE, FILE }; 30 struct Header { 31 Header() : type(INVALID), size(0), open_flag(0) {} 32 Header(Type type_arg, uint32 size_arg, int32 open_flag_arg) 33 : type(type_arg), size(size_arg), open_flag(open_flag_arg) { 34 } 35 Type type; 36 uint32 size; 37 int32 open_flag; 38 }; 39 40 SerializedHandle(); 41 // Create an invalid handle of the given type. 42 explicit SerializedHandle(Type type); 43 44 // Create a shared memory handle. 45 SerializedHandle(const base::SharedMemoryHandle& handle, uint32 size); 46 47 // Create a socket, channel or file handle. 48 SerializedHandle(const Type type, 49 const IPC::PlatformFileForTransit& descriptor); 50 51 Type type() const { return type_; } 52 bool is_shmem() const { return type_ == SHARED_MEMORY; } 53 bool is_socket() const { return type_ == SOCKET; } 54 bool is_channel_handle() const { return type_ == CHANNEL_HANDLE; } 55 bool is_file() const { return type_ == FILE; } 56 const base::SharedMemoryHandle& shmem() const { 57 DCHECK(is_shmem()); 58 return shm_handle_; 59 } 60 uint32 size() const { 61 DCHECK(is_shmem()); 62 return size_; 63 } 64 const IPC::PlatformFileForTransit& descriptor() const { 65 DCHECK(is_socket() || is_channel_handle() || is_file()); 66 return descriptor_; 67 } 68 int32 open_flag() const { 69 return open_flag_; 70 } 71 void set_shmem(const base::SharedMemoryHandle& handle, uint32 size) { 72 type_ = SHARED_MEMORY; 73 shm_handle_ = handle; 74 size_ = size; 75 76 descriptor_ = IPC::InvalidPlatformFileForTransit(); 77 } 78 void set_socket(const IPC::PlatformFileForTransit& socket) { 79 type_ = SOCKET; 80 descriptor_ = socket; 81 82 shm_handle_ = base::SharedMemory::NULLHandle(); 83 size_ = 0; 84 } 85 void set_channel_handle(const IPC::PlatformFileForTransit& descriptor) { 86 type_ = CHANNEL_HANDLE; 87 88 descriptor_ = descriptor; 89 shm_handle_ = base::SharedMemory::NULLHandle(); 90 size_ = 0; 91 } 92 void set_file_handle(const IPC::PlatformFileForTransit& descriptor, 93 int32 open_flag) { 94 type_ = FILE; 95 96 descriptor_ = descriptor; 97 shm_handle_ = base::SharedMemory::NULLHandle(); 98 size_ = 0; 99 open_flag_ = open_flag; 100 } 101 void set_null_shmem() { 102 set_shmem(base::SharedMemory::NULLHandle(), 0); 103 } 104 void set_null_socket() { 105 set_socket(IPC::InvalidPlatformFileForTransit()); 106 } 107 void set_null_channel_handle() { 108 set_channel_handle(IPC::InvalidPlatformFileForTransit()); 109 } 110 void set_null_file_handle() { 111 set_file_handle(IPC::InvalidPlatformFileForTransit(), 0); 112 } 113 bool IsHandleValid() const; 114 115 Header header() const { 116 return Header(type_, size_, open_flag_); 117 } 118 119 // Closes the handle and sets it to invalid. 120 void Close(); 121 122 // Write/Read a Header, which contains all the data except the handle. This 123 // allows us to write the handle in a platform-specific way, as is necessary 124 // in NaClIPCAdapter to share handles with NaCl from Windows. 125 static bool WriteHeader(const Header& hdr, Pickle* pickle); 126 static bool ReadHeader(PickleIterator* iter, Header* hdr); 127 128 private: 129 // The kind of handle we're holding. 130 Type type_; 131 132 // We hold more members than we really need; we can't easily use a union, 133 // because we hold non-POD types. But these types are pretty light-weight. If 134 // we add more complex things later, we should come up with a more memory- 135 // efficient strategy. 136 // These are valid if type == SHARED_MEMORY. 137 base::SharedMemoryHandle shm_handle_; 138 uint32 size_; 139 140 // This is valid if type == SOCKET || type == CHANNEL_HANDLE || type == FILE. 141 IPC::PlatformFileForTransit descriptor_; 142 143 // This is valid if type == FILE. 144 int32 open_flag_; 145 }; 146 147 } // namespace proxy 148 } // namespace ppapi 149 150 #endif // PPAPI_PROXY_SERIALIZED_HANDLES_H_ 151