MemoryMappedFileSecurity missing in .NET 6
Solution 1:
I did a workaround. Put together the call I needed to create the memory mapped file with the correct security and call it once in the service that owns it. I changed the mainline code to use OpenExisting
after the call to the routine below so the remainder of the code can use the .NET 6 library as intended. Not ideal, but it fixed the issue.
using System.ComponentModel;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
namespace MMFService {
internal class MMFNet6Shim : IDisposable {
private bool win32Result = false;
private int cbSid = SECURITY_MAX_SID_SIZE;
private SECURITY_ATTRIBUTES securityAttributes = new SECURITY_ATTRIBUTES();
private SafeMemoryMappedFileHandle hFile;
private const int SDDL_REVISION_1 = 1;
private const int SECURITY_MAX_SID_SIZE = 68;
private const int PAGE_READWRITE = 0x04;
private const int FILE_MAP_WRITE = 0X02;
public MMFNet6Shim(FileStream fs, string DBName) {
win32Result = ConvertStringSecurityDescriptorToSecurityDescriptor("D:(A;OICI;GA;;;WD)", SDDL_REVISION_1, out securityAttributes.lpSecurityDescriptor, IntPtr.Zero);
if (!win32Result)
throw new Exception("ConvertStringSecurityDescriptorToSecurityDescriptor", new Win32Exception(Marshal.GetLastWin32Error()));
securityAttributes.nLength = Marshal.SizeOf(securityAttributes);
securityAttributes.bInheritHandle = false;
long fLen = fs.Length;
hFile = CreateFileMapping(fs.SafeFileHandle, ref securityAttributes, PAGE_READWRITE, 0, Convert.ToInt32(fLen), DBName);
if (hFile.IsInvalid)
throw new Exception("CreateFileMapping", new Win32Exception(Marshal.GetLastWin32Error()));
}
public void Dispose() {
if(!hFile.IsInvalid)
hFile.Close();
}
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES {
public int nLength;
public IntPtr lpSecurityDescriptor;
public bool bInheritHandle;
}
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor
(
[In] string StringSecurityDescriptor,
[In] int StringSDRevision,
[Out] out IntPtr SecurityDescriptor,
[Out] IntPtr SecurityDescriptorSize
);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LocalFree([In] IntPtr hMem);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern SafeMemoryMappedFileHandle CreateFileMapping(
[In] SafeFileHandle hFile,
[In][Optional] ref SECURITY_ATTRIBUTES lpAttributes,
[In] int flProtect,
[In] int dwMaximumSizeHigh,
[In] int dwMaximumSizeLow,
[In][Optional] string lpName
);
}
}