private void Initialize(string fileMappingName, int fileMappingSize, int initialOffset) { string lpName = fileMappingName; SharedUtils.CheckEnvironment(); SafeLocalMemHandle pSecurityDescriptor = null; new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); try { string stringSecurityDescriptor = "D:(A;OICI;FRFWGRGW;;;AU)(A;OICI;FRFWGRGW;;;S-1-5-33)"; if (!SafeLocalMemHandle.ConvertStringSecurityDescriptorToSecurityDescriptor(stringSecurityDescriptor, 1, out pSecurityDescriptor, IntPtr.Zero)) { throw new InvalidOperationException(SR.GetString("SetSecurityDescriptorFailed")); } Microsoft.Win32.NativeMethods.SECURITY_ATTRIBUTES lpFileMappingAttributes = new Microsoft.Win32.NativeMethods.SECURITY_ATTRIBUTES { lpSecurityDescriptor = pSecurityDescriptor, bInheritHandle = false }; int num = 14; int millisecondsTimeout = 0; bool flag = false; while (!flag && (num > 0)) { this.fileMappingHandle = Microsoft.Win32.NativeMethods.CreateFileMapping((IntPtr) (-1), lpFileMappingAttributes, 4, 0, fileMappingSize, lpName); if ((Marshal.GetLastWin32Error() != 5) || !this.fileMappingHandle.IsInvalid) { flag = true; } else { this.fileMappingHandle.SetHandleAsInvalid(); this.fileMappingHandle = Microsoft.Win32.NativeMethods.OpenFileMapping(2, false, lpName); if ((Marshal.GetLastWin32Error() != 2) || !this.fileMappingHandle.IsInvalid) { flag = true; continue; } num--; if (millisecondsTimeout == 0) { millisecondsTimeout = 10; } else { Thread.Sleep(millisecondsTimeout); millisecondsTimeout *= 2; } } } if (this.fileMappingHandle.IsInvalid) { throw new InvalidOperationException(SR.GetString("CantCreateFileMapping")); } this.fileViewAddress = SafeFileMapViewHandle.MapViewOfFile(this.fileMappingHandle, 2, 0, 0, UIntPtr.Zero); if (this.fileViewAddress.IsInvalid) { throw new InvalidOperationException(SR.GetString("CantMapFileView")); } Microsoft.Win32.NativeMethods.MEMORY_BASIC_INFORMATION buffer = new Microsoft.Win32.NativeMethods.MEMORY_BASIC_INFORMATION(); if (Microsoft.Win32.NativeMethods.VirtualQuery(this.fileViewAddress, ref buffer, (IntPtr) sizeof(Microsoft.Win32.NativeMethods.MEMORY_BASIC_INFORMATION)) == IntPtr.Zero) { throw new InvalidOperationException(SR.GetString("CantGetMappingSize")); } this.FileMappingSize = (int) ((uint) buffer.RegionSize); } finally { if (pSecurityDescriptor != null) { pSecurityDescriptor.Close(); } CodeAccessPermission.RevertAssert(); } Microsoft.Win32.SafeNativeMethods.InterlockedCompareExchange(this.fileViewAddress.DangerousGetHandle(), initialOffset, 0); }
private unsafe void Initialize(string fileMappingName, int fileMappingSize, int initialOffset) { string mappingName = fileMappingName; SharedUtils.CheckEnvironment(); SafeLocalMemHandle securityDescriptorPointer = null; new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); try { // The sddl string consists of these parts: // D: it's a DACL // (A; this is an allow ACE // OICI; object inherit and container inherit // FRFWGRGW;;; allow file read, file write, generic read and generic write // AU) granted to Authenticated Users // ;S-1-5-33) the same permission granted to AU is also granted to restricted services string sddlString = "D:(A;OICI;FRFWGRGW;;;AU)(A;OICI;FRFWGRGW;;;S-1-5-33)"; if (!SafeLocalMemHandle.ConvertStringSecurityDescriptorToSecurityDescriptor(sddlString, NativeMethods.SDDL_REVISION_1, out securityDescriptorPointer, IntPtr.Zero)) throw new InvalidOperationException(SR.GetString(SR.SetSecurityDescriptorFailed)); NativeMethods.SECURITY_ATTRIBUTES securityAttributes = new NativeMethods.SECURITY_ATTRIBUTES(); securityAttributes.lpSecurityDescriptor = securityDescriptorPointer; securityAttributes.bInheritHandle = false; // // // Here we call CreateFileMapping to create the memory mapped file. When CreateFileMapping fails // with ERROR_ACCESS_DENIED, we know the file mapping has been created and we then open it with OpenFileMapping. // // There is chance of a race condition between CreateFileMapping and OpenFileMapping; The memory mapped file // may actually be closed in between these two calls. When this happens, OpenFileMapping returns ERROR_FILE_NOT_FOUND. // In this case, we need to loop back and retry creating the memory mapped file. // // This loop will timeout in approximately 1.4 minutes. An InvalidOperationException is thrown in the timeout case. // // int waitRetries = 14; //((2^13)-1)*10ms == approximately 1.4mins int waitSleep = 0; bool created = false; while (!created && waitRetries > 0) { fileMappingHandle = NativeMethods.CreateFileMapping((IntPtr)(-1), securityAttributes, NativeMethods.PAGE_READWRITE, 0, fileMappingSize, mappingName); if ((Marshal.GetLastWin32Error() != NativeMethods.ERROR_ACCESS_DENIED) || !fileMappingHandle.IsInvalid) { created = true; } else { // Invalidate the old safehandle before we get rid of it. This prevents it from trying to finalize fileMappingHandle.SetHandleAsInvalid(); fileMappingHandle = NativeMethods.OpenFileMapping(NativeMethods.FILE_MAP_WRITE, false, mappingName); if ((Marshal.GetLastWin32Error() != NativeMethods.ERROR_FILE_NOT_FOUND) || !fileMappingHandle.IsInvalid) { created = true; } else { --waitRetries; if (waitSleep == 0) { waitSleep = 10; } else { System.Threading.Thread.Sleep(waitSleep); waitSleep *= 2; } } } } if (fileMappingHandle.IsInvalid) { throw new InvalidOperationException(SR.GetString(SR.CantCreateFileMapping)); } fileViewAddress = SafeFileMapViewHandle.MapViewOfFile(fileMappingHandle, NativeMethods.FILE_MAP_WRITE, 0,0, UIntPtr.Zero); if (fileViewAddress.IsInvalid) throw new InvalidOperationException(SR.GetString(SR.CantMapFileView)); // figure out what size the share memory really is. NativeMethods.MEMORY_BASIC_INFORMATION meminfo = new NativeMethods.MEMORY_BASIC_INFORMATION(); if (NativeMethods.VirtualQuery(fileViewAddress, ref meminfo, (IntPtr) sizeof(NativeMethods.MEMORY_BASIC_INFORMATION)) == IntPtr.Zero) throw new InvalidOperationException(SR.GetString(SR.CantGetMappingSize)); FileMappingSize = (int) meminfo.RegionSize; } finally { if (securityDescriptorPointer != null) securityDescriptorPointer.Close(); SecurityPermission.RevertAssert(); } SafeNativeMethods.InterlockedCompareExchange(fileViewAddress.DangerousGetHandle(), initialOffset, 0); }
unsafe internal static extern IntPtr VirtualQuery(SafeFileMapViewHandle address, ref MEMORY_BASIC_INFORMATION buffer, IntPtr sizeOfBuffer);