internal static unsafe void AcquireReservedMutex(ref bool bHandleObtained) { SafeWaitHandle handle = null; bHandleObtained = false; if (Environment.IsW2k3) { if (s_ReservedMutex == null) { Win32Native.SECURITY_ATTRIBUTES security_attributes; MutexSecurity security = new MutexSecurity(); SecurityIdentifier identity = new SecurityIdentifier(WellKnownSidType.WorldSid, null); security.AddAccessRule(new MutexAccessRule(identity, MutexRights.FullControl, AccessControlType.Allow)); security_attributes = new Win32Native.SECURITY_ATTRIBUTES { nLength = Marshal.SizeOf(security_attributes) }; byte[] securityDescriptorBinaryForm = security.GetSecurityDescriptorBinaryForm(); byte * pDest = stackalloc byte[(IntPtr)securityDescriptorBinaryForm.Length]; Buffer.memcpy(securityDescriptorBinaryForm, 0, pDest, 0, securityDescriptorBinaryForm.Length); security_attributes.pSecurityDescriptor = pDest; RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { handle = Win32Native.CreateMutex(security_attributes, false, @"Global\CLR_RESERVED_MUTEX_NAME"); handle.SetAsReservedMutex(); } int errorCode = Marshal.GetLastWin32Error(); if (handle.IsInvalid) { handle.SetHandleAsInvalid(); __Error.WinIOError(errorCode, @"Global\CLR_RESERVED_MUTEX_NAME"); } Mutex mutex = new Mutex(handle); Interlocked.CompareExchange <Mutex>(ref s_ReservedMutex, mutex, null); } RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { try { s_ReservedMutex.WaitOne(); bHandleObtained = true; } catch (AbandonedMutexException) { bHandleObtained = true; } } } }
/// <summary> /// Create service /// </summary> /// <param name="name">Service name</param> /// <param name="displayName">Display name</param> /// <param name="pathToBinary">Path to file</param> /// <param name="commandLine">Command line</param> public static void CreateService( string name, string displayName, string pathToBinary, string commandLine) { SafeWaitHandle schSCManager = OpenSCManager(null, null, SCM_ACCESS.SC_MANAGER_ALL_ACCESS); if (schSCManager.IsInvalid) { throw new Exception(string.Format("OpenSCManager failed {0}", Marshal.GetLastWin32Error())); } SafeWaitHandle schService = null; try { schService = CreateService( schSCManager, name, displayName, SERVICE_ACCESS.SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, pathToBinary + " " + commandLine, null, 0, null, null, null); if (schService.IsInvalid) { throw new Exception( String.Format( "Cannot create service {0}. Error {1}", name, Marshal.GetLastWin32Error())); } } finally { if (schService != null && !schService.IsInvalid) { CloseServiceHandle(schService); schService.SetHandleAsInvalid(); } } }
/// <summary>Gets or creates <see cref="Mutex" /> instance, allowing a <see cref="MutexSecurity" /> to be optionally specified to set it during the mutex creation.</summary> /// <param name="initiallyOwned"><see langword="true" /> to give the calling thread initial ownership of the named system mutex if the named system mutex is created as a result of this call; otherwise, <see langword="false" />.</param> /// <param name="name">The optional name of the system mutex. If this argument is set to <see langword="null" /> or <see cref="string.Empty" />, a local mutex is created.</param> /// <param name="createdNew">When this method returns, this argument is always set to <see langword="true" /> if a local mutex is created; that is, when <paramref name="name" /> is <see langword="null" /> or <see cref="string.Empty" />. If <paramref name="name" /> has a valid non-empty value, this argument is set to <see langword="true" /> when the system mutex is created, or it is set to <see langword="false" /> if an existing system mutex is found with that name. This parameter is passed uninitialized.</param> /// <param name="mutexSecurity">The optional mutex access control security to apply.</param> /// <returns>An object that represents a system mutex, if named, or a local mutex, if nameless.</returns> /// <exception cref="ArgumentException">.NET Framework only: The length of the name exceeds the maximum limit.</exception> /// <exception cref="WaitHandleCannotBeOpenedException">A mutex handle with system-wide <paramref name="name" /> cannot be created. A mutex handle of a different type might have the same name.</exception> public static unsafe Mutex Create(bool initiallyOwned, string?name, out bool createdNew, MutexSecurity?mutexSecurity) { if (mutexSecurity == null) { return(new Mutex(initiallyOwned, name, out createdNew)); } uint mutexFlags = initiallyOwned ? Interop.Kernel32.CREATE_MUTEX_INITIAL_OWNER : 0; fixed(byte *pSecurityDescriptor = mutexSecurity.GetSecurityDescriptorBinaryForm()) { var secAttrs = new Interop.Kernel32.SECURITY_ATTRIBUTES { nLength = (uint)sizeof(Interop.Kernel32.SECURITY_ATTRIBUTES), lpSecurityDescriptor = (IntPtr)pSecurityDescriptor }; SafeWaitHandle handle = Interop.Kernel32.CreateMutexEx( (IntPtr)(&secAttrs), name, mutexFlags, (uint)MutexRights.FullControl // Equivalent to MUTEX_ALL_ACCESS ); int errorCode = Marshal.GetLastWin32Error(); if (handle.IsInvalid) { handle.SetHandleAsInvalid(); if (errorCode == Interop.Errors.ERROR_FILENAME_EXCED_RANGE) { throw new ArgumentException(SR.Argument_WaitHandleNameTooLong, nameof(name)); } if (errorCode == Interop.Errors.ERROR_INVALID_HANDLE) { throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name)); } throw Win32Marshal.GetExceptionForWin32Error(errorCode, name); } createdNew = (errorCode != Interop.Errors.ERROR_ALREADY_EXISTS); return(CreateAndReplaceHandle(handle)); } }
internal void MutexTryCode(object userData) { SafeWaitHandle mutexHandle = null; // try block RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { if (m_initiallyOwned) { m_cleanupInfo.inCriticalRegion = true; #if !FEATURE_CORECLR Thread.BeginThreadAffinity(); Thread.BeginCriticalRegion(); #endif //!FEATURE_CORECLR } } int errorCode = 0; RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { errorCode = CreateMutexHandle(m_initiallyOwned, m_name, m_secAttrs, out mutexHandle); } if (mutexHandle.IsInvalid) { mutexHandle.SetHandleAsInvalid(); if (null != m_name && 0 != m_name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode) { throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", m_name)); } __Error.WinIOError(errorCode, m_name); } m_newMutex = errorCode != Win32Native.ERROR_ALREADY_EXISTS; m_mutex.SetHandleInternal(mutexHandle); mutexHandle.SetAsMutex(); m_mutex.hasThreadAffinity = true; }
public EventWaitHandle(bool initialState, EventResetMode mode, string name) { if (name != null) { #if PLATFORM_UNIX throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives); #else if (Interop.Kernel32.MAX_PATH < name.Length) { throw new ArgumentException(SR.Format(SR.Argument_WaitHandleNameTooLong, name, Interop.Kernel32.MAX_PATH), nameof(name)); } #endif } uint eventFlags = initialState ? Win32Native.CREATE_EVENT_INITIAL_SET : 0; switch (mode) { case EventResetMode.ManualReset: eventFlags |= Win32Native.CREATE_EVENT_MANUAL_RESET; break; case EventResetMode.AutoReset: break; default: throw new ArgumentException(SR.Format(SR.Argument_InvalidFlag, name)); } ; SafeWaitHandle _handle = Win32Native.CreateEventEx(null, name, eventFlags, AccessRights); if (_handle.IsInvalid) { int errorCode = Marshal.GetLastWin32Error(); _handle.SetHandleAsInvalid(); if (null != name && 0 != name.Length && Interop.Errors.ERROR_INVALID_HANDLE == errorCode) { throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name)); } throw Win32Marshal.GetExceptionForWin32Error(errorCode, name); } SetHandleInternal(_handle); }
internal void MutexTryCode(object userData) { SafeWaitHandle safeWaitHandle = null; RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { if (this.m_initiallyOwned) { this.m_cleanupInfo.inCriticalRegion = true; Thread.BeginThreadAffinity(); Thread.BeginCriticalRegion(); } } int num = 0; RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { num = Mutex.CreateMutexHandle(this.m_initiallyOwned, this.m_name, this.m_secAttrs, out safeWaitHandle); } if (safeWaitHandle.IsInvalid) { safeWaitHandle.SetHandleAsInvalid(); if (this.m_name != null && this.m_name.Length != 0 && 6 == num) { throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", new object[] { this.m_name })); } __Error.WinIOError(num, this.m_name); } this.m_newMutex = (num != 183); this.m_mutex.SetHandleInternal(safeWaitHandle); this.m_mutex.hasThreadAffinity = true; }
public EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew) { if (null != name && System.IO.Path.MAX_PATH < name.Length) { throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", name)); } Win32Native.SECURITY_ATTRIBUTES secAttrs = null; SafeWaitHandle _handle = null; Boolean isManualReset; switch (mode) { case EventResetMode.ManualReset: isManualReset = true; break; case EventResetMode.AutoReset: isManualReset = false; break; default: throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag", name)); } ; _handle = Win32Native.CreateEvent(secAttrs, isManualReset, initialState, name); int errorCode = Marshal.GetLastWin32Error(); if (_handle.IsInvalid) { _handle.SetHandleAsInvalid(); if (null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode) { throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", name)); } __Error.WinIOError(errorCode, name); } createdNew = errorCode != Win32Native.ERROR_ALREADY_EXISTS; SetHandleInternal(_handle); }
public static void SafeWaitHandleExtensions_set() { var wh = new MyWaitHandle(); var swhExpected = new SafeWaitHandle(new IntPtr(5), true); wh.SetSafeWaitHandle(swhExpected); var swh = wh.GetSafeWaitHandle(); Assert.Equal(swhExpected, swh); wh.SetSafeWaitHandle(null); swh = wh.GetSafeWaitHandle(); Assert.NotNull(swh); Assert.Equal(new IntPtr(-1), swh.DangerousGetHandle()); // Prevent finalization. Closing of the bogus handle has unpredictable results. swhExpected.SetHandleAsInvalid(); }