Win32Native.SECURITY_ATTRIBUTES GetProcessSecurityAttributes()
 {
     var secAttr = new Win32Native.SECURITY_ATTRIBUTES();
     secAttr.nLength = Marshal.SizeOf(secAttr);
     return secAttr;
 }
        private unsafe TransactedRegistryKey CreateSubKeyInternal(String subkey, RegistryKeyPermissionCheck permissionCheck, object registrySecurityObj)
        {
            ValidateKeyName(subkey);
            // RegCreateKeyTransacted requires a non-empty key name, so let's deal with that here.
            if (string.Empty == subkey)
            {
                throw new ArgumentException(RegistryProviderStrings.Arg_RegKeyStrEmpty);
            }

            ValidateKeyMode(permissionCheck);
            EnsureWriteable();
            subkey = FixupName(subkey); // Fixup multiple slashes to a single slash

            // only keys opened under read mode is not writable
            TransactedRegistryKey existingKey = InternalOpenSubKey(subkey, (permissionCheck != RegistryKeyPermissionCheck.ReadSubTree));
            if (existingKey != null)
            { // Key already exits
                CheckSubKeyWritePermission(subkey);
                CheckSubTreePermission(subkey, permissionCheck);
                existingKey._checkMode = permissionCheck;
                return existingKey;
            }

            CheckSubKeyCreatePermission(subkey);

            Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
            TransactedRegistrySecurity registrySecurity = registrySecurityObj as TransactedRegistrySecurity;
            // For ACL's, get the security descriptor from the RegistrySecurity.
            if (registrySecurity != null)
            {
                secAttrs = new Win32Native.SECURITY_ATTRIBUTES();
                secAttrs.nLength = (int)Marshal.SizeOf(secAttrs);

                byte[] sd = registrySecurity.GetSecurityDescriptorBinaryForm();
                // We allocate memory on the stack to improve the speed.
                // So this part of code can't be refactored into a method.
                byte* pSecDescriptor = stackalloc byte[sd.Length];
                Microsoft.PowerShell.Commands.Internal.Buffer.memcpy(sd, 0, pSecDescriptor, 0, sd.Length);
                secAttrs.pSecurityDescriptor = pSecDescriptor;
            }
            int disposition = 0;

            // By default, the new key will be writable.
            SafeRegistryHandle result = null;
            int ret = 0;
            SafeTransactionHandle safeTransactionHandle = GetTransactionHandle();

            ret = Win32Native.RegCreateKeyTransacted(_hkey,
                subkey,
                0,
                null,
                0,
                GetRegistryKeyAccess(permissionCheck != RegistryKeyPermissionCheck.ReadSubTree),
                secAttrs,
                out result,
                out disposition,
                safeTransactionHandle,
                IntPtr.Zero
                );

            if (ret == 0 && !result.IsInvalid)
            {
                TransactedRegistryKey key = new TransactedRegistryKey(result, (permissionCheck != RegistryKeyPermissionCheck.ReadSubTree), false,
                                                                      Transaction.Current, safeTransactionHandle);
                CheckSubTreePermission(subkey, permissionCheck);
                key._checkMode = permissionCheck;

                if (subkey.Length == 0)
                    key._keyName = _keyName;
                else
                    key._keyName = _keyName + "\\" + subkey;
                return key;
            }
            else if (ret != 0) // syscall failed, ret is an error code.
                Win32Error(ret, _keyName + "\\" + subkey);  // Access denied?

            BCLDebug.Assert(false, "Unexpected code path in RegistryKey::CreateSubKey");
            return null;
        }
