12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/serialized_handle.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 79ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/memory/shared_memory.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/pickle.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/platform_file.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "build/build_config.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_platform_file.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_NACL) 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <unistd.h> 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ppapi { 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace proxy { 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedHandle::SerializedHandle() 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : type_(INVALID), 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shm_handle_(base::SharedMemory::NULLHandle()), 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_(0), 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) descriptor_(IPC::InvalidPlatformFileForTransit()) { 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedHandle::SerializedHandle(Type type_param) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : type_(type_param), 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shm_handle_(base::SharedMemory::NULLHandle()), 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_(0), 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) descriptor_(IPC::InvalidPlatformFileForTransit()) { 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedHandle::SerializedHandle(const base::SharedMemoryHandle& handle, 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 size) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : type_(SHARED_MEMORY), 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shm_handle_(handle), 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_(size), 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) descriptor_(IPC::InvalidPlatformFileForTransit()) { 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedHandle::SerializedHandle( 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Type type, 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const IPC::PlatformFileForTransit& socket_descriptor) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : type_(type), 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shm_handle_(base::SharedMemory::NULLHandle()), 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_(0), 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) descriptor_(socket_descriptor) { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SerializedHandle::IsHandleValid() const { 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type_) { 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SHARED_MEMORY: 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::SharedMemory::IsHandleValid(shm_handle_); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SOCKET: 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case CHANNEL_HANDLE: 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case FILE: 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return !(IPC::InvalidPlatformFileForTransit() == descriptor_); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case INVALID: 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No default so the compiler will warn us if a new type is added. 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SerializedHandle::Close() { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IsHandleValid()) { 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type_) { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case INVALID: 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SHARED_MEMORY: 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SharedMemory::CloseHandle(shm_handle_); 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SOCKET: 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case CHANNEL_HANDLE: 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case FILE: 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::PlatformFile file = 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC::PlatformFileForTransitToPlatformFile(descriptor_); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_NACL) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ClosePlatformFile(file); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close(file); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No default so the compiler will warn us if a new type is added. 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *this = SerializedHandle(); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SerializedHandle::WriteHeader(const Header& hdr, Pickle* pickle) { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!pickle->WriteInt(hdr.type)) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (hdr.type == SHARED_MEMORY) { 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!pickle->WriteUInt32(hdr.size)) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 100a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (hdr.type == FILE) { 101a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!pickle->WriteInt(hdr.open_flag)) 102a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return false; 103a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SerializedHandle::ReadHeader(PickleIterator* iter, Header* hdr) { 109a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) *hdr = Header(INVALID, 0, 0); 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int type = 0; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!iter->ReadInt(&type)) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool valid_type = false; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SHARED_MEMORY: { 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 size = 0; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!iter->ReadUInt32(&size)) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hdr->size = size; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) valid_type = true; 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 123a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) case FILE: { 124a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) int open_flag = 0; 125a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!iter->ReadInt(&open_flag)) 126a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return false; 127a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) hdr->open_flag = open_flag; 128a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) valid_type = true; 129a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SOCKET: 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case CHANNEL_HANDLE: 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case INVALID: 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) valid_type = true; 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No default so the compiler will warn us if a new type is added. 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (valid_type) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hdr->type = Type(type); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return valid_type; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace proxy 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace ppapi 144