예제 #1
0
        public unsafe Semaphore(int initialCount, int maximumCount, string name, out bool createdNew, SemaphoreSecurity semaphoreSecurity)
#endif
        {
            if (initialCount < 0)
            {
                throw new ArgumentOutOfRangeException("initialCount", SR.GetString(SR.ArgumentOutOfRange_NeedNonNegNumRequired));
            }

            if (maximumCount < 1)
            {
                throw new ArgumentOutOfRangeException("maximumCount", SR.GetString(SR.ArgumentOutOfRange_NeedNonNegNumRequired));
            }

            if (initialCount > maximumCount)
            {
                throw new ArgumentException(SR.GetString(SR.Argument_SemaphoreInitialMaximum));
            }

            if (null != name && MAX_PATH < name.Length)
            {
                throw new ArgumentException(SR.GetString(SR.Argument_WaitHandleNameTooLong));
            }
            SafeWaitHandle myHandle;

#if !FEATURE_PAL && !FEATURE_NETCORE
            // For ACL's, get the security descriptor from the SemaphoreSecurity.
            if (semaphoreSecurity != null)
            {
                NativeMethods.SECURITY_ATTRIBUTES secAttrs = null;
                secAttrs         = new NativeMethods.SECURITY_ATTRIBUTES();
                secAttrs.nLength = (int)Marshal.SizeOf(secAttrs);
                byte[] sd = semaphoreSecurity.GetSecurityDescriptorBinaryForm();
                fixed(byte *pSecDescriptor = sd)
                {
                    secAttrs.lpSecurityDescriptor = new SafeLocalMemHandle((IntPtr)pSecDescriptor, false);
                    myHandle = SafeNativeMethods.CreateSemaphore(secAttrs, initialCount, maximumCount, name);
                }
            }
            else
            {
#endif
            myHandle = SafeNativeMethods.CreateSemaphore(null, initialCount, maximumCount, name);
#if !FEATURE_PAL && !FEATURE_NETCORE
        }
#endif
            int errorCode = Marshal.GetLastWin32Error();
            if (myHandle.IsInvalid)
            {
                if (null != name && 0 != name.Length && NativeMethods.ERROR_INVALID_HANDLE == errorCode)
                {
                    throw new WaitHandleCannotBeOpenedException(SR.GetString(SR.WaitHandleCannotBeOpenedException_InvalidHandle, name));
                }
                InternalResources.WinIOError();
            }
            createdNew          = errorCode != NativeMethods.ERROR_ALREADY_EXISTS;
            this.SafeWaitHandle = myHandle;
        }
