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
        );

    }
}