| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- //----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //----------------------------------------------------------------------------
- namespace System.ServiceModel.Activation
- {
- using System;
- using System.Collections.Generic;
- using System.Runtime;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
- using System.Security;
- using System.Security.Principal;
- using System.Security.Permissions;
- using System.ServiceModel.Channels;
- using System.Threading;
- using System.ServiceModel;
- using System.ComponentModel;
- unsafe class SharedMemory : IDisposable
- {
- SafeFileMappingHandle fileMapping;
- SharedMemory(SafeFileMappingHandle fileMapping)
- {
- this.fileMapping = fileMapping;
- }
- [PermissionSet(SecurityAction.Demand, Unrestricted = true), SecuritySafeCritical]
- 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();
- }
- }
- public void Dispose()
- {
- if (fileMapping != null)
- {
- fileMapping.Close();
- fileMapping = null;
- }
- }
- 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));
- }
- }
- [PermissionSet(SecurityAction.Demand, Unrestricted = true), SecuritySafeCritical]
- public static string Read(string name)
- {
- string content;
- if (Read(name, out content))
- {
- return content;
- }
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(UnsafeNativeMethods.ERROR_FILE_NOT_FOUND));
- }
- [PermissionSet(SecurityAction.Demand, Unrestricted = true), SecuritySafeCritical]
- [ResourceConsumption(ResourceScope.Machine)]
- public static bool Read(string name, out string content)
- {
- content = null;
- SafeFileMappingHandle fileMapping = UnsafeNativeMethods.OpenFileMapping(UnsafeNativeMethods.FILE_MAP_READ, false, ListenerConstants.GlobalPrefix + name);
- int errorCode = Marshal.GetLastWin32Error();
- if (fileMapping.IsInvalid)
- {
- fileMapping.SetHandleAsInvalid();
- fileMapping.Close();
- if (errorCode == UnsafeNativeMethods.ERROR_FILE_NOT_FOUND)
- {
- return false;
- }
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
- }
- try
- {
- SafeViewOfFileHandle view;
- if (!GetView(fileMapping, false, out view))
- {
- return false;
- }
- try
- {
- SharedMemoryContents* contents = (SharedMemoryContents*)view.DangerousGetHandle();
- content = contents->isInitialized ? contents->pipeGuid.ToString() : null;
- return true;
- }
- finally
- {
- view.Close();
- }
- }
- finally
- {
- fileMapping.Close();
- }
- }
- [StructLayout(LayoutKind.Sequential)]
- struct SharedMemoryContents
- {
- public bool isInitialized;
- public Guid pipeGuid;
- }
- }
- }
|