private static bool GetView(SafeFileMappingHandle fileMapping, bool writable, out SafeViewOfFileHandle handle) { handle = UnsafeNativeMethods.MapViewOfFile(fileMapping, writable ? 2 : 4, 0, 0, (IntPtr) sizeof(SharedMemoryContents)); int error = Marshal.GetLastWin32Error(); if (!handle.IsInvalid) { return true; } handle.SetHandleAsInvalid(); fileMapping.Close(); if (writable || (error != 2)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error)); } return false; }
public static unsafe SharedMemory Create(string name, Guid content, List<SecurityIdentifier> allowedSids) { int errorCode = UnsafeNativeMethods.ERROR_SUCCESS; byte[] binarySecurityDescriptor = SecurityDescriptorHelper.FromSecurityIdentifiers(allowedSids, UnsafeNativeMethods.GENERIC_READ); SafeFileMappingHandle fileMapping; UnsafeNativeMethods.SECURITY_ATTRIBUTES securityAttributes = new UnsafeNativeMethods.SECURITY_ATTRIBUTES(); fixed (byte* pinnedSecurityDescriptor = binarySecurityDescriptor) { securityAttributes.lpSecurityDescriptor = (IntPtr)pinnedSecurityDescriptor; fileMapping = UnsafeNativeMethods.CreateFileMapping((IntPtr)(-1), securityAttributes, UnsafeNativeMethods.PAGE_READWRITE, 0, sizeof(SharedMemoryContents), name); errorCode = Marshal.GetLastWin32Error(); } if (fileMapping.IsInvalid) { fileMapping.SetHandleAsInvalid(); fileMapping.Close(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode)); } SharedMemory sharedMemory = new SharedMemory(fileMapping); SafeViewOfFileHandle view; // Ignore return value. GetView(fileMapping, true, out view); try { SharedMemoryContents* contents = (SharedMemoryContents*)view.DangerousGetHandle(); contents->pipeGuid = content; Thread.MemoryBarrier(); contents->isInitialized = true; return sharedMemory; } finally { view.Close(); } }
static bool GetView(SafeFileMappingHandle fileMapping, bool writable, out SafeViewOfFileHandle handle) { handle = UnsafeNativeMethods.MapViewOfFile(fileMapping, writable ? UnsafeNativeMethods.FILE_MAP_WRITE : UnsafeNativeMethods.FILE_MAP_READ, 0, 0, (IntPtr)sizeof(SharedMemoryContents)); int errorCode = Marshal.GetLastWin32Error(); if (!handle.IsInvalid) { return true; } else { handle.SetHandleAsInvalid(); fileMapping.Close(); // Only return false when it's reading time. if (!writable && errorCode == UnsafeNativeMethods.ERROR_FILE_NOT_FOUND) { return false; } throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode)); } }
public unsafe static bool TryCreate(List<SecurityIdentifier> allowedSids, Uri pipeUri, string sharedMemoryName, out PipeSharedMemory result) { Guid pipeGuid = Guid.NewGuid(); string pipeName = BuildPipeName(pipeGuid.ToString()); byte[] binarySecurityDescriptor; try { binarySecurityDescriptor = SecurityDescriptorHelper.FromSecurityIdentifiers(allowedSids, UnsafeNativeMethods.GENERIC_READ); } catch (Win32Exception e) { // While Win32exceptions are not expected, if they do occur we need to obey the pipe/communication exception model. Exception innerException = new PipeException(e.Message, e); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(innerException.Message, innerException)); } SafeFileMappingHandle fileMapping; int error; result = null; fixed (byte* pinnedSecurityDescriptor = binarySecurityDescriptor) { UnsafeNativeMethods.SECURITY_ATTRIBUTES securityAttributes = new UnsafeNativeMethods.SECURITY_ATTRIBUTES(); securityAttributes.lpSecurityDescriptor = (IntPtr)pinnedSecurityDescriptor; fileMapping = UnsafeNativeMethods.CreateFileMapping((IntPtr)(-1), securityAttributes, UnsafeNativeMethods.PAGE_READWRITE, 0, sizeof(SharedMemoryContents), sharedMemoryName); error = Marshal.GetLastWin32Error(); } if (fileMapping.IsInvalid) { fileMapping.SetHandleAsInvalid(); if (error == UnsafeNativeMethods.ERROR_ACCESS_DENIED) { return false; } else { Exception innerException = new PipeException(SR.GetString(SR.PipeNameCantBeReserved, pipeUri.AbsoluteUri, PipeError.GetErrorString(error)), error); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new AddressAccessDeniedException(innerException.Message, innerException)); } } // now we have a valid file mapping handle if (error == UnsafeNativeMethods.ERROR_ALREADY_EXISTS) { fileMapping.Close(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreatePipeNameInUseException(error, pipeUri)); } PipeSharedMemory pipeSharedMemory = new PipeSharedMemory(fileMapping, pipeUri, pipeName); bool disposeSharedMemory = true; try { pipeSharedMemory.InitializeContents(pipeGuid); disposeSharedMemory = false; result = pipeSharedMemory; if (TD.PipeSharedMemoryCreatedIsEnabled()) { TD.PipeSharedMemoryCreated(sharedMemoryName); } return true; } finally { if (disposeSharedMemory) { pipeSharedMemory.Dispose(); } } }