Beispiel #3
0
        [System.Security.SecurityCritical]  // auto-generated_required
        public unsafe EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew, EventWaitHandleSecurity eventSecurity)
        {
            if (name != null)
            {
#if PLATFORM_UNIX
                throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_NamedSynchronizationPrimitives"));
#else
                if (System.IO.Path.MaxPath < name.Length)
                {
                    throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", name));
                }
#endif
            }
            Contract.EndContractBlock();
            Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
#if FEATURE_MACL
            // For ACL's, get the security descriptor from the EventWaitHandleSecurity.
            if (eventSecurity != null)
            {
                secAttrs         = new Win32Native.SECURITY_ATTRIBUTES();
                secAttrs.nLength = (int)Marshal.SizeOf(secAttrs);

                byte[] sd             = eventSecurity.GetSecurityDescriptorBinaryForm();
                byte * pSecDescriptor = stackalloc byte[sd.Length];
                Buffer.Memcpy(pSecDescriptor, 0, sd, 0, sd.Length);
                secAttrs.pSecurityDescriptor = pSecDescriptor;
            }
#endif

            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);
        }
        // ReSharper restore ParameterHidesMember
        //From MSDN: If UAC is enabled, LogonUserW returns the restricted token for interactive sessions under some conditions.
        //The details of this behavior should be documented.
        //What conditions ??????
        IntPtr CreateUserToken(
            // ReSharper disable ParameterHidesMember
             String domain,
            // ReSharper restore ParameterHidesMember
             String username,
            // ReSharper disable ParameterHidesMember
             String password)
        {
            int errorCode;
            if (Win32Native.RevertToSelf())
            {
                var token = IntPtr.Zero;
                var logonType = Win32Native.LOGON32_LOGON_BATCH;
                if (!UACFeatureIntroduced)
                {
                    logonType = Win32Native.LOGON32_LOGON_INTERACTIVE;
                }
                var startProcessForceLogonType = ConfigurationManager.AppSettings["startProcessForceLogonType"];
                if (!string.IsNullOrEmpty(startProcessForceLogonType))
                {
                    if (string.Compare(startProcessForceLogonType, "batch", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        logonType = Win32Native.LOGON32_LOGON_BATCH;
                    }
                    if (string.Compare(startProcessForceLogonType, "interactive", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        logonType = Win32Native.LOGON32_LOGON_BATCH;
                    }
                }
                if (!Win32Native.LogonUserW(username, domain, password, logonType, Win32Native.LOGON32_PROVIDER_DEFAULT, ref token))
                {
                    errorCode = Marshal.GetLastWin32Error();
                    Logger.Instance.Error(String.Format("LogonUserW() failed: error={0}", errorCode));
                    throw new Win32Exception(errorCode);
                }
                if (!UACFeatureIntroduced) return token;

                ////The DuplicateTokenEx function allows you to create a primary token that you can use in the CreateProcessAsUser function.
                ////Note that the DuplicateToken function can create only impersonation tokens, which are not valid for CreateProcessAsUser.
                var duplicateToken = IntPtr.Zero;
                var sa = new Win32Native.SECURITY_ATTRIBUTES { bInheritHandle = false };
                sa.nLength = Marshal.SizeOf(sa);
                sa.lpSecurityDescriptor = (IntPtr)0;
                if (!Win32Native.DuplicateTokenEx(token, MAXIMUM_ALLOWED, ref sa, SecurityImpersonation, TokenPrimary, ref duplicateToken))
                {
                    errorCode = Marshal.GetLastWin32Error();
                    Logger.Instance.Error(String.Format("DuplicateTokenEx() failed: error={0}", errorCode));
                    throw new Win32Exception(errorCode);
                }
                //close the token created by LogonUserW
                if (token != IntPtr.Zero)
                {
                    Win32Native.CloseHandle(token);
                    // ReSharper disable RedundantAssignment
                    token = IntPtr.Zero;
                    // ReSharper restore RedundantAssignment
                }
                return duplicateToken;
            }
            errorCode = Marshal.GetLastWin32Error();
            Logger.Instance.Error(String.Format("RevertToSelf() failed: error={0}", errorCode));
            throw new Win32Exception(errorCode);
        }
Beispiel #5
0
 internal MutexTryCodeHelper(bool initiallyOwned, MutexCleanupInfo cleanupInfo, String name, Win32Native.SECURITY_ATTRIBUTES secAttrs, Mutex mutex)
 {
     m_initiallyOwned = initiallyOwned;
     m_cleanupInfo    = cleanupInfo;
     m_name           = name;
     m_secAttrs       = secAttrs;
     m_mutex          = mutex;
 }
Beispiel #6
0
        static int CreateMutexHandle(bool initiallyOwned, String name, Win32Native.SECURITY_ATTRIBUTES securityAttribute, out SafeWaitHandle mutexHandle)
        {
            int  errorCode;
            bool fAffinity = false;

            while (true)
            {
                mutexHandle = Win32Native.CreateMutex(securityAttribute, initiallyOwned, name);
                errorCode   = Marshal.GetLastWin32Error();
                if (!mutexHandle.IsInvalid)
                {
                    break;
                }

                if (errorCode == Win32Native.ERROR_ACCESS_DENIED)
                {
                    // If a mutex with the name already exists, OS will try to open it with FullAccess.
                    // It might fail if we don't have enough access. In that case, we try to open the mutex will modify and synchronize access.
                    //

                    RuntimeHelpers.PrepareConstrainedRegions();
                    try
                    {
                        try
                        {
                        }
                        finally
                        {
#if !FEATURE_CORECLR
                            Thread.BeginThreadAffinity();
#endif
                            fAffinity = true;
                        }
                        mutexHandle = Win32Native.OpenMutex(Win32Native.MUTEX_MODIFY_STATE | Win32Native.SYNCHRONIZE, false, name);
                        if (!mutexHandle.IsInvalid)
                        {
                            errorCode = Win32Native.ERROR_ALREADY_EXISTS;
                        }
                        else
                        {
                            errorCode = Marshal.GetLastWin32Error();
                        }
                    }
                    finally
                    {
                        if (fAffinity)
                        {
#if !FEATURE_CORECLR
                            Thread.EndThreadAffinity();
#endif
                        }
                    }

                    // There could be a race condition here, the other owner of the mutex can free the mutex,
                    // We need to retry creation in that case.
                    if (errorCode != Win32Native.ERROR_FILE_NOT_FOUND)
                    {
                        if (errorCode == Win32Native.ERROR_SUCCESS)
                        {
                            errorCode = Win32Native.ERROR_ALREADY_EXISTS;
                        }
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
            return(errorCode);
        }
Beispiel #7
0
        internal void CreateMutexWithGuaranteedCleanup(bool initiallyOwned, String name, out bool createdNew, Win32Native.SECURITY_ATTRIBUTES secAttrs)
        {
#if FEATURE_LEGACYNETCF
            if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
            {
                name = WinCEObjectNameQuirk(name);
            }
#endif

            RuntimeHelpers.CleanupCode cleanupCode   = new RuntimeHelpers.CleanupCode(MutexCleanupCode);
            MutexCleanupInfo           cleanupInfo   = new MutexCleanupInfo(null, false);
            MutexTryCodeHelper         tryCodeHelper = new MutexTryCodeHelper(initiallyOwned, cleanupInfo, name, secAttrs, this);
            RuntimeHelpers.TryCode     tryCode       = new RuntimeHelpers.TryCode(tryCodeHelper.MutexTryCode);
            RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(
                tryCode,
                cleanupCode,
                cleanupInfo);
            createdNew = tryCodeHelper.m_newMutex;
        }
 internal void CreateMutexWithGuaranteedCleanup(bool initiallyOwned, string name, out bool createdNew, Win32Native.SECURITY_ATTRIBUTES secAttrs)
 {
     RuntimeHelpers.CleanupCode backoutCode        = new RuntimeHelpers.CleanupCode(this.MutexCleanupCode);
     Mutex.MutexCleanupInfo     mutexCleanupInfo   = new Mutex.MutexCleanupInfo(null, false);
     Mutex.MutexTryCodeHelper   mutexTryCodeHelper = new Mutex.MutexTryCodeHelper(initiallyOwned, mutexCleanupInfo, name, secAttrs, this);
     RuntimeHelpers.TryCode     code = new RuntimeHelpers.TryCode(mutexTryCodeHelper.MutexTryCode);
     RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(code, backoutCode, mutexCleanupInfo);
     createdNew = mutexTryCodeHelper.m_newMutex;
 }
Beispiel #9
0
        public unsafe Mutex(bool initiallyOwned, string name, out bool createdNew, MutexSecurity mutexSecurity)
        {
            if ((name != null) && (260 < name.Length))
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", new object[] { name }));
            }
            Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
            if (mutexSecurity != null)
            {
                secAttrs = new Win32Native.SECURITY_ATTRIBUTES {
                    nLength = Marshal.SizeOf(secAttrs)
                };
                byte[] securityDescriptorBinaryForm = mutexSecurity.GetSecurityDescriptorBinaryForm();
                byte * pDest = stackalloc byte[1 * securityDescriptorBinaryForm.Length];
                Buffer.memcpy(securityDescriptorBinaryForm, 0, pDest, 0, securityDescriptorBinaryForm.Length);
                secAttrs.pSecurityDescriptor = pDest;
            }
            SafeWaitHandle mutexHandle = null;
            bool           newMutex    = false;

            RuntimeHelpers.CleanupCode backoutCode = new RuntimeHelpers.CleanupCode(this.MutexCleanupCode);
            MutexCleanupInfo           cleanupInfo = new MutexCleanupInfo(mutexHandle, false);

            RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(delegate(object userData) {
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                }
                finally
                {
                    if (initiallyOwned)
                    {
                        cleanupInfo.inCriticalRegion = true;
                        Thread.BeginThreadAffinity();
                        Thread.BeginCriticalRegion();
                    }
                }
                int errorCode = 0;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                }
                finally
                {
                    errorCode = CreateMutexHandle(initiallyOwned, name, secAttrs, out mutexHandle);
                }
                if (mutexHandle.IsInvalid)
                {
                    mutexHandle.SetHandleAsInvalid();
                    if (((name != null) && (name.Length != 0)) && (6 == errorCode))
                    {
                        throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", new object[] { name }));
                    }
                    __Error.WinIOError(errorCode, name);
                }
                newMutex = errorCode != 0xb7;
                this.SetHandleInternal(mutexHandle);
                this.hasThreadAffinity = true;
            }, backoutCode, cleanupInfo);
            createdNew = newMutex;
        }
Beispiel #10
0
        private static int CreateMutexHandle(bool initiallyOwned, string name, Win32Native.SECURITY_ATTRIBUTES securityAttribute, out SafeWaitHandle mutexHandle)
        {
            bool flag  = false;
            bool flag2 = false;
            bool flag3 = false;

Label_0006:
            flag2       = false;
            flag3       = false;
            mutexHandle = Win32Native.CreateMutex(securityAttribute, initiallyOwned, name);
            int num = Marshal.GetLastWin32Error();

            if (!mutexHandle.IsInvalid || (num != 5))
            {
                return(num);
            }
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                }
                finally
                {
                    Thread.BeginThreadAffinity();
                    flag = true;
                }
                mutexHandle = Win32Native.OpenMutex(0x100001, false, name);
                if (!mutexHandle.IsInvalid)
                {
                    num = 0xb7;
                    if (Environment.IsW2k3)
                    {
                        SafeWaitHandle handle = Win32Native.OpenMutex(0x100001, false, name);
                        if (!handle.IsInvalid)
                        {
                            RuntimeHelpers.PrepareConstrainedRegions();
                            try
                            {
                                uint     num2    = 0;
                                IntPtr   ptr     = mutexHandle.DangerousGetHandle();
                                IntPtr   ptr2    = handle.DangerousGetHandle();
                                IntPtr[] handles = new IntPtr[] { ptr, ptr2 };
                                num2 = Win32Native.WaitForMultipleObjects(2, handles, true, 0);
                                GC.KeepAlive(handles);
                                if (num2 == uint.MaxValue)
                                {
                                    if (Marshal.GetLastWin32Error() != 0x57)
                                    {
                                        mutexHandle.Dispose();
                                        flag3 = true;
                                    }
                                }
                                else
                                {
                                    flag2 = true;
                                    if ((num2 >= 0) && (num2 < 2))
                                    {
                                        Win32Native.ReleaseMutex(mutexHandle);
                                        Win32Native.ReleaseMutex(handle);
                                    }
                                    else if ((num2 >= 0x80) && (num2 < 130))
                                    {
                                        Win32Native.ReleaseMutex(mutexHandle);
                                        Win32Native.ReleaseMutex(handle);
                                    }
                                    mutexHandle.Dispose();
                                }
                                goto Label_0166;
                            }
                            finally
                            {
                                handle.Dispose();
                            }
                        }
                        mutexHandle.Dispose();
                        flag3 = true;
                    }
                }
                else
                {
                    num = Marshal.GetLastWin32Error();
                }
            }
            finally
            {
                if (flag)
                {
                    Thread.EndThreadAffinity();
                }
            }
Label_0166:
            if ((flag2 || flag3) || (num == 2))
            {
                goto Label_0006;
            }
            if (num == 0)
            {
                num = 0xb7;
            }
            return(num);
        }
Beispiel #11
0
            internal MutexTryCodeHelper(bool initiallyOwned, MutexCleanupInfo cleanupInfo, String name, Win32Native.SECURITY_ATTRIBUTES secAttrs, Mutex mutex)
            {
                Debug.Assert(name == null || name.Length != 0);

                m_initiallyOwned = initiallyOwned;
                m_cleanupInfo    = cleanupInfo;
                m_name           = name;
                m_secAttrs       = secAttrs;
                m_mutex          = mutex;
            }