#include "src/tracing/ipc/shared_memory_windows.h"
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <memory>
#include <random>
#include <Windows.h>
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/string_utils.h"
namespace perfetto {
std::unique_ptr<SharedMemoryWindows> SharedMemoryWindows::Create(
size_t size, Flags flags) {
base::ScopedPlatformHandle shmem_handle;
std::random_device rnd_dev;
uint64_t rnd_key = (static_cast<uint64_t>(rnd_dev()) << 32) | rnd_dev();
std::string key = "perfetto_shm_" + base::Uint64ToHexStringNoPrefix(rnd_key);
SECURITY_ATTRIBUTES security_attributes = {};
security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
if (flags & Flags::kInheritableHandles)
security_attributes.bInheritHandle = TRUE;
shmem_handle.reset(CreateFileMappingA(
INVALID_HANDLE_VALUE,
&security_attributes,
PAGE_READWRITE,
static_cast<DWORD>(size >> 32),
static_cast<DWORD>(size),
key.c_str()));
if (!shmem_handle) {
PERFETTO_PLOG("CreateFileMapping() call failed");
return nullptr;
}
void* start =
MapViewOfFile(*shmem_handle, FILE_MAP_ALL_ACCESS, 0,
0, size);
if (!start) {
PERFETTO_PLOG("MapViewOfFile() failed");
return nullptr;
}
return std::unique_ptr<SharedMemoryWindows>(new SharedMemoryWindows(
start, size, std::move(key), std::move(shmem_handle)));
}
std::unique_ptr<SharedMemoryWindows> SharedMemoryWindows::Attach(
const std::string& key) {
base::ScopedPlatformHandle shmem_handle;
shmem_handle.reset(
OpenFileMappingA(FILE_MAP_ALL_ACCESS, false, key.c_str()));
if (!shmem_handle) {
PERFETTO_PLOG("Failed to OpenFileMapping()");
return nullptr;
}
void* start =
MapViewOfFile(*shmem_handle, FILE_MAP_ALL_ACCESS, 0,
0, 0);
if (!start) {
PERFETTO_PLOG("MapViewOfFile() failed");
return nullptr;
}
MEMORY_BASIC_INFORMATION info{};
if (!VirtualQuery(start, &info, sizeof(info))) {
PERFETTO_PLOG("VirtualQuery() failed");
return nullptr;
}
size_t size = info.RegionSize;
return std::unique_ptr<SharedMemoryWindows>(
new SharedMemoryWindows(start, size, key, std::move(shmem_handle)));
}
std::unique_ptr<SharedMemoryWindows> SharedMemoryWindows::AttachToHandleWithKey(
base::ScopedPlatformHandle shmem_handle, const std::string& key) {
void* start =
MapViewOfFile(*shmem_handle, FILE_MAP_ALL_ACCESS, 0,
0, 0);
if (!start) {
PERFETTO_PLOG("MapViewOfFile() failed");
return nullptr;
}
MEMORY_BASIC_INFORMATION info{};
if (!VirtualQuery(start, &info, sizeof(info))) {
PERFETTO_PLOG("VirtualQuery() failed");
return nullptr;
}
size_t size = info.RegionSize;
return std::unique_ptr<SharedMemoryWindows>(
new SharedMemoryWindows(start, size, key, std::move(shmem_handle)));
}
SharedMemoryWindows::SharedMemoryWindows(void* start,
size_t size,
std::string key,
base::ScopedPlatformHandle handle)
: start_(start),
size_(size),
key_(std::move(key)),
handle_(std::move(handle)) {}
SharedMemoryWindows::~SharedMemoryWindows() {
if (start_)
UnmapViewOfFile(start_);
}
SharedMemoryWindows::Factory::~Factory() = default;
std::unique_ptr<SharedMemory> SharedMemoryWindows::Factory::CreateSharedMemory(
size_t size) {
return SharedMemoryWindows::Create(size);
}
}
#endif