internal static SafeFileHandle CreateFileCore(KernelTransaction transaction, bool? isFolder, string path, ExtendedFileAttributes attributes, FileSecurity fileSecurity, FileMode fileMode, FileSystemRights fileSystemRights, FileShare fileShare, bool checkPath, bool continueOnException, PathFormat pathFormat) { if (checkPath && pathFormat == PathFormat.RelativePath) Path.CheckSupportedPathFormat(path, true, true); // When isFile == null, we're working with a device. // When opening a VOLUME or removable media drive (for example, a floppy disk drive or flash memory thumb drive), // the path string should be the following form: "\\.\X:" // Do not use a trailing backslash ('\'), which indicates the root. var pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator); // CreateFileXxx() does not support FileMode.Append mode. var isAppend = fileMode == FileMode.Append; if (isAppend) { fileMode = FileMode.OpenOrCreate; fileSystemRights |= FileSystemRights.AppendData; } if (null != fileSecurity) fileSystemRights |= (FileSystemRights)SECURITY_INFORMATION.UNPROTECTED_SACL_SECURITY_INFORMATION; using ((fileSystemRights & (FileSystemRights)SECURITY_INFORMATION.UNPROTECTED_SACL_SECURITY_INFORMATION) != 0 || (fileSystemRights & (FileSystemRights) SECURITY_INFORMATION.UNPROTECTED_DACL_SECURITY_INFORMATION) != 0 ? new PrivilegeEnabler(Privilege.Security) : null) using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(fileSecurity)) { var safeHandle = transaction == null || !NativeMethods.IsAtLeastWindowsVista // CreateFile() / CreateFileTransacted() // 2013-01-13: MSDN confirms LongPath usage. ? NativeMethods.CreateFile(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero) : NativeMethods.CreateFileTransacted(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero, transaction.SafeHandle, IntPtr.Zero, IntPtr.Zero); var lastError = Marshal.GetLastWin32Error(); NativeMethods.CloseHandleAndPossiblyThrowException(safeHandle, lastError, isFolder, path, !continueOnException); if (isAppend) { var success = NativeMethods.SetFilePointerEx(safeHandle, 0, IntPtr.Zero, SeekOrigin.End); lastError = Marshal.GetLastWin32Error(); if (!success) { NativeMethods.CloseHandleAndPossiblyThrowException(safeHandle, lastError, isFolder, path, !continueOnException); return null; } } return safeHandle; } }
public KernelTransaction(ObjectSecurity securityDescriptor, uint timeout, string description) { if (!NativeMethods.IsAtLeastWindowsVista) throw new PlatformNotSupportedException(Resources.RequiresWindowsVistaOrHigher); using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(securityDescriptor)) { _hTrans = NativeMethods.CreateTransaction(securityAttributes, IntPtr.Zero, 0, 0, 0, timeout, description); int lastError = Marshal.GetLastWin32Error(); NativeMethods.IsValidHandle(_hTrans, lastError); } }
public KernelTransaction(ObjectSecurity securityDescriptor, int timeout, string description) { if (!NativeMethods.IsAtLeastWindowsVista) { throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher); } using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(securityDescriptor)) { _hTrans = NativeMethods.CreateTransaction(securityAttributes, IntPtr.Zero, 0, 0, 0, timeout, description); int lastError = Marshal.GetLastWin32Error(); NativeMethods.IsValidHandle(_hTrans, lastError); } }
public KernelTransaction(ObjectSecurity securityDescriptor, int timeout, string description) { if (!NativeMethods.IsAtLeastWindowsVista) { throw new PlatformNotSupportedException(new Win32Exception((int)Win32Errors.ERROR_OLD_WIN_VERSION).Message); } using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(securityDescriptor)) { _hTrans = NativeMethods.CreateTransaction(securityAttributes, IntPtr.Zero, 0, 0, 0, timeout, description); int lastError = Marshal.GetLastWin32Error(); NativeMethods.IsValidHandle(_hTrans, lastError); } }
internal static extern SafeKernelTransactionHandle CreateTransaction([MarshalAs(UnmanagedType.LPStruct)] Security.NativeMethods.SecurityAttributes lpTransactionAttributes, IntPtr uow, [MarshalAs(UnmanagedType.U4)] uint createOptions, [MarshalAs(UnmanagedType.U4)] uint isolationLevel, [MarshalAs(UnmanagedType.U4)] uint isolationFlags, [MarshalAs(UnmanagedType.U4)] int timeout, [MarshalAs(UnmanagedType.LPWStr)] string description);
internal static SafeFileHandle CreateFileCore(KernelTransaction transaction, string path, ExtendedFileAttributes attributes, FileSecurity fileSecurity, FileMode fileMode, FileSystemRights fileSystemRights, FileShare fileShare, bool checkPath, PathFormat pathFormat) { if (checkPath && pathFormat == PathFormat.RelativePath) { Path.CheckSupportedPathFormat(path, true, true); } // When isFile == null, we're working with a device. // When opening a VOLUME or removable media drive (for example, a floppy disk drive or flash memory thumb drive), // the path string should be the following form: "\\.\X:" // Do not use a trailing backslash (\), which indicates the root. var pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator); PrivilegeEnabler privilegeEnabler = null; var isAppend = fileMode == FileMode.Append; // CreateFileXxx() does not support FileMode.Append mode. if (isAppend) { fileMode = FileMode.OpenOrCreate; fileSystemRights &= FileSystemRights.AppendData; // Add right. } if (fileSecurity != null) { fileSystemRights |= (FileSystemRights)0x1000000; // Set right. } // AccessSystemSecurity = 0x1000000 AccessSystemAcl access type. // MaximumAllowed = 0x2000000 MaximumAllowed access type. if ((fileSystemRights & (FileSystemRights)0x1000000) != 0 || (fileSystemRights & (FileSystemRights)0x2000000) != 0) { privilegeEnabler = new PrivilegeEnabler(Privilege.Security); } using (privilegeEnabler) using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(fileSecurity)) { var handle = transaction == null || !NativeMethods.IsAtLeastWindowsVista // CreateFile() / CreateFileTransacted() // In the ANSI version of this function, the name is limited to MAX_PATH characters. // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. // 2013-01-13: MSDN confirms LongPath usage. ? NativeMethods.CreateFile(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero) : NativeMethods.CreateFileTransacted(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero, transaction.SafeHandle, IntPtr.Zero, IntPtr.Zero); var lastError = Marshal.GetLastWin32Error(); if (handle.IsInvalid) { handle.Close(); NativeError.ThrowException(lastError, pathLp); } if (isAppend) { var stream = new FileStream(handle, FileAccess.Write, NativeMethods.DefaultFileBufferSize, (attributes & ExtendedFileAttributes.Overlapped) != 0); stream.Seek(0, SeekOrigin.End); } return(handle); } }
internal static extern bool CreateDirectoryEx([MarshalAs(UnmanagedType.LPWStr)] string lpTemplateDirectory, [MarshalAs(UnmanagedType.LPWStr)] string lpPathName, [MarshalAs(UnmanagedType.LPStruct)] Security.NativeMethods.SecurityAttributes lpSecurityAttributes);
internal static extern bool CreateDirectoryTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpTemplateDirectory, [MarshalAs(UnmanagedType.LPWStr)] string lpNewDirectory, [MarshalAs(UnmanagedType.LPStruct)] Security.NativeMethods.SecurityAttributes lpSecurityAttributes, SafeHandle hTransaction);
internal static DirectoryInfo CreateDirectoryInternal(KernelTransaction transaction, string path, string templatePath, ObjectSecurity directorySecurity, bool compress, PathFormat pathFormat) { if (pathFormat == PathFormat.RelativePath) { if (path != null && path[0] == Path.VolumeSeparatorChar) throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Resources.PathFormatUnsupported, path)); if (templatePath != null && templatePath[0] == Path.VolumeSeparatorChar) throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Resources.PathFormatUnsupported, templatePath)); Path.CheckValidPath(path, true, true); Path.CheckValidPath(templatePath, true, true); } else // MSDN:. NET 3.5+: NotSupportedException: Path contains a colon character (:) that is not part of a drive label ("C:\"). Path.CheckValidPath(path, false, false); string pathLp = Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator); // Return DirectoryInfo instance if the directory specified by path already exists. if (File.ExistsInternal(true, transaction, pathLp, PathFormat.LongFullPath)) return new DirectoryInfo(transaction, pathLp, PathFormat.LongFullPath); // MSDN: .NET 3.5+: IOException: The directory specified by path is a file or the network name was not found. if (File.ExistsInternal(false, transaction, pathLp, PathFormat.LongFullPath)) NativeError.ThrowException(Win32Errors.ERROR_ALREADY_EXISTS, pathLp); string templatePathLp = Utils.IsNullOrWhiteSpace(templatePath) ? null : Path.GetExtendedLengthPathInternal(transaction, templatePath, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator); #region Construct Full Path string longPathPrefix = Path.IsUncPath(path, false) ? Path.LongPathUncPrefix : Path.LongPathPrefix; path = Path.GetRegularPathInternal(pathLp, GetFullPathOptions.None); int length = path.Length; if (length >= 2 && Path.IsDVsc(path[length - 1], false)) --length; int rootLength = Path.GetRootLength(path, false); if (length == 2 && Path.IsDVsc(path[1], false)) throw new ArgumentException(Resources.CannotCreateDirectory, path); // Check if directories are missing. Stack<string> list = new Stack<string>(100); if (length > rootLength) { for (int index = length - 1; index >= rootLength; --index) { string path1 = path.Substring(0, index + 1); string path2 = longPathPrefix + path1.TrimStart('\\'); if (!File.ExistsInternal(true, transaction, path2, PathFormat.LongFullPath)) list.Push(path2); while (index > rootLength && !Path.IsDVsc(path[index], false)) --index; } } #endregion // Construct Full Path // Directory security. using (Security.NativeMethods.SecurityAttributes securityAttributes = new Security.NativeMethods.SecurityAttributes(directorySecurity)) { // Create the directory paths. while (list.Count > 0) { string folderLp = list.Pop(); // In the ANSI version of this function, the name is limited to 248 characters. // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. // 2013-01-13: MSDN confirms LongPath usage. bool createOk = (transaction == null || !NativeMethods.IsAtLeastWindowsVista ? (templatePathLp == null ? NativeMethods.CreateDirectory(folderLp, securityAttributes) : NativeMethods.CreateDirectoryEx(templatePathLp, folderLp, securityAttributes)) : NativeMethods.CreateDirectoryTransacted(templatePathLp, folderLp, securityAttributes, transaction.SafeHandle)); if (!createOk) { int lastError = Marshal.GetLastWin32Error(); switch ((uint)lastError) { // MSDN: .NET 3.5+: If the directory already exists, this method does nothing. // MSDN: .NET 3.5+: IOException: The directory specified by path is a file. case Win32Errors.ERROR_ALREADY_EXISTS: if (File.ExistsInternal(false, transaction, pathLp, PathFormat.LongFullPath)) NativeError.ThrowException(lastError, pathLp); if (File.ExistsInternal(false, transaction, folderLp, PathFormat.LongFullPath)) NativeError.ThrowException(Win32Errors.ERROR_PATH_NOT_FOUND, folderLp); break; case Win32Errors.ERROR_BAD_NET_NAME: NativeError.ThrowException(lastError, pathLp); break; case Win32Errors.ERROR_DIRECTORY: // MSDN: .NET 3.5+: NotSupportedException: path contains a colon character (:) that is not part of a drive label ("C:\"). throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, Resources.PathFormatUnsupported, path)); default: NativeError.ThrowException(lastError, folderLp); break; } } else if (compress) Device.ToggleCompressionInternal(true, transaction, folderLp, true, PathFormat.LongFullPath); } } return new DirectoryInfo(transaction, pathLp, PathFormat.FullPath); }
internal static SafeFileHandle CreateFileInternal(KernelTransaction transaction, string path, ExtendedFileAttributes attributes, FileSecurity fileSecurity, FileMode fileMode, FileSystemRights fileSystemRights, FileShare fileShare, bool checkPath, PathFormat pathFormat) { if (checkPath && pathFormat == PathFormat.RelativePath) { Path.CheckValidPath(path, true, true); } // When isFile == null, we're working with a device. // When opening a VOLUME or removable media drive (for example, a floppy disk drive or flash memory thumb drive), // the path string should be the following form: "\\.\X:" // Do not use a trailing backslash (\), which indicates the root. string pathLp = Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator); PrivilegeEnabler privilegeEnabler = null; try { if (fileSecurity != null) { fileSystemRights |= (FileSystemRights)0x1000000; } // AccessSystemSecurity = 0x1000000 AccessSystemAcl access type. // MaximumAllowed = 0x2000000 MaximumAllowed access type. if ((fileSystemRights & (FileSystemRights)0x1000000) != 0 || (fileSystemRights & (FileSystemRights)0x2000000) != 0) { privilegeEnabler = new PrivilegeEnabler(Privilege.Security); } using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(fileSecurity)) { SafeFileHandle handle = transaction == null || !NativeMethods.IsAtLeastWindowsVista // CreateFile() / CreateFileTransacted() // In the ANSI version of this function, the name is limited to MAX_PATH characters. // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. // 2013-01-13: MSDN confirms LongPath usage. ? NativeMethods.CreateFile(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero) : NativeMethods.CreateFileTransacted(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero, transaction.SafeHandle, IntPtr.Zero, IntPtr.Zero); int lastError = Marshal.GetLastWin32Error(); if (handle.IsInvalid) { handle.Close(); NativeError.ThrowException(lastError, pathLp); } return(handle); } } finally { if (privilegeEnabler != null) { privilegeEnabler.Dispose(); } } }
internal static SafeFileHandle CreateFileInternal(KernelTransaction transaction, string path, ExtendedFileAttributes attributes, FileSecurity fileSecurity, FileMode fileMode, FileSystemRights fileSystemRights, FileShare fileShare, bool checkPath, PathFormat pathFormat) { if (checkPath && pathFormat == PathFormat.RelativePath) Path.CheckValidPath(path, true, true); // When isFile == null, we're working with a device. // When opening a VOLUME or removable media drive (for example, a floppy disk drive or flash memory thumb drive), // the path string should be the following form: "\\.\X:" // Do not use a trailing backslash (\), which indicates the root. string pathLp = Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator); PrivilegeEnabler privilegeEnabler = null; try { if (fileSecurity != null) fileSystemRights |= (FileSystemRights)0x1000000; // AccessSystemSecurity = 0x1000000 AccessSystemAcl access type. // MaximumAllowed = 0x2000000 MaximumAllowed access type. if ((fileSystemRights & (FileSystemRights)0x1000000) != 0 || (fileSystemRights & (FileSystemRights)0x2000000) != 0) privilegeEnabler = new PrivilegeEnabler(Privilege.Security); using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(fileSecurity)) { SafeFileHandle handle = transaction == null || !NativeMethods.IsAtLeastWindowsVista // CreateFile() / CreateFileTransacted() // In the ANSI version of this function, the name is limited to MAX_PATH characters. // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. // 2013-01-13: MSDN confirms LongPath usage. ? NativeMethods.CreateFile(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero) : NativeMethods.CreateFileTransacted(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero, transaction.SafeHandle, IntPtr.Zero, IntPtr.Zero); int lastError = Marshal.GetLastWin32Error(); if (handle.IsInvalid) { handle.Close(); NativeError.ThrowException(lastError, pathLp); } return handle; } } finally { if (privilegeEnabler != null) privilegeEnabler.Dispose(); } }