public unsafe Mutex(bool initiallyOwned, String name, out bool createdNew, MutexSecurity mutexSecurity) { if(null != name && System.IO.Path.MAX_PATH < name.Length) { throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong",name)); } Contract.EndContractBlock(); Win32Native.SECURITY_ATTRIBUTES secAttrs = null; #if !FEATURE_PAL && FEATURE_MACL // For ACL's, get the security descriptor from the MutexSecurity. if (mutexSecurity != null) { secAttrs = new Win32Native.SECURITY_ATTRIBUTES(); secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); byte[] sd = mutexSecurity.GetSecurityDescriptorBinaryForm(); byte* pSecDescriptor = stackalloc byte[sd.Length]; Buffer.memcpy(sd, 0, pSecDescriptor, 0, sd.Length); secAttrs.pSecurityDescriptor = pSecDescriptor; } #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; }
public unsafe Mutex(bool initiallyOwned, String name, out bool createdNew, MutexSecurity mutexSecurity) { if (name == string.Empty) { // Empty name is treated as an unnamed mutex. Set to null, and we will check for null from now on. name = null; } #if !PLATFORM_UNIX if (name != null && System.IO.Path.MaxPath < name.Length) { throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name"); } #endif Contract.EndContractBlock(); Win32Native.SECURITY_ATTRIBUTES secAttrs = null; #if FEATURE_MACL // For ACL's, get the security descriptor from the MutexSecurity. if (mutexSecurity != null) { secAttrs = new Win32Native.SECURITY_ATTRIBUTES(); secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); byte[] sd = mutexSecurity.GetSecurityDescriptorBinaryForm(); byte* pSecDescriptor = stackalloc byte[sd.Length]; Buffer.Memcpy(pSecDescriptor, 0, sd, 0, sd.Length); secAttrs.pSecurityDescriptor = pSecDescriptor; } #endif CreateMutexWithGuaranteedCleanup(initiallyOwned, name, out createdNew, secAttrs); }
public unsafe Mutex(bool initiallyOwned, String name, out bool createdNew, MutexSecurity mutexSecurity) { 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 MutexSecurity. if (mutexSecurity != null) { secAttrs = new Win32Native.SECURITY_ATTRIBUTES(); secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); byte[] sd = mutexSecurity.GetSecurityDescriptorBinaryForm(); byte* pSecDescriptor = stackalloc byte[sd.Length]; Buffer.Memcpy(pSecDescriptor, 0, sd, 0, sd.Length); secAttrs.pSecurityDescriptor = pSecDescriptor; } #endif CreateMutexWithGuaranteedCleanup(initiallyOwned, name, out createdNew, secAttrs); }
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; }
public unsafe EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew, EventWaitHandleSecurity eventSecurity) { bool flag; if ((name != null) && (260 < name.Length)) { throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", new object[] { name })); } Win32Native.SECURITY_ATTRIBUTES structure = null; if (eventSecurity != null) { structure = new Win32Native.SECURITY_ATTRIBUTES { nLength = Marshal.SizeOf(structure) }; byte[] securityDescriptorBinaryForm = eventSecurity.GetSecurityDescriptorBinaryForm(); byte* pDest = stackalloc byte[1 * securityDescriptorBinaryForm.Length]; Buffer.memcpy(securityDescriptorBinaryForm, 0, pDest, 0, securityDescriptorBinaryForm.Length); structure.pSecurityDescriptor = pDest; } SafeWaitHandle handle = null; switch (mode) { case EventResetMode.AutoReset: flag = false; break; case EventResetMode.ManualReset: flag = true; break; default: throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag", new object[] { name })); } handle = Win32Native.CreateEvent(structure, flag, initialState, name); int errorCode = Marshal.GetLastWin32Error(); if (handle.IsInvalid) { handle.SetHandleAsInvalid(); if (((name != null) && (name.Length != 0)) && (6 == errorCode)) { throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", new object[] { name })); } __Error.WinIOError(errorCode, name); } createdNew = errorCode != 0xb7; base.SetHandleInternal(handle); }
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 structure = null; if (mutexSecurity != null) { structure = new Win32Native.SECURITY_ATTRIBUTES { nLength = Marshal.SizeOf(structure) }; byte[] securityDescriptorBinaryForm = mutexSecurity.GetSecurityDescriptorBinaryForm(); byte* pDest = stackalloc byte[(IntPtr) securityDescriptorBinaryForm.Length]; Buffer.memcpy(securityDescriptorBinaryForm, 0, pDest, 0, securityDescriptorBinaryForm.Length); structure.pSecurityDescriptor = pDest; } RuntimeHelpers.CleanupCode backoutCode = new RuntimeHelpers.CleanupCode(this.MutexCleanupCode); MutexCleanupInfo cleanupInfo = new MutexCleanupInfo(null, false); MutexTryCodeHelper helper = new MutexTryCodeHelper(initiallyOwned, cleanupInfo, name, structure, this); RuntimeHelpers.TryCode code = new RuntimeHelpers.TryCode(helper.MutexTryCode); RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(code, backoutCode, cleanupInfo); createdNew = helper.m_newMutex; }
private unsafe RegistryKey CreateSubKeyInternal(String subkey, RegistryKeyPermissionCheck permissionCheck, object registrySecurityObj, RegistryOptions registryOptions) { ValidateKeyOptions(registryOptions); ValidateKeyName(subkey); ValidateKeyMode(permissionCheck); EnsureWriteable(); subkey = FixupName(subkey); // Fixup multiple slashes to a single slash // only keys opened under read mode is not writable if (!remoteKey) { RegistryKey key = InternalOpenSubKey(subkey, (permissionCheck != RegistryKeyPermissionCheck.ReadSubTree)); if (key != null) { // Key already exits CheckPermission(RegistryInternalCheck.CheckSubKeyWritePermission, subkey, false, RegistryKeyPermissionCheck.Default); CheckPermission(RegistryInternalCheck.CheckSubTreePermission, subkey, false, permissionCheck); key.checkMode = permissionCheck; return key; } } CheckPermission(RegistryInternalCheck.CheckSubKeyCreatePermission, subkey, false, RegistryKeyPermissionCheck.Default); Win32Native.SECURITY_ATTRIBUTES secAttrs = null; #if FEATURE_MACL RegistrySecurity registrySecurity = (RegistrySecurity)registrySecurityObj; // 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]; Buffer.Memcpy(pSecDescriptor, 0, sd, 0, sd.Length); secAttrs.pSecurityDescriptor = pSecDescriptor; } #endif int disposition = 0; // By default, the new key will be writable. SafeRegistryHandle result = null; int ret = Win32Native.RegCreateKeyEx(hkey, subkey, 0, null, (int)registryOptions /* specifies if the key is volatile */, GetRegistryKeyAccess(permissionCheck != RegistryKeyPermissionCheck.ReadSubTree) | (int)regView, secAttrs, out result, out disposition); if (ret == 0 && !result.IsInvalid) { RegistryKey key = new RegistryKey(result, (permissionCheck != RegistryKeyPermissionCheck.ReadSubTree), false, remoteKey, false, regView); CheckPermission(RegistryInternalCheck.CheckSubTreePermission, subkey, false, 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; }
private static unsafe Win32Native.SECURITY_ATTRIBUTES GetSecAttrs(FileShare share, FileSecurity fileSecurity, out object pinningHandle) { pinningHandle = null; Win32Native.SECURITY_ATTRIBUTES structure = null; if (((share & FileShare.Inheritable) != FileShare.None) || (fileSecurity != null)) { structure = new Win32Native.SECURITY_ATTRIBUTES { nLength = Marshal.SizeOf(structure) }; if ((share & FileShare.Inheritable) != FileShare.None) { structure.bInheritHandle = 1; } if (fileSecurity == null) { return structure; } byte[] securityDescriptorBinaryForm = fileSecurity.GetSecurityDescriptorBinaryForm(); pinningHandle = GCHandle.Alloc(securityDescriptorBinaryForm, GCHandleType.Pinned); fixed (byte* numRef = securityDescriptorBinaryForm) { structure.pSecurityDescriptor = numRef; } } return structure; }
private static Win32Native.SECURITY_ATTRIBUTES GetSecAttrs(FileShare share) { Win32Native.SECURITY_ATTRIBUTES structure = null; if ((share & FileShare.Inheritable) != FileShare.None) { structure = new Win32Native.SECURITY_ATTRIBUTES { nLength = Marshal.SizeOf(structure), bInheritHandle = 1 }; } return structure; }
internal static unsafe void AcquireReservedMutex(ref bool bHandleObtained) { #if FEATURE_MACL SafeWaitHandle mutexHandle = null; int errorCode; bHandleObtained = false; if (!Environment.IsW2k3) { return; } if (s_ReservedMutex == null) { // Create a maximally-permissive security descriptor, to ensure we never get an // ACCESS_DENIED error when calling CreateMutex MutexSecurity sec = new MutexSecurity(); SecurityIdentifier everyoneSid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); sec.AddAccessRule(new MutexAccessRule(everyoneSid, MutexRights.FullControl, AccessControlType.Allow)); // For ACL's, get the security descriptor from the MutexSecurity. Win32Native.SECURITY_ATTRIBUTES secAttrs = new Win32Native.SECURITY_ATTRIBUTES(); secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); byte[] sd = sec.GetSecurityDescriptorBinaryForm(); byte * bytesOnStack = stackalloc byte[sd.Length]; Buffer.Memcpy(bytesOnStack, 0, sd, 0, sd.Length); secAttrs.pSecurityDescriptor = bytesOnStack; RuntimeHelpers.PrepareConstrainedRegions(); try {} finally { mutexHandle = Win32Native.CreateMutex(secAttrs, false, c_ReservedMutexName); // need to set specially, since this mutex cannot lock on itself while closing itself. mutexHandle.SetAsReservedMutex(); } errorCode = Marshal.GetLastWin32Error(); if (mutexHandle.IsInvalid) { mutexHandle.SetHandleAsInvalid(); __Error.WinIOError(errorCode, c_ReservedMutexName); } Mutex m = new Mutex(mutexHandle); Interlocked.CompareExchange(ref s_ReservedMutex, m, null); } RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { try { s_ReservedMutex.WaitOne(); bHandleObtained = true; } catch (AbandonedMutexException) { // we don't care if another process holding the Mutex was killed bHandleObtained = true; } } #else bHandleObtained = true; #endif }
private static unsafe Mutex GetMutexWithAcl(string mutexName) { // We need to set at a DACL on the Mutex we're going to create to allow it to be shared. // The DACL here grants MUTEX_ALL_ACCESS (0x001F0001) to the current user. This allows hosts // like sllaucher.exe which strip the admin sections of the current user token to access the // Mutex. IntPtr byteArray = IntPtr.Zero; uint byteArraySize = 0; try { if (Win32Native.ConvertStringSdToSd(String.Format(CultureInfo.InvariantCulture, "D:(A;;0x001F0001;;;{0})", GetCurrentSIDAsString()), 1 /*SDDL_REVISION_1*/, out byteArray, ref byteArraySize) == 0) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error(), new IntPtr(-1)); } Win32Native.SECURITY_ATTRIBUTES secAttrs = new Win32Native.SECURITY_ATTRIBUTES(); secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); // The Win32 function ConvertStringSecurityDescriptorToSecurityDescriptor allocated the buffer pointed to by byteArray // it isn't tracked by the GC so we don't need to pin it. secAttrs.pSecurityDescriptor = (byte*)byteArray.ToPointer(); bool createdNew; /* not used */ return new Mutex(false, mutexName, out createdNew, secAttrs); } finally { if (byteArray != IntPtr.Zero) { Win32Native.LocalFree(byteArray); } } }
internal static unsafe void InternalCreateDirectory(string fullPath, string path, object dirSecurityObj) { DirectorySecurity security = (DirectorySecurity) dirSecurityObj; int length = fullPath.Length; if ((length >= 2) && Path.IsDirectorySeparator(fullPath[length - 1])) { length--; } int rootLength = Path.GetRootLength(fullPath); if ((length == 2) && Path.IsDirectorySeparator(fullPath[1])) { throw new IOException(Environment.GetResourceString("IO.IO_CannotCreateDirectory", new object[] { path })); } List<string> list = new List<string>(); bool flag = false; if (length > rootLength) { for (int i = length - 1; (i >= rootLength) && !flag; i--) { string str = fullPath.Substring(0, i + 1); if (!InternalExists(str)) { list.Add(str); } else { flag = true; } while (((i > rootLength) && (fullPath[i] != Path.DirectorySeparatorChar)) && (fullPath[i] != Path.AltDirectorySeparatorChar)) { i--; } } } int count = list.Count; if (list.Count != 0) { string[] array = new string[list.Count]; list.CopyTo(array, 0); for (int j = 0; j < array.Length; j++) { string[] strArray2; IntPtr ptr; (strArray2 = array)[(int) (ptr = (IntPtr) j)] = strArray2[(int) ptr] + @"\."; } AccessControlActions control = (security == null) ? AccessControlActions.None : AccessControlActions.Change; new FileIOPermission(FileIOPermissionAccess.Write, control, array, false, false).Demand(); } Win32Native.SECURITY_ATTRIBUTES structure = null; if (security != null) { structure = new Win32Native.SECURITY_ATTRIBUTES { nLength = Marshal.SizeOf(structure) }; byte[] securityDescriptorBinaryForm = security.GetSecurityDescriptorBinaryForm(); byte* pDest = stackalloc byte[(IntPtr) securityDescriptorBinaryForm.Length]; Buffer.memcpy(securityDescriptorBinaryForm, 0, pDest, 0, securityDescriptorBinaryForm.Length); structure.pSecurityDescriptor = pDest; } bool flag2 = true; int errorCode = 0; string maybeFullPath = path; while (list.Count > 0) { string str3 = list[list.Count - 1]; list.RemoveAt(list.Count - 1); if (str3.Length >= 0xf8) { throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong")); } flag2 = Win32Native.CreateDirectory(str3, structure); if (!flag2 && (errorCode == 0)) { int lastError = Marshal.GetLastWin32Error(); if (lastError != 0xb7) { errorCode = lastError; } else if (File.InternalExists(str3) || (!InternalExists(str3, out lastError) && (lastError == 5))) { errorCode = lastError; try { new FileIOPermission(FileIOPermissionAccess.PathDiscovery, GetDemandDir(str3, true)).Demand(); maybeFullPath = str3; continue; } catch (SecurityException) { continue; } } } } if ((count == 0) && !flag) { if (!InternalExists(InternalGetDirectoryRoot(fullPath))) { __Error.WinIOError(3, InternalGetDirectoryRoot(path)); } } else if (!flag2 && (errorCode != 0)) { __Error.WinIOError(errorCode, maybeFullPath); } }
private unsafe RegistryKey CreateSubKeyInternal(string subkey, RegistryKeyPermissionCheck permissionCheck, object registrySecurityObj, RegistryOptions registryOptions) { ValidateKeyOptions(registryOptions); ValidateKeyName(subkey); ValidateKeyMode(permissionCheck); this.EnsureWriteable(); subkey = FixupName(subkey); if (!this.remoteKey) { RegistryKey key = this.InternalOpenSubKey(subkey, permissionCheck != RegistryKeyPermissionCheck.ReadSubTree); if (key != null) { this.CheckPermission(RegistryInternalCheck.CheckSubKeyWritePermission, subkey, false, RegistryKeyPermissionCheck.Default); this.CheckPermission(RegistryInternalCheck.CheckSubTreePermission, subkey, false, permissionCheck); key.checkMode = permissionCheck; return key; } } this.CheckPermission(RegistryInternalCheck.CheckSubKeyCreatePermission, subkey, false, RegistryKeyPermissionCheck.Default); Win32Native.SECURITY_ATTRIBUTES structure = null; RegistrySecurity security = (RegistrySecurity) registrySecurityObj; if (security != null) { structure = new Win32Native.SECURITY_ATTRIBUTES { nLength = Marshal.SizeOf(structure) }; byte[] securityDescriptorBinaryForm = security.GetSecurityDescriptorBinaryForm(); byte* pDest = stackalloc byte[(IntPtr) securityDescriptorBinaryForm.Length]; Buffer.memcpy(securityDescriptorBinaryForm, 0, pDest, 0, securityDescriptorBinaryForm.Length); structure.pSecurityDescriptor = pDest; } int lpdwDisposition = 0; SafeRegistryHandle hkResult = null; int errorCode = Win32Native.RegCreateKeyEx(this.hkey, subkey, 0, null, (int) registryOptions, GetRegistryKeyAccess(permissionCheck != RegistryKeyPermissionCheck.ReadSubTree, this.regView), structure, out hkResult, out lpdwDisposition); if ((errorCode == 0) && !hkResult.IsInvalid) { RegistryKey key2 = new RegistryKey(hkResult, permissionCheck != RegistryKeyPermissionCheck.ReadSubTree, false, this.remoteKey, false, this.regView); this.CheckPermission(RegistryInternalCheck.CheckSubTreePermission, subkey, false, permissionCheck); key2.checkMode = permissionCheck; if (subkey.Length == 0) { key2.keyName = this.keyName; return key2; } key2.keyName = this.keyName + @"\" + subkey; return key2; } if (errorCode != 0) { this.Win32Error(errorCode, this.keyName + @"\" + subkey); } return null; }
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; } } } }
public unsafe EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew, EventWaitHandleSecurity eventSecurity) { if(null != name && System.IO.Path.MAX_PATH < name.Length) { throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong",name)); } 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); }
internal MutexTryCodeHelper(bool initiallyOwned,MutexCleanupInfo cleanupInfo, String name, Win32Native.SECURITY_ATTRIBUTES secAttrs, Mutex mutex) { Contract.Assert(name == null || name.Length != 0); m_initiallyOwned = initiallyOwned; m_cleanupInfo = cleanupInfo; m_name = name; m_secAttrs = secAttrs; m_mutex = mutex; }
internal FileStream(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync, String msgPath, bool bFromProxy) { // Note: msgPath must be safe to hand back to untrusted code. _fileName = msgPath; // To handle odd cases of finalizing partially constructed objects. if (path == null) throw new ArgumentNullException("path", Environment.GetResourceString("ArgumentNull_Path")); if (path.Length == 0) throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); if (mode < FileMode.CreateNew || mode > FileMode.Append || access < FileAccess.Read || access > FileAccess.ReadWrite || share < FileShare.None || share > FileShare.ReadWrite) { String badArg = "mode"; if (access < FileAccess.Read || access > FileAccess.ReadWrite) badArg = "access"; if (share < FileShare.None || share > FileShare.ReadWrite) badArg = "share"; throw new ArgumentOutOfRangeException(badArg, Environment.GetResourceString("ArgumentOutOfRange_Enum")); } if (bufferSize <= 0) throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum")); int fAccess = access == FileAccess.Read? GENERIC_READ: access == FileAccess.Write? GENERIC_WRITE: GENERIC_READ | GENERIC_WRITE; // Get absolute path - Security needs this to prevent something // like trying to create a file in c:\tmp with the name // "..\WinNT\System32\ntoskrnl.exe". Store it for user convenience. String filePath = Path.GetFullPathInternal(path); _fileName = filePath; // Build up security permissions required, as well as validate we // have a sensible set of parameters. IE, creating a brand new file // for reading doesn't make much sense. FileIOPermissionAccess secAccess = FileIOPermissionAccess.NoAccess; if ((access & FileAccess.Read) != 0) { if (mode==FileMode.Append) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidAppendMode")); else secAccess = secAccess | FileIOPermissionAccess.Read; } // I can't think of any combos of FileMode we should disallow if we // don't have read access. Writing would pretty much always be valid // in those cases. if ((access & FileAccess.Write) != 0) { if (mode==FileMode.Append) secAccess = secAccess | FileIOPermissionAccess.Append; else secAccess = secAccess | FileIOPermissionAccess.Write; } else { // No write access if (mode==FileMode.Truncate || mode==FileMode.CreateNew || mode==FileMode.Create || mode==FileMode.Append) throw new ArgumentException(String.Format(Environment.GetResourceString("Argument_InvalidFileMode&AccessCombo"), mode, access)); } new FileIOPermission(secAccess, new String[] { filePath }, false, false).Demand(); bool seekToEnd = (mode==FileMode.Append); // Must use a valid Win32 constant here... if (mode == FileMode.Append) mode = FileMode.OpenOrCreate; // By default, FileStream-provided handles are not inheritable by // child processes, but with FileShare.Inheritable you can redirect // stdout from a child process to a log file from your parent, etc. Win32Native.SECURITY_ATTRIBUTES secAttrs = null; if ((share & FileShare.Inheritable) != 0) { secAttrs = new Win32Native.SECURITY_ATTRIBUTES(); secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); secAttrs.bInheritHandle = 1; share &= ~FileShare.Inheritable; } // Do the right thing for whatever platform we're on. This way, // someone can easily write code that opens a file asynchronously // no matter what their platform is. IntPtr handle; if (_canUseAsync && useAsync) { handle = Win32Native.CreateFile(filePath, fAccess, share, secAttrs, mode, FILE_FLAG_OVERLAPPED, Win32Native.NULL); _isAsync = true; } else { handle = Win32Native.CreateFile(filePath, fAccess, share, secAttrs, mode, FILE_ATTRIBUTE_NORMAL, Win32Native.NULL); _isAsync = false; } if (handle != Win32Native.INVALID_HANDLE_VALUE) { _handleProtector = new __FileStreamHandleProtector(handle, true); } else { // Return a meaningful error, using the RELATIVE path to // the file to avoid returning extra information to the caller // unless they have path discovery permission, in which case // the full path is fine & useful. // NT5 oddity - when trying to open "C:\" as a FileStream, // we usually get ERROR_PATH_NOT_FOUND from the OS. We should // probably be consistent w/ every other directory. int hr = Marshal.GetLastWin32Error(); if (hr==__Error.ERROR_PATH_NOT_FOUND && filePath.Equals(Directory.InternalGetDirectoryRoot(filePath))) hr = __Error.ERROR_ACCESS_DENIED; // We need to give an exception, and preferably it would include // the fully qualified path name. Do security check here. If // we fail, give back the msgPath, which should not reveal much. bool canGiveFullPath = false; if (!bFromProxy) { try { new FileIOPermission(FileIOPermissionAccess.PathDiscovery, new String[] { _fileName }, false, false ).Demand(); canGiveFullPath = true; } catch(SecurityException) {} } if (canGiveFullPath) __Error.WinIOError(hr, _fileName); else __Error.WinIOError(hr, msgPath); } // Disallow access to all non-file devices from the FileStream // constructors that take a String. Everyone else can call // CreateFile themselves then use the constructor that takes an // IntPtr. Disallows "con:", "com1:", "lpt1:", etc. int fileType = Win32Native.GetFileType(handle); if (fileType != Win32Native.FILE_TYPE_DISK) { _handleProtector.Close(); throw new NotSupportedException(Environment.GetResourceString("NotSupported_FileStreamOnNonFiles")); } _canRead = (access & FileAccess.Read) != 0; _canWrite = (access & FileAccess.Write) != 0; _canSeek = true; _isPipe = false; _pos = 0; _bufferSize = bufferSize; _readPos = 0; _readLen = 0; _writePos = 0; // For Append mode... if (seekToEnd) { _appendStart = SeekCore(0, SeekOrigin.End); } else { _appendStart = -1; } }
private static Win32Native.SECURITY_ATTRIBUTES GetSecAttrs(FileShare share) { Win32Native.SECURITY_ATTRIBUTES secAttrs = null; if ((share & FileShare.Inheritable) != 0) { secAttrs = new Win32Native.SECURITY_ATTRIBUTES(); secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); secAttrs.bInheritHandle = 1; } return secAttrs; }
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; }
internal unsafe static void InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj, bool checkHost) { #if FEATURE_MACL DirectorySecurity dirSecurity = (DirectorySecurity)dirSecurityObj; #endif // FEATURE_MACL int length = fullPath.Length; // We need to trim the trailing slash or the code will try to create 2 directories of the same name. if (length >= 2 && Path.IsDirectorySeparator(fullPath[length - 1])) length--; int lengthRoot = Path.GetRootLength(fullPath); // For UNC paths that are only // or /// if (length == 2 && Path.IsDirectorySeparator(fullPath[1])) throw new IOException(Environment.GetResourceString("IO.IO_CannotCreateDirectory", path)); // We can save a bunch of work if the directory we want to create already exists. This also // saves us in the case where sub paths are inaccessible (due to ERROR_ACCESS_DENIED) but the // final path is accessable and the directory already exists. For example, consider trying // to create c:\Foo\Bar\Baz, where everything already exists but ACLS prevent access to c:\Foo // and c:\Foo\Bar. In that case, this code will think it needs to create c:\Foo, and c:\Foo\Bar // and fail to due so, causing an exception to be thrown. This is not what we want. if (InternalExists(fullPath)) { return; } List<string> stackDir = new List<string>(); // Attempt to figure out which directories don't exist, and only // create the ones we need. Note that InternalExists may fail due // to Win32 ACL's preventing us from seeing a directory, and this // isn't threadsafe. bool somepathexists = false; if (length > lengthRoot) { // Special case root (fullpath = X:\\) int i = length-1; while (i >= lengthRoot && !somepathexists) { String dir = fullPath.Substring(0, i+1); if (!InternalExists(dir)) // Create only the ones missing stackDir.Add(dir); else somepathexists = true; while (i > lengthRoot && fullPath[i] != Path.DirectorySeparatorChar && fullPath[i] != Path.AltDirectorySeparatorChar) i--; i--; } } int count = stackDir.Count; if (stackDir.Count != 0 #if FEATURE_CAS_POLICY // All demands in full trust domains are no-ops, so skip // // The full path went through validity checks by being passed through FileIOPermissions already. // As a sub string of the full path can't fail the checks if the full path passes. && !CodeAccessSecurityEngine.QuickCheckForAllDemands() #endif ) { String[] securityList = new String[stackDir.Count]; stackDir.CopyTo(securityList, 0); for (int j = 0 ; j < securityList.Length; j++) securityList[j] += "\\."; // leaf will never have a slash at the end // Security check for all directories not present only. #if FEATURE_MACL AccessControlActions control = (dirSecurity == null) ? AccessControlActions.None : AccessControlActions.Change; FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, control, securityList, false, false); #else #if FEATURE_CORECLR if (checkHost) { foreach (String demandPath in securityList) { FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Write, String.Empty, demandPath); state.EnsureState(); } } #else FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, securityList, false, false); #endif #endif //FEATURE_MACL } // If we were passed a DirectorySecurity, convert it to a security // descriptor and set it in he call to CreateDirectory. Win32Native.SECURITY_ATTRIBUTES secAttrs = null; #if FEATURE_MACL if (dirSecurity != null) { secAttrs = new Win32Native.SECURITY_ATTRIBUTES(); secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); // For ACL's, get the security descriptor from the FileSecurity. byte[] sd = dirSecurity.GetSecurityDescriptorBinaryForm(); byte * bytesOnStack = stackalloc byte[sd.Length]; Buffer.Memcpy(bytesOnStack, 0, sd, 0, sd.Length); secAttrs.pSecurityDescriptor = bytesOnStack; } #endif bool r = true; int firstError = 0; String errorString = path; // If all the security checks succeeded create all the directories while (stackDir.Count > 0) { String name = stackDir[stackDir.Count - 1]; stackDir.RemoveAt(stackDir.Count - 1); if (PathInternal.IsDirectoryTooLong(name)) throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong")); r = Win32Native.CreateDirectory(name, secAttrs); if (!r && (firstError == 0)) { int currentError = Marshal.GetLastWin32Error(); // While we tried to avoid creating directories that don't // exist above, there are at least two cases that will // cause us to see ERROR_ALREADY_EXISTS here. InternalExists // can fail because we didn't have permission to the // directory. Secondly, another thread or process could // create the directory between the time we check and the // time we try using the directory. Thirdly, it could // fail because the target does exist, but is a file. if (currentError != Win32Native.ERROR_ALREADY_EXISTS) firstError = currentError; else { // If there's a file in this directory's place, or if we have ERROR_ACCESS_DENIED when checking if the directory already exists throw. if (File.InternalExists(name) || (!InternalExists(name, out currentError) && currentError == Win32Native.ERROR_ACCESS_DENIED)) { firstError = currentError; // Give the user a nice error message, but don't leak path information. try { #if FEATURE_CORECLR if (checkHost) { FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, GetDemandDir(name, true)); state.EnsureState(); } #else FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, GetDemandDir(name, true)); #endif // FEATURE_CORECLR errorString = name; } catch(SecurityException) {} } } } } // We need this check to mask OS differences // Handle CreateDirectory("X:\\foo") when X: doesn't exist. Similarly for n/w paths. if ((count == 0) && !somepathexists) { String root = InternalGetDirectoryRoot(fullPath); if (!InternalExists(root)) { // Extract the root from the passed in path again for security. __Error.WinIOError(Win32Native.ERROR_PATH_NOT_FOUND, InternalGetDirectoryRoot(path)); } return; } // Only throw an exception if creating the exact directory we // wanted failed to work correctly. if (!r && (firstError != 0)) { __Error.WinIOError(firstError, errorString); } }
[System.Security.SecuritySafeCritical] // auto-generated private unsafe static Win32Native.SECURITY_ATTRIBUTES GetSecAttrs(FileShare share, FileSecurity fileSecurity, out Object pinningHandle) { pinningHandle = null; Win32Native.SECURITY_ATTRIBUTES secAttrs = null; if ((share & FileShare.Inheritable) != 0 || fileSecurity != null) { secAttrs = new Win32Native.SECURITY_ATTRIBUTES(); secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); if ((share & FileShare.Inheritable) != 0) { secAttrs.bInheritHandle = 1; } // For ACL's, get the security descriptor from the FileSecurity. if (fileSecurity != null) { byte[] sd = fileSecurity.GetSecurityDescriptorBinaryForm(); pinningHandle = GCHandle.Alloc(sd, GCHandleType.Pinned); fixed(byte* pSecDescriptor = sd) secAttrs.pSecurityDescriptor = pSecDescriptor; } } return secAttrs; }