예제 #2
0
        /// <summary>Gets or creates an <see cref="Semaphore" /> instance, allowing a <see cref="SemaphoreSecurity " /> instance to be optionally specified to set it during the event creation.</summary>
        /// <param name="initialCount">The initial number of requests for the semaphore that can be satisfied concurrently.</param>
        /// <param name="maximumCount">The maximum number of requests for the semaphore that can be satisfied concurrently.</param>
        /// <param name="name">Optional argument to create a system semaphore. Set to <see langword="null" /> or <see cref="string.Empty" /> to create a local semaphore.</param>
        /// <param name="createdNew">When this method returns, this argument is always set to <see langword="true" /> if a local semaphore 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 semaphore is created, or it is set to <see langword="false" /> if an existing system semaphore is found with that name. This parameter is passed uninitialized.</param>
        /// <param name="semaphoreSecurity">The optional semaphore access control security to apply.</param>
        /// <returns>An object that represents a system semaphore, if named, or a local semaphore, if nameless.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="initialCount" /> is a negative number.
        /// -or-
        /// <paramref name="maximumCount" /> is not a positive number.</exception>
        /// <exception cref="ArgumentException"><paramref name="initialCount" /> is greater than <paramref name="maximumCount" />.</exception>
        /// <exception cref="WaitHandleCannotBeOpenedException">A semaphore handle with the system-wide name '<paramref name="name" />' cannot be created. A semaphore handle of a different type might have the same name.</exception>
        public static unsafe Semaphore Create(int initialCount, int maximumCount, string name, out bool createdNew, SemaphoreSecurity semaphoreSecurity)
        {
            if (semaphoreSecurity == null)
            {
                return(new Semaphore(initialCount, maximumCount, name, out createdNew));
            }

            if (initialCount < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(initialCount), SR.ArgumentOutOfRange_NeedNonNegNum);
            }

            if (maximumCount < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(maximumCount), SR.ArgumentOutOfRange_NeedPosNum);
            }

            if (initialCount > maximumCount)
            {
                throw new ArgumentException(SR.Argument_SemaphoreInitialMaximum);
            }

            fixed(byte *pSecurityDescriptor = semaphoreSecurity.GetSecurityDescriptorBinaryForm())
            {
                var secAttrs = new Interop.Kernel32.SECURITY_ATTRIBUTES
                {
                    nLength = (uint)sizeof(Interop.Kernel32.SECURITY_ATTRIBUTES),
                    lpSecurityDescriptor = (IntPtr)pSecurityDescriptor
                };

                SafeWaitHandle handle = Interop.Kernel32.CreateSemaphoreEx(
                    (IntPtr)(&secAttrs),
                    initialCount,
                    maximumCount,
                    name,
                    0,                                // This parameter is reserved and must be 0.
                    (uint)SemaphoreRights.FullControl // Equivalent to SEMAPHORE_ALL_ACCESS
                    );

                ValidateHandle(handle, name, out createdNew);

                Semaphore      semaphore = new Semaphore(initialCount, maximumCount);
                SafeWaitHandle old       = semaphore.SafeWaitHandle;

                semaphore.SafeWaitHandle = handle;
                old.Dispose();

                return(semaphore);
            }
        }
예제 #3
0
        public unsafe Semaphore(int initialCount, int maximumCount, string name, out bool createdNew, SemaphoreSecurity semaphoreSecurity)
        {
            SafeWaitHandle handle;

            if (initialCount < 0)
            {
                throw new ArgumentOutOfRangeException("initialCount", SR.GetString("ArgumentOutOfRange_NeedNonNegNumRequired"));
            }
            if (maximumCount < 1)
            {
                throw new ArgumentOutOfRangeException("maximumCount", SR.GetString("ArgumentOutOfRange_NeedNonNegNumRequired"));
            }
            if (initialCount > maximumCount)
            {
                throw new ArgumentException(SR.GetString("Argument_SemaphoreInitialMaximum"));
            }
            if ((name != null) && (MAX_PATH < name.Length))
            {
                throw new ArgumentException(SR.GetString("Argument_WaitHandleNameTooLong"));
            }
            if (semaphoreSecurity != null)
            {
                Microsoft.Win32.NativeMethods.SECURITY_ATTRIBUTES structure = null;
                structure = new Microsoft.Win32.NativeMethods.SECURITY_ATTRIBUTES {
                    nLength = Marshal.SizeOf(structure)
                };
                fixed(byte *numRef = semaphoreSecurity.GetSecurityDescriptorBinaryForm())
                {
                    structure.lpSecurityDescriptor = new SafeLocalMemHandle((IntPtr)numRef, false);
                    handle = Microsoft.Win32.SafeNativeMethods.CreateSemaphore(structure, initialCount, maximumCount, name);
                }
            }
            else
            {
                handle = Microsoft.Win32.SafeNativeMethods.CreateSemaphore(null, initialCount, maximumCount, name);
            }
            int num = Marshal.GetLastWin32Error();

            if (handle.IsInvalid)
            {
                if (((name != null) && (name.Length != 0)) && (6 == num))
                {
                    throw new WaitHandleCannotBeOpenedException(SR.GetString("WaitHandleCannotBeOpenedException_InvalidHandle", new object[] { name }));
                }
                InternalResources.WinIOError();
            }
            createdNew          = num != 0xb7;
            base.SafeWaitHandle = handle;
        }