shared_rwlock\sys\windows/
shared_memory.rs

1// C++ Original code
2// - open, create, close: https://github.com/SARDONYX-forks/CommonLibVR/blob/ng/src/REL/ID.cpp
3// SPDX-FileCopyrightText: (C) 2018 Ryan-rsm-McKenzie
4// SPDX-License-Identifier: MIT
5//
6// SPDX-FileCopyrightText: (C) 2025 SARDONYX
7// SPDX-License-Identifier: Apache-2.0 OR MIT
8
9//! Memory-mapped file handling module.
10//!
11//! This module provides a safe wrapper around Windows memory-mapped files,
12//! allowing users to open and manipulate shared memory regions.
13//!
14//! This is the code to realize the data sharing of `AddressLibrary`.
15//!
16//! The intention is to avoid wasteful use of memory by referencing the same database.
17
18pub use super::errors::MemoryMapError;
19use core::ffi::c_void;
20use windows::{
21    Win32::{Foundation::HANDLE, System::Memory::MEMORY_MAPPED_VIEW_ADDRESS},
22    core::HSTRING,
23};
24
25pub fn open(
26    name: &HSTRING,
27    size: usize,
28) -> Result<(HANDLE, MEMORY_MAPPED_VIEW_ADDRESS), MemoryMapError> {
29    use windows::Win32::Foundation::CloseHandle;
30    use windows::Win32::System::Memory::{
31        FILE_MAP_READ, FILE_MAP_WRITE, MapViewOfFile, OpenFileMappingW,
32    };
33
34    let handle = unsafe { OpenFileMappingW((FILE_MAP_READ | FILE_MAP_WRITE).0, false, name) }
35        .map_err(|e| MemoryMapError::OpenMapping { source: e })?;
36
37    // MapViewOfFile: https://learn.microsoft.com/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffile
38    let view_address = unsafe { MapViewOfFile(handle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, size) };
39    if view_address.Value.is_null() {
40        let _ = unsafe { CloseHandle(handle) };
41        return Err(MemoryMapError::MapView);
42    }
43
44    Ok((handle, view_address))
45}
46
47pub fn create(
48    name: &windows::core::HSTRING,
49    size: usize,
50) -> Result<(HANDLE, MEMORY_MAPPED_VIEW_ADDRESS), MemoryMapError> {
51    use windows::Win32::Foundation::CloseHandle;
52    use windows::Win32::Foundation::INVALID_HANDLE_VALUE;
53    use windows::Win32::System::Memory::{
54        CreateFileMappingW, FILE_MAP_READ, FILE_MAP_WRITE, MapViewOfFile, PAGE_READWRITE,
55    };
56
57    // CreateFileMappingW: https://learn.microsoft.com/windows/win32/api/memoryapi/nf-memoryapi-createfilemappingw
58
59    let handle = unsafe {
60        let (max, min) = ((size >> 32) as u32, size as u32); // Split to high, low
61        CreateFileMappingW(INVALID_HANDLE_VALUE, None, PAGE_READWRITE, max, min, name)
62    }
63    .map_err(|e| MemoryMapError::CreateMapping { source: e })?;
64
65    let view = {
66        let view_address =
67            unsafe { MapViewOfFile(handle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, size) };
68
69        if view_address.Value.is_null() {
70            // CloseHandle: https://learn.microsoft.com/windows/win32/api/handleapi/nf-handleapi-closehandle
71            let _ = unsafe { CloseHandle(handle) };
72            return Err(MemoryMapError::MapView);
73        }
74
75        view_address
76    };
77
78    Ok((handle, view))
79}
80
81pub fn close(handle: *mut c_void, view: *mut c_void) -> Result<(), MemoryMapError> {
82    use windows::Win32::Foundation::CloseHandle;
83    use windows::Win32::System::Memory::UnmapViewOfFile;
84
85    // view is NonNull
86    {
87        let view = MEMORY_MAPPED_VIEW_ADDRESS { Value: view };
88        unsafe { UnmapViewOfFile(view) }.map_err(|e| MemoryMapError::UnmapView { source: e })?;
89    }
90
91    unsafe { CloseHandle(HANDLE(handle)) }
92        .map_err(|e| MemoryMapError::CloseHandle { source: e })?;
93
94    Ok(())
95}