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));
            }
        }
Example #4
0
        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();
                }
            }
        }