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; }
[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); }
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; }
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); }
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; }
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; }
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); }
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; }