1// Copyright 2014 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/embedder/simple_platform_shared_buffer.h" 6 7#include <windows.h> 8 9#include <limits> 10 11#include "base/logging.h" 12#include "base/sys_info.h" 13#include "mojo/embedder/platform_handle.h" 14#include "mojo/embedder/scoped_platform_handle.h" 15 16namespace mojo { 17namespace embedder { 18 19// SimplePlatformSharedBuffer -------------------------------------------------- 20 21bool SimplePlatformSharedBuffer::Init() { 22 DCHECK(!handle_.is_valid()); 23 24 // TODO(vtl): Currently, we only support mapping up to 2^32-1 bytes. 25 if (static_cast<uint64_t>(num_bytes_) > 26 static_cast<uint64_t>(std::numeric_limits<DWORD>::max())) { 27 return false; 28 } 29 30 // IMPORTANT NOTE: Unnamed objects are NOT SECURABLE. Thus if we ever want to 31 // share read-only to other processes, we'll have to name our file mapping 32 // object. 33 // TODO(vtl): Unlike |base::SharedMemory|, we don't round up the size (to a 34 // multiple of 64 KB). This may cause problems with NaCl. Cross this bridge 35 // when we get there. crbug.com/210609 36 handle_.reset(PlatformHandle(CreateFileMapping(INVALID_HANDLE_VALUE, 37 nullptr, 38 PAGE_READWRITE, 39 0, 40 static_cast<DWORD>(num_bytes_), 41 nullptr))); 42 if (!handle_.is_valid()) { 43 PLOG(ERROR) << "CreateFileMapping"; 44 return false; 45 } 46 47 return true; 48} 49 50bool SimplePlatformSharedBuffer::InitFromPlatformHandle( 51 ScopedPlatformHandle platform_handle) { 52 DCHECK(!handle_.is_valid()); 53 54 // TODO(vtl): Implement. 55 NOTIMPLEMENTED(); 56 return false; 57} 58 59scoped_ptr<PlatformSharedBufferMapping> SimplePlatformSharedBuffer::MapImpl( 60 size_t offset, 61 size_t length) { 62 size_t offset_rounding = offset % base::SysInfo::VMAllocationGranularity(); 63 size_t real_offset = offset - offset_rounding; 64 size_t real_length = length + offset_rounding; 65 66 // This should hold (since we checked |num_bytes| versus the maximum value of 67 // |off_t| on creation, but it never hurts to be paranoid. 68 DCHECK_LE(static_cast<uint64_t>(real_offset), 69 static_cast<uint64_t>(std::numeric_limits<DWORD>::max())); 70 71 void* real_base = MapViewOfFile(handle_.get().handle, 72 FILE_MAP_READ | FILE_MAP_WRITE, 73 0, 74 static_cast<DWORD>(real_offset), 75 real_length); 76 if (!real_base) { 77 PLOG(ERROR) << "MapViewOfFile"; 78 return scoped_ptr<PlatformSharedBufferMapping>(); 79 } 80 81 void* base = static_cast<char*>(real_base) + offset_rounding; 82 return scoped_ptr<PlatformSharedBufferMapping>( 83 new SimplePlatformSharedBufferMapping( 84 base, length, real_base, real_length)); 85} 86 87// SimplePlatformSharedBufferMapping ------------------------------------------- 88 89void SimplePlatformSharedBufferMapping::Unmap() { 90 BOOL result = UnmapViewOfFile(real_base_); 91 PLOG_IF(ERROR, !result) << "UnmapViewOfFile"; 92} 93 94} // namespace embedder 95} // namespace mojo 96