gpt4 book ai didi

c# - 如何在 C# 中正确设置 MemoryMappedFile 安全选项

转载 作者:行者123 更新时间:2023-11-30 18:37:48 25 4
gpt4 key购买 nike

我的问题不是如何在 C++/C# 中读取/写入共享内存 (MemoryMappedFiles),而是更多关于如何在 C# 中正确设置 MemoryMappedFile 的安全选项(我对 C# 很陌生,所以请原谅我如果这个问题很愚蠢)。

我有一个作为服务运行的进程(在 SYSTEM 帐户下),它设置了一个共享内存空间。然后我还有另一个进程,也作为服务运行(在 SYSTEM 帐户下),它访问共享内存空间。

它们的第一个版本都是用 C++ 编写的,服务器(“编写器”)主要做的(假设我想要一个 1024 字节的内存段,名称为 Global\mySegment):

HANDLE m_memoryHandle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 1024, "Global\\mySegment");
SetSecurityInfo(m_memoryHandle, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, 0, 0, (PACL) NULL, NULL);
LPVOID m_pSharedMemorySegment = MapViewOfFile(m_memoryHandle, FILE_MAP_ALL_ACCESS, 0, 0, 1024);

读者:

HANDLE m_memoryHandle = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, "Global\\mySegment");
LPVOID m_pSharedMemorySegment = MapViewOfFile(m_memoryHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);

此代码运行良好,即在任何情况下(即,如果编写器作为服务运行或在当前(登录)用户帐户(具有管理员身份)下,读者都可以访问编写器创建的共享内存空间权利)以及阅读器是否作为服务运行或在相同的当前(登录)用户帐户下运行)。

现在,我将这段代码(仅限作者)翻译成 C#,主要是这样做的:

MemoryMappedFile mappedFile = MemoryMappedFile.CreateNew(@"Global\mySegment", 1024, MemoryMappedFileAccess.ReadWrite);

对于此编写器,它仅在编写器由当前用户运行时才有效。当它作为服务启动时(因此由“SYSTEM”用户运行),阅读器不再访问共享内存空间(“访问被拒绝”,在这两种情况下,当阅读器由当前用户运行或作为SYSTEM 提供的服务)。

所以我尝试翻译C++行

SetSecurityInfo(m_memoryHandle, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, 0, 0, (PACL) NULL, NULL);

到 C#。我发现的最接近的实现是:

var security = new MemoryMappedFileSecurity();
// Create a SecurityIdentifier object for "everyone".
SecurityIdentifier everyoneSid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
security.AddAccessRule(new AccessRule<MemoryMappedFileRights>(everyoneSid, MemoryMappedFileRights.FullControl, AccessControlType.Allow));
MemoryMappedFile mappedFile = MemoryMappedFile.CreateNew(_memoryRegionName, _memRegionSize, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, security, HandleInheritability.Inheritable);

但结果是,在上述4种service-no service组合下,此时reader根本无法访问共享内存空间

考虑到这种行为对于 C# 代码来说是完全违反直觉的,我有点迷茫......

有人对如何解决这个问题有很好的实现或想法吗?

非常感谢。

最佳答案

尝试将 Global\ 添加到用于内存映射文件的名称的开头。我遇到了与您描述的完全相同的问题,但是使用了在 NETWORK 帐户下运行的服务,这解决了它。

关于c# - 如何在 C# 中正确设置 MemoryMappedFile 安全选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12194804/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com