diff --git a/AlphaFS/AlphaFS.csproj b/AlphaFS/AlphaFS.csproj new file mode 100644 index 0000000..8268e49 --- /dev/null +++ b/AlphaFS/AlphaFS.csproj @@ -0,0 +1,393 @@ + + + + Debug + AnyCPU + 2.0 + {F0F9AF1E-D5B5-4D72-804A-5380622FBDEA} + Library + Properties + Alphaleonis.Win32 + AlphaFS + 512 + false + ..\AlphaFS.snk + AlphaFS.ruleset + false + Client + + + true + full + false + ..\Bin\Debug\Net35 + DEBUG;TRACE;NET35 + prompt + 4 + true + ..\Bin\Debug\Net35\AlphaFS.XML + false + false + true + AnyCPU + false + false + AlphaFS.ruleset + v3.5 + + + pdbonly + true + ..\Bin\Release\Net35 + TRACE;NET35 + prompt + 4 + ..\Bin\Release\Net35\AlphaFS.XML + false + false + v3.5 + true + AlphaFS.ruleset + false + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Resources.resx + + + Code + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AlphaFS/AlphaFS.ruleset b/AlphaFS/AlphaFS.ruleset new file mode 100644 index 0000000..37302d4 --- /dev/null +++ b/AlphaFS/AlphaFS.ruleset @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/AlphaFS/AssemblyVersionInfo.cs b/AlphaFS/AssemblyVersionInfo.cs new file mode 100644 index 0000000..3881818 --- /dev/null +++ b/AlphaFS/AssemblyVersionInfo.cs @@ -0,0 +1,35 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Resources; + +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AlphaFS")] +[assembly: AssemblyCopyright("© 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov")] +[assembly: AssemblyTrademark("")] + +[assembly: AssemblyVersion("2.1.0.0")] +[assembly: AssemblyFileVersion("2.1.0.0")] +[assembly: AssemblyInformationalVersion("2.0")] +[assembly: NeutralResourcesLanguageAttribute("en-US")] + diff --git a/AlphaFS/Filesystem/AlternateDataStreamInfo.cs b/AlphaFS/Filesystem/AlternateDataStreamInfo.cs new file mode 100644 index 0000000..d4416c5 --- /dev/null +++ b/AlphaFS/Filesystem/AlternateDataStreamInfo.cs @@ -0,0 +1,138 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Information about an alternate data stream. + /// + public struct AlternateDataStreamInfo + { + #region Constructor + + internal AlternateDataStreamInfo(string fullPath, NativeMethods.WIN32_FIND_STREAM_DATA findData) : this() + { + StreamName = ParseStreamName(findData.cStreamName); + Size = findData.StreamSize; + _fullPath = fullPath; + } + + #endregion // Constructor + + #region Public Properties + + /// Gets the name of the alternate data stream. + /// This value is an empty string for the default stream (:$DATA), and for any other data stream it contains the name of the stream. + /// The name of the stream. + public string StreamName { get; private set; } + + /// Gets the size of the stream. + public long Size { get; private set; } + + + private readonly string _fullPath; + + /// Gets the full path to the stream. + /// + /// This is a path in long path format that can be passed to to open the stream if + /// or + /// is specified. + /// + /// The full path to the stream in long path format. + public string FullPath + { + get { return _fullPath + Path.StreamSeparator + StreamName + Path.StreamDataLabel; } + } + + #endregion // Public Properties + + #region Public Methods + + /// Returns the hash code for this instance. + /// A 32-bit signed integer that is the hash code for this instance. + public override int GetHashCode() + { + return StreamName.GetHashCode(); + } + + /// Indicates whether this instance and a specified object are equal. + /// The object to compare with the current instance. + /// + /// true if and this instance are the same type and represent the same value; otherwise, false. + /// + public override bool Equals(object obj) + { + if (obj is AlternateDataStreamInfo) + { + AlternateDataStreamInfo other = (AlternateDataStreamInfo) obj; + return StreamName.Equals(other.StreamName, StringComparison.OrdinalIgnoreCase) && Size.Equals(other.Size); + } + + return false; + } + + /// Equality operator. + /// The first operand. + /// The second operand. + /// The result of the operation. + public static bool operator ==(AlternateDataStreamInfo first, AlternateDataStreamInfo second) + { + return first.Equals(second); + } + + /// Inequality operator. + /// The first operand. + /// The second operand. + /// The result of the operation. + public static bool operator !=(AlternateDataStreamInfo first, AlternateDataStreamInfo second) + { + return !first.Equals(second); + } + + #endregion // Public Methods + + #region Private Methods + + private static string ParseStreamName(string input) + { + if (input == null || input.Length < 2) + return string.Empty; + + if (input[0] != Path.StreamSeparatorChar) + throw new ArgumentException(Resources.Invalid_Stream_Name); + + var sb = new StringBuilder(); + for (int i = 1; i < input.Length; i++) + { + if (input[i] == Path.StreamSeparatorChar) + break; + + sb.Append(input[i]); + } + + return sb.ToString(); + } + + #endregion // Private Methods + } +} diff --git a/AlphaFS/Filesystem/BackupFileStream.cs b/AlphaFS/Filesystem/BackupFileStream.cs new file mode 100644 index 0000000..3a03001 --- /dev/null +++ b/AlphaFS/Filesystem/BackupFileStream.cs @@ -0,0 +1,650 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Security; +using Microsoft.Win32.SafeHandles; +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.AccessControl; +using SecurityNativeMethods = Alphaleonis.Win32.Security.NativeMethods; + +namespace Alphaleonis.Win32.Filesystem +{ + /// The provides access to data associated with a specific file or directory, including security information and alternative data streams, for backup and restore operations. + /// This class uses the BackupRead, + /// BackupSeek and + /// BackupWrite functions from the Win32 API to provide access to the file or directory. + /// + public sealed class BackupFileStream : Stream + { + #region Private Fields + + private readonly bool _canRead; + private readonly bool _canWrite; + private readonly bool _processSecurity; + + [SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")] + private IntPtr _context = IntPtr.Zero; + + #endregion // Private Fields + + #region Construction and Destruction + + /// Initializes a new instance of the class with the specified path and creation mode. + /// A relative or absolute path for the file that the current object will encapsulate. + /// A constant that determines how to open or create the file. + /// The file will be opened for exclusive access for both reading and writing. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public BackupFileStream(string path, FileMode mode) + : this(File.CreateFileCore(null, path, ExtendedFileAttributes.Normal, null, mode, FileSystemRights.Read | FileSystemRights.Write, FileShare.None, true, PathFormat.RelativePath), FileSystemRights.Read | FileSystemRights.Write) + { + } + + /// Initializes a new instance of the class with the specified path, creation mode and access rights. + /// A relative or absolute path for the file that the current object will encapsulate. + /// A constant that determines how to open or create the file. + /// A constant that determines the access rights to use when creating access and audit rules for the file. + /// The file will be opened for exclusive access. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public BackupFileStream(string path, FileMode mode, FileSystemRights access) + : this(File.CreateFileCore(null, path, ExtendedFileAttributes.Normal, null, mode, access, FileShare.None, true, PathFormat.RelativePath), access) + { + } + + /// Initializes a new instance of the class with the specified path, creation mode, access rights and sharing permission. + /// A relative or absolute path for the file that the current object will encapsulate. + /// A constant that determines how to open or create the file. + /// A constant that determines the access rights to use when creating access and audit rules for the file. + /// A constant that determines how the file will be shared by processes. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public BackupFileStream(string path, FileMode mode, FileSystemRights access, FileShare share) + : this(File.CreateFileCore(null, path, ExtendedFileAttributes.Normal, null, mode, access, share, true, PathFormat.RelativePath), access) + { + } + + /// Initializes a new instance of the class with the specified path, creation mode, access rights and sharing permission, and additional file attributes. + /// A relative or absolute path for the file that the current object will encapsulate. + /// A constant that determines how to open or create the file. + /// A constant that determines the access rights to use when creating access and audit rules for the file. + /// A constant that determines how the file will be shared by processes. + /// A constant that specifies additional file attributes. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public BackupFileStream(string path, FileMode mode, FileSystemRights access, FileShare share, ExtendedFileAttributes attributes) + : this(File.CreateFileCore(null, path, attributes, null, mode, access, share, true, PathFormat.RelativePath), access) + { + } + + /// Initializes a new instance of the class with the specified path, creation mode, access rights and sharing permission, additional file attributes, access control and audit security. + /// A relative or absolute path for the file that the current object will encapsulate. + /// A constant that determines how to open or create the file. + /// A constant that determines the access rights to use when creating access and audit rules for the file. + /// A constant that determines how the file will be shared by processes. + /// A constant that specifies additional file attributes. + /// A constant that determines the access control and audit security for the file. This parameter This parameter may be . + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public BackupFileStream(string path, FileMode mode, FileSystemRights access, FileShare share, ExtendedFileAttributes attributes, FileSecurity security) + : this(File.CreateFileCore(null, path, attributes, security, mode, access, share, true, PathFormat.RelativePath), access) + { + } + + #region Transactional + + /// Initializes a new instance of the class with the specified path and creation mode. + /// The transaction. + /// A relative or absolute path for the file that the current object will encapsulate. + /// A constant that determines how to open or create the file. + /// The file will be opened for exclusive access for both reading and writing. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public BackupFileStream(KernelTransaction transaction, string path, FileMode mode) + : this(File.CreateFileCore(transaction, path, ExtendedFileAttributes.Normal, null, mode, FileSystemRights.Read | FileSystemRights.Write, FileShare.None, true, PathFormat.RelativePath), FileSystemRights.Read | FileSystemRights.Write) + { + } + + /// Initializes a new instance of the class with the specified path, creation mode and access rights. + /// The transaction. + /// A relative or absolute path for the file that the current object will encapsulate. + /// A constant that determines how to open or create the file. + /// A constant that determines the access rights to use when creating access and audit rules for the file. + /// The file will be opened for exclusive access. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public BackupFileStream(KernelTransaction transaction, string path, FileMode mode, FileSystemRights access) + : this(File.CreateFileCore(transaction, path, ExtendedFileAttributes.Normal, null, mode, access, FileShare.None, true, PathFormat.RelativePath), access) + { + } + + /// Initializes a new instance of the class with the specified path, creation mode, access rights and sharing permission. + /// The transaction. + /// A relative or absolute path for the file that the current object will encapsulate. + /// A constant that determines how to open or create the file. + /// A constant that determines the access rights to use when creating access and audit rules for the file. + /// A constant that determines how the file will be shared by processes. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public BackupFileStream(KernelTransaction transaction, string path, FileMode mode, FileSystemRights access, FileShare share) + : this(File.CreateFileCore(transaction, path, ExtendedFileAttributes.Normal, null, mode, access, share, true, PathFormat.RelativePath), access) + { + } + + /// Initializes a new instance of the class with the specified path, creation mode, access rights and sharing permission, and additional file attributes. + /// The transaction. + /// A relative or absolute path for the file that the current object will encapsulate. + /// A constant that determines how to open or create the file. + /// A constant that determines the access rights to use when creating access and audit rules for the file. + /// A constant that determines how the file will be shared by processes. + /// A constant that specifies additional file attributes. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public BackupFileStream(KernelTransaction transaction, string path, FileMode mode, FileSystemRights access, FileShare share, ExtendedFileAttributes attributes) + : this(File.CreateFileCore(transaction, path, attributes, null, mode, access, share, true, PathFormat.RelativePath), access) + { + } + + /// Initializes a new instance of the class with the specified path, creation mode, access rights and sharing permission, additional file attributes, access control and audit security. + /// The transaction. + /// A relative or absolute path for the file that the current object will encapsulate. + /// A constant that determines how to open or create the file. + /// A constant that determines the access rights to use when creating access and audit rules for the file. + /// A constant that determines how the file will be shared by processes. + /// A constant that specifies additional file attributes. + /// A constant that determines the access control and audit security for the file. This parameter This parameter may be . + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public BackupFileStream(KernelTransaction transaction, string path, FileMode mode, FileSystemRights access, FileShare share, ExtendedFileAttributes attributes, FileSecurity security) + : this(File.CreateFileCore(transaction, path, attributes, security, mode, access, share, true, PathFormat.RelativePath), access) + { + } + + #endregion // Transacted + + + #region Stream + + /// Initializes a new instance of the class for the specified file handle, with the specified read/write permission. + /// A file handle for the file that this object will encapsulate. + /// A constant that gets the and properties of the object. + + [SecurityCritical] + public BackupFileStream(SafeFileHandle handle, FileSystemRights access) + { + if (handle == null) + throw new ArgumentNullException("handle", Resources.Handle_Is_Invalid); + + if (handle.IsInvalid) + { + handle.Close(); + throw new ArgumentException(Resources.Handle_Is_Invalid); + } + + if (handle.IsClosed) + throw new ArgumentException(Resources.Handle_Is_Closed); + + + SafeFileHandle = handle; + + _canRead = (access & FileSystemRights.ReadData) != 0; + _canWrite = (access & FileSystemRights.WriteData) != 0; + _processSecurity = true; + } + + #endregion // Stream + + #endregion // Construction and Destruction + + #region NotSupportedException + + /// When overridden in a derived class, gets the length in bytes of the stream. + /// This method always throws an exception. + /// + public override long Length + { + get { throw new NotSupportedException(Resources.No_Stream_Seeking_Support); } + } + + /// When overridden in a derived class, gets or sets the position within the current stream. + /// This method always throws an exception. + /// + public override long Position + { + get { throw new NotSupportedException(Resources.No_Stream_Seeking_Support); } + set { throw new NotSupportedException(Resources.No_Stream_Seeking_Support); } + } + + + /// When overridden in a derived class, sets the position within the current stream. + /// A byte offset relative to the parameter. + /// A value of type indicating the reference point used to obtain the new position. + /// The new position within the current stream. + /// This stream does not support seeking using this method, and calling this method will always throw . See for an alternative way of seeking forward. + /// + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(Resources.No_Stream_Seeking_Support); + } + + + /// When overridden in a derived class, sets the length of the current stream. + /// The desired length of the current stream in bytes. + /// This method is not supported by the class, and calling it will always generate a . + /// + public override void SetLength(long value) + { + throw new NotSupportedException(Resources.No_Stream_Seeking_Support); + } + + #endregion // NotSupportedException + + #region Properties + + /// Gets a value indicating whether the current stream supports reading. + /// if the stream supports reading, otherwise. + public override bool CanRead + { + get { return _canRead; } + } + + /// Gets a value indicating whether the current stream supports seeking. + /// This method always returns . + public override bool CanSeek + { + get { return false; } + } + + /// Gets a value indicating whether the current stream supports writing. + /// if the stream supports writing, otherwise. + public override bool CanWrite + { + get { return _canWrite; } + } + + /// Gets a object that represents the operating system file handle for the file that the current object encapsulates. + /// A object that represents the operating system file handle for the file that + /// the current object encapsulates. + private SafeFileHandle SafeFileHandle { get; set; } + + #endregion // Properties + + #region Methods + + /// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. + /// This method will not backup the access-control list (ACL) data for the file or directory. + /// + /// An array of bytes. When this method returns, the buffer contains the specified byte array with the values between + /// and ( + - 1) replaced by the bytes read from the + /// current source. + /// + /// + /// The zero-based byte offset in at which to begin storing the data read from the current stream. + /// + /// The maximum number of bytes to be read from the current stream. + /// + /// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not + /// currently available, or zero (0) if the end of the stream has been reached. + /// + /// + /// + /// + /// + /// + /// + public override int Read(byte[] buffer, int offset, int count) + { + return Read(buffer, offset, count, false); + } + + /// When overridden in a derived class, reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. + /// An array of bytes. When this method returns, the buffer contains the specified byte array with the values + /// between and ( + - 1) replaced by the bytes read from the current source. + /// The zero-based byte offset in at which to begin storing the data read from the current stream. + /// The maximum number of bytes to be read from the current stream. + /// Indicates whether the function will backup the access-control list (ACL) data for the file or directory. + /// + /// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not + /// currently available, or zero (0) if the end of the stream has been reached. + /// + /// + /// + /// + /// + /// + [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] + [SecurityCritical] + public int Read(byte[] buffer, int offset, int count, bool processSecurity) + { + if (buffer == null) + throw new ArgumentNullException("buffer"); + + if (!CanRead) + throw new NotSupportedException("Stream does not support reading"); + + if (offset + count > buffer.Length) + throw new ArgumentException("The sum of offset and count is larger than the size of the buffer."); + + if (offset < 0) + throw new ArgumentOutOfRangeException("offset", offset, Resources.Negative_Offset); + + if (count < 0) + throw new ArgumentOutOfRangeException("count", count, Resources.Negative_Count); + + + using (var safeBuffer = new SafeGlobalMemoryBufferHandle(count)) + { + uint numberOfBytesRead; + + if (!NativeMethods.BackupRead(SafeFileHandle, safeBuffer, (uint)safeBuffer.Capacity, out numberOfBytesRead, false, processSecurity, ref _context)) + NativeError.ThrowException(Marshal.GetLastWin32Error()); + + // See File.GetAccessControlCore(): .CopyTo() does not work there? + safeBuffer.CopyTo(buffer, offset, count); + + return (int)numberOfBytesRead; + } + } + + + /// Writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written. + /// + /// Writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written. + /// + /// An array of bytes. This method copies bytes from to the current stream. + /// The zero-based byte offset in at which to begin copying bytes to the current stream. + /// The number of bytes to be written to the current stream. + /// + /// + /// + /// + /// + /// This method will not process the access-control list (ACL) data for the file or directory. + public override void Write(byte[] buffer, int offset, int count) + { + Write(buffer, offset, count, false); + } + + /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written. + /// An array of bytes. This method copies bytes from to the current stream. + /// The zero-based byte offset in at which to begin copying bytes to the current stream. + /// The number of bytes to be written to the current stream. + /// Specifies whether the function will restore the access-control list (ACL) data for the file or directory. + /// If this is you need to specify and access when + /// opening the file or directory handle. If the handle does not have those access rights, the operating system denies + /// access to the ACL data, and ACL data restoration will not occur. + /// + /// + /// + /// + /// + [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] + [SecurityCritical] + public void Write(byte[] buffer, int offset, int count, bool processSecurity) + { + if (buffer == null) + throw new ArgumentNullException("buffer"); + + if (offset < 0) + throw new ArgumentOutOfRangeException("offset", offset, Resources.Negative_Offset); + + if (count < 0) + throw new ArgumentOutOfRangeException("count", count, Resources.Negative_Count); + + if (offset + count > buffer.Length) + throw new ArgumentException(Resources.Buffer_Not_Large_Enough); + + + using (var safeBuffer = new SafeGlobalMemoryBufferHandle(count)) + { + safeBuffer.CopyFrom(buffer, offset, count); + + uint bytesWritten; + + if (!NativeMethods.BackupWrite(SafeFileHandle, safeBuffer, (uint)safeBuffer.Capacity, out bytesWritten, false, processSecurity, ref _context)) + NativeError.ThrowException(Marshal.GetLastWin32Error()); + } + } + + + /// Clears all buffers for this stream and causes any buffered data to be written to the underlying device. + public override void Flush() + { + if (!NativeMethods.FlushFileBuffers(SafeFileHandle)) + NativeError.ThrowException(Marshal.GetLastWin32Error()); + } + + + /// Skips ahead the specified number of bytes from the current stream. + /// This method represents the Win32 API implementation of BackupSeek. + /// + /// Applications use the method to skip portions of a data stream that cause errors. This function does not + /// seek across stream headers. For example, this function cannot be used to skip the stream name. If an application + /// attempts to seek past the end of a substream, the function fails, the return value indicates the actual number of bytes + /// the function seeks, and the file position is placed at the start of the next stream header. + /// + /// + /// The number of bytes to skip. + /// The number of bytes actually skipped. + [SecurityCritical] + public long Skip(long bytes) + { + uint lowSought, highSought; + if (!NativeMethods.BackupSeek(SafeFileHandle, NativeMethods.GetLowOrderDword(bytes), NativeMethods.GetHighOrderDword(bytes), out lowSought, out highSought, ref _context)) + { + int lastError = Marshal.GetLastWin32Error(); + + // Error Code 25 indicates a seek error, we just skip that here. + if (lastError != Win32Errors.NO_ERROR && lastError != Win32Errors.ERROR_SEEK) + NativeError.ThrowException(lastError); + } + + return NativeMethods.ToLong(highSought, lowSought); + } + + + /// Gets a object that encapsulates the access control list (ACL) entries for the file described by the current object. + /// + /// + /// A object that encapsulates the access control list (ACL) entries for the file described by the current + /// object. + /// + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")] + [SecurityCritical] + public FileSecurity GetAccessControl() + { + IntPtr pSidOwner, pSidGroup, pDacl, pSacl; + SafeGlobalMemoryBufferHandle pSecurityDescriptor; + + uint lastError = SecurityNativeMethods.GetSecurityInfo(SafeFileHandle, ObjectType.FileObject, + SecurityInformation.Group | SecurityInformation.Owner | SecurityInformation.Label | SecurityInformation.Dacl | SecurityInformation.Sacl, + out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor); + + try + { + if (lastError != Win32Errors.ERROR_SUCCESS) + NativeError.ThrowException((int)lastError); + + if (pSecurityDescriptor != null && pSecurityDescriptor.IsInvalid) + { + pSecurityDescriptor.Close(); + throw new IOException(Resources.Returned_Invalid_Security_Descriptor); + } + + uint length = SecurityNativeMethods.GetSecurityDescriptorLength(pSecurityDescriptor); + + byte[] managedBuffer = new byte[length]; + + + // .CopyTo() does not work there? + if (pSecurityDescriptor != null) + pSecurityDescriptor.CopyTo(managedBuffer, 0, (int) length); + + + var fs = new FileSecurity(); + fs.SetSecurityDescriptorBinaryForm(managedBuffer); + + return fs; + } + finally + { + if (pSecurityDescriptor != null) + pSecurityDescriptor.Close(); + } + } + + + /// Applies access control list (ACL) entries described by a object to the file described by the current object. + /// A object that describes an ACL entry to apply to the current file. + [SecurityCritical] + public void SetAccessControl(ObjectSecurity fileSecurity) + { + File.SetAccessControlCore(null, SafeFileHandle, fileSecurity, AccessControlSections.All, PathFormat.LongFullPath); + } + + + /// Prevents other processes from changing the while permitting read access. + /// The beginning of the range to lock. The value of this parameter must be equal to or greater than zero (0). + /// The range to be locked. + /// + /// + [SecurityCritical] + public void Lock(long position, long length) + { + if (position < 0) + throw new ArgumentOutOfRangeException("position", position, Resources.Unlock_Position_Negative); + + if (length < 0) + throw new ArgumentOutOfRangeException("length", length, Resources.Negative_Lock_Length); + + if (!NativeMethods.LockFile(SafeFileHandle, NativeMethods.GetLowOrderDword(position), NativeMethods.GetHighOrderDword(position), NativeMethods.GetLowOrderDword(length), NativeMethods.GetHighOrderDword(length))) + NativeError.ThrowException(Marshal.GetLastWin32Error()); + } + + + /// Allows access by other processes to all or part of a file that was previously locked. + /// The beginning of the range to unlock. + /// The range to be unlocked. + /// + /// + /// + [SecurityCritical] + public void Unlock(long position, long length) + { + if (position < 0) + throw new ArgumentOutOfRangeException("position", position, Resources.Unlock_Position_Negative); + + if (length < 0) + throw new ArgumentOutOfRangeException("length", length, Resources.Negative_Lock_Length); + + if (!NativeMethods.UnlockFile(SafeFileHandle, NativeMethods.GetLowOrderDword(position), NativeMethods.GetHighOrderDword(position), NativeMethods.GetLowOrderDword(length), NativeMethods.GetHighOrderDword(length))) + NativeError.ThrowException(Marshal.GetLastWin32Error()); + } + + + /// Reads a stream header from the current . + /// The stream header read from the current , or if the end-of-file + /// was reached before the required number of bytes of a header could be read. + /// + /// The stream must be positioned at where an actual header starts for the returned object to represent valid + /// information. + [SecurityCritical] + public BackupStreamInfo ReadStreamInfo() + { + var sizeOf = Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID)); + + using (var hBuf = new SafeGlobalMemoryBufferHandle(sizeOf)) + { + uint numberOfBytesRead; + + if (!NativeMethods.BackupRead(SafeFileHandle, hBuf, (uint) sizeOf, out numberOfBytesRead, false, _processSecurity, ref _context)) + NativeError.ThrowException(); + + + if (numberOfBytesRead == 0) + return null; + + + if (numberOfBytesRead < sizeOf) + throw new IOException(Resources.Read_Incomplete_Header); + + var streamID = hBuf.PtrToStructure(0); + + uint nameLength = (uint) Math.Min(streamID.dwStreamNameSize, hBuf.Capacity); + + + if (!NativeMethods.BackupRead(SafeFileHandle, hBuf, nameLength, out numberOfBytesRead, false, _processSecurity, ref _context)) + NativeError.ThrowException(); + + string name = hBuf.PtrToStringUni(0, (int) nameLength/2); + + return new BackupStreamInfo(streamID, name); + } + } + + #endregion // Methods + + #region Disposable Members + + /// Releases the unmanaged resources used by the and optionally releases the managed resources. + /// to release both managed and unmanaged resources; to release only unmanaged resources. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + protected override void Dispose(bool disposing) + { + // If one of the constructors previously threw an exception, + // than the object hasn't been initialized properly and call from finalize will fail. + + if (SafeFileHandle != null && !SafeFileHandle.IsInvalid) + { + if (_context != IntPtr.Zero) + { + try + { + uint temp; + + // MSDN: To release the memory used by the data structure, call BackupRead with the bAbort parameter set to TRUE when the backup operation is complete. + if (!NativeMethods.BackupRead(SafeFileHandle, new SafeGlobalMemoryBufferHandle(), 0, out temp, true, false, ref _context)) + NativeError.ThrowException(Marshal.GetLastWin32Error()); + } + finally + { + _context = IntPtr.Zero; + SafeFileHandle.Close(); + } + } + } + + base.Dispose(disposing); + } + + /// Releases unmanaged resources and performs other cleanup operations before the is reclaimed by garbage collection. + ~BackupFileStream() + { + Dispose(false); + } + + #endregion // Disposable Members + } +} diff --git a/AlphaFS/Filesystem/BackupStreamInfo.cs b/AlphaFS/Filesystem/BackupStreamInfo.cs new file mode 100644 index 0000000..2bc85a5 --- /dev/null +++ b/AlphaFS/Filesystem/BackupStreamInfo.cs @@ -0,0 +1,84 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + /// The structure contains stream header data. + /// + public sealed class BackupStreamInfo + { + #region Private Fields + + private readonly long m_size; + private readonly string m_name; + private readonly BackupStreamType m_streamType; + private readonly StreamAttributes m_attributes; + + #endregion + + #region Constructor + + /// Initializes a new instance of the class. + /// The stream ID. + /// The name. + internal BackupStreamInfo(NativeMethods.WIN32_STREAM_ID streamID, string name) + { + m_name = name; + m_size = (long) streamID.Size; + m_attributes = streamID.dwStreamAttributes; + m_streamType = streamID.dwStreamId; + } + + #endregion + + #region Public Properties + + /// Gets the size of the data in the substream, in bytes. + /// The size of the data in the substream, in bytes. + public long Size + { + get { return m_size; } + } + + /// Gets a string that specifies the name of the alternative data stream. + /// A string that specifies the name of the alternative data stream. + public string Name + { + get { return m_name; } + } + + /// Gets the type of the data in the stream. + /// The type of the data in the stream. + public BackupStreamType StreamType + { + get { return m_streamType; } + } + + /// Gets the attributes of the data to facilitate cross-operating system transfer. + /// Attributes of the data to facilitate cross-operating system transfer. + public StreamAttributes Attributes + { + get { return m_attributes; } + } + + #endregion // Public Properties + } +} diff --git a/AlphaFS/Filesystem/ByHandleFileInfo.cs b/AlphaFS/Filesystem/ByHandleFileInfo.cs new file mode 100644 index 0000000..e46dbcd --- /dev/null +++ b/AlphaFS/Filesystem/ByHandleFileInfo.cs @@ -0,0 +1,177 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + #region ByHandleFileInfo + + /// Contains information that the GetFileInformationByHandle function retrieves. + [SerializableAttribute] + [SecurityCritical] + public sealed class ByHandleFileInfo + { + #region Constructor + + internal ByHandleFileInfo(NativeMethods.BY_HANDLE_FILE_INFORMATION fibh) + { + CreationTimeUtc = DateTime.FromFileTimeUtc(fibh.ftCreationTime); + LastAccessTimeUtc = DateTime.FromFileTimeUtc(fibh.ftLastAccessTime); + LastWriteTimeUtc = DateTime.FromFileTimeUtc(fibh.ftLastWriteTime); + + Attributes = fibh.dwFileAttributes; + FileIndex = NativeMethods.ToLong(fibh.nFileIndexHigh, fibh.nFileIndexLow); + FileSize = NativeMethods.ToLong(fibh.nFileSizeHigh, fibh.nFileSizeLow); + NumberOfLinks = fibh.nNumberOfLinks; + VolumeSerialNumber = fibh.dwVolumeSerialNumber; + } + + #endregion // Constructor + + #region Properties + + #region Attributes + + /// Gets the file attributes. + /// The file attributes. + public FileAttributes Attributes { get; private set; } + + #endregion // Attributes + + #region CreationTime + + /// Gets the time this entry was created. + /// The time this entry was created. + public DateTime CreationTime + { + get { return CreationTimeUtc.ToLocalTime(); } + } + + #endregion // CreationTime + + #region CreationTimeUtc + + /// Gets the time, in coordinated universal time (UTC), this entry was created. + /// The time, in coordinated universal time (UTC), this entry was created. + public DateTime CreationTimeUtc { get; private set; } + + #endregion // CreationTimeUtc + + #region LastAccessTime + + /// Gets the time this entry was last accessed. + /// For a file, the structure specifies the last time that a file is read from or written to. + /// For a directory, the structure specifies when the directory is created. + /// For both files and directories, the specified date is correct, but the time of day is always set to midnight. + /// If the underlying file system does not support the last access time, this member is zero (0). + /// + /// The time this entry was last accessed. + public DateTime LastAccessTime + { + get { return LastAccessTimeUtc.ToLocalTime(); } + } + + #endregion // LastAccessTime + + #region LastAccessTimeUtc + + /// Gets the time, in coordinated universal time (UTC), this entry was last accessed. + /// For a file, the structure specifies the last time that a file is read from or written to. + /// For a directory, the structure specifies when the directory is created. + /// For both files and directories, the specified date is correct, but the time of day is always set to midnight. + /// If the underlying file system does not support the last access time, this member is zero (0). + /// + /// The time, in coordinated universal time (UTC), this entry was last accessed. + public DateTime LastAccessTimeUtc { get; private set; } + + #endregion // LastAccessTimeUtc + + #region LastWriteTime + + /// Gets the time this entry was last modified. + /// For a file, the structure specifies the last time that a file is written to. + /// For a directory, the structure specifies when the directory is created. + /// If the underlying file system does not support the last access time, this member is zero (0). + /// + /// The time this entry was last modified. + public DateTime LastWriteTime + { + get { return LastWriteTimeUtc.ToLocalTime(); } + } + + #endregion // LastWriteTime + + #region LastWriteTimeUtc + + /// Gets the time, in coordinated universal time (UTC), this entry was last modified. + /// For a file, the structure specifies the last time that a file is written to. + /// For a directory, the structure specifies when the directory is created. + /// If the underlying file system does not support the last access time, this member is zero (0). + /// + /// The time, in coordinated universal time (UTC), this entry was last modified. + public DateTime LastWriteTimeUtc { get; private set; } + + #endregion // LastWriteTimeUtc + + #region VolumeSerialNumber + + /// Gets the serial number of the volume that contains a file. + /// The serial number of the volume that contains a file. + public int VolumeSerialNumber { get; private set; } + + #endregion // VolumeSerialNumber + + #region FileSize + + /// Gets the size of the file. + /// The size of the file. + public long FileSize { get; private set; } + + #endregion // FileSize + + #region NumberOfLinks + + /// Gets the number of links to this file. For the FAT file system this member is always 1. For the NTFS file system, it can be more than 1. + /// The number of links to this file. + public int NumberOfLinks { get; private set; } + + #endregion // NumberOfLinks + + #region FileIndex + + /// + /// Gets the unique identifier associated with the file. The identifier and the volume serial number uniquely identify a + /// file on a single computer. To determine whether two open handles represent the same file, combine the identifier + /// and the volume serial number for each file and compare them. + /// + /// The unique identifier of the file. + public long FileIndex { get; private set; } + + #endregion // FileIndex + + #endregion // Properties + } + + #endregion // ByHandleFileInfo +} diff --git a/AlphaFS/Filesystem/ChangeErrorMode.cs b/AlphaFS/Filesystem/ChangeErrorMode.cs new file mode 100644 index 0000000..035d52b --- /dev/null +++ b/AlphaFS/Filesystem/ChangeErrorMode.cs @@ -0,0 +1,56 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Controls whether the system will handle the specified types of serious errors or whether the process will handle them. + /// Minimum supported client: Windows 2000 Professional + /// Minimum supported server: Windows 2000 Server + public sealed class ChangeErrorMode : IDisposable + { + private readonly ErrorMode _oldMode; + + /// ChangeErrorMode is for the Win32 SetThreadErrorMode() method, used to suppress possible pop-ups. + /// One of the values. + public ChangeErrorMode(ErrorMode mode) + { + if (IsAtLeastWindows7) + SetThreadErrorMode(mode, out _oldMode); + else + _oldMode = SetErrorMode(mode); + } + + void IDisposable.Dispose() + { + ErrorMode oldMode; + + if (IsAtLeastWindows7) + SetThreadErrorMode(_oldMode, out oldMode); + else + SetErrorMode(_oldMode); + } + } + } +} diff --git a/AlphaFS/Filesystem/CopyMoveProgressRoutine.cs b/AlphaFS/Filesystem/CopyMoveProgressRoutine.cs new file mode 100644 index 0000000..648bd9d --- /dev/null +++ b/AlphaFS/Filesystem/CopyMoveProgressRoutine.cs @@ -0,0 +1,28 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Callback used by CopyFileXxx and MoveFileXxx to report progress about the copy/move operation. + public delegate CopyMoveProgressResult CopyMoveProgressRoutine(long totalFileSize, long totalBytesTransferred, long streamSize, long streamBytesTransferred, int streamNumber, CopyMoveProgressCallbackReason callbackReason, object userData); +} diff --git a/AlphaFS/Filesystem/CopyMoveResult.cs b/AlphaFS/Filesystem/CopyMoveResult.cs new file mode 100644 index 0000000..4e8cfe9 --- /dev/null +++ b/AlphaFS/Filesystem/CopyMoveResult.cs @@ -0,0 +1,82 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Class for CopyMoveResult that contains the results for the Copy or Move action. + public sealed class CopyMoveResult + { + /// Create a CopyMoveResult class instance for the Copy or Move action. + /// Indicates the source file or directory. + /// Indicates the destination file or directory. + /// Indicates if the action was canceled. + /// The error code encountered during the Copy or Move action. + public CopyMoveResult(string source, string destination, bool isCanceled, int errorCode) + { + Source = source; + Destination = destination; + IsCanceled = isCanceled; + ErrorCode = errorCode; + } + + + /// The error code encountered during the Copy or Move action. + /// 0 (zero) indicates success. + public int ErrorCode { get; internal set; } + + + /// The error message from the that was encountered during the Copy or Move action. + /// A message describing the error. + [SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] + public string ErrorMessage + { + get { return new Win32Exception(ErrorCode).Message; } + } + + + /// When true indicates that the Copy or Move action was canceled. + /// when the Copy/Move action was canceled. Otherwise . + public bool IsCanceled { get; internal set; } + + + /// Indicates the source file or directory. + public string Source { get; private set; } + + + /// Indicates the destination file or directory. + public string Destination { get; private set; } + + + /// The total number of folders copied. + public long TotalFolders { get; internal set; } + + + /// The total number of files copied. + public long TotalFiles { get; internal set; } + + + /// The total number of bytes copied. + public long TotalBytes { get; internal set; } + } +} diff --git a/AlphaFS/Filesystem/Device.cs b/AlphaFS/Filesystem/Device.cs new file mode 100644 index 0000000..0d3318b --- /dev/null +++ b/AlphaFS/Filesystem/Device.cs @@ -0,0 +1,459 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Network; +using Microsoft.Win32.SafeHandles; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.AccessControl; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Provides static methods to retrieve device resource information from a local or remote host. + public static class Device + { + #region EnumerateDevices + + /// Enumerates all available devices on the local host. + /// instances of type from the local host. + /// One of the devices. + [SecurityCritical] + public static IEnumerable EnumerateDevices(DeviceGuid deviceGuid) + { + return EnumerateDevices(null, deviceGuid); + } + + /// Enumerates all available devices of type on the local or remote host. + /// instances of type for the specified . + /// The name of the local or remote host on which the device resides. refers to the local host. + /// One of the devices. + [SecurityCritical] + public static IEnumerable EnumerateDevices(string hostName, DeviceGuid deviceGuid) + { + return EnumerateDevicesCore(null, hostName, deviceGuid); + } + + #endregion // EnumerateDevices + + #region Internal Methods + + #region EnumerateDevicesCore + + /// Enumerates all available devices on the local or remote host. + [SecurityCritical] + internal static IEnumerable EnumerateDevicesCore(SafeHandle safeHandle, string hostName, DeviceGuid deviceInterfaceGuid) + { + var callerHandle = safeHandle != null; + var deviceGuid = new Guid(Utils.GetEnumDescription(deviceInterfaceGuid)); + + + // CM_Connect_Machine() + // MSDN Note: Beginning in Windows 8 and Windows Server 2012 functionality to access remote machines has been removed. + // You cannot access remote machines when running on these versions of Windows. + // http://msdn.microsoft.com/en-us/library/windows/hardware/ff537948%28v=vs.85%29.aspx + + SafeCmConnectMachineHandle safeMachineHandle; + var lastError = NativeMethods.CM_Connect_Machine(Path.LocalToUncCore(Host.GetUncName(hostName), false, false, false), out safeMachineHandle); + + if (safeMachineHandle != null && safeMachineHandle.IsInvalid) + { + safeMachineHandle.Close(); + NativeError.ThrowException(lastError, Resources.Handle_Is_Invalid); + } + + using (safeMachineHandle) + { + // Start at the "Root" of the device tree of the specified machine. + if (!callerHandle) + safeHandle = NativeMethods.SetupDiGetClassDevsEx(ref deviceGuid, IntPtr.Zero, IntPtr.Zero, + NativeMethods.SetupDiGetClassDevsExFlags.Present | + NativeMethods.SetupDiGetClassDevsExFlags.DeviceInterface, + IntPtr.Zero, hostName, IntPtr.Zero); + + if (safeHandle != null && safeHandle.IsInvalid) + { + safeHandle.Close(); + NativeError.ThrowException(Marshal.GetLastWin32Error(), Resources.Handle_Is_Invalid); + } + + + try + { + uint memberInterfaceIndex = 0; + var deviceInterfaceData = CreateDeviceInterfaceDataInstance(); + + // Start enumerating Device Interfaces. + while (NativeMethods.SetupDiEnumDeviceInterfaces(safeHandle, IntPtr.Zero, ref deviceGuid, memberInterfaceIndex++, ref deviceInterfaceData)) + { + lastError = Marshal.GetLastWin32Error(); + if (lastError != Win32Errors.NO_ERROR) + NativeError.ThrowException(lastError, hostName); + + + var deviceInfoData = CreateDeviceInfoDataInstance(); + var deviceInterfaceDetailData = GetDeviceInterfaceDetailDataInstance(safeHandle, deviceInterfaceData, deviceInfoData); + + // Get device interace details. + if (!NativeMethods.SetupDiGetDeviceInterfaceDetail(safeHandle, ref deviceInterfaceData, ref deviceInterfaceDetailData, NativeMethods.DefaultFileBufferSize, IntPtr.Zero, ref deviceInfoData)) + { + lastError = Marshal.GetLastWin32Error(); + if (lastError != Win32Errors.NO_ERROR) + NativeError.ThrowException(lastError, hostName); + } + + // Create DeviceInfo instance. + // Set DevicePath property of DeviceInfo instance. + var deviceInfo = new DeviceInfo(hostName) { DevicePath = deviceInterfaceDetailData.DevicePath }; + + + // Current InstanceId is at the "USBSTOR" level, so we + // need up "move up" one level to get to the "USB" level. + uint ptrPrevious; + + // CM_Get_Parent_Ex() + // Note: Using this function to access remote machines is not supported + // beginning with Windows 8 and Windows Server 2012, as this functionality has been removed. + // http://msdn.microsoft.com/en-us/library/windows/hardware/ff538615%28v=vs.85%29.aspx + + lastError = NativeMethods.CM_Get_Parent_Ex(out ptrPrevious, deviceInfoData.DevInst, 0, safeMachineHandle); + if (lastError != Win32Errors.CR_SUCCESS) + NativeError.ThrowException(lastError, hostName); + + + // Now we get the InstanceID of the USB level device. + using (var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize)) + { + // CM_Get_Device_ID_Ex() + // Note: Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, + // as this functionality has been removed. + // http://msdn.microsoft.com/en-us/library/windows/hardware/ff538411%28v=vs.85%29.aspx + + lastError = NativeMethods.CM_Get_Device_ID_Ex(deviceInfoData.DevInst, safeBuffer, (uint)safeBuffer.Capacity, 0, safeMachineHandle); + if (lastError != Win32Errors.CR_SUCCESS) + NativeError.ThrowException(lastError, hostName); + + // Add to instance. + deviceInfo.InstanceId = safeBuffer.PtrToStringUni(); + } + + #region Get Registry Properties + + using (var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize)) + { + uint regType; + string dataString; + var safeBufferCapacity = (uint) safeBuffer.Capacity; + + + if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.BaseContainerId, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) + { + dataString = safeBuffer.PtrToStringUni(); + if (!Utils.IsNullOrWhiteSpace(dataString)) + deviceInfo.BaseContainerId = new Guid(dataString); + } + + if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.ClassGuid, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) + { + dataString = safeBuffer.PtrToStringUni(); + if (!Utils.IsNullOrWhiteSpace(dataString)) + deviceInfo.ClassGuid = new Guid(dataString); + } + + + if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.Class, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) + deviceInfo.Class = safeBuffer.PtrToStringUni(); + + if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.CompatibleIds, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) + deviceInfo.CompatibleIds = safeBuffer.PtrToStringUni(); + + if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.DeviceDescription, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) + deviceInfo.DeviceDescription = safeBuffer.PtrToStringUni(); + + if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.Driver, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) + deviceInfo.Driver = safeBuffer.PtrToStringUni(); + + if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.EnumeratorName, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) + deviceInfo.EnumeratorName = safeBuffer.PtrToStringUni(); + + if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.FriendlyName, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) + deviceInfo.FriendlyName = safeBuffer.PtrToStringUni(); + + if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.HardwareId, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) + deviceInfo.HardwareId = safeBuffer.PtrToStringUni(); + + if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.LocationInformation, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) + deviceInfo.LocationInformation = safeBuffer.PtrToStringUni(); + + if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.LocationPaths, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) + deviceInfo.LocationPaths = safeBuffer.PtrToStringUni(); + + if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.Manufacturer, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) + deviceInfo.Manufacturer = safeBuffer.PtrToStringUni(); + + if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.PhysicalDeviceObjectName, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) + deviceInfo.PhysicalDeviceObjectName = safeBuffer.PtrToStringUni(); + + if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.Service, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) + deviceInfo.Service = safeBuffer.PtrToStringUni(); + } + + #endregion // Get Registry Properties + + yield return deviceInfo; + + // Get new structure instance. + deviceInterfaceData = CreateDeviceInterfaceDataInstance(); + } + } + finally + { + // Handle is ours, dispose. + if (!callerHandle && safeHandle != null) + safeHandle.Close(); + } + } + } + + #endregion // EnumerateDevicesCore + + #region GetLinkTargetInfoCore + + /// Get information about the target of a mount point or symbolic link on an NTFS file system. + [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Disposing is controlled.")] + [SecurityCritical] + internal static LinkTargetInfo GetLinkTargetInfoCore(SafeFileHandle safeHandle) + { + // Start with a large buffer to prevent a 2nd call. + // MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16384 + uint bytesReturned = 4*NativeMethods.DefaultFileBufferSize; + + using (var safeBuffer = new SafeGlobalMemoryBufferHandle((int) bytesReturned)) + { + while (true) + { + // DeviceIoControlMethod.Buffered = 0, + // DeviceIoControlFileDevice.FileSystem = 9 + // FsctlGetReparsePoint = (DeviceIoControlFileDevice.FileSystem << 16) | (42 << 2) | DeviceIoControlMethod.Buffered | (0 << 14) + + if (!NativeMethods.DeviceIoControl(safeHandle, ((9 << 16) | (42 << 2) | 0 | (0 << 14)), IntPtr.Zero, 0, safeBuffer, (uint) safeBuffer.Capacity, out bytesReturned, IntPtr.Zero)) + { + var lastError = Marshal.GetLastWin32Error(); + switch ((uint) lastError) + { + case Win32Errors.ERROR_MORE_DATA: + case Win32Errors.ERROR_INSUFFICIENT_BUFFER: + if (safeBuffer.Capacity < bytesReturned) + { + safeBuffer.Close(); + break; + } + + NativeError.ThrowException(lastError); + break; + } + } + else + break; + } + + + var marshalReparseBuffer = (int) Marshal.OffsetOf(typeof(NativeMethods.ReparseDataBufferHeader), "data"); + + var header = safeBuffer.PtrToStructure(0); + + var dataOffset = (int) (marshalReparseBuffer + (header.ReparseTag == ReparsePointTag.MountPoint + ? Marshal.OffsetOf(typeof (NativeMethods.MountPointReparseBuffer), "data") + : Marshal.OffsetOf(typeof (NativeMethods.SymbolicLinkReparseBuffer), "data")).ToInt64()); + + var dataBuffer = new byte[bytesReturned - dataOffset]; + + + switch (header.ReparseTag) + { + case ReparsePointTag.MountPoint: + var mountPoint = safeBuffer.PtrToStructure(marshalReparseBuffer); + + safeBuffer.CopyTo(dataOffset, dataBuffer, 0, dataBuffer.Length); + + return new LinkTargetInfo( + Encoding.Unicode.GetString(dataBuffer, mountPoint.SubstituteNameOffset, mountPoint.SubstituteNameLength), + Encoding.Unicode.GetString(dataBuffer, mountPoint.PrintNameOffset, mountPoint.PrintNameLength)); + + + case ReparsePointTag.SymLink: + var symLink = safeBuffer.PtrToStructure(marshalReparseBuffer); + + safeBuffer.CopyTo(dataOffset, dataBuffer, 0, dataBuffer.Length); + + return new SymbolicLinkTargetInfo( + Encoding.Unicode.GetString(dataBuffer, symLink.SubstituteNameOffset, symLink.SubstituteNameLength), + Encoding.Unicode.GetString(dataBuffer, symLink.PrintNameOffset, symLink.PrintNameLength), symLink.Flags); + + + default: + throw new UnrecognizedReparsePointException(); + } + } + } + + #endregion // GetLinkTargetInfoCore + + #region ToggleCompressionCore + + /// Sets the NTFS compression state of a file or directory on a volume whose file system supports per-file and per-directory compression. + /// Specifies that is a file or directory. + /// The transaction. + /// A path that describes a folder or file to compress or decompress. + /// = compress, = decompress + /// Indicates the format of the path parameter(s). + + [SecurityCritical] + internal static void ToggleCompressionCore(bool isFolder, KernelTransaction transaction, string path, bool compress, PathFormat pathFormat) + { + using (var handle = File.CreateFileCore(transaction, path, isFolder ? ExtendedFileAttributes.BackupSemantics : ExtendedFileAttributes.Normal, null, FileMode.Open, FileSystemRights.Modify, FileShare.None, true, pathFormat)) + { + // DeviceIoControlMethod.Buffered = 0, + // DeviceIoControlFileDevice.FileSystem = 9 + // FsctlSetCompression = (DeviceIoControlFileDevice.FileSystem << 16) | (16 << 2) | DeviceIoControlMethod.Buffered | ((FileAccess.Read | FileAccess.Write) << 14) + + // 0 = Decompress, 1 = Compress. + InvokeIoControlUnknownSize(handle, ((9 << 16) | (16 << 2) | 0 | ((uint)(FileAccess.Read | FileAccess.Write) << 14)), (compress) ? 1 : 0); + } + } + + #endregion // ToggleCompressionCore + + + #region Private + + #region CreateDeviceInfoDataInstance + + /// Builds a DeviceInfo Data structure. + /// An initialized NativeMethods.SP_DEVINFO_DATA instance. + [SecurityCritical] + private static NativeMethods.SP_DEVINFO_DATA CreateDeviceInfoDataInstance() + { + var did = new NativeMethods.SP_DEVINFO_DATA(); + did.cbSize = (uint) Marshal.SizeOf(did); + + return did; + } + + #endregion // CreateDeviceInfoDataInstance + + #region CreateDeviceInterfaceDataInstance + + /// Builds a Device Interface Data structure. + /// An initialized NativeMethods.SP_DEVICE_INTERFACE_DATA instance. + [SecurityCritical] + private static NativeMethods.SP_DEVICE_INTERFACE_DATA CreateDeviceInterfaceDataInstance() + { + var did = new NativeMethods.SP_DEVICE_INTERFACE_DATA(); + did.cbSize = (uint) Marshal.SizeOf(did); + + return did; + } + + #endregion // CreateDeviceInterfaceDataInstance + + #region GetDeviceInterfaceDetailDataInstance + + /// Builds a Device Interface Detail Data structure. + /// An initialized NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA instance. + [SecurityCritical] + private static NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA GetDeviceInterfaceDetailDataInstance(SafeHandle safeHandle, NativeMethods.SP_DEVICE_INTERFACE_DATA deviceInterfaceData, NativeMethods.SP_DEVINFO_DATA deviceInfoData) + { + // Build a Device Interface Detail Data structure. + var didd = new NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA + { + cbSize = (IntPtr.Size == 4) ? (uint) (Marshal.SystemDefaultCharSize + 4) : 8 + }; + + // Get device interace details. + if (!NativeMethods.SetupDiGetDeviceInterfaceDetail(safeHandle, ref deviceInterfaceData, ref didd, NativeMethods.DefaultFileBufferSize, IntPtr.Zero, ref deviceInfoData)) + { + var lastError = Marshal.GetLastWin32Error(); + if (lastError != Win32Errors.NO_ERROR) + NativeError.ThrowException(lastError); + } + + return didd; + } + + #endregion // GetDeviceInterfaceDetailDataInstance + + #region InvokeIoControlUnknownSize + + /// Repeatedly invokes InvokeIoControl with the specified input until enough memory has been allocated. + [SecurityCritical] + private static byte[] InvokeIoControlUnknownSize(SafeFileHandle handle, uint controlCode, TV input, uint increment = 128) + { + byte[] output; + uint bytesReturned; + + var inputSize = (uint) Marshal.SizeOf(input); + var outputLength = increment; + + do + { + output = new byte[outputLength]; + if (!NativeMethods.DeviceIoControl(handle, controlCode, input, inputSize, output, outputLength, out bytesReturned, IntPtr.Zero)) + { + var lastError = Marshal.GetLastWin32Error(); + switch ((uint)lastError) + { + case Win32Errors.ERROR_MORE_DATA: + case Win32Errors.ERROR_INSUFFICIENT_BUFFER: + outputLength += increment; + break; + + default: + NativeError.ThrowException(lastError); + break; + } + } + else + break; + + } while (true); + + // Return the result + if (output.Length == bytesReturned) + return output; + + var res = new byte[bytesReturned]; + Array.Copy(output, res, bytesReturned); + + return res; + } + + #endregion // InvokeIoControlUnknownSize + + #endregion // Private + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/DeviceInfo.cs b/AlphaFS/Filesystem/DeviceInfo.cs new file mode 100644 index 0000000..82e0946 --- /dev/null +++ b/AlphaFS/Filesystem/DeviceInfo.cs @@ -0,0 +1,141 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Network; +using System; +using System.Collections.Generic; +using System.Security; +using System.Security.Permissions; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Provides access to information of a device, on a local or remote host. + [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)] + [SerializableAttribute] + [SecurityCritical] + public sealed class DeviceInfo + { + #region Constructors + + /// Initializes a DeviceInfo class. + [SecurityCritical] + public DeviceInfo() + { + HostName = Host.GetUncName(); + } + + /// Initializes a DeviceInfo class. + /// The DNS or NetBIOS name of the remote server. refers to the local host. + [SecurityCritical] + public DeviceInfo(string host) + { + HostName = Host.GetUncName(host).Replace(Path.UncPrefix, string.Empty); + } + + #endregion // Constructors + + + #region Methods + + /// Enumerates all available devices on the local host. + /// One of the devices. + /// instances of type from the local host. + [SecurityCritical] + public IEnumerable EnumerateDevices(DeviceGuid deviceGuid) + { + return Device.EnumerateDevicesCore(null, HostName, deviceGuid); + } + + #endregion // Methods + + + #region Properties + + /// Represents the value of the base container identifier (ID) .The Windows Plug and Play (PnP) manager assigns this value to the device node (devnode). + public Guid BaseContainerId { get; internal set; } + + + /// Represents the name of the device setup class that a device instance belongs to. + public string Class { get; internal set; } + + + /// Represents the of the device setup class that a device instance belongs to. + public Guid ClassGuid { get; internal set; } + + + /// Represents the list of compatible identifiers for a device instance. + public string CompatibleIds { get; internal set; } + + + /// Represents a description of a device instance. + public string DeviceDescription { get; internal set; } + + + /// The device interface path. + public string DevicePath { get; internal set; } + + + /// Represents the registry entry name of the driver key for a device instance. + public string Driver { get; internal set; } + + + /// Represents the name of the enumerator for a device instance. + public string EnumeratorName { get; internal set; } + + + /// Represents the friendly name of a device instance. + public string FriendlyName { get; internal set; } + + + /// Represents the list of hardware identifiers for a device instance. + public string HardwareId { get; internal set; } + + + /// The host name that was passed to the class constructor. + public string HostName { get; internal set; } + + + /// Gets the instance Id of the device. + public string InstanceId { get; internal set; } + + + /// Represents the bus-specific physical location of a device instance. + public string LocationInformation { get; internal set; } + + + /// Represents the location of a device instance in the device tree. + public string LocationPaths { get; internal set; } + + + /// Represents the name of the manufacturer of a device instance. + public string Manufacturer { get; internal set; } + + + /// Encapsulates the physical device location information provided by a device's firmware to Windows. + public string PhysicalDeviceObjectName { get; internal set; } + + + /// Represents the name of the service that is installed for a device instance. + public string Service { get; internal set; } + + #endregion // Properties + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.Compression.cs b/AlphaFS/Filesystem/Directory Class/Directory.Compression.cs new file mode 100644 index 0000000..13fb15f --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.Compression.cs @@ -0,0 +1,484 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region Compress + + /// [AlphaFS] Compresses a directory using NTFS compression. + /// This will only compress the root items (non recursive). + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to compress. + [SecurityCritical] + public static void Compress(string path) + { + CompressDecompressCore(null, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Compresses a directory using NTFS compression. + /// This will only compress the root items (non recursive). + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to compress. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Compress(string path, PathFormat pathFormat) + { + CompressDecompressCore(null, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, true, pathFormat); + } + + + + /// [AlphaFS] Compresses a directory using NTFS compression. + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to compress. + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static void Compress(string path, DirectoryEnumerationOptions options) + { + CompressDecompressCore(null, path, Path.WildcardStarMatchAll, options, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Compresses a directory using NTFS compression. + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to compress. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Compress(string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + CompressDecompressCore(null, path, Path.WildcardStarMatchAll, options, true, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Compresses a directory using NTFS compression. + /// This will only compress the root items (non recursive). + /// + /// + /// + /// + /// + /// + /// The transaction. + /// A path that describes a directory to compress. + [SecurityCritical] + public static void CompressTransacted(KernelTransaction transaction, string path) + { + CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Compresses a directory using NTFS compression. + /// This will only compress the root items (non recursive). + /// + /// + /// + /// + /// + /// + /// The transaction. + /// A path that describes a directory to compress. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void CompressTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, true, pathFormat); + } + + + + /// [AlphaFS] Compresses a directory using NTFS compression. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// A path that describes a directory to compress. + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static void CompressTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options) + { + CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, options, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Compresses a directory using NTFS compression. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// A path that describes a directory to compress. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void CompressTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, options, true, pathFormat); + } + + #endregion // Transactional + + #endregion // Compress + + #region Decompress + + /// [AlphaFS] Decompresses an NTFS compressed directory. + /// This will only decompress the root items (non recursive). + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to decompress. + [SecurityCritical] + public static void Decompress(string path) + { + CompressDecompressCore(null, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Decompresses an NTFS compressed directory. + /// This will only decompress the root items (non recursive). + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to decompress. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Decompress(string path, PathFormat pathFormat) + { + CompressDecompressCore(null, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, false, pathFormat); + } + + + + /// [AlphaFS] Decompresses an NTFS compressed directory. + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to decompress. + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static void Decompress(string path, DirectoryEnumerationOptions options) + { + CompressDecompressCore(null, path, Path.WildcardStarMatchAll, options, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Decompresses an NTFS compressed directory. + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to decompress. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Decompress(string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + CompressDecompressCore(null, path, Path.WildcardStarMatchAll, options, false, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Decompresses an NTFS compressed directory. + /// This will only decompress the root items (non recursive). + /// + /// + /// + /// + /// + /// + /// The transaction. + /// A path that describes a directory to decompress. + [SecurityCritical] + public static void DecompressTransacted(KernelTransaction transaction, string path) + { + CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Decompresses an NTFS compressed directory. + /// This will only decompress the root items (non recursive). + /// + /// + /// + /// + /// + /// + /// The transaction. + /// A path that describes a directory to decompress. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void DecompressTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, false, pathFormat); + } + + + + /// [AlphaFS] Decompresses an NTFS compressed directory. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// A path that describes a directory to decompress. + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static void DecompressTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options) + { + CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, options, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Decompresses an NTFS compressed directory. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// A path that describes a directory to decompress. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void DecompressTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, options, false, pathFormat); + } + + #endregion // Transactional + + #endregion // Decompress + + #region DisableCompression + + /// [AlphaFS] Disables NTFS compression of the specified directory and the files in it. + /// This method disables the directory-compression attribute. It will not decompress the current contents of the directory. However, newly created files and directories will be uncompressed. + /// + /// + /// + /// + /// + /// + /// A path to a directory to decompress. + [SecurityCritical] + public static void DisableCompression(string path) + { + Device.ToggleCompressionCore(true, null, path, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Disables NTFS compression of the specified directory and the files in it. + /// This method disables the directory-compression attribute. It will not decompress the current contents of the directory. However, newly created files and directories will be uncompressed. + /// + /// + /// + /// + /// + /// + /// A path to a directory to decompress. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void DisableCompression(string path, PathFormat pathFormat) + { + Device.ToggleCompressionCore(true, null, path, false, pathFormat); + } + + + + /// [AlphaFS] Disables NTFS compression of the specified directory and the files in it. + /// This method disables the directory-compression attribute. It will not decompress the current contents of the directory. However, newly created files and directories will be uncompressed. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// A path to a directory to decompress. + [SecurityCritical] + public static void DisableCompressionTransacted(KernelTransaction transaction, string path) + { + Device.ToggleCompressionCore(true, transaction, path, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Disables NTFS compression of the specified directory and the files in it. + /// This method disables the directory-compression attribute. It will not decompress the current contents of the directory. However, newly created files and directories will be uncompressed. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// Indicates the format of the path parameter(s). + /// A path to a directory to decompress. + [SecurityCritical] + public static void DisableCompressionTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + Device.ToggleCompressionCore(true, transaction, path, false, pathFormat); + } + + #endregion // DisableCompression + + #region EnableCompression + + /// [AlphaFS] Enables NTFS compression of the specified directory and the files in it. + /// This method enables the directory-compression attribute. It will not compress the current contents of the directory. However, newly created files and directories will be compressed. + /// + /// + /// + /// + /// + /// + /// A path to a directory to compress. + [SecurityCritical] + public static void EnableCompression(string path) + { + Device.ToggleCompressionCore(true, null, path, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Enables NTFS compression of the specified directory and the files in it. + /// This method enables the directory-compression attribute. It will not compress the current contents of the directory. However, newly created files and directories will be compressed. + /// + /// + /// + /// + /// + /// + /// A path to a directory to compress. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void EnableCompression(string path, PathFormat pathFormat) + { + Device.ToggleCompressionCore(true, null, path, true, pathFormat); + } + + + + /// [AlphaFS] Enables NTFS compression of the specified directory and the files in it. + /// This method enables the directory-compression attribute. It will not compress the current contents of the directory. However, newly created files and directories will be compressed. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// A path to a directory to compress. + [SecurityCritical] + public static void EnableCompressionTransacted(KernelTransaction transaction, string path) + { + Device.ToggleCompressionCore(true, transaction, path, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Enables NTFS compression of the specified directory and the files in it. + /// This method enables the directory-compression attribute. It will not compress the current contents of the directory. However, newly created files and directories will be compressed. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// A path to a directory to compress. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void EnableCompressionTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + Device.ToggleCompressionCore(true, transaction, path, true, pathFormat); + } + + #endregion // EnableCompression + + #region Internal Methods + + /// Compress/decompress Non-/Transacted files/directories. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// A path that describes a directory to compress. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + /// compress, when decompress. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static void CompressDecompressCore(KernelTransaction transaction, string path, string searchPattern, DirectoryEnumerationOptions options, bool compress, PathFormat pathFormat) + { + string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + + // Process directories and files. + foreach (var fsei in EnumerateFileSystemEntryInfosCore(transaction, pathLp, searchPattern, options | DirectoryEnumerationOptions.AsLongPath, PathFormat.LongFullPath)) + Device.ToggleCompressionCore(true, transaction, fsei, compress, PathFormat.LongFullPath); + + // Compress the root directory, the given path. + Device.ToggleCompressionCore(true, transaction, pathLp, compress, PathFormat.LongFullPath); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.CopyMove.cs b/AlphaFS/Filesystem/Directory Class/Directory.CopyMove.cs new file mode 100644 index 0000000..946ceec --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.CopyMove.cs @@ -0,0 +1,969 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region Copy + + // .NET: Directory class does not contain the Copy() method. + // Mimic .NET File.Copy() methods. + + /// [AlphaFS] Copies an existing directory to a new directory. Overwriting a directory of the same name is not allowed. + /// + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The source directory path. + /// The destination directory path. + [SecurityCritical] + public static CopyMoveResult Copy(string sourcePath, string destinationPath) + { + return CopyMoveCore(null, sourcePath, destinationPath, CopyOptions.FailIfExists, null, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies an existing directory to a new directory. Overwriting a directory of the same name is not allowed. + /// + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The source directory path. + /// The destination directory path. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult Copy(string sourcePath, string destinationPath, PathFormat pathFormat) + { + return CopyMoveCore(null, sourcePath, destinationPath, CopyOptions.FailIfExists, null, null, null, null, pathFormat); + } + + + + /// [AlphaFS] Copies an existing directory to a new directory. Overwriting a directory of the same name is allowed. + /// + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The source directory path. + /// The destination directory path. + /// if the destination directory should ignoring the read-only and hidden attributes and overwrite; otherwise, . + [SecurityCritical] + public static CopyMoveResult Copy(string sourcePath, string destinationPath, bool overwrite) + { + return CopyMoveCore(null, sourcePath, destinationPath, overwrite ? CopyOptions.None : CopyOptions.FailIfExists, null, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies an existing directory to a new directory. Overwriting a directory of the same name is allowed. + /// + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The source directory path. + /// The destination directory path. + /// if the destination directory should ignoring the read-only and hidden attributes and overwrite; otherwise, . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult Copy(string sourcePath, string destinationPath, bool overwrite, PathFormat pathFormat) + { + return CopyMoveCore(null, sourcePath, destinationPath, overwrite ? CopyOptions.None : CopyOptions.FailIfExists, null, null, null, null, pathFormat); + } + + + #region Transactional + + /// [AlphaFS] Copies an existing directory to a new directory. Overwriting a directory of the same name is not allowed. + /// + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The source directory path. + /// The destination directory path. + [SecurityCritical] + public static CopyMoveResult CopyTransacted(KernelTransaction transaction, string sourcePath, string destinationPath) + { + return CopyMoveCore(transaction, sourcePath, destinationPath, CopyOptions.FailIfExists, null, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies an existing directory to a new directory. Overwriting a directory of the same name is not allowed. + /// + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The source directory path. + /// The destination directory path. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult CopyTransacted(KernelTransaction transaction, string sourcePath, string destinationPath, PathFormat pathFormat) + { + return CopyMoveCore(transaction, sourcePath, destinationPath, CopyOptions.FailIfExists, null, null, null, null, pathFormat); + } + + + + /// [AlphaFS] Copies an existing directory to a new directory. Overwriting a directory of the same name is allowed. + /// + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The source directory path. + /// The destination directory path. + /// if the destination directory should ignoring the read-only and hidden attributes and overwrite; otherwise, . + [SecurityCritical] + public static CopyMoveResult CopyTransacted(KernelTransaction transaction, string sourcePath, string destinationPath, bool overwrite) + { + return CopyMoveCore(transaction, sourcePath, destinationPath, overwrite ? CopyOptions.None : CopyOptions.FailIfExists, null, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies an existing directory to a new directory. Overwriting a directory of the same name is allowed. + /// + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The source directory path. + /// The destination directory path. + /// if the destination directory should ignoring the read-only and hidden attributes and overwrite; otherwise, . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult CopyTransacted(KernelTransaction transaction, string sourcePath, string destinationPath, bool overwrite, PathFormat pathFormat) + { + return CopyMoveCore(transaction, sourcePath, destinationPath, overwrite ? CopyOptions.None : CopyOptions.FailIfExists, null, null, null, null, pathFormat); + } + + #endregion // Transactional + + #endregion // Copy + + + #region Copy (CopyOptions) + + /// [AlphaFS] Copies a directory and its contents to a new location, can be specified. + /// + /// Option is recommended for very large file transfers. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be copied. This parameter can be . + [SecurityCritical] + public static CopyMoveResult Copy(string sourcePath, string destinationPath, CopyOptions copyOptions) + { + return CopyMoveCore(null, sourcePath, destinationPath, copyOptions, null, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies a directory and its contents to a new location, can be specified. + /// + /// Option is recommended for very large file transfers. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be copied. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult Copy(string sourcePath, string destinationPath, CopyOptions copyOptions, PathFormat pathFormat) + { + return CopyMoveCore(null, sourcePath, destinationPath, copyOptions, null, null, null, null, pathFormat); + } + + + + /// [AlphaFS] Copies a directory and its contents to a new location, can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// Option is recommended for very large file transfers. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be copied. This parameter can be . + /// A callback function that is called each time another portion of the directory has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + [SecurityCritical] + public static CopyMoveResult Copy(string sourcePath, string destinationPath, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData) + { + return CopyMoveCore(null, sourcePath, destinationPath, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies a directory and its contents to a new location, can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// Option is recommended for very large file transfers. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be copied. This parameter can be . + /// A callback function that is called each time another portion of the directory has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult Copy(string sourcePath, string destinationPath, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat) + { + return CopyMoveCore(null, sourcePath, destinationPath, copyOptions, null, progressHandler, userProgressData, null, pathFormat); + } + + + #region Transactional + + /// [AlphaFS] Copies a directory and its contents to a new location, can be specified. + /// + /// Option is recommended for very large file transfers. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be copied. This parameter can be . + [SecurityCritical] + public static CopyMoveResult CopyTransacted(KernelTransaction transaction, string sourcePath, string destinationPath, CopyOptions copyOptions) + { + return CopyMoveCore(transaction, sourcePath, destinationPath, copyOptions, null, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies a directory and its contents to a new location, can be specified. + /// + /// Option is recommended for very large file transfers. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be copied. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult CopyTransacted(KernelTransaction transaction, string sourcePath, string destinationPath, CopyOptions copyOptions, PathFormat pathFormat) + { + return CopyMoveCore(transaction, sourcePath, destinationPath, copyOptions, null, null, null, null, pathFormat); + } + + + + /// [AlphaFS] Copies a directory and its contents to a new location, can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// Option is recommended for very large file transfers. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be copied. This parameter can be . + /// A callback function that is called each time another portion of the directory has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + [SecurityCritical] + public static CopyMoveResult CopyTransacted(KernelTransaction transaction, string sourcePath, string destinationPath, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData) + { + return CopyMoveCore(transaction, sourcePath, destinationPath, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies a directory and its contents to a new location, can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// Option is recommended for very large file transfers. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be copied. This parameter can be . + /// A callback function that is called each time another portion of the directory has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult CopyTransacted(KernelTransaction transaction, string sourcePath, string destinationPath, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat) + { + return CopyMoveCore(transaction, sourcePath, destinationPath, copyOptions, null, progressHandler, userProgressData, null, pathFormat); + } + + #endregion // Transactional + + #endregion // Copy (CopyOptions) + + + #region Move + + #region .NET + + /// Moves a file or a directory and its contents to a new location. + /// + /// This method does not work across disk volumes. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Move action. + /// + /// + /// + /// + /// + /// + /// The source directory path. + /// The destination directory path. + [SecurityCritical] + public static CopyMoveResult Move(string sourcePath, string destinationPath) + { + return CopyMoveCore(null, sourcePath, destinationPath, null, MoveOptions.None, null, null, null, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Moves a file or a directory and its contents to a new location. + /// + /// This method does not work across disk volumes. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Move action. + /// + /// + /// + /// + /// + /// + /// The source directory path. + /// The destination directory path. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult Move(string sourcePath, string destinationPath, PathFormat pathFormat) + { + return CopyMoveCore(null, sourcePath, destinationPath, null, MoveOptions.None, null, null, null, pathFormat); + } + + + + #region Transactional + + /// [AlphaFS] Moves a file or a directory and its contents to a new location. + /// + /// This method does not work across disk volumes. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Move action. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The source directory path. + /// The destination directory path. + [SecurityCritical] + public static CopyMoveResult MoveTransacted(KernelTransaction transaction, string sourcePath, string destinationPath) + { + return CopyMoveCore(transaction, sourcePath, destinationPath, null, MoveOptions.None, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Moves a file or a directory and its contents to a new location. + /// + /// This method does not work across disk volumes. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Move action. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The source directory path. + /// The destination directory path. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult MoveTransacted(KernelTransaction transaction, string sourcePath, string destinationPath, PathFormat pathFormat) + { + return CopyMoveCore(transaction, sourcePath, destinationPath, null, MoveOptions.None, null, null, null, pathFormat); + } + + #endregion // Transactional + + #endregion // Move + + + #region Move (MoveOptions) + + /// [AlphaFS] Moves a file or a directory and its contents to a new location, can be specified. + /// + /// This method does not work across disk volumes unless contains . + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Move action. + /// + /// + /// + /// + /// + /// + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be moved. This parameter can be . + [SecurityCritical] + public static CopyMoveResult Move(string sourcePath, string destinationPath, MoveOptions moveOptions) + { + return CopyMoveCore(null, sourcePath, destinationPath, null, moveOptions, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Moves a file or a directory and its contents to a new location, can be specified. + /// + /// This method does not work across disk volumes unless contains . + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Move action. + /// + /// + /// + /// + /// + /// + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be moved. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult Move(string sourcePath, string destinationPath, MoveOptions moveOptions, PathFormat pathFormat) + { + return CopyMoveCore(null, sourcePath, destinationPath, null, moveOptions, null, null, null, pathFormat); + } + + + + /// [AlphaFS] Moves a file or a directory and its contents to a new location, can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// This method does not work across disk volumes unless contains . + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Move action. + /// + /// + /// + /// + /// + /// + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be moved. This parameter can be . + /// A callback function that is called each time another portion of the directory has been moved. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + [SecurityCritical] + public static CopyMoveResult Move(string sourcePath, string destinationPath, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData) + { + return CopyMoveCore(null, sourcePath, destinationPath, null, moveOptions, progressHandler, userProgressData, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Moves a file or a directory and its contents to a new location, can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// This method does not work across disk volumes unless contains . + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Move action. + /// + /// + /// + /// + /// + /// + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be moved. This parameter can be . + /// A callback function that is called each time another portion of the directory has been moved. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult Move(string sourcePath, string destinationPath, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat) + { + return CopyMoveCore(null, sourcePath, destinationPath, null, moveOptions, progressHandler, userProgressData, null, pathFormat); + } + + + #region Transactional + + /// [AlphaFS] Moves a file or a directory and its contents to a new location, can be specified. + /// + /// This method does not work across disk volumes unless contains . + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Move action. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be moved. This parameter can be . + [SecurityCritical] + public static CopyMoveResult MoveTransacted(KernelTransaction transaction, string sourcePath, string destinationPath, MoveOptions moveOptions) + { + return CopyMoveCore(transaction, sourcePath, destinationPath, null, moveOptions, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Moves a file or a directory and its contents to a new location, can be specified. + /// + /// This method does not work across disk volumes unless contains . + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Move action. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be moved. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult MoveTransacted(KernelTransaction transaction, string sourcePath, string destinationPath, MoveOptions moveOptions, PathFormat pathFormat) + { + return CopyMoveCore(transaction, sourcePath, destinationPath, null, moveOptions, null, null, null, pathFormat); + } + + + + /// [AlphaFS] Moves a file or a directory and its contents to a new location, can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// This method does not work across disk volumes unless contains . + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Move action. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be moved. This parameter can be . + /// A callback function that is called each time another portion of the directory has been moved. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + [SecurityCritical] + public static CopyMoveResult MoveTransacted(KernelTransaction transaction, string sourcePath, string destinationPath, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData) + { + return CopyMoveCore(transaction, sourcePath, destinationPath, null, moveOptions, progressHandler, userProgressData, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Moves a file or a directory and its contents to a new location, can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// A class with the status of the Move action. + /// + /// This method does not work across disk volumes unless contains . + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Move action. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be moved. This parameter can be . + /// A callback function that is called each time another portion of the directory has been moved. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult MoveTransacted(KernelTransaction transaction, string sourcePath, string destinationPath, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat) + { + return CopyMoveCore(transaction, sourcePath, destinationPath, null, moveOptions, progressHandler, userProgressData, null, pathFormat); + } + + #endregion // Transactional + + #endregion // Move (MoveOptions) + + + #region Internal Methods + + /// Copy/move a Non-/Transacted file or directory including its children to a new location, + /// or can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// Option is recommended for very large file transfers. + /// You cannot use the Move method to overwrite an existing file, unless contains . + /// Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an IOException. + /// + /// + /// A class with the status of the Copy or Move action. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The source directory path. + /// The destination directory path. + /// that specify how the directory is to be copied. This parameter can be . + /// that specify how the directory is to be moved. This parameter can be . + /// A callback function that is called each time another portion of the file has been copied/moved. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + [SecurityCritical] + internal static CopyMoveResult CopyMoveCore(KernelTransaction transaction, string sourcePath, string destinationPath, CopyOptions? copyOptions, MoveOptions? moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, CopyMoveResult copyMoveResult, PathFormat pathFormat) + { + #region Setup + + var sourcePathLp = sourcePath; + var destinationPathLp = destinationPath; + var skipPathChecks = pathFormat == PathFormat.LongFullPath; + + + if (!skipPathChecks) + { + Path.CheckSupportedPathFormat(sourcePathLp, true, true); + Path.CheckSupportedPathFormat(destinationPathLp, true, true); + + + // MSDN: .NET 4+ Trailing spaces are removed from the end of the path parameters before moving the directory. + // TrimEnd() is also applied for AlphaFS implementation of method Directory.Copy(), .NET does not have this method. + + const GetFullPathOptions fullPathOptions = GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator; + + sourcePathLp = Path.GetExtendedLengthPathCore(transaction, sourcePath, pathFormat, fullPathOptions); + destinationPathLp = Path.GetExtendedLengthPathCore(transaction, destinationPath, pathFormat, fullPathOptions); + + + // MSDN: .NET3.5+: IOException: The sourceDirName and destDirName parameters refer to the same file or directory. + if (sourcePathLp.Equals(destinationPathLp, StringComparison.OrdinalIgnoreCase)) + NativeError.ThrowException(Win32Errors.ERROR_SAME_DRIVE, destinationPathLp); + } + + + var emulateMove = false; + + // Determine Copy or Move action. + var isCopy = File.DetermineIsCopy(copyOptions, moveOptions); + var isMove = !isCopy; + + var cmr = copyMoveResult ?? new CopyMoveResult(sourcePathLp, destinationPathLp, false, (int) Win32Errors.ERROR_SUCCESS); + + + // Execute once only. + if (!skipPathChecks && isMove) + { + // Compare the root part of both paths. + var equalRootPaths = Path.GetPathRoot(sourcePathLp, false).Equals(Path.GetPathRoot(destinationPathLp, false), StringComparison.OrdinalIgnoreCase); + + // Method Volume.IsSameVolume() returns true when both paths refer to the same volume, even if one of the paths is a UNC path. + // For example, src = C:\TempSrc and dst = \\localhost\C$\TempDst + var isSameVolume = equalRootPaths || Volume.IsSameVolume(sourcePathLp, destinationPathLp); + + isMove = isSameVolume && equalRootPaths; + + + if (!isMove) + { + // A Move() can be emulated by using Copy() and Delete(), but only if the CopyAllowed flag is set. + isMove = ((MoveOptions) moveOptions & MoveOptions.CopyAllowed) != 0; + + // MSDN: .NET3.5+: IOException: An attempt was made to move a directory to a different volume. + if (!isMove) + NativeError.ThrowException(Win32Errors.ERROR_NOT_SAME_DEVICE, sourcePathLp, destinationPathLp); + } + + + // The NativeMethod.MoveFileXxx() methods fail when: + // - A directory is being moved; + // - One of the paths is a UNC path, even though both paths refer to the same volume. + // For example, src = C:\TempSrc and dst = \\localhost\C$\TempDst + if (isMove) + { + var srcIsUncPath = Path.IsUncPathCore(sourcePathLp, false, false); + var dstIsUncPath = Path.IsUncPathCore(destinationPathLp, false, false); + + isMove = srcIsUncPath && dstIsUncPath; + if (!isMove) + isMove = !srcIsUncPath && !dstIsUncPath; + } + + + isMove = isMove && isSameVolume && equalRootPaths; + + + // Emulate Move(). + if (!isMove) + { + emulateMove = true; + + moveOptions = null; + + isCopy = true; + copyOptions = CopyOptions.FailIfExists; + } + } + + #endregion // Setup + + + #region Copy + + if (isCopy) + { + CreateDirectoryCore(transaction, destinationPathLp, null, null, false, PathFormat.LongFullPath); + + foreach (var fsei in EnumerateFileSystemEntryInfosCore(transaction, sourcePathLp, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath)) + { + var newDestinationPathLp = Path.CombineCore(false, destinationPathLp, fsei.FileName); + + cmr = fsei.IsDirectory + ? CopyMoveCore(transaction, fsei.LongFullPath, newDestinationPathLp, copyOptions, moveOptions, progressHandler, userProgressData, cmr, PathFormat.LongFullPath) + : File.CopyMoveCore(false, transaction, fsei.LongFullPath, newDestinationPathLp, false, copyOptions, moveOptions, progressHandler, userProgressData, cmr, PathFormat.LongFullPath); + + + if (cmr.ErrorCode == Win32Errors.ERROR_SUCCESS) + { + if (fsei.IsDirectory) + cmr.TotalFolders++; + else + { + cmr.TotalFiles++; + cmr.TotalBytes += fsei.FileSize; + } + + + // Remove the folder or file when copying was successful. + if (emulateMove) + { + if (fsei.IsDirectory) + DeleteDirectoryCore(fsei, transaction, null, true, true, false, true, PathFormat.LongFullPath); + else + File.DeleteFileCore(transaction, fsei.LongFullPath, true, PathFormat.LongFullPath); + } + } + + + if (cmr.IsCanceled) + return cmr; + } + + + // Remove source folder. + if (emulateMove && cmr.ErrorCode == Win32Errors.ERROR_SUCCESS) + DeleteDirectoryCore(null, transaction, sourcePathLp, true, true, false, true, PathFormat.LongFullPath); + } + + #endregion // Copy + + + #region Move + + else + { + // MoveOptions.ReplaceExisting: This value cannot be used if lpNewFileName or lpExistingFileName names a directory. + if (((MoveOptions) moveOptions & MoveOptions.ReplaceExisting) != 0) + DeleteDirectoryCore(null, transaction, destinationPathLp, true, true, false, true, PathFormat.LongFullPath); + + + // Moves a file or directory, including its children. + // Copies an existing directory, including its children to a new directory. + cmr = File.CopyMoveCore(true, transaction, sourcePathLp, destinationPathLp, false, copyOptions, moveOptions, progressHandler, userProgressData, cmr, PathFormat.LongFullPath); + } + + #endregion // Move + + + return cmr; + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.CountFileSystemObjects.cs b/AlphaFS/Filesystem/Directory Class/Directory.CountFileSystemObjects.cs new file mode 100644 index 0000000..9bbb8af --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.CountFileSystemObjects.cs @@ -0,0 +1,195 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Linq; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + /// [AlphaFS] Counts file system objects: files, folders or both) in a given directory. + /// The counted number of file system objects. + /// + /// + /// + /// + /// + /// + /// The directory path. + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static long CountFileSystemObjects(string path, DirectoryEnumerationOptions options) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, options, PathFormat.RelativePath).Count(); + } + + /// [AlphaFS] Counts file system objects: files, folders or both) in a given directory. + /// The counted number of file system objects. + /// + /// + /// + /// + /// + /// + /// The directory path. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static long CountFileSystemObjects(string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, options, pathFormat).Count(); + } + + + + /// [AlphaFS] Counts file system objects: files, folders or both) in a given directory. + /// The counted number of file system objects. + /// + /// + /// + /// + /// + /// + /// The directory path. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static long CountFileSystemObjects(string path, string searchPattern, DirectoryEnumerationOptions options) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, PathFormat.RelativePath).Count(); + } + + /// [AlphaFS] Counts file system objects: files, folders or both) in a given directory. + /// The counted number of file system objects. + /// + /// + /// + /// + /// + /// + /// The directory path. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static long CountFileSystemObjects(string path, string searchPattern, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, pathFormat).Count(); + } + + #region Transactional + + /// [AlphaFS] Counts file system objects: files, folders or both) in a given directory. + /// The counted number of file system objects. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory path. + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static long CountFileSystemObjectsTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, options, PathFormat.RelativePath).Count(); + } + + /// [AlphaFS] Counts file system objects: files, folders or both) in a given directory. + /// The counted number of file system objects. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory path. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static long CountFileSystemObjectsTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, options, pathFormat).Count(); + } + + + + /// [AlphaFS] Counts file system objects: files, folders or both) in a given directory. + /// The counted number of file system objects. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory path. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static long CountFileSystemObjectsTransacted(KernelTransaction transaction, string path, string searchPattern, DirectoryEnumerationOptions options) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, PathFormat.RelativePath).Count(); + } + + /// [AlphaFS] Counts file system objects: files, folders or both) in a given directory. + /// The counted number of file system objects. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory path. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static long CountFileSystemObjectsTransacted(KernelTransaction transaction, string path, string searchPattern, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, pathFormat).Count(); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.CreateDirectory.cs b/AlphaFS/Filesystem/Directory Class/Directory.CreateDirectory.cs new file mode 100644 index 0000000..4637e2c --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.CreateDirectory.cs @@ -0,0 +1,800 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.AccessControl; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region .NET + + /// Creates all directories and subdirectories in the specified path unless they already exist. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The directory to create. + [SecurityCritical] + public static DirectoryInfo CreateDirectory(string path) + { + return CreateDirectoryCore(null, path, null, null, false, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Creates all the directories in the specified path, applying the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The directory to create. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectory(string path, PathFormat pathFormat) + { + return CreateDirectoryCore(null, path, null, null, false, pathFormat); + } + + + + /// [AlphaFS] Creates all the directories in the specified path, applying the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The directory to create. + /// When compresses the directory. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectory(string path, bool compress) + { + return CreateDirectoryCore(null, path, null, null, compress, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates all the directories in the specified path, applying the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The directory to create. + /// When compresses the directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectory(string path, bool compress, PathFormat pathFormat) + { + return CreateDirectoryCore(null, path, null, null, compress, pathFormat); + } + + + + /// Creates all the directories in the specified path, unless the already exist, applying the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The directory to create. + /// The access control to apply to the directory. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity) + { + return CreateDirectoryCore(null, path, null, directorySecurity, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates all the directories in the specified path, applying the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The directory to create. + /// The access control to apply to the directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity, PathFormat pathFormat) + { + return CreateDirectoryCore(null, path, null, directorySecurity, false, pathFormat); + } + + + + /// [AlphaFS] Creates all the directories in the specified path, applying the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The directory to create. + /// The access control to apply to the directory. + /// When compresses the directory. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity, bool compress) + { + return CreateDirectoryCore(null, path, null, directorySecurity, compress, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates all the directories in the specified path, applying the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The directory to create. + /// The access control to apply to the directory. + /// When compresses the directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity, bool compress, PathFormat pathFormat) + { + return CreateDirectoryCore(null, path, null, directorySecurity, compress, pathFormat); + } + + + + /// [AlphaFS] Creates a new directory, with the attributes of a specified template directory. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectory(string path, string templatePath) + { + return CreateDirectoryCore(null, path, templatePath, null, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates a new directory, with the attributes of a specified template directory. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectory(string path, string templatePath, PathFormat pathFormat) + { + return CreateDirectoryCore(null, path, templatePath, null, false, pathFormat); + } + + + + /// [AlphaFS] Creates a new directory, with the attributes of a specified template directory. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. + /// When compresses the directory. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectory(string path, string templatePath, bool compress) + { + return CreateDirectoryCore(null, path, templatePath, null, compress, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates a new directory, with the attributes of a specified template directory. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. + /// When compresses the directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectory(string path, string templatePath, bool compress, PathFormat pathFormat) + { + return CreateDirectoryCore(null, path, templatePath, null, compress, pathFormat); + } + + + + /// [AlphaFS] Creates all the directories in the specified path of a specified template directory and applies the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. + /// The access control to apply to the directory. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectory(string path, string templatePath, DirectorySecurity directorySecurity) + { + return CreateDirectoryCore(null, path, templatePath, directorySecurity, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates all the directories in the specified path of a specified template directory and applies the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. + /// The access control to apply to the directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectory(string path, string templatePath, DirectorySecurity directorySecurity, PathFormat pathFormat) + { + return CreateDirectoryCore(null, path, templatePath, directorySecurity, false, pathFormat); + } + + + + /// [AlphaFS] Creates all the directories in the specified path of a specified template directory and applies the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. + /// The access control to apply to the directory. + /// When compresses the directory. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectory(string path, string templatePath, DirectorySecurity directorySecurity, bool compress) + { + return CreateDirectoryCore(null, path, templatePath, directorySecurity, compress, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates all the directories in the specified path of a specified template directory and applies the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. + /// The access control to apply to the directory. + /// When compresses the directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectory(string path, string templatePath, DirectorySecurity directorySecurity, bool compress, PathFormat pathFormat) + { + return CreateDirectoryCore(null, path, templatePath, directorySecurity, compress, pathFormat); + } + + #region Transactional + + /// Creates all directories and subdirectories in the specified path unless they already exist. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + [SecurityCritical] + public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path) + { + return CreateDirectoryCore(transaction, path, null, null, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates all the directories in the specified path, applying the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return CreateDirectoryCore(transaction, path, null, null, false, pathFormat); + } + + + + /// [AlphaFS] Creates all the directories in the specified path, applying the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + /// When compresses the directory. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, bool compress) + { + return CreateDirectoryCore(transaction, path, null, null, compress, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates all the directories in the specified path, applying the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + /// When compresses the directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, bool compress, PathFormat pathFormat) + { + return CreateDirectoryCore(transaction, path, null, null, compress, pathFormat); + } + + + + /// Creates all the directories in the specified path, unless the already exist, applying the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + /// The access control to apply to the directory. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, DirectorySecurity directorySecurity) + { + return CreateDirectoryCore(transaction, path, null, directorySecurity, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates all the directories in the specified path, applying the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + /// The access control to apply to the directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, DirectorySecurity directorySecurity, PathFormat pathFormat) + { + return CreateDirectoryCore(transaction, path, null, directorySecurity, false, pathFormat); + } + + + + /// [AlphaFS] Creates all the directories in the specified path, applying the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + /// The access control to apply to the directory. + /// When compresses the directory. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, DirectorySecurity directorySecurity, bool compress) + { + return CreateDirectoryCore(transaction, path, null, directorySecurity, compress, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates all the directories in the specified path, applying the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + /// The access control to apply to the directory. + /// When compresses the directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, DirectorySecurity directorySecurity, bool compress, PathFormat pathFormat) + { + return CreateDirectoryCore(transaction, path, null, directorySecurity, compress, pathFormat); + } + + + + /// [AlphaFS] Creates a new directory, with the attributes of a specified template directory. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, string templatePath) + { + return CreateDirectoryCore(transaction, path, templatePath, null, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates a new directory, with the attributes of a specified template directory. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, string templatePath, PathFormat pathFormat) + { + return CreateDirectoryCore(transaction, path, templatePath, null, false, pathFormat); + } + + + + /// [AlphaFS] Creates a new directory, with the attributes of a specified template directory. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. + /// When compresses the directory. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, string templatePath, bool compress) + { + return CreateDirectoryCore(transaction, path, templatePath, null, compress, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates a new directory, with the attributes of a specified template directory. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. + /// When compresses the directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, string templatePath, bool compress, PathFormat pathFormat) + { + return CreateDirectoryCore(transaction, path, templatePath, null, compress, pathFormat); + } + + + + /// [AlphaFS] Creates all the directories in the specified path of a specified template directory and applies the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. + /// The access control to apply to the directory. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, string templatePath, DirectorySecurity directorySecurity) + { + return CreateDirectoryCore(transaction, path, templatePath, directorySecurity, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates all the directories in the specified path of a specified template directory and applies the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. + /// The access control to apply to the directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, string templatePath, DirectorySecurity directorySecurity, PathFormat pathFormat) + { + return CreateDirectoryCore(transaction, path, templatePath, directorySecurity, false, pathFormat); + } + + + + /// [AlphaFS] Creates all the directories in the specified path of a specified template directory and applies the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. + /// The access control to apply to the directory. + /// When compresses the directory. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, string templatePath, DirectorySecurity directorySecurity, bool compress) + { + return CreateDirectoryCore(transaction, path, templatePath, directorySecurity, compress, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates all the directories in the specified path of a specified template directory and applies the specified Windows security. + /// An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. + /// The access control to apply to the directory. + /// When compresses the directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, string templatePath, DirectorySecurity directorySecurity, bool compress, PathFormat pathFormat) + { + return CreateDirectoryCore(transaction, path, templatePath, directorySecurity, compress, pathFormat); + } + + #endregion // Transactional + + #region Internal Methods + + /// Creates a new directory with the attributes of a specified template directory (if one is specified). + /// If the underlying file system supports security on files and directories, the function applies the specified security descriptor to the new directory. + /// The new directory retains the other attributes of the specified template directory. + /// + /// + /// Returns an object that represents the directory at the specified path. + /// This object is returned regardless of whether a directory at the specified path already exists. + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to create. + /// The path of the directory to use as a template when creating the new directory. May be to indicate that no template should be used. + /// The access control to apply to the directory, may be null. + /// When compresses the directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + [SecurityCritical] + internal static DirectoryInfo CreateDirectoryCore(KernelTransaction transaction, string path, string templatePath, ObjectSecurity directorySecurity, bool compress, PathFormat pathFormat) + { + bool fullCheck = pathFormat == PathFormat.RelativePath; + + Path.CheckSupportedPathFormat(path, fullCheck, fullCheck); + Path.CheckSupportedPathFormat(templatePath, fullCheck, fullCheck); + + + string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator); + + // Return DirectoryInfo instance if the directory specified by path already exists. + if (File.ExistsCore(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.ExistsCore(false, transaction, pathLp, PathFormat.LongFullPath)) + NativeError.ThrowException(Win32Errors.ERROR_ALREADY_EXISTS, pathLp); + + + string templatePathLp = Utils.IsNullOrWhiteSpace(templatePath) + ? null + : Path.GetExtendedLengthPathCore(transaction, templatePath, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator); + + + #region Construct Full Path + + string longPathPrefix = Path.IsUncPathCore(path, false, false) ? Path.LongPathUncPrefix : Path.LongPathPrefix; + path = Path.GetRegularPathCore(pathLp, GetFullPathOptions.None, false); + + 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.Cannot_Create_Directory, path); + + + // Check if directories are missing. + var list = new Stack(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.ExistsCore(true, transaction, path2, PathFormat.LongFullPath)) + list.Push(path2); + + while (index > rootLength && !Path.IsDVsc(path[index], false)) + --index; + } + } + + #endregion // Construct Full Path + + + // Directory security. + using (var 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. + + if (!(transaction == null || !NativeMethods.IsAtLeastWindowsVista + ? (templatePathLp == null + ? NativeMethods.CreateDirectory(folderLp, securityAttributes) + : NativeMethods.CreateDirectoryEx(templatePathLp, folderLp, securityAttributes)) + : NativeMethods.CreateDirectoryTransacted(templatePathLp, folderLp, securityAttributes, transaction.SafeHandle))) + { + 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.ExistsCore(false, transaction, pathLp, PathFormat.LongFullPath)) + NativeError.ThrowException(lastError, pathLp); + + if (File.ExistsCore(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.Unsupported_Path_Format, path)); + + default: + NativeError.ThrowException(lastError, folderLp); + break; + } + } + + else if (compress) + Device.ToggleCompressionCore(true, transaction, folderLp, true, PathFormat.LongFullPath); + } + + return new DirectoryInfo(transaction, pathLp, PathFormat.LongFullPath); + } + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.CurrentDirectory.cs b/AlphaFS/Filesystem/Directory Class/Directory.CurrentDirectory.cs new file mode 100644 index 0000000..df427f3 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.CurrentDirectory.cs @@ -0,0 +1,126 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + /// + /// Gets the current working directory of the application. + /// + /// MSDN: Multithreaded applications and shared library code should not use the GetCurrentDirectory function and should avoid using relative path names. + /// The current directory state written by the SetCurrentDirectory function is stored as a global variable in each process, + /// therefore multithreaded applications cannot reliably use this value without possible data corruption from other threads that may also be reading or setting this value. + /// This limitation also applies to the SetCurrentDirectory and GetFullPathName functions. The exception being when the application is guaranteed to be running in a single thread, + /// for example parsing file names from the command line argument string in the main thread prior to creating any additional threads. + /// Using relative path names in multithreaded applications or shared library code can yield unpredictable results and is not supported. + /// + /// + /// The path of the current working directory without a trailing directory separator. + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate"), SecurityCritical] + public static string GetCurrentDirectory() + { + var nameBuffer = new StringBuilder(NativeMethods.MaxPathUnicode); + + // SetCurrentDirectory() + // 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. + // 2016-09-29: MSDN does not confirm LongPath usage but a Unicode version of this function exists. + + var folderNameLength = NativeMethods.GetCurrentDirectory((uint) nameBuffer.Capacity, nameBuffer); + var lastError = Marshal.GetLastWin32Error(); + + if (folderNameLength == 0) + NativeError.ThrowException(lastError); + + if (folderNameLength > NativeMethods.MaxPathUnicode) + throw new PathTooLongException(string.Format(CultureInfo.InvariantCulture, "Path is greater than {0} characters: {1}", NativeMethods.MaxPathUnicode, folderNameLength)); + + return nameBuffer.ToString(); + } + + + /// + /// Sets the application's current working directory to the specified directory. + /// + /// MSDN: Multithreaded applications and shared library code should not use the GetCurrentDirectory function and should avoid using relative path names. + /// The current directory state written by the SetCurrentDirectory function is stored as a global variable in each process, + /// therefore multithreaded applications cannot reliably use this value without possible data corruption from other threads that may also be reading or setting this value. + /// This limitation also applies to the SetCurrentDirectory and GetFullPathName functions. The exception being when the application is guaranteed to be running in a single thread, + /// for example parsing file names from the command line argument string in the main thread prior to creating any additional threads. + /// Using relative path names in multithreaded applications or shared library code can yield unpredictable results and is not supported. + /// + /// + /// The path to which the current working directory is set. + [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Utils.IsNullOrWhiteSpace validates arguments.")] + [SecurityCritical] + public static void SetCurrentDirectory(string path) + { + SetCurrentDirectory(path, PathFormat.RelativePath); + } + + + /// + /// Sets the application's current working directory to the specified directory. + /// + /// MSDN: Multithreaded applications and shared library code should not use the GetCurrentDirectory function and should avoid using relative path names. + /// The current directory state written by the SetCurrentDirectory function is stored as a global variable in each process, + /// therefore multithreaded applications cannot reliably use this value without possible data corruption from other threads that may also be reading or setting this value. + /// This limitation also applies to the SetCurrentDirectory and GetFullPathName functions. The exception being when the application is guaranteed to be running in a single thread, + /// for example parsing file names from the command line argument string in the main thread prior to creating any additional threads. + /// Using relative path names in multithreaded applications or shared library code can yield unpredictable results and is not supported. + /// + /// + /// The path to which the current working directory is set. + /// Indicates the format of the path parameter. + [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Utils.IsNullOrWhiteSpace validates arguments.")] + [SecurityCritical] + public static void SetCurrentDirectory(string path, PathFormat pathFormat) + { + if (Utils.IsNullOrWhiteSpace(path)) + throw new ArgumentNullException("path"); + + var fullCheck = pathFormat == PathFormat.RelativePath; + Path.CheckSupportedPathFormat(path, fullCheck, fullCheck); + var pathLp = Path.GetExtendedLengthPathCore(null, path, pathFormat, GetFullPathOptions.AddTrailingDirectorySeparator); + + if (pathFormat == PathFormat.FullPath) + pathLp = Path.GetRegularPathCore(pathLp, GetFullPathOptions.None, false); + + + // SetCurrentDirectory() + // 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. + // 2016-09-29: MSDN confirms LongPath usage starting with Windows 10, version 1607. + + if (!NativeMethods.SetCurrentDirectory(pathLp)) + NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); + } + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.Delete.cs b/AlphaFS/Filesystem/Directory Class/Directory.Delete.cs new file mode 100644 index 0000000..8581e27 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.Delete.cs @@ -0,0 +1,417 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region .NET + + /// Deletes an empty directory from a specified path. + /// + /// + /// + /// + /// + /// + /// + /// The name of the empty directory to remove. This directory must be writable and empty. + [SecurityCritical] + public static void Delete(string path) + { + DeleteDirectoryCore(null, null, path, false, false, true, false, PathFormat.RelativePath); + } + + /// Deletes the specified directory and, if indicated, any subdirectories in the directory. + /// + /// + /// + /// + /// + /// + /// + /// The name of the directory to remove. + /// to remove directories, subdirectories, and files in . otherwise. + [SecurityCritical] + public static void Delete(string path, bool recursive) + { + DeleteDirectoryCore(null, null, path, recursive, false, !recursive, false, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Deletes an empty directory from a specified path. + /// + /// + /// + /// + /// + /// + /// + /// The name of the empty directory to remove. This directory must be writable and empty. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Delete(string path, PathFormat pathFormat) + { + DeleteDirectoryCore(null, null, path, false, false, true, false, pathFormat); + } + + + + /// [AlphaFS] Deletes the specified directory and, if indicated, any subdirectories in the directory. + /// + /// + /// + /// + /// + /// + /// + /// The name of the directory to remove. + /// to remove directories, subdirectories, and files in . otherwise. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Delete(string path, bool recursive, PathFormat pathFormat) + { + DeleteDirectoryCore(null, null, path, recursive, false, !recursive, false, pathFormat); + } + + + + /// [AlphaFS] Deletes the specified directory and, if indicated, any subdirectories in the directory. + /// + /// + /// + /// + /// + /// + /// + /// The name of the directory to remove. + /// to remove directories, subdirectories, and files in . otherwise. + /// overrides read only of files and directories. + [SecurityCritical] + public static void Delete(string path, bool recursive, bool ignoreReadOnly) + { + DeleteDirectoryCore(null, null, path, recursive, ignoreReadOnly, !recursive, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Deletes the specified directory and, if indicated, any subdirectories in the directory. + /// + /// + /// + /// + /// + /// + /// + /// The name of the directory to remove. + /// to remove directories, subdirectories, and files in . otherwise. + /// overrides read only of files and directories. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Delete(string path, bool recursive, bool ignoreReadOnly, PathFormat pathFormat) + { + DeleteDirectoryCore(null, null, path, recursive, ignoreReadOnly, !recursive, false, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Deletes an empty directory from a specified path. + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The name of the empty directory to remove. This directory must be writable and empty. + [SecurityCritical] + public static void DeleteTransacted(KernelTransaction transaction, string path) + { + DeleteDirectoryCore(null, transaction, path, false, false, true, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Deletes an empty directory from a specified path. + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The name of the empty directory to remove. This directory must be writable and empty. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void DeleteTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + DeleteDirectoryCore(null, transaction, path, false, false, true, false, pathFormat); + } + + + + /// [AlphaFS] Deletes the specified directory and, if indicated, any subdirectories in the directory. + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The name of the directory to remove. + /// to remove directories, subdirectories, and files in . otherwise. + [SecurityCritical] + public static void DeleteTransacted(KernelTransaction transaction, string path, bool recursive) + { + DeleteDirectoryCore(null, transaction, path, recursive, false, !recursive, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Deletes the specified directory and, if indicated, any subdirectories in the directory. + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The name of the directory to remove. + /// to remove directories, subdirectories, and files in . otherwise. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void DeleteTransacted(KernelTransaction transaction, string path, bool recursive, PathFormat pathFormat) + { + DeleteDirectoryCore(null, transaction, path, recursive, false, !recursive, false, pathFormat); + } + + + + /// [AlphaFS] Deletes the specified directory and, if indicated, any subdirectories in the directory. + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The name of the directory to remove. + /// to remove directories, subdirectories, and files in . otherwise. + /// overrides read only of files and directories. + [SecurityCritical] + public static void DeleteTransacted(KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly) + { + DeleteDirectoryCore(null, transaction, path, recursive, ignoreReadOnly, !recursive, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Deletes the specified directory and, if indicated, any subdirectories in the directory. + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The name of the directory to remove. + /// to remove directories, subdirectories, and files in . otherwise. + /// overrides read only of files and directories. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void DeleteTransacted(KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly, PathFormat pathFormat) + { + DeleteDirectoryCore(null, transaction, path, recursive, ignoreReadOnly, !recursive, false, pathFormat); + } + + #endregion // Transactional + + #region Internal Methods + + /// Deletes the specified directory and, if indicated, any subdirectories in the directory. + /// The RemoveDirectory function marks a directory for deletion on close. Therefore, the directory is not removed until the last handle to the directory is closed. + /// + /// + /// + /// + /// + /// + /// + /// A FileSystemEntryInfo instance. Use either or , not both. + /// The transaction. + /// The name of the directory to remove. Use either or , not both. + /// to remove all files and subdirectories recursively; otherwise only the top level empty directory. + /// overrides read only attribute of files and directories. + /// requires the directory must be empty. + /// does not throw an Exception when the file system object does not exist. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + [SecurityCritical] + internal static void DeleteDirectoryCore(FileSystemEntryInfo fileSystemEntryInfo, KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly, bool requireEmpty, bool continueOnNotExist, PathFormat pathFormat) + { + #region Setup + + if (pathFormat == PathFormat.RelativePath) + Path.CheckSupportedPathFormat(path, true, true); + + if (fileSystemEntryInfo == null) + { + // MSDN: .NET 3.5+: DirectoryNotFoundException: + // Path does not exist or could not be found. + // Path refers to a file instead of a directory. + // The specified path is invalid (for example, it is on an unmapped drive). + + fileSystemEntryInfo = File.GetFileSystemEntryInfoCore(true, transaction, Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator), continueOnNotExist, pathFormat); + } + + if (fileSystemEntryInfo == null) + return; + + string pathLp = fileSystemEntryInfo.LongFullPath; + + #endregion // Setup + + // Do not follow mount points nor symbolic links, but do delete the reparse point itself. + + // If directory is reparse point, disable recursion. + if (recursive && fileSystemEntryInfo.IsReparsePoint) + recursive = false; + + + // Check to see if this is a mount point, and unmount it. + if (fileSystemEntryInfo.IsMountPoint) + { + int lastError = Volume.DeleteVolumeMountPointCore(pathLp, true); + + if (lastError != Win32Errors.ERROR_SUCCESS && lastError != Win32Errors.ERROR_PATH_NOT_FOUND) + NativeError.ThrowException(lastError, pathLp); + + // Now it is safe to delete the actual directory. + } + + + if (recursive) + { + // Enumerate all file system objects. + foreach (var fsei in EnumerateFileSystemEntryInfosCore(transaction, pathLp, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath)) + { + if (fsei.IsDirectory) + DeleteDirectoryCore(fsei, transaction, null, true, ignoreReadOnly, requireEmpty, true, PathFormat.LongFullPath); + else + File.DeleteFileCore(transaction, fsei.LongFullPath, ignoreReadOnly, PathFormat.LongFullPath); + } + } + + #region Remove + + startRemoveDirectory: + + if (!(transaction == null || !NativeMethods.IsAtLeastWindowsVista + + // RemoveDirectory() / RemoveDirectoryTransacted() + // 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. + // 2014-09-09: MSDN confirms LongPath usage. + + // RemoveDirectory on a symbolic link will remove the link itself. + + ? NativeMethods.RemoveDirectory(pathLp) + : NativeMethods.RemoveDirectoryTransacted(pathLp, transaction.SafeHandle))) + { + int lastError = Marshal.GetLastWin32Error(); + switch ((uint) lastError) + { + case Win32Errors.ERROR_DIR_NOT_EMPTY: + if (requireEmpty) + // MSDN: .NET 3.5+: IOException: The directory specified by path is not an empty directory. + throw new DirectoryNotEmptyException(pathLp); + + goto startRemoveDirectory; + + + case Win32Errors.ERROR_DIRECTORY: + // MSDN: .NET 3.5+: DirectoryNotFoundException: Path refers to a file instead of a directory. + if (File.ExistsCore(false, transaction, pathLp, PathFormat.LongFullPath)) + throw new DirectoryNotFoundException(string.Format(CultureInfo.CurrentCulture, "({0}) {1}", Win32Errors.ERROR_INVALID_PARAMETER, string.Format(CultureInfo.CurrentCulture, Resources.Target_Directory_Is_A_File, pathLp))); + break; + + + case Win32Errors.ERROR_PATH_NOT_FOUND: + if (continueOnNotExist) + return; + break; + + case Win32Errors.ERROR_SHARING_VIOLATION: + // MSDN: .NET 3.5+: IOException: The directory is being used by another process or there is an open handle on the directory. + NativeError.ThrowException(lastError, pathLp); + break; + + case Win32Errors.ERROR_ACCESS_DENIED: + var data = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA(); + int dataInitialised = File.FillAttributeInfoCore(transaction, pathLp, ref data, false, true); + + if (data.dwFileAttributes != (FileAttributes) (-1)) + { + if ((data.dwFileAttributes & FileAttributes.ReadOnly) != 0) + { + // MSDN: .NET 3.5+: IOException: The directory specified by path is read-only. + + if (ignoreReadOnly) + { + // Reset directory attributes. + File.SetAttributesCore(true, transaction, pathLp, FileAttributes.Normal, true, PathFormat.LongFullPath); + goto startRemoveDirectory; + } + + // MSDN: .NET 3.5+: IOException: The directory is read-only. + throw new DirectoryReadOnlyException(pathLp); + } + } + + if (dataInitialised == Win32Errors.ERROR_SUCCESS) + // MSDN: .NET 3.5+: UnauthorizedAccessException: The caller does not have the required permission. + NativeError.ThrowException(lastError, pathLp); + + break; + } + + // MSDN: .NET 3.5+: IOException: + // A file with the same name and location specified by path exists. + // The directory specified by path is read-only, or recursive is false and path is not an empty directory. + // The directory is the application's current working directory. + // The directory contains a read-only file. + // The directory is being used by another process. + + NativeError.ThrowException(lastError, pathLp); + } + + #endregion // Remove + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.DeleteEmptySubdirectories.cs b/AlphaFS/Filesystem/Directory Class/Directory.DeleteEmptySubdirectories.cs new file mode 100644 index 0000000..7740354 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.DeleteEmptySubdirectories.cs @@ -0,0 +1,211 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + /// [AlphaFS] Deletes empty subdirectories from the specified directory. + /// + /// + /// + /// The name of the directory to remove empty subdirectories from. + /// deletes empty subdirectories from this directory and its subdirectories. + [SecurityCritical] + public static void DeleteEmptySubdirectories(string path, bool recursive) + { + DeleteEmptySubdirectoriesCore(null, null, path, recursive, false, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Deletes empty subdirectories from the specified directory. + /// + /// + /// + /// The name of the directory to remove empty subdirectories from. + /// deletes empty subdirectories from this directory and its subdirectories. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void DeleteEmptySubdirectories(string path, bool recursive, PathFormat pathFormat) + { + DeleteEmptySubdirectoriesCore(null, null, path, recursive, false, true, pathFormat); + } + + + + /// [AlphaFS] Deletes empty subdirectories from the specified directory. + /// + /// + /// + /// The name of the directory to remove empty subdirectories from. + /// deletes empty subdirectories from this directory and its subdirectories. + /// overrides read only of empty directories. + [SecurityCritical] + public static void DeleteEmptySubdirectories(string path, bool recursive, bool ignoreReadOnly) + { + DeleteEmptySubdirectoriesCore(null, null, path, recursive, ignoreReadOnly, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Deletes empty subdirectories from the specified directory. + /// + /// + /// + /// The name of the directory to remove empty subdirectories from. + /// deletes empty subdirectories from this directory and its subdirectories. + /// overrides read only of empty directories. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void DeleteEmptySubdirectories(string path, bool recursive, bool ignoreReadOnly, PathFormat pathFormat) + { + DeleteEmptySubdirectoriesCore(null, null, path, recursive, ignoreReadOnly, true, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Deletes empty subdirectories from the specified directory. + /// + /// + /// + /// The transaction. + /// The name of the directory to remove empty subdirectories from. + /// deletes empty subdirectories from this directory and its subdirectories. + [SecurityCritical] + public static void DeleteEmptySubdirectoriesTransacted(KernelTransaction transaction, string path, bool recursive) + { + DeleteEmptySubdirectoriesCore(null, transaction, path, recursive, false, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Deletes empty subdirectories from the specified directory. + /// + /// + /// + /// The transaction. + /// The name of the directory to remove empty subdirectories from. + /// deletes empty subdirectories from this directory and its subdirectories. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void DeleteEmptySubdirectoriesTransacted(KernelTransaction transaction, string path, bool recursive, PathFormat pathFormat) + { + DeleteEmptySubdirectoriesCore(null, transaction, path, recursive, false, true, pathFormat); + } + + + + /// [AlphaFS] Deletes empty subdirectories from the specified directory. + /// + /// + /// + /// The transaction. + /// The name of the directory to remove empty subdirectories from. + /// deletes empty subdirectories from this directory and its subdirectories. + /// overrides read only of empty directories. + [SecurityCritical] + public static void DeleteEmptySubdirectoriesTransacted(KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly) + { + DeleteEmptySubdirectoriesCore(null, transaction, path, recursive, ignoreReadOnly, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Deletes empty subdirectories from the specified directory. + /// + /// + /// + /// The transaction. + /// The name of the directory to remove empty subdirectories from. + /// deletes empty subdirectories from this directory and its subdirectories. + /// overrides read only of empty directories. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void DeleteEmptySubdirectoriesTransacted(KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly, PathFormat pathFormat) + { + DeleteEmptySubdirectoriesCore(null, transaction, path, recursive, ignoreReadOnly, true, pathFormat); + } + + #endregion // Transactional + + #region Internal Methods + + /// Delete empty subdirectories from the specified directory. + /// + /// + /// + /// + /// + /// + /// A FileSystemEntryInfo instance. Use either or , not both. + /// The transaction. + /// The name of the directory to remove empty subdirectories from. Use either or , not both. + /// deletes empty subdirectories from this directory and its subdirectories. + /// overrides read only of empty directories. + /// When indicates the method is called externally. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static void DeleteEmptySubdirectoriesCore(FileSystemEntryInfo fileSystemEntryInfo, KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly, bool initialize, PathFormat pathFormat) + { + #region Setup + + if (pathFormat == PathFormat.RelativePath) + Path.CheckSupportedPathFormat(path, true, true); + + if (fileSystemEntryInfo == null) + { + if (!File.ExistsCore(true, transaction, path, pathFormat)) + NativeError.ThrowException(Win32Errors.ERROR_PATH_NOT_FOUND, path); + + fileSystemEntryInfo = File.GetFileSystemEntryInfoCore(true, transaction, Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck) , false, pathFormat); + } + + if (fileSystemEntryInfo == null) + throw new ArgumentNullException("path"); + + string pathLp = fileSystemEntryInfo.LongFullPath; + + #endregion // Setup + + // Ensure path is a directory. + if (!fileSystemEntryInfo.IsDirectory) + throw new IOException(string.Format(CultureInfo.CurrentCulture, Resources.Target_Directory_Is_A_File, pathLp)); + + + var dirEnumOptions = DirectoryEnumerationOptions.Folders; + + if (recursive) + dirEnumOptions |= DirectoryEnumerationOptions.Recursive; + + foreach (var fsei in EnumerateFileSystemEntryInfosCore(transaction, pathLp, Path.WildcardStarMatchAll, dirEnumOptions, PathFormat.LongFullPath)) + DeleteEmptySubdirectoriesCore(fsei, transaction, null, recursive, ignoreReadOnly, false, PathFormat.LongFullPath); + + + if (!EnumerateFileSystemEntryInfosCore(transaction, pathLp, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath).Any()) + { + // Prevent deleting path itself. + if (!initialize) + DeleteDirectoryCore(fileSystemEntryInfo, transaction, null, false, ignoreReadOnly, true, true, PathFormat.LongFullPath); + } + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.EncryptedDirectoryRaw.cs b/AlphaFS/Filesystem/Directory Class/Directory.EncryptedDirectoryRaw.cs new file mode 100644 index 0000000..ee0698e --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.EncryptedDirectoryRaw.cs @@ -0,0 +1,154 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.IO; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region Export + + /// [AlphaFS] Backs up (export) encrypted directories. This is one of a group of Encrypted File System (EFS) functions that is + /// intended to implement backup and restore functionality, while maintaining files in their encrypted state. + /// + /// + /// The directory being backed up is not decrypted; it is backed up in its encrypted state. + /// If the caller does not have access to the key for the file, the caller needs to export encrypted files. See . + /// To backup an encrypted directory call one of the overloads and specify the directory to backup along with the destination stream of the backup data. + /// This function is intended for the backup of only encrypted directories; see for backup of unencrypted directories. + /// Note that this method does not back up the files inside the directory, only the directory entry itself. + /// + /// + /// + /// + /// The name of the file to be backed up. + /// The destination stream to which the backup data will be written. + public static void ExportEncryptedDirectoryRaw(string fileName, Stream outputStream) + { + File.ImportExportEncryptedFileDirectoryRawCore(true, false, outputStream, fileName, PathFormat.RelativePath, false); + } + + /// [AlphaFS] Backs up (export) encrypted directories. This is one of a group of Encrypted File System (EFS) functions that is + /// intended to implement backup and restore functionality, while maintaining files in their encrypted state. + /// + /// + /// The directory being backed up is not decrypted; it is backed up in its encrypted state. + /// If the caller does not have access to the key for the file, the caller needs to export encrypted files. See . + /// To backup an encrypted directory call one of the overloads and specify the directory to backup along with the destination stream of the backup data. + /// This function is intended for the backup of only encrypted directories; see for backup of unencrypted directories. + /// Note that this method does not back up the files inside the directory, only the directory entry itself. + /// + /// + /// + /// + /// The name of the file to be backed up. + /// The destination stream to which the backup data will be written. + /// The path format of the parameter. + public static void ExportEncryptedDirectoryRaw(string fileName, Stream outputStream, PathFormat pathFormat) + { + File.ImportExportEncryptedFileDirectoryRawCore(true, false, outputStream, fileName, pathFormat, false); + } + + #endregion // Export + + #region Import + + /// [AlphaFS] Restores (import) encrypted directories. This is one of a group of Encrypted File System (EFS) functions that is + /// intended to implement backup and restore functionality, while maintaining files in their encrypted state. + /// + /// + /// If the caller does not have access to the key for the directory, the caller needs to restore encrypted directories. See . + /// To restore an encrypted directory call one of the overloads and specify the file to restore along with the destination stream of the restored data. + /// This function is intended for the restoration of only encrypted directories; see for backup of unencrypted files. + /// + /// + /// + /// + /// The stream to read previously backed up data from. + /// The path of the destination directory to restore to. + public static void ImportEncryptedDirectoryRaw(Stream inputStream, string destinationPath) + { + File.ImportExportEncryptedFileDirectoryRawCore(false, true, inputStream, destinationPath, PathFormat.RelativePath, false); + } + + /// [AlphaFS] Restores (import) encrypted directories. This is one of a group of Encrypted File System (EFS) functions that is + /// intended to implement backup and restore functionality, while maintaining files in their encrypted state. + /// + /// + /// If the caller does not have access to the key for the directory, the caller needs to restore encrypted directories. See . + /// To restore an encrypted directory call one of the overloads and specify the file to restore along with the destination stream of the restored data. + /// This function is intended for the restoration of only encrypted directories; see for backup of unencrypted files. + /// + /// + /// + /// + /// The stream to read previously backed up data from. + /// The path of the destination directory to restore to. + /// The path format of the parameter. + public static void ImportEncryptedDirectoryRaw(Stream inputStream, string destinationPath, PathFormat pathFormat) + { + File.ImportExportEncryptedFileDirectoryRawCore(false, true, inputStream, destinationPath, pathFormat, false); + } + + + /// [AlphaFS] Restores (import) encrypted directories. This is one of a group of Encrypted File System (EFS) functions that is + /// intended to implement backup and restore functionality, while maintaining files in their encrypted state. + /// + /// + /// If the caller does not have access to the key for the directory, the caller needs to restore encrypted directories. See . + /// To restore an encrypted directory call one of the overloads and specify the file to restore along with the destination stream of the restored data. + /// This function is intended for the restoration of only encrypted directories; see for backup of unencrypted files. + /// + /// + /// + /// + /// The stream to read previously backed up data from. + /// The path of the destination directory to restore to. + /// If set to a hidden directory will be overwritten on import. + public static void ImportEncryptedDirectoryRaw(Stream inputStream, string destinationPath, bool overwriteHidden) + { + File.ImportExportEncryptedFileDirectoryRawCore(false, true, inputStream, destinationPath, PathFormat.RelativePath, overwriteHidden); + } + + /// [AlphaFS] Restores (import) encrypted directories. This is one of a group of Encrypted File System (EFS) functions that is + /// intended to implement backup and restore functionality, while maintaining files in their encrypted state. + /// + /// + /// If the caller does not have access to the key for the directory, the caller needs to restore encrypted directories. See . + /// To restore an encrypted directory call one of the overloads and specify the file to restore along with the destination stream of the restored data. + /// This function is intended for the restoration of only encrypted directories; see for backup of unencrypted files. + /// + /// + /// + /// + /// The stream to read previously backed up data from. + /// The path of the destination directory to restore to. + /// If set to a hidden directory will be overwritten on import. + /// The path format of the parameter. + public static void ImportEncryptedDirectoryRaw(Stream inputStream, string destinationPath, bool overwriteHidden, PathFormat pathFormat) + { + File.ImportExportEncryptedFileDirectoryRawCore(false, true, inputStream, destinationPath, pathFormat, overwriteHidden); + } + + #endregion // Import + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.Encryption.cs b/AlphaFS/Filesystem/Directory Class/Directory.Encryption.cs new file mode 100644 index 0000000..5b1c780 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.Encryption.cs @@ -0,0 +1,272 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region Decrypt + + /// [AlphaFS] Decrypts a directory that was encrypted by the current account using the Encrypt method. + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to decrypt. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Decrypt(string path, PathFormat pathFormat) + { + EncryptDecryptDirectoryCore(path, false, false, pathFormat); + } + + /// [AlphaFS] Decrypts a directory that was encrypted by the current account using the Encrypt method. + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to decrypt. + /// to decrypt the directory recursively. only decrypt the directory. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Decrypt(string path, bool recursive, PathFormat pathFormat) + { + EncryptDecryptDirectoryCore(path, false, recursive, pathFormat); + } + + /// [AlphaFS] Decrypts a directory that was encrypted by the current account using the Encrypt method. + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to decrypt. + [SecurityCritical] + public static void Decrypt(string path) + { + EncryptDecryptDirectoryCore(path, false, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Decrypts a directory that was encrypted by the current account using the Encrypt method. + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to decrypt. + /// to decrypt the directory recursively. only decrypt the directory. + [SecurityCritical] + public static void Decrypt(string path, bool recursive) + { + EncryptDecryptDirectoryCore(path, false, recursive, PathFormat.RelativePath); + } + + #endregion // Decrypt + + #region Encrypt + + /// [AlphaFS] Encrypts a directory so that only the account used to encrypt the directory can decrypt it. + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to encrypt. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Encrypt(string path, PathFormat pathFormat) + { + EncryptDecryptDirectoryCore(path, true, false, pathFormat); + } + + /// [AlphaFS] Encrypts a directory so that only the account used to encrypt the directory can decrypt it. + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to encrypt. + /// to encrypt the directory recursively. only encrypt the directory. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Encrypt(string path, bool recursive, PathFormat pathFormat) + { + EncryptDecryptDirectoryCore(path, true, recursive, pathFormat); + } + + + /// [AlphaFS] Encrypts a directory so that only the account used to encrypt the directory can decrypt it. + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to encrypt. + [SecurityCritical] + public static void Encrypt(string path) + { + EncryptDecryptDirectoryCore(path, true, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Encrypts a directory so that only the account used to encrypt the directory can decrypt it. + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to encrypt. + /// to encrypt the directory recursively. only encrypt the directory. + [SecurityCritical] + public static void Encrypt(string path, bool recursive) + { + EncryptDecryptDirectoryCore(path, true, recursive, PathFormat.RelativePath); + } + + #endregion // Encrypt + + #region DisableEncryption + + /// [AlphaFS] Disables encryption of the specified directory and the files in it. + /// This method only creates/modifies the file "Desktop.ini" in the root of and disables encryption by writing: "Disable=1" + /// This method does not affect encryption of files and subdirectories below the indicated directory. + /// + /// The name of the directory for which to disable encryption. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void DisableEncryption(string path, PathFormat pathFormat) + { + EnableDisableEncryptionCore(path, false, pathFormat); + } + + /// [AlphaFS] Disables encryption of the specified directory and the files in it. + /// This method only creates/modifies the file "Desktop.ini" in the root of and disables encryption by writing: "Disable=1" + /// This method does not affect encryption of files and subdirectories below the indicated directory. + /// + /// The name of the directory for which to disable encryption. + [SecurityCritical] + public static void DisableEncryption(string path) + { + EnableDisableEncryptionCore(path, false, PathFormat.RelativePath); + } + + #endregion // DisableEncryption + + #region EnableEncryption + + /// [AlphaFS] Enables encryption of the specified directory and the files in it. + /// This method only creates/modifies the file "Desktop.ini" in the root of and enables encryption by writing: "Disable=0" + /// This method does not affect encryption of files and subdirectories below the indicated directory. + /// + /// The name of the directory for which to enable encryption. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void EnableEncryption(string path, PathFormat pathFormat) + { + EnableDisableEncryptionCore(path, true, pathFormat); + } + + /// [AlphaFS] Enables encryption of the specified directory and the files in it. + /// This method only creates/modifies the file "Desktop.ini" in the root of and enables encryption by writing: "Disable=0" + /// This method does not affect encryption of files and subdirectories below the indicated directory. + /// + /// The name of the directory for which to enable encryption. + [SecurityCritical] + public static void EnableEncryption(string path) + { + EnableDisableEncryptionCore(path, true, PathFormat.RelativePath); + } + + #endregion // EnableEncryption + + #region Internal Methods + + /// Enables/disables encryption of the specified directory and the files in it. + /// This method only creates/modifies the file "Desktop.ini" in the root of and enables/disables encryption by writing: "Disable=0" or "Disable=1". + /// This method does not affect encryption of files and subdirectories below the indicated directory. + /// + /// The name of the directory for which to enable encryption. + /// enabled encryption, disables encryption. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static void EnableDisableEncryptionCore(string path, bool enable, PathFormat pathFormat) + { + if (Utils.IsNullOrWhiteSpace(path)) + throw new ArgumentNullException("path"); + + string pathLp = Path.GetExtendedLengthPathCore(null, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + + // EncryptionDisable() + // 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 does not confirm LongPath usage but a Unicode version of this function exists. + + if (!NativeMethods.EncryptionDisable(pathLp, !enable)) + NativeError.ThrowException(pathLp); + } + + /// Decrypts/encrypts a directory recursively so that only the account used to encrypt the directory can decrypt it. + /// + /// + /// + /// + /// + /// + /// A path that describes a directory to encrypt. + /// encrypt, decrypt. + /// to decrypt the directory recursively. only decrypt files and directories in the root of . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static void EncryptDecryptDirectoryCore(string path, bool encrypt, bool recursive, PathFormat pathFormat) + { + string pathLp = Path.GetExtendedLengthPathCore(null, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + + var options = DirectoryEnumerationOptions.FilesAndFolders | DirectoryEnumerationOptions.AsLongPath; + + // Process folders and files when recursive. + if (recursive) + { + options |= DirectoryEnumerationOptions.Recursive; + + foreach (string fsei in EnumerateFileSystemEntryInfosCore(null, pathLp, Path.WildcardStarMatchAll, options, PathFormat.LongFullPath)) + File.EncryptDecryptFileCore(true, fsei, encrypt, PathFormat.LongFullPath); + } + + // Process the root folder, the given path. + File.EncryptDecryptFileCore(true, pathLp, encrypt, PathFormat.LongFullPath); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.EnumerateAlternateDataStreams.cs b/AlphaFS/Filesystem/Directory Class/Directory.EnumerateAlternateDataStreams.cs new file mode 100644 index 0000000..8ddcf9d --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.EnumerateAlternateDataStreams.cs @@ -0,0 +1,69 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Collections.Generic; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + /// [AlphaFS] Enumerates the streams of type :$DATA from the specified directory. + /// The path to the directory to enumerate streams of. + /// The streams of type :$DATA in the specified directory. + [SecurityCritical] + public static IEnumerable EnumerateAlternateDataStreams(string path) + { + return File.EnumerateAlternateDataStreamsCore(null, path, PathFormat.RelativePath); + } + + /// [AlphaFS] Enumerates the streams of type :$DATA from the specified directory. + /// The path to the directory to enumerate streams of. + /// Indicates the format of the path parameter(s). + /// The streams of type :$DATA in the specified directory. + [SecurityCritical] + public static IEnumerable EnumerateAlternateDataStreams(string path, PathFormat pathFormat) + { + return File.EnumerateAlternateDataStreamsCore(null, path, pathFormat); + } + + /// [AlphaFS] Enumerates the streams of type :$DATA from the specified directory. + /// The transaction. + /// The path to the directory to enumerate streams of. + /// The streams of type :$DATA in the specified directory. + [SecurityCritical] + public static IEnumerable EnumerateAlternateDataStreamsTransacted(KernelTransaction transaction, string path) + { + return File.EnumerateAlternateDataStreamsCore(transaction, path, PathFormat.RelativePath); + } + + /// [AlphaFS] Enumerates the streams of type :$DATA from the specified directory. + /// The transaction. + /// The path to the directory to enumerate streams of. + /// Indicates the format of the path parameter(s). + /// The streams of type :$DATA in the specified directory. + [SecurityCritical] + public static IEnumerable EnumerateAlternateDataStreamsTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return File.EnumerateAlternateDataStreamsCore(transaction, path, pathFormat); + } + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.EnumerateDirectories.cs b/AlphaFS/Filesystem/Directory Class/Directory.EnumerateDirectories.cs new file mode 100644 index 0000000..d666b10 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.EnumerateDirectories.cs @@ -0,0 +1,500 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Security; +using SearchOption = System.IO.SearchOption; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region .NET + + /// Returns an enumerable collection of directory names in a specified . + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The directory to search. + [SecurityCritical] + public static IEnumerable EnumerateDirectories(string path) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Folders, PathFormat.RelativePath); + } + + /// Returns an enumerable collection of directory names that match a in a specified . + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by and that match the specified . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SecurityCritical] + public static IEnumerable EnumerateDirectories(string path, string searchPattern) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, DirectoryEnumerationOptions.Folders, PathFormat.RelativePath); + } + + /// Returns an enumerable collection of directory names that match a in a specified , and optionally searches subdirectories. + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by and that match the specified and . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + [SecurityCritical] + public static IEnumerable EnumerateDirectories(string path, string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.Folders | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Returns an enumerable collection of directory names in a specified . + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateDirectories(string path, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Folders, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of directory names that match a in a specified . + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by and that match the specified . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateDirectories(string path, string searchPattern, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, DirectoryEnumerationOptions.Folders, pathFormat); + } + + /// [AlphaFS] Returns an enumerable collection of directory names that match a in a specified , and optionally searches subdirectories. + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by and that match the specified and . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateDirectories(string path, string searchPattern, SearchOption searchOption, PathFormat pathFormat) + { + var options = DirectoryEnumerationOptions.Folders | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of directory names in a specified . + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static IEnumerable EnumerateDirectories(string path, DirectoryEnumerationOptions options) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Files; // Remove enumeration of files. + options |= DirectoryEnumerationOptions.Folders; // Add enumeration of directories. + + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of directory names in a specified . + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateDirectories(string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Files; + options |= DirectoryEnumerationOptions.Folders; + + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, options, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of directory names in a specified . + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static IEnumerable EnumerateDirectories(string path, string searchPattern, DirectoryEnumerationOptions options) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Files; + options |= DirectoryEnumerationOptions.Folders; + + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of directory names in a specified . + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateDirectories(string path, string searchPattern, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Files; + options |= DirectoryEnumerationOptions.Folders; + + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, pathFormat); + } + + + + #region Transactional + + /// [AlphaFS] Returns an enumerable collection of directory instances in a specified . + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + [SecurityCritical] + public static IEnumerable EnumerateDirectoriesTransacted(KernelTransaction transaction, string path) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Folders, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of directory instances that match a in a specified . + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by and that match the specified . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SecurityCritical] + public static IEnumerable EnumerateDirectoriesTransacted(KernelTransaction transaction, string path, string searchPattern) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, DirectoryEnumerationOptions.Folders, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of directory names that match a in a specified , and optionally searches subdirectories. + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by and that match the specified and . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + [SecurityCritical] + public static IEnumerable EnumerateDirectoriesTransacted(KernelTransaction transaction, string path, string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.Folders | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, PathFormat.RelativePath); + } + + + + /// [AlphaFS] Returns an enumerable collection of directory instances in a specified . + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateDirectoriesTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Folders, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of directory instances that match a in a specified . + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by and that match the specified . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateDirectoriesTransacted(KernelTransaction transaction, string path, string searchPattern, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, DirectoryEnumerationOptions.Folders, pathFormat); + } + + /// [AlphaFS] Returns an enumerable collection of directory names that match a in a specified , and optionally searches subdirectories. + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by and that match the specified and . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateDirectoriesTransacted(KernelTransaction transaction, string path, string searchPattern, SearchOption searchOption, PathFormat pathFormat) + { + var options = DirectoryEnumerationOptions.Folders | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of directory instances in a specified . + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static IEnumerable EnumerateDirectoriesTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Files; + options |= DirectoryEnumerationOptions.Folders; + + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of directory instances in a specified . + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateDirectoriesTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Files; + options |= DirectoryEnumerationOptions.Folders; + + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, options, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of directory instances that match a in a specified . + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by and that match the specified . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static IEnumerable EnumerateDirectoriesTransacted(KernelTransaction transaction, string path, string searchPattern, DirectoryEnumerationOptions options) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Files; + options |= DirectoryEnumerationOptions.Folders; + + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of directory instances that match a in a specified . + /// An enumerable collection of the full names (including paths) for the directories in the directory specified by and that match the specified . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateDirectoriesTransacted(KernelTransaction transaction, string path, string searchPattern, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Files; + options |= DirectoryEnumerationOptions.Folders; + + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, pathFormat); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.EnumerateFileIdBothDirectoryInfo.cs b/AlphaFS/Filesystem/Directory Class/Directory.EnumerateFileIdBothDirectoryInfo.cs new file mode 100644 index 0000000..68f63aa --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.EnumerateFileIdBothDirectoryInfo.cs @@ -0,0 +1,230 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Microsoft.Win32.SafeHandles; +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.AccessControl; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + /// [AlphaFS] Retrieves information about files in the directory specified by in mode. + /// An enumeration of records for each file system entry in the specified diretory. + /// A path to a directory from which to retrieve information. + [SecurityCritical] + public static IEnumerable EnumerateFileIdBothDirectoryInfo(string path) + { + return EnumerateFileIdBothDirectoryInfoCore(null, null, path, FileShare.ReadWrite, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Retrieves information about files in the directory specified by in mode. + /// An enumeration of records for each file system entry in the specified diretory. + /// A path to a directory from which to retrieve information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFileIdBothDirectoryInfo(string path, PathFormat pathFormat) + { + return EnumerateFileIdBothDirectoryInfoCore(null, null, path, FileShare.ReadWrite, false, pathFormat); + } + + + + /// [AlphaFS] Retrieves information about files in the directory specified by in specified mode. + /// An enumeration of records for each file system entry in the specified diretory. + /// A path to a directory from which to retrieve information. + /// The mode with which to open a handle to the directory. + [SecurityCritical] + public static IEnumerable EnumerateFileIdBothDirectoryInfo(string path, FileShare shareMode) + { + return EnumerateFileIdBothDirectoryInfoCore(null, null, path, shareMode, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Retrieves information about files in the directory specified by in specified mode. + /// An enumeration of records for each file system entry in the specified diretory. + /// A path to a directory from which to retrieve information. + /// The mode with which to open a handle to the directory. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFileIdBothDirectoryInfo(string path, FileShare shareMode, PathFormat pathFormat) + { + return EnumerateFileIdBothDirectoryInfoCore(null, null, path, shareMode, false, pathFormat); + } + + + + /// [AlphaFS] Retrieves information about files in the directory handle specified. + /// An IEnumerable of records for each file system entry in the specified diretory. + /// An open handle to the directory from which to retrieve information. + [SecurityCritical] + public static IEnumerable EnumerateFileIdBothDirectoryInfo(SafeFileHandle handle) + { + // FileShare has no effect since a handle is already opened. + return EnumerateFileIdBothDirectoryInfoCore(null, handle, null, FileShare.ReadWrite, false, PathFormat.RelativePath); + } + + #region Transactional + + /// [AlphaFS] Retrieves information about files in the directory specified by in mode. + /// An enumeration of records for each file system entry in the specified diretory. + /// The transaction. + /// A path to a directory from which to retrieve information. + [SecurityCritical] + public static IEnumerable EnumerateFileIdBothDirectoryInfoTransacted(KernelTransaction transaction, string path) + { + return EnumerateFileIdBothDirectoryInfoCore(transaction, null, path, FileShare.ReadWrite, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Retrieves information about files in the directory specified by in mode. + /// An enumeration of records for each file system entry in the specified diretory. + /// The transaction. + /// A path to a directory from which to retrieve information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFileIdBothDirectoryInfoTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return EnumerateFileIdBothDirectoryInfoCore(transaction, null, path, FileShare.ReadWrite, false, pathFormat); + } + + + + /// [AlphaFS] Retrieves information about files in the directory specified by in specified mode. + /// An enumeration of records for each file system entry in the specified diretory. + /// The transaction. + /// A path to a directory from which to retrieve information. + /// The mode with which to open a handle to the directory. + [SecurityCritical] + public static IEnumerable EnumerateFileIdBothDirectoryInfoTransacted(KernelTransaction transaction, string path, FileShare shareMode) + { + return EnumerateFileIdBothDirectoryInfoCore(transaction, null, path, shareMode, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Retrieves information about files in the directory specified by in specified mode. + /// An enumeration of records for each file system entry in the specified diretory. + /// The transaction. + /// A path to a directory from which to retrieve information. + /// The mode with which to open a handle to the directory. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFileIdBothDirectoryInfoTransacted(KernelTransaction transaction, string path, FileShare shareMode, PathFormat pathFormat) + { + return EnumerateFileIdBothDirectoryInfoCore(transaction, null, path, shareMode, false, pathFormat); + } + + #endregion // Transactional + + #region Internal Methods + + /// Returns an enumerable collection of information about files in the directory handle specified. + /// An IEnumerable of records for each file system entry in the specified diretory. + /// + /// Either use or , not both. + /// + /// The number of files that are returned for each call to GetFileInformationByHandleEx depends on the size of the buffer that is passed to the function. + /// Any subsequent calls to GetFileInformationByHandleEx on the same handle will resume the enumeration operation after the last file is returned. + /// + /// + /// The transaction. + /// An open handle to the directory from which to retrieve information. + /// A path to the directory. + /// The mode with which to open a handle to the directory. + /// suppress any Exception that might be thrown as a result from a failure, such as ACLs protected directories or non-accessible reparse points. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static IEnumerable EnumerateFileIdBothDirectoryInfoCore(KernelTransaction transaction, SafeFileHandle safeHandle, string path, FileShare shareMode, bool continueOnException, PathFormat pathFormat) + { + if (!NativeMethods.IsAtLeastWindowsVista) + throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher); + + bool callerHandle = safeHandle != null; + if (!callerHandle) + { + if (Utils.IsNullOrWhiteSpace(path)) + throw new ArgumentNullException("path"); + + string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + + safeHandle = File.CreateFileCore(transaction, pathLp, ExtendedFileAttributes.BackupSemantics, null, FileMode.Open, FileSystemRights.ReadData, shareMode, true, PathFormat.LongFullPath); + } + + + try + { + if (!NativeMethods.IsValidHandle(safeHandle, Marshal.GetLastWin32Error(), !continueOnException)) + yield break; + + var fileNameOffset = (int)Marshal.OffsetOf(typeof(NativeMethods.FILE_ID_BOTH_DIR_INFO), "FileName"); + + using (var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize)) + { + while (true) + { + if (!NativeMethods.GetFileInformationByHandleEx(safeHandle, NativeMethods.FileInfoByHandleClass.FileIdBothDirectoryInfo, safeBuffer, (uint)safeBuffer.Capacity)) + { + uint lastError = (uint)Marshal.GetLastWin32Error(); + switch (lastError) + { + case Win32Errors.ERROR_SUCCESS: + case Win32Errors.ERROR_NO_MORE_FILES: + case Win32Errors.ERROR_HANDLE_EOF: + yield break; + + case Win32Errors.ERROR_MORE_DATA: + continue; + + default: + NativeError.ThrowException(lastError, path); + yield break; // we should never get to this yield break. + } + } + + int offset = 0; + NativeMethods.FILE_ID_BOTH_DIR_INFO fibdi; + do + { + fibdi = safeBuffer.PtrToStructure(offset); + string fileName = safeBuffer.PtrToStringUni(offset + fileNameOffset, (int)(fibdi.FileNameLength / 2)); + + if (!fileName.Equals(Path.CurrentDirectoryPrefix, StringComparison.OrdinalIgnoreCase) && + !fileName.Equals(Path.ParentDirectoryPrefix, StringComparison.OrdinalIgnoreCase)) + yield return new FileIdBothDirectoryInfo(fibdi, fileName); + + offset += fibdi.NextEntryOffset; + } + while (fibdi.NextEntryOffset != 0); + } + } + } + finally + { + // Handle is ours, dispose. + if (!callerHandle && safeHandle != null) + safeHandle.Close(); + } + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.EnumerateFileSystemEntries.cs b/AlphaFS/Filesystem/Directory Class/Directory.EnumerateFileSystemEntries.cs new file mode 100644 index 0000000..f346b00 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.EnumerateFileSystemEntries.cs @@ -0,0 +1,472 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Security; +using SearchOption = System.IO.SearchOption; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region .NET + + /// Returns an enumerable collection of file names and directory names in a specified . + /// An enumerable collection of file system entries in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The directory to search. + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntries(string path) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.RelativePath); + } + + + + /// Returns an enumerable collection of file names and directory names that match a in a specified . + /// An enumerable collection of file system entries in the directory specified by and that match the specified . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntries(string path, string searchPattern) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.RelativePath); + } + + /// Returns an enumerable collection of file names and directory names that match a in a specified , and optionally searches subdirectories. + /// An enumerable collection of file system entries in the directory specified by and that match the specified and . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.FilesAndFolders | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Returns an enumerable collection of file names and directory names in a specified . + /// An enumerable collection of file system entries in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntries(string path, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file names and directory names that match a in a specified . + /// An enumerable collection of file system entries in the directory specified by and that match the specified . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntries(string path, string searchPattern, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, DirectoryEnumerationOptions.FilesAndFolders, pathFormat); + } + + /// [AlphaFS] Returns an enumerable collection of file names and directory names that match a in a specified , and optionally searches subdirectories. + /// An enumerable collection of file system entries in the directory specified by and that match the specified and . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption, PathFormat pathFormat) + { + var options = DirectoryEnumerationOptions.FilesAndFolders | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file names and directory names in a specified . + /// An enumerable collection of file system entries in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntries(string path, DirectoryEnumerationOptions options) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file names and directory names in a specified . + /// An enumerable collection of file system entries in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntries(string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, options, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file names and directory names that match a in a specified . + /// An enumerable collection of file system entries in the directory specified by and that match the specified . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntries(string path, string searchPattern, DirectoryEnumerationOptions options) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file names and directory names that match a in a specified . + /// An enumerable collection of file system entries in the directory specified by and that match the specified . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// Indicates the format of the path parameter(s). + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntries(string path, string searchPattern, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, pathFormat); + } + + + + #region Transactional + + /// [AlphaFS] Returns an enumerable collection of file names and directory names in a specified . + /// An enumerable collection of file system entries in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntriesTransacted(KernelTransaction transaction, string path) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.RelativePath); + } + + + + /// [AlphaFS] Returns an enumerable collection of file names and directory names that match a in a specified . + /// An enumerable collection of file system entries in the directory specified by and that match the specified . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntriesTransacted(KernelTransaction transaction, string path, string searchPattern) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file names and directory names that match a in a specified , and optionally searches subdirectories. + /// An enumerable collection of file system entries in the directory specified by and that match the specified and . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntriesTransacted(KernelTransaction transaction, string path, string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.FilesAndFolders | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, PathFormat.RelativePath); + } + + + + /// [AlphaFS] Returns an enumerable collection of file names and directory names in a specified . + /// An enumerable collection of file system entries in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntriesTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file names and directory names that match a in a specified . + /// An enumerable collection of file system entries in the directory specified by and that match the specified . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntriesTransacted(KernelTransaction transaction, string path, string searchPattern, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, DirectoryEnumerationOptions.FilesAndFolders, pathFormat); + } + + /// [AlphaFS] Returns an enumerable collection of file names and directory names that match a in a specified , and optionally searches subdirectories. + /// An enumerable collection of file system entries in the directory specified by and that match the specified and . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntriesTransacted(KernelTransaction transaction, string path, string searchPattern, SearchOption searchOption, PathFormat pathFormat) + { + var options = DirectoryEnumerationOptions.FilesAndFolders | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file names and directory names in a specified . + /// An enumerable collection of file system entries in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntriesTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file names and directory names in a specified . + /// An enumerable collection of file system entries in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntriesTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, options, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file names and directory names that match a in a specified . + /// An enumerable collection of file system entries in the directory specified by and that match the specified . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntriesTransacted(KernelTransaction transaction, string path, string searchPattern, DirectoryEnumerationOptions options) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file names and directory names that match a in a specified . + /// An enumerable collection of file system entries in the directory specified by and that match the specified . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntriesTransacted(KernelTransaction transaction, string path, string searchPattern, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, pathFormat); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.EnumerateFileSystemEntryInfos.cs b/AlphaFS/Filesystem/Directory Class/Directory.EnumerateFileSystemEntryInfos.cs new file mode 100644 index 0000000..890d394 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.EnumerateFileSystemEntryInfos.cs @@ -0,0 +1,670 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + /// [AlphaFS] Returns an enumerable collection of file system entries in a specified path. + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The directory to search. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntryInfos(string path) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file system entries in a specified path. + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The directory to search. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntryInfos(string path, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file system entries in a specified path. + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The directory to search. + /// flags that specify how the directory is to be enumerated. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntryInfos(string path, DirectoryEnumerationOptions options) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file system entries in a specified path. + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The directory to search. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntryInfos(string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, options, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file system entries that match a in a specified path. + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntryInfos(string path, string searchPattern) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file system entries that match a in a specified path. + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntryInfos(string path, string searchPattern, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, DirectoryEnumerationOptions.FilesAndFolders, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file system entries that match a in a specified path using . + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntryInfos(string path, string searchPattern, DirectoryEnumerationOptions options) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file system entries that match a in a specified path using . + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntryInfos(string path, string searchPattern, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Returns an enumerable collection of file system entries in a specified path. + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The transaction. + /// The directory to search. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntryInfosTransacted(KernelTransaction transaction, string path) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file system entries in a specified path. + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The transaction. + /// The directory to search. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntryInfosTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file system entries in a specified path. + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The transaction. + /// The directory to search. + /// flags that specify how the directory is to be enumerated. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntryInfosTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file system entries in a specified path. + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The transaction. + /// The directory to search. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntryInfosTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, options, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file system entries that match a in a specified path. + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntryInfosTransacted(KernelTransaction transaction, string path, string searchPattern) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file system entries that match a in a specified path. + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntryInfosTransacted(KernelTransaction transaction, string path, string searchPattern, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, DirectoryEnumerationOptions.FilesAndFolders, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file system entries that match a in a specified path using . + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntryInfosTransacted(KernelTransaction transaction, string path, string searchPattern, DirectoryEnumerationOptions options) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file system entries that match a in a specified path using . + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public static IEnumerable EnumerateFileSystemEntryInfosTransacted(KernelTransaction transaction, string path, string searchPattern, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, pathFormat); + } + + #endregion // Transactional + + #region Internal Methods + + /// Returns an enumerable collection of file system entries in a specified path using . + /// The matching file system entries. The type of the items is determined by the type . + /// + /// + /// + /// + /// + /// + /// The type to return. This may be one of the following types: + /// + /// + /// + /// This method will return instances of instances. + /// + /// + /// + /// This method will return instances of and instances. + /// + /// + /// + /// This method will return the full path of each item. + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static IEnumerable EnumerateFileSystemEntryInfosCore(KernelTransaction transaction, string path, string searchPattern, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + // Enable BasicSearch and LargeCache by default. + options |= DirectoryEnumerationOptions.BasicSearch | DirectoryEnumerationOptions.LargeCache; + + return new FindFileSystemEntryInfo(true, transaction, path, searchPattern, options, typeof(T), pathFormat).Enumerate(); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.EnumerateFiles.cs b/AlphaFS/Filesystem/Directory Class/Directory.EnumerateFiles.cs new file mode 100644 index 0000000..f4ee086 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.EnumerateFiles.cs @@ -0,0 +1,502 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Security; +using SearchOption = System.IO.SearchOption; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region .NET + + /// Returns an enumerable collection of file names in a specified . + /// An enumerable collection of the full names (including paths) for the files in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The directory to search. + [SecurityCritical] + public static IEnumerable EnumerateFiles(string path) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Files, PathFormat.RelativePath); + } + + /// Returns an enumerable collection of file names in a specified . + /// An enumerable collection of the full names (including paths) for the files in the directory specified by and that match the . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SecurityCritical] + public static IEnumerable EnumerateFiles(string path, string searchPattern) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, DirectoryEnumerationOptions.Files, PathFormat.RelativePath); + } + + /// Returns an enumerable collection of file names that match a in a specified , and optionally searches subdirectories. + /// An enumerable collection of the full names (including paths) for the files in the directory specified by and that match the specified and . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + [SecurityCritical] + public static IEnumerable EnumerateFiles(string path, string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.Files | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Returns an enumerable collection of file names in a specified . + /// An enumerable collection of the full names (including paths) for the files in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFiles(string path, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Files, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file names in a specified . + /// An enumerable collection of the full names (including paths) for the files in the directory specified by and that match the . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFiles(string path, string searchPattern, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, DirectoryEnumerationOptions.Files, pathFormat); + } + + /// [AlphaFS] Returns an enumerable collection of file names that match a in a specified , and optionally searches subdirectories. + /// An enumerable collection of the full names (including paths) for the files in the directory specified by and that match the specified and . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFiles(string path, string searchPattern, SearchOption searchOption, PathFormat pathFormat) + { + var options = DirectoryEnumerationOptions.Files | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file names in a specified . + /// An enumerable collection of the full names (including paths) for the files in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static IEnumerable EnumerateFiles(string path, DirectoryEnumerationOptions options) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Folders; // Remove enumeration of directories. + options |= DirectoryEnumerationOptions.Files; // Add enumeration of files. + + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file names in a specified . + /// An enumerable collection of the full names (including paths) for the files in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFiles(string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Folders; + options |= DirectoryEnumerationOptions.Files; + + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, options, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file names in a specified . + /// An enumerable collection of the full names (including paths) for the files in the directory specified by and that match the . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static IEnumerable EnumerateFiles(string path, string searchPattern, DirectoryEnumerationOptions options) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Folders; + options |= DirectoryEnumerationOptions.Files; + + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file names in a specified . + /// An enumerable collection of the full names (including paths) for the files in the directory specified by and that match the . + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFiles(string path, string searchPattern, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Folders; + options |= DirectoryEnumerationOptions.Files; + + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, pathFormat); + } + + + + #region Transactional + + /// [AlphaFS] Returns an enumerable collection of file names in a specified . + /// An enumerable collection of the full names (including paths) for the files in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + [SecurityCritical] + public static IEnumerable EnumerateFilesTransacted(KernelTransaction transaction, string path) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Files, PathFormat.RelativePath); + } + + + + /// [AlphaFS] Returns an enumerable collection of file instances that match a in a specified . + /// An enumerable collection of the full names (including paths) for the files in the directory specified by and that match the . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SecurityCritical] + public static IEnumerable EnumerateFilesTransacted(KernelTransaction transaction, string path, string searchPattern) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, DirectoryEnumerationOptions.Files, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file instances instances that match a in a specified , and optionally searches subdirectories. + /// An enumerable collection of the full names (including paths) for the files in the directory specified by and that match the specified and . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + [SecurityCritical] + public static IEnumerable EnumerateFilesTransacted(KernelTransaction transaction, string path, string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.Files | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, PathFormat.RelativePath); + } + + + + /// [AlphaFS] Returns an enumerable collection of file names in a specified . + /// An enumerable collection of the full names (including paths) for the files in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFilesTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Files, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file instances that match a in a specified . + /// An enumerable collection of the full names (including paths) for the files in the directory specified by and that match the . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFilesTransacted(KernelTransaction transaction, string path, string searchPattern, PathFormat pathFormat) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, DirectoryEnumerationOptions.Files, pathFormat); + } + + /// [AlphaFS] Returns an enumerable collection of file instances instances that match a in a specified , and optionally searches subdirectories. + /// An enumerable collection of the full names (including paths) for the files in the directory specified by and that match the specified and . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFilesTransacted(KernelTransaction transaction, string path, string searchPattern, SearchOption searchOption, PathFormat pathFormat) + { + var options = DirectoryEnumerationOptions.Files | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file names in a specified . + /// An enumerable collection of the full names (including paths) for the files in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static IEnumerable EnumerateFilesTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Folders; + options |= DirectoryEnumerationOptions.Files; + + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file names in a specified . + /// An enumerable collection of the full names (including paths) for the files in the directory specified by . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFilesTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Folders; + options |= DirectoryEnumerationOptions.Files; + + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, options, pathFormat); + } + + + + /// [AlphaFS] Returns an enumerable collection of file instances that match a in a specified . + /// An enumerable collection of the full names (including paths) for the files in the directory specified by and that match the . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static IEnumerable EnumerateFilesTransacted(KernelTransaction transaction, string path, string searchPattern, DirectoryEnumerationOptions options) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Folders; + options |= DirectoryEnumerationOptions.Files; + + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Returns an enumerable collection of file instances that match a in a specified . + /// An enumerable collection of the full names (including paths) for the files in the directory specified by and that match the . + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static IEnumerable EnumerateFilesTransacted(KernelTransaction transaction, string path, string searchPattern, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Folders; + options |= DirectoryEnumerationOptions.Files; + + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, pathFormat); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.Exists.cs b/AlphaFS/Filesystem/Directory Class/Directory.Exists.cs new file mode 100644 index 0000000..c0639b0 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.Exists.cs @@ -0,0 +1,110 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region .NET + + /// Determines whether the given path refers to an existing directory on disk. + /// + /// Returns if refers to an existing directory. + /// Returns if the directory does not exist or an error occurs when trying to determine if the specified file exists. + /// + /// + /// The Exists method returns if any error occurs while trying to determine if the specified file exists. + /// This can occur in situations that raise exceptions such as passing a file name with invalid characters or too many characters, + /// a failing or missing disk, or if the caller does not have permission to read the file. + /// + /// The path to test. + [SecurityCritical] + public static bool Exists(string path) + { + return File.ExistsCore(true, null, path, PathFormat.RelativePath); + } + + #endregion // .NET + + + + /// [AlphaFS] Determines whether the given path refers to an existing directory on disk. + /// + /// Returns if refers to an existing directory. + /// Returns if the directory does not exist or an error occurs when trying to determine if the specified file exists. + /// + /// + /// The Exists method returns if any error occurs while trying to determine if the specified file exists. + /// This can occur in situations that raise exceptions such as passing a file name with invalid characters or too many characters, + /// a failing or missing disk, or if the caller does not have permission to read the file. + /// + /// The path to test. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static bool Exists(string path, PathFormat pathFormat) + { + return File.ExistsCore(true, null, path, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Determines whether the given path refers to an existing directory on disk. + /// + /// Returns if refers to an existing directory. + /// Returns if the directory does not exist or an error occurs when trying to determine if the specified file exists. + /// + /// + /// The Exists method returns if any error occurs while trying to determine if the specified file exists. + /// This can occur in situations that raise exceptions such as passing a file name with invalid characters or too many characters, + /// a failing or missing disk, or if the caller does not have permission to read the file. + /// + /// The transaction. + /// The path to test. + [SecurityCritical] + public static bool ExistsTransacted(KernelTransaction transaction, string path) + { + return File.ExistsCore(true, transaction, path, PathFormat.RelativePath); + } + + /// [AlphaFS] Determines whether the given path refers to an existing directory on disk. + /// + /// Returns if refers to an existing directory. + /// Returns if the directory does not exist or an error occurs when trying to determine if the specified file exists. + /// + /// + /// The Exists method returns if any error occurs while trying to determine if the specified file exists. + /// This can occur in situations that raise exceptions such as passing a file name with invalid characters or too many characters, + /// a failing or missing disk, or if the caller does not have permission to read the file. + /// + /// The transaction. + /// The path to test. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static bool ExistsTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return File.ExistsCore(true, transaction, path, pathFormat); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.GetAccessControl.cs b/AlphaFS/Filesystem/Directory Class/Directory.GetAccessControl.cs new file mode 100644 index 0000000..9d90e02 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.GetAccessControl.cs @@ -0,0 +1,113 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.AccessControl; +using Alphaleonis.Win32.Security; +using Microsoft.Win32.SafeHandles; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + /// Gets a object that encapsulates the access control list (ACL) entries for the specified directory. + /// A object that encapsulates the access control rules for the file described by the parameter. + /// + /// + /// + /// The path to a directory containing a object that describes the file's access control list (ACL) information. + [SecurityCritical] + public static DirectorySecurity GetAccessControl(string path) + { + return File.GetAccessControlCore(true, path, AccessControlSections.Access | AccessControlSections.Group | AccessControlSections.Owner, PathFormat.RelativePath); + } + + /// Gets a object that encapsulates the specified type of access control list (ACL) entries for a particular directory. + /// A object that encapsulates the access control rules for the directory described by the parameter. + /// + /// + /// + /// The path to a directory containing a object that describes the directory's access control list (ACL) information. + /// One (or more) of the values that specifies the type of access control list (ACL) information to receive. + [SecurityCritical] + public static DirectorySecurity GetAccessControl(string path, AccessControlSections includeSections) + { + return File.GetAccessControlCore(true, path, includeSections, PathFormat.RelativePath); + } + + + /// [AlphaFS] Gets a object that encapsulates the access control list (ACL) entries for the specified directory. + /// A object that encapsulates the access control rules for the file described by the parameter. + /// + /// + /// + /// The path to a directory containing a object that describes the file's access control list (ACL) information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DirectorySecurity GetAccessControl(string path, PathFormat pathFormat) + { + return File.GetAccessControlCore(true, path, AccessControlSections.Access | AccessControlSections.Group | AccessControlSections.Owner, pathFormat); + } + + /// [AlphaFS] Gets a object that encapsulates the specified type of access control list (ACL) entries for a particular directory. + /// A object that encapsulates the access control rules for the directory described by the parameter. + /// + /// + /// + /// The path to a directory containing a object that describes the directory's access control list (ACL) information. + /// One (or more) of the values that specifies the type of access control list (ACL) information to receive. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DirectorySecurity GetAccessControl(string path, AccessControlSections includeSections, PathFormat pathFormat) + { + return File.GetAccessControlCore(true, path, includeSections, pathFormat); + } + + + /// [AlphaFS] Gets a object that encapsulates the access control list (ACL) entries for the specified directory handle. + /// A object that encapsulates the access control rules for the file described by the parameter. + /// + /// + /// + /// A to a directory containing a object that describes the directory's access control list (ACL) information. + [SecurityCritical] + public static DirectorySecurity GetAccessControl(SafeFileHandle handle) + { + return File.GetAccessControlHandleCore(false, true, handle, AccessControlSections.Access | AccessControlSections.Group | AccessControlSections.Owner, SecurityInformation.None); + } + + /// [AlphaFS] Gets a object that encapsulates the specified type of access control list (ACL) entries for a particular directory handle. + /// A object that encapsulates the access control rules for the directory described by the parameter. + /// + /// + /// + /// A to a directory containing a object that describes the directory's access control list (ACL) information. + /// One (or more) of the values that specifies the type of access control list (ACL) information to receive. + [SecurityCritical] + public static DirectorySecurity GetAccessControl(SafeFileHandle handle, AccessControlSections includeSections) + { + return File.GetAccessControlHandleCore(false, true, handle, includeSections, SecurityInformation.None); + } + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.GetChangeTime.cs b/AlphaFS/Filesystem/Directory Class/Directory.GetChangeTime.cs new file mode 100644 index 0000000..d70676c --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.GetChangeTime.cs @@ -0,0 +1,138 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Microsoft.Win32.SafeHandles; +using System; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + /// [AlphaFS] Gets the change date and time of the specified directory. + /// A structure set to the change date and time for the specified directory. This value is expressed in local time. + /// The directory for which to obtain creation date and time information. + [SecurityCritical] + public static DateTime GetChangeTime(string path) + { + return File.GetChangeTimeCore(true, null, null, path, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the change date and time of the specified directory. + /// A structure set to the change date and time for the specified directory. This value is expressed in local time. + /// The directory for which to obtain creation date and time information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetChangeTime(string path, PathFormat pathFormat) + { + return File.GetChangeTimeCore(true, null, null, path, false, pathFormat); + } + + + + /// [AlphaFS] Gets the change date and time, in Coordinated Universal Time (UTC) format, of the specified directory. + /// A structure set to the change date and time for the specified directory. This value is expressed in UTC time. + /// The file for which to obtain change date and time information, in Coordinated Universal Time (UTC) format. + [SecurityCritical] + public static DateTime GetChangeTimeUtc(string path) + { + return File.GetChangeTimeCore(true, null, null, path, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the change date and time, in Coordinated Universal Time (UTC) format, of the specified directory. + /// A structure set to the change date and time for the specified directory. This value is expressed in UTC time. + /// The file for which to obtain change date and time information, in Coordinated Universal Time (UTC) format. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetChangeTimeUtc(string path, PathFormat pathFormat) + { + return File.GetChangeTimeCore(true, null, null, path, true, pathFormat); + } + + + + /// [AlphaFS] Gets the change date and time of the specified directory. + /// A structure set to the change date and time for the specified directory. This value is expressed in local time. + /// An open handle to the directory from which to retrieve information. + [SecurityCritical] + public static DateTime GetChangeTime(SafeFileHandle safeHandle) + { + return File.GetChangeTimeCore(true, null, safeHandle, null, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the change date and time, in Coordinated Universal Time (UTC) format, of the specified directory. + /// A structure set to the change date and time for the specified directory. This value is expressed in UTC time. + /// An open handle to the directory from which to retrieve information. + [SecurityCritical] + public static DateTime GetChangeTimeUtc(SafeFileHandle safeHandle) + { + return File.GetChangeTimeCore(true, null, safeHandle, null, true, PathFormat.RelativePath); + } + + #region Transactional + + /// [AlphaFS] Gets the change date and time of the specified directory. + /// A structure set to the change date and time for the specified directory. This value is expressed in local time. + /// The transaction. + /// The directory for which to obtain creation date and time information. + [SecurityCritical] + public static DateTime GetChangeTimeTransacted(KernelTransaction transaction, string path) + { + return File.GetChangeTimeCore(true, transaction, null, path, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the change date and time of the specified directory. + /// A structure set to the change date and time for the specified directory. This value is expressed in local time. + /// The transaction. + /// The directory for which to obtain creation date and time information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetChangeTimeTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return File.GetChangeTimeCore(true, transaction, null, path, false, pathFormat); + } + + + + /// [AlphaFS] Gets the change date and time, in Coordinated Universal Time (UTC) format, of the specified directory. + /// A structure set to the change date and time for the specified directory. This value is expressed in UTC time. + /// The transaction. + /// The file for which to obtain change date and time information, in Coordinated Universal Time (UTC) format. + [SecurityCritical] + public static DateTime GetChangeTimeUtcTransacted(KernelTransaction transaction, string path) + { + return File.GetChangeTimeCore(true, transaction, null, path, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the change date and time, in Coordinated Universal Time (UTC) format, of the specified directory. + /// A structure set to the change date and time for the specified directory. This value is expressed in UTC time. + /// The transaction. + /// The file for which to obtain change date and time information, in Coordinated Universal Time (UTC) format. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetChangeTimeUtcTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return File.GetChangeTimeCore(true, transaction, null, path, true, pathFormat); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.GetCreationTime.cs b/AlphaFS/Filesystem/Directory Class/Directory.GetCreationTime.cs new file mode 100644 index 0000000..8b6b3aa --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.GetCreationTime.cs @@ -0,0 +1,124 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region .NET + + /// Gets the creation date and time of the specified directory. + /// A structure set to the creation date and time for the specified directory. This value is expressed in local time. + /// The directory for which to obtain creation date and time information. + [SecurityCritical] + public static DateTime GetCreationTime(string path) + { + return File.GetCreationTimeCore(null, path, false, PathFormat.RelativePath).ToLocalTime(); + } + + + + /// Gets the creation date and time, in Coordinated Universal Time (UTC) format, of the specified directory. + /// A structure set to the creation date and time for the specified directory. This value is expressed in UTC time. + /// The directory for which to obtain creation date and time information, in Coordinated Universal Time (UTC) format. + [SecurityCritical] + public static DateTime GetCreationTimeUtc(string path) + { + return File.GetCreationTimeCore(null, path, true, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Gets the creation date and time of the specified directory. + /// A structure set to the creation date and time for the specified directory. This value is expressed in local time. + /// The directory for which to obtain creation date and time information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetCreationTime(string path, PathFormat pathFormat) + { + return File.GetCreationTimeCore(null, path, false, pathFormat).ToLocalTime(); + } + + + + /// [AlphaFS] Gets the creation date and time, in Coordinated Universal Time (UTC) format, of the specified directory. + /// A structure set to the creation date and time for the specified directory. This value is expressed in UTC time. + /// The directory for which to obtain creation date and time information, in Coordinated Universal Time (UTC) format. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetCreationTimeUtc(string path, PathFormat pathFormat) + { + return File.GetCreationTimeCore(null, path, true, pathFormat); + } + + + #region Transactional + + /// [AlphaFS] Gets the creation date and time of the specified directory. + /// A structure set to the creation date and time for the specified directory. This value is expressed in local time. + /// The transaction. + /// The directory for which to obtain creation date and time information. + [SecurityCritical] + public static DateTime GetCreationTimeTransacted(KernelTransaction transaction, string path) + { + return File.GetCreationTimeCore(transaction, path, false, PathFormat.RelativePath).ToLocalTime(); + } + + /// [AlphaFS] Gets the creation date and time of the specified directory. + /// A structure set to the creation date and time for the specified directory. This value is expressed in local time. + /// The transaction. + /// The directory for which to obtain creation date and time information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetCreationTimeTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return File.GetCreationTimeCore(transaction, path, false, pathFormat).ToLocalTime(); + } + + + + /// [AlphaFS] Gets the creation date and time, in Coordinated Universal Time (UTC) format, of the specified directory. + /// A structure set to the creation date and time for the specified directory. This value is expressed in UTC time. + /// The transaction. + /// The directory for which to obtain creation date and time information, in Coordinated Universal Time (UTC) format. + [SecurityCritical] + public static DateTime GetCreationTimeUtcTransacted(KernelTransaction transaction, string path) + { + return File.GetCreationTimeCore(transaction, path, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the creation date and time, in Coordinated Universal Time (UTC) format, of the specified directory. + /// A structure set to the creation date and time for the specified directory. This value is expressed in UTC time. + /// The transaction. + /// The directory for which to obtain creation date and time information, in Coordinated Universal Time (UTC) format. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetCreationTimeUtcTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return File.GetCreationTimeCore(transaction, path, true, pathFormat); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.GetDirectories.cs b/AlphaFS/Filesystem/Directory Class/Directory.GetDirectories.cs new file mode 100644 index 0000000..ccac010 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.GetDirectories.cs @@ -0,0 +1,210 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Linq; +using System.Security; +using SearchOption = System.IO.SearchOption; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + // Since Directory.GetDirectories() is less efficient than Directory.EnumerateDirectories(), + // only .NET and AlphaFS Transactional methods are implemented. No additional overloaded methods. + + #region .NET + + /// Returns the names of subdirectories (including their paths) in the specified directory. + /// An array of the full names (including paths) of subdirectories in the specified path, or an empty array if no directories are found. + /// + /// The names returned by this method are prefixed with the directory information provided in path. + /// The EnumerateDirectories and GetDirectories methods differ as follows: When you use EnumerateDirectories, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetDirectories, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateDirectories can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The directory to search. + [SecurityCritical] + public static string[] GetDirectories(string path) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Folders, PathFormat.RelativePath).ToArray(); + } + + /// Returns the names of subdirectories (including their paths) that match the specified search pattern in the specified directory. + /// An array of the full names (including paths) of the subdirectories that match the search pattern in the specified directory, or an empty array if no directories are found. + /// + /// The names returned by this method are prefixed with the directory information provided in path. + /// The EnumerateDirectories and GetDirectories methods differ as follows: When you use EnumerateDirectories, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetDirectories, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateDirectories can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SecurityCritical] + public static string[] GetDirectories(string path, string searchPattern) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, DirectoryEnumerationOptions.Folders, PathFormat.RelativePath).ToArray(); + } + + /// Returns the names of the subdirectories (including their paths) that match the specified search pattern in the specified directory, and optionally searches subdirectories. + /// An array of the full names (including paths) of the subdirectories that match the specified criteria, or an empty array if no directories are found. + /// + /// The names returned by this method are prefixed with the directory information provided in path. + /// The EnumerateDirectories and GetDirectories methods differ as follows: When you use EnumerateDirectories, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetDirectories, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateDirectories can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + [SecurityCritical] + public static string[] GetDirectories(string path, string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.Folders | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, PathFormat.RelativePath).ToArray(); + } + + #endregion // .NET + + #region Transactional + + /// Returns the names of subdirectories (including their paths) in the specified directory. + /// An array of the full names (including paths) of subdirectories in the specified path, or an empty array if no directories are found. + /// + /// The names returned by this method are prefixed with the directory information provided in path. + /// The EnumerateDirectories and GetDirectories methods differ as follows: When you use EnumerateDirectories, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetDirectories, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateDirectories can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + [SecurityCritical] + public static string[] GetDirectoriesTransacted(KernelTransaction transaction, string path) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Folders, PathFormat.RelativePath).ToArray(); + } + + /// Returns the names of subdirectories (including their paths) that match the specified search pattern in the specified directory. + /// An array of the full names (including paths) of the subdirectories that match the search pattern in the specified directory, or an empty array if no directories are found. + /// + /// The names returned by this method are prefixed with the directory information provided in path. + /// The EnumerateDirectories and GetDirectories methods differ as follows: When you use EnumerateDirectories, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetDirectories, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateDirectories can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SecurityCritical] + public static string[] GetDirectoriesTransacted(KernelTransaction transaction, string path, string searchPattern) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, DirectoryEnumerationOptions.Folders, PathFormat.RelativePath).ToArray(); + } + + /// Returns the names of the subdirectories (including their paths) that match the specified search pattern in the specified directory, and optionally searches subdirectories. + /// An array of the full names (including paths) of the subdirectories that match the specified criteria, or an empty array if no directories are found. + /// + /// The names returned by this method are prefixed with the directory information provided in path. + /// The EnumerateDirectories and GetDirectories methods differ as follows: When you use EnumerateDirectories, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetDirectories, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateDirectories can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + [SecurityCritical] + public static string[] GetDirectoriesTransacted(KernelTransaction transaction, string path, string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.Folders | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, PathFormat.RelativePath).ToArray(); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.GetDirectoryRoot.cs b/AlphaFS/Filesystem/Directory Class/Directory.GetDirectoryRoot.cs new file mode 100644 index 0000000..91b62f6 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.GetDirectoryRoot.cs @@ -0,0 +1,115 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region .NET + + /// Returns the volume information, root information, or both for the specified path. + /// The volume information, root information, or both for the specified path, or if path does not contain root directory information. + /// + /// + /// + /// The path of a file or directory. + [SecurityCritical] + public static string GetDirectoryRoot(string path) + { + return GetDirectoryRootCore(null, path, PathFormat.RelativePath); + } + + #endregion // .NET + + /// Returns the volume information, root information, or both for the specified path. + /// The volume information, root information, or both for the specified path, or if path does not contain root directory information. + /// + /// + /// + /// The path of a file or directory. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static string GetDirectoryRoot(string path, PathFormat pathFormat) + { + return GetDirectoryRootCore(null, path, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Returns the volume information, root information, or both for the specified path. + /// The volume information, root information, or both for the specified path, or if path does not contain root directory information. + /// + /// + /// + /// The transaction. + /// The path of a file or directory. + [SecurityCritical] + public static string GetDirectoryRootTransacted(KernelTransaction transaction, string path) + { + return GetDirectoryRootCore(transaction, path, PathFormat.RelativePath); + } + + /// Returns the volume information, root information, or both for the specified path. + /// The volume information, root information, or both for the specified path, or if path does not contain root directory information. + /// + /// + /// + /// The transaction. + /// The path of a file or directory. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static string GetDirectoryRootTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return GetDirectoryRootCore(transaction, path, pathFormat); + } + + #endregion // Transactional + + #region Internal Methods + + /// Returns the volume information, root information, or both for the specified path. + /// The volume information, root information, or both for the specified path, or if path does not contain root directory information. + /// + /// + /// + /// The transaction. + /// The path of a file or directory. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static string GetDirectoryRootCore(KernelTransaction transaction, string path, PathFormat pathFormat) + { + Path.CheckInvalidUncPath(path); + + string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.CheckInvalidPathChars); + + pathLp = Path.GetRegularPathCore(pathLp, GetFullPathOptions.None, false); + + string rootPath = Path.GetPathRoot(pathLp, false); + + return Utils.IsNullOrWhiteSpace(rootPath) ? null : rootPath; + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.GetFileSystemEntries.cs b/AlphaFS/Filesystem/Directory Class/Directory.GetFileSystemEntries.cs new file mode 100644 index 0000000..e4974a0 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.GetFileSystemEntries.cs @@ -0,0 +1,210 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Linq; +using System.Security; +using SearchOption = System.IO.SearchOption; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + // Since Directory.GetFileSystemEntries() is less efficient than Directory.EnumerateFileSystemEntries(), + // only .NET and AlphaFS Transactional methods are implemented. No additional overloaded methods. + + #region .NET + + /// Returns the names of all files and subdirectories in the specified directory. + /// An string[] array of the names of files and subdirectories in the specified directory. + /// + /// The EnumerateFileSystemEntries and GetFileSystemEntries methods differ as follows: When you use EnumerateFileSystemEntries, + /// you can start enumerating the collection of entries before the whole collection is returned; when you use GetFileSystemEntries, + /// you must wait for the whole array of entries to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The directory for which file and subdirectory names are returned. + [SecurityCritical] + public static string[] GetFileSystemEntries(string path) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.RelativePath).ToArray(); + } + + /// Returns an array of file system entries that match the specified search criteria. + /// An string[] array of file system entries that match the specified search criteria. + /// + /// The EnumerateFileSystemEntries and GetFileSystemEntries methods differ as follows: When you use EnumerateFileSystemEntries, + /// you can start enumerating the collection of entries before the whole collection is returned; when you use GetFileSystemEntries, + /// you must wait for the whole array of entries to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The path to be searched. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SecurityCritical] + public static string[] GetFileSystemEntries(string path, string searchPattern) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.RelativePath).ToArray(); + } + + /// Gets an array of all the file names and directory names that match a in a specified path, and optionally searches subdirectories. + /// An string[] array of file system entries that match the specified search criteria. + /// + /// The EnumerateFileSystemEntries and GetFileSystemEntries methods differ as follows: When you use EnumerateFileSystemEntries, + /// you can start enumerating the collection of entries before the whole collection is returned; when you use GetFileSystemEntries, + /// you must wait for the whole array of entries to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + [SecurityCritical] + public static string[] GetFileSystemEntries(string path, string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.FilesAndFolders | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, PathFormat.RelativePath).ToArray(); + } + + #endregion // .NET + + #region Transactional + + /// Returns the names of all files and subdirectories in the specified directory. + /// An string[] array of the names of files and subdirectories in the specified directory. + /// + /// The EnumerateFileSystemEntries and GetFileSystemEntries methods differ as follows: When you use EnumerateFileSystemEntries, + /// you can start enumerating the collection of entries before the whole collection is returned; when you use GetFileSystemEntries, + /// you must wait for the whole array of entries to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory for which file and subdirectory names are returned. + [SecurityCritical] + public static string[] GetFileSystemEntriesTransacted(KernelTransaction transaction, string path) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.RelativePath).ToArray(); + } + + /// Returns an array of file system entries that match the specified search criteria. + /// An string[] array of file system entries that match the specified search criteria. + /// + /// The EnumerateFileSystemEntries and GetFileSystemEntries methods differ as follows: When you use EnumerateFileSystemEntries, + /// you can start enumerating the collection of entries before the whole collection is returned; when you use GetFileSystemEntries, + /// you must wait for the whole array of entries to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The path to be searched. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SecurityCritical] + public static string[] GetFileSystemEntriesTransacted(KernelTransaction transaction, string path, string searchPattern) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.RelativePath).ToArray(); + } + + /// Gets an array of all the file names and directory names that match a in a specified path, and optionally searches subdirectories. + /// An string[] array of file system entries that match the specified search criteria. + /// + /// The EnumerateFileSystemEntries and GetFileSystemEntries methods differ as follows: When you use EnumerateFileSystemEntries, + /// you can start enumerating the collection of entries before the whole collection is returned; when you use GetFileSystemEntries, + /// you must wait for the whole array of entries to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + [SecurityCritical] + public static string[] GetFileSystemEntriesTransacted(KernelTransaction transaction, string path, string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.FilesAndFolders | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, PathFormat.RelativePath).ToArray(); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.GetFiles.cs b/AlphaFS/Filesystem/Directory Class/Directory.GetFiles.cs new file mode 100644 index 0000000..4d1d46f --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.GetFiles.cs @@ -0,0 +1,216 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Linq; +using System.Security; +using SearchOption = System.IO.SearchOption; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + // Since Directory.GetFiles() is less efficient than Directory.EnumerateFiles(), + // only .NET and AlphaFS Transactional methods are implemented. No additional overloaded methods. + + #region .NET + + /// Returns the names of files (including their paths) in the specified directory. + /// An array of the full names (including paths) for the files in the specified directory, or an empty array if no files are found. + /// + /// The returned file names are appended to the supplied parameter. + /// The order of the returned file names is not guaranteed; use the Sort() method if a specific sort order is required. + /// The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetFiles, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The directory to search. + [SecurityCritical] + public static string[] GetFiles(string path) + { + return EnumerateFileSystemEntryInfosCore(null, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Files, PathFormat.RelativePath).ToArray(); + } + + /// Returns the names of files (including their paths) that match the specified search pattern in the specified directory. + /// An array of the full names (including paths) for the files in the specified directory that match the specified search pattern, or an empty array if no files are found. + /// + /// The returned file names are appended to the supplied parameter. + /// The order of the returned file names is not guaranteed; use the Sort() method if a specific sort order is required. + /// The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetFiles, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SecurityCritical] + public static string[] GetFiles(string path, string searchPattern) + { + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, DirectoryEnumerationOptions.Files, PathFormat.RelativePath).ToArray(); + } + + /// Returns the names of files (including their paths) that match the specified search pattern in the current directory, and optionally searches subdirectories. + /// An array of the full names (including paths) for the files in the specified directory that match the specified search pattern and option, or an empty array if no files are found. + /// + /// The returned file names are appended to the supplied parameter. + /// The order of the returned file names is not guaranteed; use the Sort() method if a specific sort order is required. + /// The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetFiles, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + [SecurityCritical] + public static string[] GetFiles(string path, string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.Files | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(null, path, searchPattern, options, PathFormat.RelativePath).ToArray(); + } + + #endregion // .NET + + #region Transactional + + /// Returns the names of files (including their paths) in the specified directory. + /// An array of the full names (including paths) for the files in the specified directory, or an empty array if no files are found. + /// + /// The returned file names are appended to the supplied parameter. + /// The order of the returned file names is not guaranteed; use the Sort() method if a specific sort order is required. + /// The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetFiles, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + [SecurityCritical] + public static string[] GetFilesTransacted(KernelTransaction transaction, string path) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Files, PathFormat.RelativePath).ToArray(); + } + + /// Returns the names of files (including their paths) that match the specified search pattern in the specified directory. + /// An array of the full names (including paths) for the files in the specified directory that match the specified search pattern, or an empty array if no files are found. + /// + /// The returned file names are appended to the supplied parameter. + /// The order of the returned file names is not guaranteed; use the Sort() method if a specific sort order is required. + /// The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetFiles, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SecurityCritical] + public static string[] GetFilesTransacted(KernelTransaction transaction, string path, string searchPattern) + { + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, DirectoryEnumerationOptions.Files, PathFormat.RelativePath).ToArray(); + } + + /// Returns the names of files (including their paths) that match the specified search pattern in the current directory, and optionally searches subdirectories. + /// An array of the full names (including paths) for the files in the specified directory that match the specified search pattern and option, or an empty array if no files are found. + /// + /// The returned file names are appended to the supplied parameter. + /// The order of the returned file names is not guaranteed; use the Sort() method if a specific sort order is required. + /// The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetFiles, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The directory to search. + /// + /// The search string to match against the names of directories in . + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + [SecurityCritical] + public static string[] GetFilesTransacted(KernelTransaction transaction, string path, string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.Files | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return EnumerateFileSystemEntryInfosCore(transaction, path, searchPattern, options, PathFormat.RelativePath).ToArray(); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.GetLastAccessTime.cs b/AlphaFS/Filesystem/Directory Class/Directory.GetLastAccessTime.cs new file mode 100644 index 0000000..9808b72 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.GetLastAccessTime.cs @@ -0,0 +1,121 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region .NET + + /// Gets the date and time that the specified directory was last accessed. + /// A structure set to the date and time that the specified directory was last accessed. This value is expressed in local time. + /// The directory for which to obtain access date and time information. + [SecurityCritical] + public static DateTime GetLastAccessTime(string path) + { + return File.GetLastAccessTimeCore(null, path, false, PathFormat.RelativePath).ToLocalTime(); + } + + /// Gets the date and time, in coordinated universal time (UTC), that the specified directory was last accessed. + /// A structure set to the date and time that the specified directory was last accessed. This value is expressed in UTC time. + /// The directory for which to obtain access date and time information. + [SecurityCritical] + public static DateTime GetLastAccessTimeUtc(string path) + { + return File.GetLastAccessTimeCore(null, path, true, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Gets the date and time that the specified directory was last accessed. + /// A structure set to the date and time that the specified directory was last accessed. This value is expressed in local time. + /// The directory for which to obtain access date and time information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetLastAccessTime(string path, PathFormat pathFormat) + { + return File.GetLastAccessTimeCore(null, path, false, pathFormat).ToLocalTime(); + } + + + + /// [AlphaFS] Gets the date and time, in coordinated universal time (UTC), that the specified directory was last accessed. + /// A structure set to the date and time that the specified directory was last accessed. This value is expressed in UTC time. + /// The directory for which to obtain access date and time information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetLastAccessTimeUtc(string path, PathFormat pathFormat) + { + return File.GetLastAccessTimeCore(null, path, true, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Gets the date and time that the specified directory was last accessed. + /// A structure set to the date and time that the specified directory was last accessed. This value is expressed in local time. + /// The transaction. + /// The directory for which to obtain access date and time information. + [SecurityCritical] + public static DateTime GetLastAccessTimeTransacted(KernelTransaction transaction, string path) + { + return File.GetLastAccessTimeCore(transaction, path, false, PathFormat.RelativePath).ToLocalTime(); + } + + /// [AlphaFS] Gets the date and time that the specified directory was last accessed. + /// A structure set to the date and time that the specified directory was last accessed. This value is expressed in local time. + /// The transaction. + /// The directory for which to obtain access date and time information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetLastAccessTimeTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return File.GetLastAccessTimeCore(transaction, path, false, pathFormat).ToLocalTime(); + } + + + + /// [AlphaFS] Gets the date and time, in coordinated universal time (UTC), that the specified directory was last accessed. + /// A structure set to the date and time that the specified directory was last accessed. This value is expressed in UTC time. + /// The transaction. + /// The directory for which to obtain access date and time information. + [SecurityCritical] + public static DateTime GetLastAccessTimeUtcTransacted(KernelTransaction transaction, string path) + { + return File.GetLastAccessTimeCore(transaction, path, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the date and time, in coordinated universal time (UTC), that the specified directory was last accessed. + /// A structure set to the date and time that the specified directory was last accessed. This value is expressed in UTC time. + /// The transaction. + /// The directory for which to obtain access date and time information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetLastAccessTimeUtcTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return File.GetLastAccessTimeCore(transaction, path, true, pathFormat); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.GetLastWriteTime.cs b/AlphaFS/Filesystem/Directory Class/Directory.GetLastWriteTime.cs new file mode 100644 index 0000000..c34a959 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.GetLastWriteTime.cs @@ -0,0 +1,123 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region .NET + + /// Gets the date and time that the specified directory was last written to. + /// A structure set to the date and time that the specified directory was last written to. This value is expressed in local time. + /// The directory for which to obtain write date and time information. + [SecurityCritical] + public static DateTime GetLastWriteTime(string path) + { + return File.GetLastWriteTimeCore(null, path, false, PathFormat.RelativePath).ToLocalTime(); + } + + + + /// Gets the date and time, in coordinated universal time (UTC) time, that the specified directory was last written to. + /// A structure set to the date and time that the specified directory was last written to. This value is expressed in UTC time. + /// The directory for which to obtain write date and time information. + [SecurityCritical] + public static DateTime GetLastWriteTimeUtc(string path) + { + return File.GetLastWriteTimeCore(null, path, true, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Gets the date and time that the specified directory was last written to. + /// A structure set to the date and time that the specified directory was last written to. This value is expressed in local time. + /// The directory for which to obtain write date and time information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetLastWriteTime(string path, PathFormat pathFormat) + { + return File.GetLastWriteTimeCore(null, path, false, pathFormat).ToLocalTime(); + } + + + + /// [AlphaFS] Gets the date and time, in coordinated universal time (UTC) time, that the specified directory was last written to. + /// A structure set to the date and time that the specified directory was last written to. This value is expressed in UTC time. + /// The directory for which to obtain write date and time information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetLastWriteTimeUtc(string path, PathFormat pathFormat) + { + return File.GetLastWriteTimeCore(null, path, true, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Gets the date and time that the specified directory was last written to. + /// A structure set to the date and time that the specified directory was last written to. This value is expressed in local time. + /// The transaction. + /// The directory for which to obtain write date and time information. + [SecurityCritical] + public static DateTime GetLastWriteTimeTransacted(KernelTransaction transaction, string path) + { + return File.GetLastWriteTimeCore(transaction, path, false, PathFormat.RelativePath).ToLocalTime(); + } + + /// [AlphaFS] Gets the date and time that the specified directory was last written to. + /// A structure set to the date and time that the specified directory was last written to. This value is expressed in local time. + /// The transaction. + /// The directory for which to obtain write date and time information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetLastWriteTimeTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return File.GetLastWriteTimeCore(transaction, path, false, pathFormat).ToLocalTime(); + } + + + + /// [AlphaFS] Gets the date and time, in coordinated universal time (UTC) time, that the specified directory was last written to. + /// A structure set to the date and time that the specified directory was last written to. This value is expressed in UTC time. + /// The transaction. + /// The directory for which to obtain write date and time information. + [SecurityCritical] + public static DateTime GetLastWriteTimeUtcTransacted(KernelTransaction transaction, string path) + { + return File.GetLastWriteTimeCore(transaction, path, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the date and time, in coordinated universal time (UTC) time, that the specified directory was last written to. + /// A structure set to the date and time that the specified directory was last written to. This value is expressed in UTC time. + /// The transaction. + /// The directory for which to obtain write date and time information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetLastWriteTimeUtcTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return File.GetLastWriteTimeCore(transaction, path, true, pathFormat); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.GetLogicalDrives.cs b/AlphaFS/Filesystem/Directory Class/Directory.GetLogicalDrives.cs new file mode 100644 index 0000000..a6a3620 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.GetLogicalDrives.cs @@ -0,0 +1,150 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region .NET + + /// Retrieves the names of the logical drives on this computer in the form "<drive letter>:\". + /// An array of type that represents the logical drives on a computer. + [SecurityCritical] + public static string[] GetLogicalDrives() + { + return EnumerateLogicalDrivesCore(false, false).Select(drive => drive.Name).ToArray(); + } + + #endregion // .NET + + /// [AlphaFS] Retrieves the names of the logical drives on this computer in the form "<drive letter>:\". + /// An array of type that represents the logical drives on a computer. + /// Retrieve logical drives as known by the Environment. + /// Retrieve only when accessible (IsReady) logical drives. + [SecurityCritical] + public static string[] GetLogicalDrives(bool fromEnvironment, bool isReady) + { + return EnumerateLogicalDrivesCore(fromEnvironment, isReady).Select(drive => drive.Name).ToArray(); + } + + + /// [AlphaFS] Enumerates the drive names of all logical drives on a computer. + /// An IEnumerable of type that represents the logical drives on a computer. + /// Retrieve logical drives as known by the Environment. + /// Retrieve only when accessible (IsReady) logical drives. + [SecurityCritical] + public static IEnumerable EnumerateLogicalDrives(bool fromEnvironment, bool isReady) + { + return EnumerateLogicalDrivesCore(fromEnvironment, isReady); + } + + #region Internal Methods + + /// Enumerates the drive names of all logical drives on a computer. + /// An IEnumerable of type that represents the logical drives on a computer. + /// Retrieve logical drives as known by the Environment. + /// Retrieve only when accessible (IsReady) logical drives. + [SecurityCritical] + internal static IEnumerable EnumerateLogicalDrivesCore(bool fromEnvironment, bool isReady) + { + #region Get from Environment + + if (fromEnvironment) + { + IEnumerable drivesEnv = isReady + ? Environment.GetLogicalDrives().Where(ld => File.ExistsCore(true, null, ld, PathFormat.FullPath)) + : Environment.GetLogicalDrives().Select(ld => ld); + + foreach (string drive in drivesEnv) + { + // Optionally check Drive .IsReady. + if (isReady) + { + if (File.ExistsCore(true, null, drive, PathFormat.FullPath)) + yield return new DriveInfo(drive); + } + else + yield return new DriveInfo(drive); + } + + yield break; + } + + #endregion // Get from Environment + + #region Get through NativeMethod + + uint lastError = NativeMethods.GetLogicalDrives(); + if (lastError == Win32Errors.ERROR_SUCCESS) + NativeError.ThrowException((int)lastError); + + uint drives = lastError; + int count = 0; + while (drives != 0) + { + if ((drives & 1) != 0) + ++count; + + drives >>= 1; + } + + string[] result = new string[count]; + char[] root = { 'A', Path.VolumeSeparatorChar }; + + drives = lastError; + count = 0; + + while (drives != 0) + { + if ((drives & 1) != 0) + { + string drive = new string(root); + + if (isReady) + { + // Optionally check Drive .IsReady. + if (File.ExistsCore(true, null, drive, PathFormat.FullPath)) + yield return new DriveInfo(drive); + } + else + { + // Ready or not. + yield return new DriveInfo(drive); + } + + result[count++] = drive; + } + + drives >>= 1; + root[0]++; + } + + #endregion // Get through NativeMethod + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.GetParent.cs b/AlphaFS/Filesystem/Directory Class/Directory.GetParent.cs new file mode 100644 index 0000000..c2945a4 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.GetParent.cs @@ -0,0 +1,92 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region .NET + + /// Retrieves the parent directory of the specified path, including both absolute and relative paths. + /// The path for which to retrieve the parent directory. + /// The parent directory, or if is the root directory, including the root of a UNC server or share name. + [SecurityCritical] + public static DirectoryInfo GetParent(string path) + { + return GetParentCore(null, path, PathFormat.RelativePath); + } + + /// [AlphaFS] Retrieves the parent directory of the specified path, including both absolute and relative paths. + /// The parent directory, or if is the root directory, including the root of a UNC server or share name. + /// The path for which to retrieve the parent directory. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DirectoryInfo GetParent(string path, PathFormat pathFormat) + { + return GetParentCore(null, path, pathFormat); + } + + #endregion // .NET + + /// [AlphaFS] Retrieves the parent directory of the specified path, including both absolute and relative paths. + /// The parent directory, or if is the root directory, including the root of a UNC server or share name. + /// The transaction. + /// The path for which to retrieve the parent directory. + [SecurityCritical] + public static DirectoryInfo GetParentTransacted(KernelTransaction transaction, string path) + { + return GetParentCore(transaction, path, PathFormat.RelativePath); + } + + /// Retrieves the parent directory of the specified path, including both absolute and relative paths. + /// The parent directory, or if is the root directory, including the root of a UNC server or share name. + /// The transaction. + /// The path for which to retrieve the parent directory. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DirectoryInfo GetParentTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return GetParentCore(transaction, path, pathFormat); + } + + #region Internal Methods + + /// Retrieves the parent directory of the specified path, including both absolute and relative paths. + /// The parent directory, or if is the root directory, including the root of a UNC server or share name. + /// The transaction. + /// The path for which to retrieve the parent directory. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static DirectoryInfo GetParentCore(KernelTransaction transaction, string path, PathFormat pathFormat) + { + string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.CheckInvalidPathChars); + + pathLp = Path.GetRegularPathCore(pathLp, GetFullPathOptions.None, false); + string dirName = Path.GetDirectoryName(pathLp, false); + + return Utils.IsNullOrWhiteSpace(dirName) ? null : new DirectoryInfo(transaction, dirName, PathFormat.RelativePath); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.GetProperties.cs b/AlphaFS/Filesystem/Directory Class/Directory.GetProperties.cs new file mode 100644 index 0000000..92dfe70 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.GetProperties.cs @@ -0,0 +1,286 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + /// [AlphaFS] Gets the properties of the particular directory without following any symbolic links or mount points. + /// Properties include aggregated info from of each encountered file system object, plus additional ones: Total, File, Size and Error. + /// Total: is the total number of enumerated objects. + /// File: is the total number of files. File is considered when object is neither nor . + /// Size: is the total size of enumerated objects. + /// Error: is the total number of errors encountered during enumeration. + /// + /// A dictionary mapping the keys mentioned above to their respective aggregated values. + /// Directory: is an object which has attribute without one. + /// + /// + /// + /// + /// + /// + /// The target directory. + [SecurityCritical] + public static Dictionary GetProperties(string path) + { + return GetPropertiesCore(null, path, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the properties of the particular directory without following any symbolic links or mount points. + /// Properties include aggregated info from of each encountered file system object, plus additional ones: Total, File, Size and Error. + /// Total: is the total number of enumerated objects. + /// File: is the total number of files. File is considered when object is neither nor . + /// Size: is the total size of enumerated objects. + /// Error: is the total number of errors encountered during enumeration. + /// + /// A dictionary mapping the keys mentioned above to their respective aggregated values. + /// Directory: is an object which has attribute without one. + /// + /// + /// + /// + /// + /// + /// The target directory. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static Dictionary GetProperties(string path, PathFormat pathFormat) + { + return GetPropertiesCore(null, path, DirectoryEnumerationOptions.FilesAndFolders, pathFormat); + } + + + /// [AlphaFS] Gets the properties of the particular directory without following any symbolic links or mount points. + /// Properties include aggregated info from of each encountered file system object, plus additional ones: Total, File, Size and Error. + /// Total: is the total number of enumerated objects. + /// File: is the total number of files. File is considered when object is neither nor . + /// Size: is the total size of enumerated objects. + /// Error: is the total number of errors encountered during enumeration. + /// + /// A dictionary mapping the keys mentioned above to their respective aggregated values. + /// Directory: is an object which has attribute without one. + /// + /// + /// + /// + /// + /// + /// The target directory. + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static Dictionary GetProperties(string path, DirectoryEnumerationOptions options) + { + return GetPropertiesCore(null, path, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the properties of the particular directory without following any symbolic links or mount points. + /// Properties include aggregated info from of each encountered file system object, plus additional ones: Total, File, Size and Error. + /// Total: is the total number of enumerated objects. + /// File: is the total number of files. File is considered when object is neither nor . + /// Size: is the total size of enumerated objects. + /// Error: is the total number of errors encountered during enumeration. + /// + /// A dictionary mapping the keys mentioned above to their respective aggregated values. + /// Directory: is an object which has attribute without one. + /// + /// + /// + /// + /// + /// + /// The target directory. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static Dictionary GetProperties(string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + return GetPropertiesCore(null, path, options, pathFormat); + } + + + #region Transactional + + /// [AlphaFS] Gets the properties of the particular directory without following any symbolic links or mount points. + /// Properties include aggregated info from of each encountered file system object, plus additional ones: Total, File, Size and Error. + /// Total: is the total number of enumerated objects. + /// File: is the total number of files. File is considered when object is neither nor . + /// Size: is the total size of enumerated objects. + /// Error: is the total number of errors encountered during enumeration. + /// + /// A dictionary mapping the keys mentioned above to their respective aggregated values. + /// Directory: is an object which has attribute without one. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The target directory. + [SecurityCritical] + public static Dictionary GetPropertiesTransacted(KernelTransaction transaction, string path) + { + return GetPropertiesCore(transaction, path, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the properties of the particular directory without following any symbolic links or mount points. + /// Properties include aggregated info from of each encountered file system object, plus additional ones: Total, File, Size and Error. + /// Total: is the total number of enumerated objects. + /// File: is the total number of files. File is considered when object is neither nor . + /// Size: is the total size of enumerated objects. + /// Error: is the total number of errors encountered during enumeration. + /// + /// A dictionary mapping the keys mentioned above to their respective aggregated values. + /// Directory: is an object which has attribute without one. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The target directory. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static Dictionary GetPropertiesTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return GetPropertiesCore(transaction, path, DirectoryEnumerationOptions.FilesAndFolders, pathFormat); + } + + + /// [AlphaFS] Gets the properties of the particular directory without following any symbolic links or mount points. + /// Properties include aggregated info from of each encountered file system object, plus additional ones: Total, File, Size and Error. + /// Total: is the total number of enumerated objects. + /// File: is the total number of files. File is considered when object is neither nor . + /// Size: is the total size of enumerated objects. + /// Error: is the total number of errors encountered during enumeration. + /// + /// A dictionary mapping the keys mentioned above to their respective aggregated values. + /// Directory: is an object which has attribute without one. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The target directory. + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public static Dictionary GetPropertiesTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options) + { + return GetPropertiesCore(transaction, path, options, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the properties of the particular directory without following any symbolic links or mount points. + /// Properties include aggregated info from of each encountered file system object, plus additional ones: Total, File, Size and Error. + /// Total: is the total number of enumerated objects. + /// File: is the total number of files. File is considered when object is neither nor . + /// Size: is the total size of enumerated objects. + /// Error: is the total number of errors encountered during enumeration. + /// + /// A dictionary mapping the keys mentioned above to their respective aggregated values. + /// Directory: is an object which has attribute without one. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The target directory. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static Dictionary GetPropertiesTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + return GetPropertiesCore(transaction, path, options, pathFormat); + } + + #endregion // Transactional + + #region Internal Methods + + /// [AlphaFS] Gets the properties of the particular directory without following any symbolic links or mount points. + /// Properties include aggregated info from of each encountered file system object, plus additional ones: Total, File, Size and Error. + /// Total: is the total number of enumerated objects. + /// File: is the total number of files. File is considered when object is neither nor . + /// Size: is the total size of enumerated objects. + /// Error: is the total number of errors encountered during enumeration. + /// + /// A dictionary mapping the keys mentioned above to their respective aggregated values. + /// Directory: is an object which has attribute without one. + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The target directory. + /// flags that specify how the directory is to be enumerated. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static Dictionary GetPropertiesCore(KernelTransaction transaction, string path, DirectoryEnumerationOptions options, PathFormat pathFormat) + { + long total = 0; + long size = 0; + + const string propFile = "File"; + const string propTotal = "Total"; + const string propSize = "Size"; + + var typeOfAttrs = typeof(FileAttributes); + var attributes = Enum.GetValues(typeOfAttrs); + var props = Enum.GetNames(typeOfAttrs).OrderBy(attrs => attrs).ToDictionary(name => name, name => 0); + var pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + + foreach (var fsei in EnumerateFileSystemEntryInfosCore(transaction, pathLp, Path.WildcardStarMatchAll, options, PathFormat.LongFullPath)) + { + total++; + + if (!fsei.IsDirectory) + size += fsei.FileSize; + + var fsei1 = fsei; + + foreach (var attributeMarker in attributes.Cast().Where(attributeMarker => (fsei1.Attributes & attributeMarker) != 0)) + props[((attributeMarker & FileAttributes.Directory) != 0 ? FileAttributes.Directory : attributeMarker).ToString()]++; + } + + // Adjust regular files count. + props.Add(propFile, total - props[FileAttributes.Directory.ToString()] - props[FileAttributes.ReparsePoint.ToString()]); + props.Add(propTotal, total); + props.Add(propSize, size); + + return props; + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.HasInheritedPermissions.cs b/AlphaFS/Filesystem/Directory Class/Directory.HasInheritedPermissions.cs new file mode 100644 index 0000000..71e4033 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.HasInheritedPermissions.cs @@ -0,0 +1,58 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security.AccessControl; +using System.Security.Principal; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + /// [AlphaFS] Check if the directory has permission inheritance enabled. + /// if permission inheritance is enabled, if permission inheritance is disabled. + /// The full path to the directory to check. + /// Indicates the format of the path parameter(s). + public static bool HasInheritedPermissions(string path, PathFormat pathFormat) + { + if (Utils.IsNullOrWhiteSpace(path)) + throw new ArgumentNullException("path"); + + var acl = File.GetAccessControlCore(true, path, AccessControlSections.Access | AccessControlSections.Group | AccessControlSections.Owner, pathFormat); + + return acl.GetAccessRules(false, true, typeof(SecurityIdentifier)).Count > 0; + } + + + /// [AlphaFS] Check if the directory has permission inheritance enabled. + /// The full path to the directory to check. + /// if permission inheritance is enabled, if permission inheritance is disabled. + public static bool HasInheritedPermissions(string path) + { + if (Utils.IsNullOrWhiteSpace(path)) + throw new ArgumentNullException("path"); + + var acl = File.GetAccessControlCore(true, path, AccessControlSections.Access | AccessControlSections.Group | AccessControlSections.Owner, PathFormat.RelativePath); + + return acl.GetAccessRules(false, true, typeof(SecurityIdentifier)).Count > 0; + } + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.SetAccessControl.cs b/AlphaFS/Filesystem/Directory Class/Directory.SetAccessControl.cs new file mode 100644 index 0000000..fc0559b --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.SetAccessControl.cs @@ -0,0 +1,104 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.Security; +using System.Security.AccessControl; +using Microsoft.Win32.SafeHandles; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + /// Applies access control list (ACL) entries described by a object to the specified directory. + /// A directory to add or remove access control list (ACL) entries from. + /// A object that describes an ACL entry to apply to the directory described by the path parameter. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static void SetAccessControl(string path, DirectorySecurity directorySecurity) + { + File.SetAccessControlCore(path, null, directorySecurity, AccessControlSections.All, PathFormat.RelativePath); + } + + /// Applies access control list (ACL) entries described by a object to the specified directory. + /// Note that unlike this method does not automatically + /// determine what parts of the specified instance has been modified. Instead, the + /// parameter is used to specify what entries from to apply to . + /// A directory to add or remove access control list (ACL) entries from. + /// A object that describes an ACL entry to apply to the directory described by the path parameter. + /// One or more of the values that specifies the type of access control list (ACL) information to set. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static void SetAccessControl(string path, DirectorySecurity directorySecurity, AccessControlSections includeSections) + { + File.SetAccessControlCore(path, null, directorySecurity, includeSections, PathFormat.RelativePath); + } + + + /// [AlphaFS] Applies access control list (ACL) entries described by a object to the specified directory. + /// A directory to add or remove access control list (ACL) entries from. + /// A object that describes an ACL entry to apply to the directory described by the path parameter. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static void SetAccessControl(string path, DirectorySecurity directorySecurity, PathFormat pathFormat) + { + File.SetAccessControlCore(path, null, directorySecurity, AccessControlSections.All, pathFormat); + } + + /// [AlphaFS] Applies access control list (ACL) entries described by a object to the specified directory. + /// Note that unlike this method does not automatically + /// determine what parts of the specified instance has been modified. Instead, the + /// parameter is used to specify what entries from to apply to . + /// A directory to add or remove access control list (ACL) entries from. + /// A object that describes an ACL entry to apply to the directory described by the path parameter. + /// One or more of the values that specifies the type of access control list (ACL) information to set. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static void SetAccessControl(string path, DirectorySecurity directorySecurity, AccessControlSections includeSections, PathFormat pathFormat) + { + File.SetAccessControlCore(path, null, directorySecurity, includeSections, pathFormat); + } + + + /// Applies access control list (ACL) entries described by a object to the specified directory. + /// A to a file to add or remove access control list (ACL) entries from. + /// A object that describes an ACL entry to apply to the directory described by the path parameter. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static void SetAccessControl(SafeFileHandle handle, DirectorySecurity directorySecurity) + { + File.SetAccessControlCore(null, handle, directorySecurity, AccessControlSections.All, PathFormat.LongFullPath); + } + + /// Applies access control list (ACL) entries described by a object to the specified directory. + /// A to a file to add or remove access control list (ACL) entries from. + /// A object that describes an ACL entry to apply to the directory described by the path parameter. + /// One or more of the values that specifies the type of access control list (ACL) information to set. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static void SetAccessControl(SafeFileHandle handle, DirectorySecurity directorySecurity, AccessControlSections includeSections) + { + File.SetAccessControlCore(null, handle, directorySecurity, includeSections, PathFormat.LongFullPath); + } + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.SetCreationTime.cs b/AlphaFS/Filesystem/Directory Class/Directory.SetCreationTime.cs new file mode 100644 index 0000000..f2698a1 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.SetCreationTime.cs @@ -0,0 +1,169 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region .NET + + /// Sets the date and time the directory was created. + /// The directory for which to set the creation date and time information. + /// A containing the value to set for the creation date and time of . This value is expressed in local time. + [SecurityCritical] + public static void SetCreationTime(string path, DateTime creationTime) + { + File.SetFsoDateTimeCore(true, null, path, creationTime.ToUniversalTime(), null, null, false, PathFormat.RelativePath); + } + + + + /// Sets the date and time, in coordinated universal time (UTC), that the directory was created. + /// The directory for which to set the creation date and time information. + /// A containing the value to set for the creation date and time of . This value is expressed in UTC time. + [SecurityCritical] + public static void SetCreationTimeUtc(string path, DateTime creationTimeUtc) + { + File.SetFsoDateTimeCore(true, null, path, creationTimeUtc, null, null, false, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Sets the date and time the directory was created. + /// The directory for which to set the creation date and time information. + /// Indicates the format of the path parameter(s). + /// A containing the value to set for the creation date and time of . This value is expressed in local time. + [SecurityCritical] + public static void SetCreationTime(string path, DateTime creationTime, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, null, path, creationTime.ToUniversalTime(), null, null, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time the directory was created. + /// The directory for which to set the creation date and time information. + /// Indicates the format of the path parameter(s). + /// A containing the value to set for the creation date and time of . This value is expressed in local time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + [SecurityCritical] + public static void SetCreationTime(string path, DateTime creationTime, bool modifyReparsePoint, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, null, path, creationTime.ToUniversalTime(), null, null, modifyReparsePoint, pathFormat); + } + + + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the directory was created. + /// The directory for which to set the creation date and time information. + /// A containing the value to set for the creation date and time of . This value is expressed in UTC time. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetCreationTimeUtc(string path, DateTime creationTimeUtc, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, null, path, creationTimeUtc, null, null, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the directory was created. + /// The directory for which to set the creation date and time information. + /// A containing the value to set for the creation date and time of . This value is expressed in UTC time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetCreationTimeUtc(string path, DateTime creationTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, null, path, creationTimeUtc, null, null, modifyReparsePoint, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Sets the date and time the directory was created. + /// The transaction. + /// The directory for which to set the creation date and time information. + /// A containing the value to set for the creation date and time of . This value is expressed in local time. + [SecurityCritical] + public static void SetCreationTimeTransacted(KernelTransaction transaction, string path, DateTime creationTime) + { + File.SetFsoDateTimeCore(true, transaction, path, creationTime.ToUniversalTime(), null, null, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the date and time the directory was created. + /// The transaction. + /// The directory for which to set the creation date and time information. + /// A containing the value to set for the creation date and time of . This value is expressed in local time. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetCreationTimeTransacted(KernelTransaction transaction, string path, DateTime creationTime, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, transaction, path, creationTime.ToUniversalTime(), null, null, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time the directory was created. + /// The transaction. + /// The directory for which to set the creation date and time information. + /// A containing the value to set for the creation date and time of . This value is expressed in local time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetCreationTimeTransacted(KernelTransaction transaction, string path, DateTime creationTime, bool modifyReparsePoint, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, transaction, path, creationTime.ToUniversalTime(), null, null, modifyReparsePoint, pathFormat); + } + + + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the directory was created. + /// The transaction. + /// The directory for which to set the creation date and time information. + /// A containing the value to set for the creation date and time of . This value is expressed in UTC time. + [SecurityCritical] + public static void SetCreationTimeUtcTransacted(KernelTransaction transaction, string path, DateTime creationTimeUtc) + { + File.SetFsoDateTimeCore(true, transaction, path, creationTimeUtc, null, null, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the directory was created. + /// The transaction. + /// The directory for which to set the creation date and time information. + /// A containing the value to set for the creation date and time of . This value is expressed in UTC time. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetCreationTimeUtcTransacted(KernelTransaction transaction, string path, DateTime creationTimeUtc, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, transaction, path, creationTimeUtc, null, null, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the directory was created. + /// The transaction. + /// The directory for which to set the creation date and time information. + /// A containing the value to set for the creation date and time of . This value is expressed in UTC time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetCreationTimeUtcTransacted(KernelTransaction transaction, string path, DateTime creationTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, transaction, path, creationTimeUtc, null, null, modifyReparsePoint, pathFormat); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.SetLastAccessTime.cs b/AlphaFS/Filesystem/Directory Class/Directory.SetLastAccessTime.cs new file mode 100644 index 0000000..998ef00 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.SetLastAccessTime.cs @@ -0,0 +1,169 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region .NET + + /// Sets the date and time that the specified directory was last accessed. + /// The file for which to set the access date and time information. + /// A containing the value to set for the last access date and time of . This value is expressed in local time. + [SecurityCritical] + public static void SetLastAccessTime(string path, DateTime lastAccessTime) + { + File.SetFsoDateTimeCore(true, null, path, null, lastAccessTime.ToUniversalTime(), null, false, PathFormat.RelativePath); + } + + + + /// Sets the date and time, in coordinated universal time (UTC), that the specified directory was last accessed. + /// The directory for which to set the access date and time information. + /// A containing the value to set for the last access date and time of . This value is expressed in UTC time. + [SecurityCritical] + public static void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc) + { + File.SetFsoDateTimeCore(true, null, path, null, lastAccessTimeUtc, null, false, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Sets the date and time that the specified directory was last accessed. + /// The file for which to set the access date and time information. + /// A containing the value to set for the last access date and time of . This value is expressed in local time. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastAccessTime(string path, DateTime lastAccessTime, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, null, path, null, lastAccessTime.ToUniversalTime(), null, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time that the specified directory was last accessed. + /// The file for which to set the access date and time information. + /// A containing the value to set for the last access date and time of . This value is expressed in local time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastAccessTime(string path, DateTime lastAccessTime, bool modifyReparsePoint, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, null, path, null, lastAccessTime.ToUniversalTime(), null, modifyReparsePoint, pathFormat); + } + + + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified directory was last accessed. + /// The directory for which to set the access date and time information. + /// A containing the value to set for the last access date and time of . This value is expressed in UTC time. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, null, path, null, lastAccessTimeUtc, null, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified directory was last accessed. + /// The directory for which to set the access date and time information. + /// A containing the value to set for the last access date and time of . This value is expressed in UTC time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, null, path, null, lastAccessTimeUtc, null, modifyReparsePoint, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Sets the date and time that the specified directory was last accessed. + /// The transaction. + /// The directory for which to set the access date and time information. + /// A containing the value to set for the last access date and time of . This value is expressed in local time. + [SecurityCritical] + public static void SetLastAccessTimeTransacted(KernelTransaction transaction, string path, DateTime lastAccessTime) + { + File.SetFsoDateTimeCore(true, transaction, path, null, lastAccessTime.ToUniversalTime(), null, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the date and time that the specified directory was last accessed. + /// The transaction. + /// The directory for which to set the access date and time information. + /// A containing the value to set for the last access date and time of . This value is expressed in local time. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastAccessTimeTransacted(KernelTransaction transaction, string path, DateTime lastAccessTime, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, transaction, path, null, lastAccessTime.ToUniversalTime(), null, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time that the specified directory was last accessed. + /// The transaction. + /// The directory for which to set the access date and time information. + /// A containing the value to set for the last access date and time of . This value is expressed in local time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastAccessTimeTransacted(KernelTransaction transaction, string path, DateTime lastAccessTime, bool modifyReparsePoint, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, transaction, path, null, lastAccessTime.ToUniversalTime(), null, modifyReparsePoint, pathFormat); + } + + + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified directory was last accessed. + /// The transaction. + /// The directory for which to set the access date and time information. + /// A containing the value to set for the last access date and time of . This value is expressed in UTC time. + [SecurityCritical] + public static void SetLastAccessTimeUtcTransacted(KernelTransaction transaction, string path, DateTime lastAccessTimeUtc) + { + File.SetFsoDateTimeCore(true, transaction, path, null, lastAccessTimeUtc, null, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified directory was last accessed. + /// The transaction. + /// The directory for which to set the access date and time information. + /// A containing the value to set for the last access date and time of . This value is expressed in UTC time. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastAccessTimeUtcTransacted(KernelTransaction transaction, string path, DateTime lastAccessTimeUtc, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, transaction, path, null, lastAccessTimeUtc, null, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified directory was last accessed. + /// The transaction. + /// The directory for which to set the access date and time information. + /// A containing the value to set for the last access date and time of . This value is expressed in UTC time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastAccessTimeUtcTransacted(KernelTransaction transaction, string path, DateTime lastAccessTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, transaction, path, null, lastAccessTimeUtc, null, modifyReparsePoint, pathFormat); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.SetLastWriteTime.cs b/AlphaFS/Filesystem/Directory Class/Directory.SetLastWriteTime.cs new file mode 100644 index 0000000..2211921 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.SetLastWriteTime.cs @@ -0,0 +1,167 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + #region .NET + + /// Sets the date and time that the specified directory was last written to. + /// The directory for which to set the date and time information. + /// A containing the value to set for the last write date and time of . This value is expressed in local time. + [SecurityCritical] + public static void SetLastWriteTime(string path, DateTime lastWriteTime) + { + File.SetFsoDateTimeCore(true, null, path, null, null, lastWriteTime.ToUniversalTime(), false, PathFormat.RelativePath); + } + + + + /// Sets the date and time, in coordinated universal time (UTC), that the specified directory was last written to. + /// The directory for which to set the date and time information. + /// A containing the value to set for the last write date and time of . This value is expressed in UTC time. + [SecurityCritical] + public static void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc) + { + File.SetFsoDateTimeCore(true, null, path, null, null, lastWriteTimeUtc, false, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Sets the date and time that the specified directory was last written to. + /// The directory for which to set the date and time information. + /// A containing the value to set for the last write date and time of . This value is expressed in local time. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastWriteTime(string path, DateTime lastWriteTime, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, null, path, null, null, lastWriteTime.ToUniversalTime(), false, pathFormat); + } + + /// [AlphaFS] Sets the date and time that the specified directory was last written to. + /// The directory for which to set the date and time information. + /// A containing the value to set for the last write date and time of . This value is expressed in local time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastWriteTime(string path, DateTime lastWriteTime, bool modifyReparsePoint, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, null, path, null, null, lastWriteTime.ToUniversalTime(), modifyReparsePoint, pathFormat); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified directory was last written to. + /// The directory for which to set the date and time information. + /// A containing the value to set for the last write date and time of . This value is expressed in UTC time. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, null, path, null, null, lastWriteTimeUtc, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified directory was last written to. + /// The directory for which to set the date and time information. + /// A containing the value to set for the last write date and time of . This value is expressed in UTC time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, null, path, null, null, lastWriteTimeUtc, modifyReparsePoint, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Sets the date and time that the specified directory was last written to. + /// The transaction. + /// The directory for which to set the date and time information. + /// A containing the value to set for the last write date and time of . This value is expressed in local time. + [SecurityCritical] + public static void SetLastWriteTimeTransacted(KernelTransaction transaction, string path, DateTime lastWriteTime) + { + File.SetFsoDateTimeCore(true, transaction, path, null, null, lastWriteTime.ToUniversalTime(), false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the date and time that the specified directory was last written to. + /// The transaction. + /// The directory for which to set the date and time information. + /// A containing the value to set for the last write date and time of . This value is expressed in local time. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastWriteTimeTransacted(KernelTransaction transaction, string path, DateTime lastWriteTime, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, transaction, path, null, null, lastWriteTime.ToUniversalTime(), false, pathFormat); + } + + /// [AlphaFS] Sets the date and time that the specified directory was last written to. + /// The transaction. + /// The directory for which to set the date and time information. + /// A containing the value to set for the last write date and time of . This value is expressed in local time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastWriteTimeTransacted(KernelTransaction transaction, string path, DateTime lastWriteTime, bool modifyReparsePoint, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, transaction, path, null, null, lastWriteTime.ToUniversalTime(), modifyReparsePoint, pathFormat); + } + + + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified directory was last written to. + /// The transaction. + /// The directory for which to set the date and time information. + /// A containing the value to set for the last write date and time of . This value is expressed in UTC time. + [SecurityCritical] + public static void SetLastWriteTimeUtcTransacted(KernelTransaction transaction, string path, DateTime lastWriteTimeUtc) + { + File.SetFsoDateTimeCore(true, transaction, path, null, null, lastWriteTimeUtc, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified directory was last written to. + /// The transaction. + /// The directory for which to set the date and time information. + /// A containing the value to set for the last write date and time of . This value is expressed in UTC time. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastWriteTimeUtcTransacted(KernelTransaction transaction, string path, DateTime lastWriteTimeUtc, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, transaction, path, null, null, lastWriteTimeUtc, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified directory was last written to. + /// The transaction. + /// The directory for which to set the date and time information. + /// A containing the value to set for the last write date and time of . This value is expressed in UTC time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastWriteTimeUtcTransacted(KernelTransaction transaction, string path, DateTime lastWriteTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, transaction, path, null, null, lastWriteTimeUtc, modifyReparsePoint, pathFormat); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.SetTimestamps.cs b/AlphaFS/Filesystem/Directory Class/Directory.SetTimestamps.cs new file mode 100644 index 0000000..a3711ca --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.SetTimestamps.cs @@ -0,0 +1,187 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + /// [AlphaFS] Sets all the date and time stamps for the specified directory, at once. + /// The directory for which to set the dates and times information. + /// A containing the value to set for the creation date and time of . This value is expressed in local time. + /// A containing the value to set for the last access date and time of . This value is expressed in local time. + /// A containing the value to set for the last write date and time of . This value is expressed in local time. + [SecurityCritical] + public static void SetTimestamps(string path, DateTime creationTime, DateTime lastAccessTime, DateTime lastWriteTime) + { + File.SetFsoDateTimeCore(true, null, path, creationTime.ToUniversalTime(), lastAccessTime.ToUniversalTime(), lastWriteTime.ToUniversalTime(), false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets all the date and time stamps for the specified directory, at once. + /// The directory for which to set the dates and times information. + /// A containing the value to set for the creation date and time of . This value is expressed in local time. + /// A containing the value to set for the last access date and time of . This value is expressed in local time. + /// A containing the value to set for the last write date and time of . This value is expressed in local time. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetTimestamps(string path, DateTime creationTime, DateTime lastAccessTime, DateTime lastWriteTime, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, null, path, creationTime.ToUniversalTime(), lastAccessTime.ToUniversalTime(), lastWriteTime.ToUniversalTime(), false, pathFormat); + } + + /// [AlphaFS] Sets all the date and time stamps for the specified directory, at once. + /// The directory for which to set the dates and times information. + /// A containing the value to set for the creation date and time of . This value is expressed in local time. + /// A containing the value to set for the last access date and time of . This value is expressed in local time. + /// A containing the value to set for the last write date and time of . This value is expressed in local time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetTimestamps(string path, DateTime creationTime, DateTime lastAccessTime, DateTime lastWriteTime, bool modifyReparsePoint, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, null, path, creationTime.ToUniversalTime(), lastAccessTime.ToUniversalTime(), lastWriteTime.ToUniversalTime(), modifyReparsePoint, pathFormat); + } + + + + /// [AlphaFS] Sets all the date and time stamps, in coordinated universal time (UTC), for the specified directory, at once. + /// The directory for which to set the dates and times information. + /// A containing the value to set for the creation date and time of . This value is expressed in UTC time. + /// A containing the value to set for the last access date and time of . This value is expressed in UTC time. + /// A containing the value to set for the last write date and time of . This value is expressed in UTC time. + [SecurityCritical] + public static void SetTimestampsUtc(string path, DateTime creationTimeUtc, DateTime lastAccessTimeUtc, DateTime lastWriteTimeUtc) + { + File.SetFsoDateTimeCore(true, null, path, creationTimeUtc, lastAccessTimeUtc, lastWriteTimeUtc, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets all the date and time stamps, in coordinated universal time (UTC), for the specified directory, at once. + /// The directory for which to set the dates and times information. + /// A containing the value to set for the creation date and time of . This value is expressed in UTC time. + /// A containing the value to set for the last access date and time of . This value is expressed in UTC time. + /// A containing the value to set for the last write date and time of . This value is expressed in UTC time. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetTimestampsUtc(string path, DateTime creationTimeUtc, DateTime lastAccessTimeUtc, DateTime lastWriteTimeUtc, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, null, path, creationTimeUtc, lastAccessTimeUtc, lastWriteTimeUtc, false, pathFormat); + } + + /// [AlphaFS] Sets all the date and time stamps, in coordinated universal time (UTC), for the specified directory, at once. + /// The directory for which to set the dates and times information. + /// A containing the value to set for the creation date and time of . This value is expressed in UTC time. + /// A containing the value to set for the last access date and time of . This value is expressed in UTC time. + /// A containing the value to set for the last write date and time of . This value is expressed in UTC time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetTimestampsUtc(string path, DateTime creationTimeUtc, DateTime lastAccessTimeUtc, DateTime lastWriteTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, null, path, creationTimeUtc, lastAccessTimeUtc, lastWriteTimeUtc, modifyReparsePoint, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Sets all the date and time stamps for the specified directory, at once. + /// The transaction. + /// The directory for which to set the dates and times information. + /// A containing the value to set for the creation date and time of . This value is expressed in local time. + /// A containing the value to set for the last access date and time of . This value is expressed in local time. + /// A containing the value to set for the last write date and time of . This value is expressed in local time. + [SecurityCritical] + public static void SetTimestampsTransacted(KernelTransaction transaction, string path, DateTime creationTime, DateTime lastAccessTime, DateTime lastWriteTime) + { + File.SetFsoDateTimeCore(true, transaction, path, creationTime.ToUniversalTime(), lastAccessTime.ToUniversalTime(), lastWriteTime.ToUniversalTime(), false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets all the date and time stamps for the specified directory, at once. + /// The transaction. + /// The directory for which to set the dates and times information. + /// A containing the value to set for the creation date and time of . This value is expressed in local time. + /// A containing the value to set for the last access date and time of . This value is expressed in local time. + /// A containing the value to set for the last write date and time of . This value is expressed in local time. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetTimestampsTransacted(KernelTransaction transaction, string path, DateTime creationTime, DateTime lastAccessTime, DateTime lastWriteTime, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, transaction, path, creationTime.ToUniversalTime(), lastAccessTime.ToUniversalTime(), lastWriteTime.ToUniversalTime(), false, pathFormat); + } + + /// [AlphaFS] Sets all the date and time stamps for the specified directory, at once. + /// The transaction. + /// The directory for which to set the dates and times information. + /// A containing the value to set for the creation date and time of . This value is expressed in local time. + /// A containing the value to set for the last access date and time of . This value is expressed in local time. + /// A containing the value to set for the last write date and time of . This value is expressed in local time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetTimestampsTransacted(KernelTransaction transaction, string path, DateTime creationTime, DateTime lastAccessTime, DateTime lastWriteTime, bool modifyReparsePoint, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, transaction, path, creationTime.ToUniversalTime(), lastAccessTime.ToUniversalTime(), lastWriteTime.ToUniversalTime(), modifyReparsePoint, pathFormat); + } + + + + /// [AlphaFS] Sets all the date and time stamps, in coordinated universal time (UTC), for the specified directory, at once. + /// The transaction. + /// The directory for which to set the dates and times information. + /// A containing the value to set for the creation date and time of . This value is expressed in UTC time. + /// A containing the value to set for the last access date and time of . This value is expressed in UTC time. + /// A containing the value to set for the last write date and time of . This value is expressed in UTC time. + [SecurityCritical] + public static void SetTimestampsUtcTransacted(KernelTransaction transaction, string path, DateTime creationTimeUtc, DateTime lastAccessTimeUtc, DateTime lastWriteTimeUtc) + { + File.SetFsoDateTimeCore(true, transaction, path, creationTimeUtc, lastAccessTimeUtc, lastWriteTimeUtc, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets all the date and time stamps, in coordinated universal time (UTC), for the specified directory, at once. + /// The transaction. + /// The directory for which to set the dates and times information. + /// A containing the value to set for the creation date and time of . This value is expressed in UTC time. + /// A containing the value to set for the last access date and time of . This value is expressed in UTC time. + /// A containing the value to set for the last write date and time of . This value is expressed in UTC time. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetTimestampsUtcTransacted(KernelTransaction transaction, string path, DateTime creationTimeUtc, DateTime lastAccessTimeUtc, DateTime lastWriteTimeUtc, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, transaction, path, creationTimeUtc, lastAccessTimeUtc, lastWriteTimeUtc, false, pathFormat); + } + + /// [AlphaFS] Sets all the date and time stamps, in coordinated universal time (UTC), for the specified directory, at once. + /// The transaction. + /// The directory for which to set the dates and times information. + /// A containing the value to set for the creation date and time of . This value is expressed in UTC time. + /// A containing the value to set for the last access date and time of . This value is expressed in UTC time. + /// A containing the value to set for the last write date and time of . This value is expressed in UTC time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetTimestampsUtcTransacted(KernelTransaction transaction, string path, DateTime creationTimeUtc, DateTime lastAccessTimeUtc, DateTime lastWriteTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + File.SetFsoDateTimeCore(true, transaction, path, creationTimeUtc, lastAccessTimeUtc, lastWriteTimeUtc, modifyReparsePoint, pathFormat); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.TransferTimestamps.cs b/AlphaFS/Filesystem/Directory Class/Directory.TransferTimestamps.cs new file mode 100644 index 0000000..069f9c9 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.TransferTimestamps.cs @@ -0,0 +1,76 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class Directory + { + /// [AlphaFS] Transfers the date and time stamps for the specified directories. + /// This method uses BackupSemantics flag to get Timestamp changed for directories. + /// The source directory to get the date and time stamps from. + /// The destination directory to set the date and time stamps. + [SecurityCritical] + public static void TransferTimestamps(string sourcePath, string destinationPath) + { + File.TransferTimestampsCore(true, null, sourcePath, destinationPath, PathFormat.RelativePath); + } + + /// [AlphaFS] Transfers the date and time stamps for the specified directories. + /// This method uses BackupSemantics flag to get Timestamp changed for directories. + /// The source directory to get the date and time stamps from. + /// The destination directory to set the date and time stamps. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void TransferTimestamps(string sourcePath, string destinationPath, PathFormat pathFormat) + { + File.TransferTimestampsCore(true, null, sourcePath, destinationPath, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Transfers the date and time stamps for the specified directories. + /// This method uses BackupSemantics flag to get Timestamp changed for directories. + /// The transaction. + /// The source directory to get the date and time stamps from. + /// The destination directory to set the date and time stamps. + [SecurityCritical] + public static void TransferTimestampsTransacted(KernelTransaction transaction, string sourcePath, string destinationPath) + { + File.TransferTimestampsCore(true, transaction, sourcePath, destinationPath, PathFormat.RelativePath); + } + + /// [AlphaFS] Transfers the date and time stamps for the specified directories. + /// This method uses BackupSemantics flag to get Timestamp changed for directories. + /// The transaction. + /// The source directory to get the date and time stamps from. + /// The destination directory to set the date and time stamps. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void TransferTimestampsTransacted(KernelTransaction transaction, string sourcePath, string destinationPath, PathFormat pathFormat) + { + File.TransferTimestampsCore(true, transaction, sourcePath, destinationPath, pathFormat); + } + + #endregion // Transactional + } +} diff --git a/AlphaFS/Filesystem/Directory Class/Directory.cs b/AlphaFS/Filesystem/Directory Class/Directory.cs new file mode 100644 index 0000000..70e6604 --- /dev/null +++ b/AlphaFS/Filesystem/Directory Class/Directory.cs @@ -0,0 +1,31 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + /// Exposes static methods for creating, moving, and enumerating through directories and subdirectories. + /// This class cannot be inherited. + /// + public static partial class Directory + { + // This file only exists for the documentation. + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Compression.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Compression.cs new file mode 100644 index 0000000..0070b8d --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Compression.cs @@ -0,0 +1,128 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region AlphaFS + + #region Compress + + /// [AlphaFS] Compresses a directory using NTFS compression. + /// This will only compress the root items (non recursive). + /// + /// + /// + /// + /// + /// + [SecurityCritical] + public void Compress() + { + Directory.CompressDecompressCore(Transaction, LongFullName, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, true, PathFormat.LongFullPath); + } + + /// [AlphaFS] Compresses a directory using NTFS compression. + /// + /// + /// + /// + /// + /// + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public void Compress(DirectoryEnumerationOptions options) + { + Directory.CompressDecompressCore(Transaction, LongFullName, Path.WildcardStarMatchAll, options, true, PathFormat.LongFullPath); + } + + #endregion // Compress + + #region Decompress + + /// [AlphaFS] Decompresses an NTFS compressed directory. + /// This will only decompress the root items (non recursive). + /// + /// + /// + /// + /// + /// + [SecurityCritical] + public void Decompress() + { + Directory.CompressDecompressCore(Transaction, LongFullName, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, false, PathFormat.LongFullPath); + } + + /// [AlphaFS] Decompresses an NTFS compressed directory. + /// + /// + /// + /// + /// + /// + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public void Decompress(DirectoryEnumerationOptions options) + { + Directory.CompressDecompressCore(Transaction, LongFullName, Path.WildcardStarMatchAll, options, false, PathFormat.LongFullPath); + } + + #endregion // Decompress + + #region DisableCompression + + /// [AlphaFS] Disables compression of the specified directory and the files in it. + /// + /// This method disables the directory-compression attribute. It will not decompress the current contents of the directory. + /// However, newly created files and directories will be uncompressed. + /// + [SecurityCritical] + public void DisableCompression() + { + Device.ToggleCompressionCore(true, Transaction, LongFullName, false, PathFormat.LongFullPath); + } + + #endregion // DisableCompression + + #region EnableCompression + + /// [AlphaFS] Enables compression of the specified directory and the files in it. + /// + /// This method enables the directory-compression attribute. It will not compress the current contents of the directory. + /// However, newly created files and directories will be compressed. + /// + [SecurityCritical] + public void EnableCompression() + { + Device.ToggleCompressionCore(true, Transaction, LongFullName, true, PathFormat.LongFullPath); + } + + #endregion // EnableCompression + + #endregion // AlphaFS + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.CopyToMoveTo.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.CopyToMoveTo.cs new file mode 100644 index 0000000..f58feda --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.CopyToMoveTo.cs @@ -0,0 +1,459 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region CopyTo + + // .NET: Directory class does not contain the Copy() method. + // Mimic .NET File.Copy() methods. + + /// [AlphaFS] Copies a instance and its contents to a new path. + /// + /// Use this method to prevent overwriting of an existing directory by default. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A new instance if the directory was completely copied. + /// + /// + /// + /// + /// + /// + /// The destination directory path. + [SecurityCritical] + public DirectoryInfo CopyTo(string destinationPath) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, CopyOptions.FailIfExists, null, null, null, out destinationPathLp, PathFormat.RelativePath); + return new DirectoryInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + /// [AlphaFS] Copies a instance and its contents to a new path. + /// + /// Use this method to prevent overwriting of an existing directory by default. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A new instance if the directory was completely copied. + /// + /// + /// + /// + /// + /// + /// The destination directory path. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public DirectoryInfo CopyTo(string destinationPath, PathFormat pathFormat) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, CopyOptions.FailIfExists, null, null, null, out destinationPathLp, pathFormat); + return new DirectoryInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + + + /// [AlphaFS] Copies an existing directory to a new directory, allowing the overwriting of an existing directory, can be specified. + /// + /// Option is recommended for very large file transfers. + /// Use this method to allow or prevent overwriting of an existing directory. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// Returns a new directory, or an overwrite of an existing directory if is not . + /// If the directory exists and contains , an is thrown. + /// + /// + /// + /// + /// + /// + /// + /// The destination directory path. + /// that specify how the directory is to be copied. This parameter can be . + [SecurityCritical] + public DirectoryInfo CopyTo(string destinationPath, CopyOptions copyOptions) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, copyOptions, null, null, null, out destinationPathLp, PathFormat.RelativePath); + return new DirectoryInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + /// [AlphaFS] Copies an existing directory to a new directory, allowing the overwriting of an existing directory, can be specified. + /// + /// Option is recommended for very large file transfers. + /// Use this method to allow or prevent overwriting of an existing directory. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// Returns a new directory, or an overwrite of an existing directory if is not . + /// If the directory exists and contains , an is thrown. + /// + /// + /// + /// + /// + /// + /// + /// The destination directory path. + /// that specify how the directory is to be copied. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public DirectoryInfo CopyTo(string destinationPath, CopyOptions copyOptions, PathFormat pathFormat) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, copyOptions, null, null, null, out destinationPathLp, pathFormat); + return new DirectoryInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + + + /// [AlphaFS] Copies an existing directory to a new directory, allowing the overwriting of an existing directory, can be specified. + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// Option is recommended for very large file transfers. + /// Use this method to allow or prevent overwriting of an existing directory. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The destination directory path. + /// that specify how the directory is to be copied. This parameter can be . + /// A callback function that is called each time another portion of the directory has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + [SecurityCritical] + public CopyMoveResult CopyTo(string destinationPath, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData) + { + string destinationPathLp; + var cmr = CopyToMoveToCore(destinationPath, copyOptions, null, progressHandler, userProgressData, out destinationPathLp, PathFormat.RelativePath); + CopyToMoveToCoreRefresh(destinationPath, destinationPathLp); + return cmr; + } + + /// [AlphaFS] Copies an existing directory to a new directory, allowing the overwriting of an existing directory, can be specified. + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// Option is recommended for very large file transfers. + /// Use this method to allow or prevent overwriting of an existing directory. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// The destination directory path. + /// that specify how the directory is to be copied. This parameter can be . + /// A callback function that is called each time another portion of the directory has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public CopyMoveResult CopyTo(string destinationPath, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat) + { + string destinationPathLp; + var cmr = CopyToMoveToCore(destinationPath, copyOptions, null, progressHandler, userProgressData, out destinationPathLp, pathFormat); + CopyToMoveToCoreRefresh(destinationPath, destinationPathLp); + return cmr; + } + + #endregion // CopyTo + + + #region MoveTo + + #region .NET + + /// Moves a instance and its contents to a new path. + /// + /// Use this method to prevent overwriting of an existing directory by default. + /// This method does not work across disk volumes. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Move action. + /// + /// + /// + /// + /// + /// + /// + /// The name and path to which to move this directory. + /// The destination cannot be another disk volume or a directory with the identical name. + /// It can be an existing directory to which you want to add this directory as a subdirectory. + /// + [SecurityCritical] + public CopyMoveResult MoveTo(string destinationPath) + { + string destinationPathLp; + var copyMoveResult = CopyToMoveToCore(destinationPath, null, MoveOptions.None, null, null, out destinationPathLp, PathFormat.RelativePath); + CopyToMoveToCoreRefresh(destinationPath, destinationPathLp); + + return copyMoveResult; + } + + #endregion // .NET + + + #region AlphaFS + + /// Moves a instance and its contents to a new path. + /// + /// Use this method to prevent overwriting of an existing directory by default. + /// This method does not work across disk volumes. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A new instance if the directory was completely moved. + /// + /// + /// + /// + /// + /// + /// + /// The name and path to which to move this directory. + /// The destination cannot be another disk volume or a directory with the identical name. + /// It can be an existing directory to which you want to add this directory as a subdirectory. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public DirectoryInfo MoveTo(string destinationPath, PathFormat pathFormat) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, null, MoveOptions.None, null, null, out destinationPathLp, pathFormat); + return new DirectoryInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + + + /// [AlphaFS] Moves a instance and its contents to a new path, can be specified. + /// + /// Use this method to allow or prevent overwriting of an existing directory. + /// This method does not work across disk volumes unless contains . + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A new instance if the directory was completely moved. + /// + /// + /// + /// + /// + /// + /// + /// The name and path to which to move this directory. + /// The destination cannot be another disk volume unless contains , or a directory with the identical name. + /// It can be an existing directory to which you want to add this directory as a subdirectory. + /// + /// that specify how the directory is to be moved. This parameter can be . + [SecurityCritical] + public DirectoryInfo MoveTo(string destinationPath, MoveOptions moveOptions) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, null, moveOptions, null, null, out destinationPathLp, PathFormat.RelativePath); + return new DirectoryInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + /// [AlphaFS] Moves a instance and its contents to a new path, can be specified. + /// + /// Use this method to allow or prevent overwriting of an existing directory. + /// This method does not work across disk volumes unless contains . + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A new instance if the directory was completely moved. + /// + /// + /// + /// + /// + /// + /// + /// The name and path to which to move this directory. + /// The destination cannot be another disk volume unless contains , or a directory with the identical name. + /// It can be an existing directory to which you want to add this directory as a subdirectory. + /// + /// that specify how the directory is to be moved. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public DirectoryInfo MoveTo(string destinationPath, MoveOptions moveOptions, PathFormat pathFormat) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, null, moveOptions, null, null, out destinationPathLp, pathFormat); + return new DirectoryInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + + + /// [AlphaFS] Moves a instance and its contents to a new path, can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// Use this method to allow or prevent overwriting of an existing directory. + /// This method does not work across disk volumes unless contains . + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Move action. + /// + /// + /// + /// + /// + /// + /// + /// The name and path to which to move this directory. + /// The destination cannot be another disk volume unless contains , or a directory with the identical name. + /// It can be an existing directory to which you want to add this directory as a subdirectory. + /// + /// that specify how the directory is to be moved. This parameter can be . + /// A callback function that is called each time another portion of the directory has been moved. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + [SecurityCritical] + public CopyMoveResult MoveTo(string destinationPath, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData) + { + string destinationPathLp; + var cmr = CopyToMoveToCore(destinationPath, null, moveOptions, progressHandler, userProgressData, out destinationPathLp, PathFormat.RelativePath); + CopyToMoveToCoreRefresh(destinationPath, destinationPathLp); + return cmr; + } + + + + /// [AlphaFS] Moves a instance and its contents to a new path, can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// Use this method to allow or prevent overwriting of an existing directory. + /// This method does not work across disk volumes unless contains . + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Move action. + /// + /// + /// + /// + /// + /// + /// + /// The name and path to which to move this directory. + /// The destination cannot be another disk volume unless contains , or a directory with the identical name. + /// It can be an existing directory to which you want to add this directory as a subdirectory. + /// + /// that specify how the directory is to be moved. This parameter can be . + /// A callback function that is called each time another portion of the directory has been moved. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public CopyMoveResult MoveTo(string destinationPath, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat) + { + string destinationPathLp; + var cmr = CopyToMoveToCore(destinationPath, null, moveOptions, progressHandler, userProgressData, out destinationPathLp, pathFormat); + CopyToMoveToCoreRefresh(destinationPath, destinationPathLp); + return cmr; + } + + #endregion // AlphaFS + + #endregion // MoveTo + + + #region Internal Methods + + /// Copy/move a Non-/Transacted file or directory including its children to a new location, + /// or can be specified, and the possibility of notifying the application of its progress through a callback function. + /// + /// Option is recommended for very large file transfers. + /// You cannot use the Move method to overwrite an existing file, unless contains . + /// Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an IOException. + /// + /// + /// A class with details of the Copy or Move action. + /// + /// + /// + /// + /// + /// + /// The destination directory path. + /// that specify how the file is to be copied. This parameter can be . + /// that specify how the file is to be moved. This parameter can be . + /// A callback function that is called each time another portion of the file has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// Returns the retrieved long full path. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + private CopyMoveResult CopyToMoveToCore(string destinationPath, CopyOptions? copyOptions, MoveOptions? moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, out string longFullPath, PathFormat pathFormat) + { + var destinationPathLp = Path.GetExtendedLengthPathCore(null, destinationPath, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + longFullPath = destinationPathLp; + + // Returns false when CopyMoveProgressResult is PROGRESS_CANCEL or PROGRESS_STOP. + return Directory.CopyMoveCore(Transaction, LongFullName, destinationPathLp, copyOptions, moveOptions, progressHandler, userProgressData, null, PathFormat.LongFullPath); + } + + + private void CopyToMoveToCoreRefresh(string destinationPath, string destinationPathLp) + { + LongFullName = destinationPathLp; + FullPath = Path.GetRegularPathCore(destinationPathLp, GetFullPathOptions.None, false); + + OriginalPath = destinationPath; + DisplayPath = Path.GetRegularPathCore(OriginalPath, GetFullPathOptions.None, false); + + // Flush any cached information about the directory. + Reset(); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.CountFileSystemObjects.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.CountFileSystemObjects.cs new file mode 100644 index 0000000..71b69ab --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.CountFileSystemObjects.cs @@ -0,0 +1,70 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Linq; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region AlphaFS + + /// [AlphaFS] Counts file system objects: files, folders or both) in a given directory. + /// The counted number of file system objects. + /// + /// + /// + /// + /// + /// + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public long CountFileSystemObjects(DirectoryEnumerationOptions options) + { + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, Path.WildcardStarMatchAll, options, PathFormat.LongFullPath).Count(); + } + + /// [AlphaFS] Counts file system objects: files, folders or both) in a given directory. + /// The counted number of file system objects. + /// + /// + /// + /// + /// + /// + /// + /// The search string to match against the names of directories in path. + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public long CountFileSystemObjects(string searchPattern, DirectoryEnumerationOptions options) + { + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, searchPattern, options, PathFormat.LongFullPath).Count(); + } + + #endregion // AlphaFS + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Create.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Create.cs new file mode 100644 index 0000000..dd01e8b --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Create.cs @@ -0,0 +1,81 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.Security; +using System.Security.AccessControl; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region .NET + + /// Creates a directory. + /// If the directory already exists, this method does nothing. + + [SecurityCritical] + public void Create() + { + Directory.CreateDirectoryCore(Transaction, LongFullName, null, null, false, PathFormat.LongFullPath); + } + + /// Creates a directory using a object. + /// The access control to apply to the directory. + /// If the directory already exists, this method does nothing. + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public void Create(DirectorySecurity directorySecurity) + { + Directory.CreateDirectoryCore(Transaction, LongFullName, null, directorySecurity, false, PathFormat.LongFullPath); + } + + #endregion // .NET + + #region AlphaFS + + /// [AlphaFS] Creates a directory using a object. + /// When compresses the directory. + /// If the directory already exists, this method does nothing. + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public void Create(bool compress) + { + Directory.CreateDirectoryCore(Transaction, LongFullName, null, null, compress, PathFormat.LongFullPath); + } + + /// [AlphaFS] Creates a directory using a object. + /// The access control to apply to the directory. + /// When compresses the directory. + /// If the directory already exists, this method does nothing. + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public void Create(DirectorySecurity directorySecurity, bool compress) + { + Directory.CreateDirectoryCore(Transaction, LongFullName, null, directorySecurity, compress, PathFormat.LongFullPath); + } + + #endregion // AlphaFS + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.CreateSubdirectory.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.CreateSubdirectory.cs new file mode 100644 index 0000000..34f6ea6 --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.CreateSubdirectory.cs @@ -0,0 +1,165 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; +using System.Security.AccessControl; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region .NET + + /// Creates a subdirectory or subdirectories on the specified path. The specified path can be relative to this instance of the class. + /// The specified path. This cannot be a different disk volume. + /// The last directory specified in . + /// + /// Any and all directories specified in path are created, unless some part of path is invalid. + /// The path parameter specifies a directory path, not a file path. + /// If the subdirectory already exists, this method does nothing. + /// + + [SecurityCritical] + public DirectoryInfo CreateSubdirectory(string path) + { + return CreateSubdirectoryCore(path, null, null, false); + } + + /// Creates a subdirectory or subdirectories on the specified path. The specified path can be relative to this instance of the class. + /// The specified path. This cannot be a different disk volume. + /// The security to apply. + /// The last directory specified in . + /// + /// Any and all directories specified in path are created, unless some part of path is invalid. + /// The path parameter specifies a directory path, not a file path. + /// If the subdirectory already exists, this method does nothing. + /// + + [SecurityCritical] + public DirectoryInfo CreateSubdirectory(string path, DirectorySecurity directorySecurity) + { + return CreateSubdirectoryCore(path, null, directorySecurity, false); + } + + #endregion // .NET + + #region AlphaFS + + /// [AlphaFS] Creates a subdirectory or subdirectories on the specified path. The specified path can be relative to this instance of the class. + /// The last directory specified in . + /// + /// Any and all directories specified in path are created, unless some part of path is invalid. + /// The path parameter specifies a directory path, not a file path. + /// If the subdirectory already exists, this method does nothing. + /// + /// The specified path. This cannot be a different disk volume. + /// When compresses the directory. + [SecurityCritical] + public DirectoryInfo CreateSubdirectory(string path, bool compress) + { + return CreateSubdirectoryCore(path, null, null, compress); + } + + /// [AlphaFS] Creates a subdirectory or subdirectories on the specified path. The specified path can be relative to this instance of the class. + /// The specified path. This cannot be a different disk volume. + /// The path of the directory to use as a template when creating the new directory. + /// When compresses the directory. + /// The last directory specified in . + /// + /// Any and all directories specified in path are created, unless some part of path is invalid. + /// The path parameter specifies a directory path, not a file path. + /// If the subdirectory already exists, this method does nothing. + /// + + [SecurityCritical] + public DirectoryInfo CreateSubdirectory(string path, string templatePath, bool compress) + { + return CreateSubdirectoryCore(path, templatePath, null, compress); + } + + + /// [AlphaFS] Creates a subdirectory or subdirectories on the specified path. The specified path can be relative to this instance of the class. + /// The specified path. This cannot be a different disk volume. + /// The security to apply. + /// When compresses the directory. + /// The last directory specified in . + /// + /// Any and all directories specified in path are created, unless some part of path is invalid. + /// The path parameter specifies a directory path, not a file path. + /// If the subdirectory already exists, this method does nothing. + /// + + [SecurityCritical] + public DirectoryInfo CreateSubdirectory(string path, DirectorySecurity directorySecurity, bool compress) + { + return CreateSubdirectoryCore(path, null, directorySecurity, compress); + } + + /// [AlphaFS] Creates a subdirectory or subdirectories on the specified path. The specified path can be relative to this instance of the class. + /// The path of the directory to use as a template when creating the new directory. + /// The specified path. This cannot be a different disk volume. + /// When compresses the directory. + /// The security to apply. + /// The last directory specified in . + /// + /// Any and all directories specified in path are created, unless some part of path is invalid. + /// The path parameter specifies a directory path, not a file path. + /// If the subdirectory already exists, this method does nothing. + /// + + [SecurityCritical] + public DirectoryInfo CreateSubdirectory(string path, string templatePath, DirectorySecurity directorySecurity, bool compress) + { + return CreateSubdirectoryCore(path, templatePath, directorySecurity, compress); + } + + #endregion // AlphaFS + + #region Internal Methods + + /// Creates a subdirectory or subdirectories on the specified path. The specified path can be relative to this instance of the DirectoryInfo class. + /// The last directory specified in path as an object. + /// + /// Any and all directories specified in path are created, unless some part of path is invalid. + /// The path parameter specifies a directory path, not a file path. + /// If the subdirectory already exists, this method does nothing. + /// + /// The specified path. This cannot be a different disk volume or Universal Naming Convention (UNC) name. + /// The path of the directory to use as a template when creating the new directory. + /// The security to apply. + /// When compresses the directory. + [SecurityCritical] + private DirectoryInfo CreateSubdirectoryCore(string path, string templatePath, DirectorySecurity directorySecurity, bool compress) + { + string pathLp = Path.CombineCore(false, LongFullName, path); + string templatePathLp = templatePath == null ? null : + Path.GetExtendedLengthPathCore(Transaction, templatePath, PathFormat.RelativePath, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator); + + if (string.Compare(LongFullName, 0, pathLp, 0, LongFullName.Length, StringComparison.OrdinalIgnoreCase) != 0) + throw new ArgumentException(Resources.Invalid_Subpath, pathLp); + + return Directory.CreateDirectoryCore(Transaction, pathLp, templatePathLp, directorySecurity, compress, PathFormat.LongFullPath); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Decrypt.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Decrypt.cs new file mode 100644 index 0000000..4e453e3 --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Decrypt.cs @@ -0,0 +1,28 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Delete.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Delete.cs new file mode 100644 index 0000000..b28347e --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Delete.cs @@ -0,0 +1,88 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region .NET + + /// Deletes this if it is empty. + /// + /// + /// + /// + /// + /// + [SecurityCritical] + public override void Delete() + { + Directory.DeleteDirectoryCore(null, Transaction, LongFullName, false, false, true, false, PathFormat.LongFullPath); + } + + /// Deletes this instance of a , specifying whether to delete subdirectories and files. + /// + /// If the has no files or subdirectories, this method deletes the even if recursive is . + /// Attempting to delete a that is not empty when recursive is false throws an . + /// + /// + /// + /// + /// + /// + /// + /// to delete this directory, its subdirectories, and all files; otherwise, . + [SecurityCritical] + public void Delete(bool recursive) + { + Directory.DeleteDirectoryCore(null, Transaction, LongFullName, recursive, false, !recursive, false, PathFormat.LongFullPath); + } + + #endregion // .NET + + #region AlphaFS + + /// [AlphaFS] Deletes this instance of a , specifying whether to delete files and subdirectories. + /// + /// If the has no files or subdirectories, this method deletes the even if recursive is . + /// Attempting to delete a that is not empty when recursive is false throws an . + /// + /// + /// + /// + /// + /// + /// + /// to delete this directory, its subdirectories, and all files; otherwise, . + /// ignores read only attribute of files and directories. + [SecurityCritical] + public void Delete(bool recursive, bool ignoreReadOnly) + { + Directory.DeleteDirectoryCore(null, Transaction, LongFullName, recursive, ignoreReadOnly, !recursive, false, PathFormat.LongFullPath); + } + + #endregion // AlphaFS + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.DeleteEmptySubdirectories.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.DeleteEmptySubdirectories.cs new file mode 100644 index 0000000..1c26fed --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.DeleteEmptySubdirectories.cs @@ -0,0 +1,57 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region AlphaFS + + /// [AlphaFS] Deletes empty subdirectories from the instance. + [SecurityCritical] + public void DeleteEmptySubdirectories() + { + Directory.DeleteEmptySubdirectoriesCore(null, Transaction, LongFullName, false, false, true, PathFormat.LongFullPath); + } + + /// [AlphaFS] Deletes empty subdirectories from the instance. + /// deletes empty subdirectories from this directory and its subdirectories. + [SecurityCritical] + public void DeleteEmptySubdirectories(bool recursive) + { + Directory.DeleteEmptySubdirectoriesCore(null, Transaction, LongFullName, recursive, false, true, PathFormat.LongFullPath); + } + + /// [AlphaFS] Deletes empty subdirectories from the instance. + /// deletes empty subdirectories from this directory and its subdirectories. + /// overrides read only of empty directories. + [SecurityCritical] + public void DeleteEmptySubdirectories(bool recursive, bool ignoreReadOnly) + { + Directory.DeleteEmptySubdirectoriesCore(null, Transaction, LongFullName, recursive, ignoreReadOnly, true, PathFormat.LongFullPath); + } + + #endregion // AlphaFS + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Encryption.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Encryption.cs new file mode 100644 index 0000000..16ff27b --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Encryption.cs @@ -0,0 +1,122 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region AlphaFS + + #region Decrypt + + /// [AlphaFS] Decrypts a directory that was encrypted by the current account using the Encrypt method. + /// + /// + /// + /// + /// + /// + [SecurityCritical] + public void Decrypt() + { + Directory.EncryptDecryptDirectoryCore(LongFullName, false, false, PathFormat.LongFullPath); + } + + /// [AlphaFS] Decrypts a directory that was encrypted by the current account using the Encrypt method. + /// + /// + /// + /// + /// + /// + /// to decrypt the directory recursively. only decrypt files and directories in the root of the directory. + [SecurityCritical] + public void Decrypt(bool recursive) + { + Directory.EncryptDecryptDirectoryCore(LongFullName, false, recursive, PathFormat.LongFullPath); + } + + #endregion // Decrypt + + #region DisableEncryption + + /// [AlphaFS] Disables encryption of the specified directory and the files in it. It does not affect encryption of subdirectories below the indicated directory. + /// on success, otherwise. + /// This method will create/change the file "Desktop.ini" and wil set Encryption value: "Disable=0" + [SecurityCritical] + public void DisableEncryption() + { + Directory.EnableDisableEncryptionCore(LongFullName, false, PathFormat.LongFullPath); + } + + #endregion // DisableEncryption + + #region EnableEncryption + + /// [AlphaFS] Enables encryption of the specified directory and the files in it. It does not affect encryption of subdirectories below the indicated directory. + /// on success, otherwise. + /// This method will create/change the file "Desktop.ini" and wil set Encryption value: "Disable=1" + [SecurityCritical] + public void EnableEncryption() + { + Directory.EnableDisableEncryptionCore(LongFullName, true, PathFormat.LongFullPath); + } + + #endregion // EnableEncryption + + #region Encrypt + + /// [AlphaFS] Encrypts a directory so that only the account used to encrypt the directory can decrypt it. + /// + /// + /// + /// + /// + /// + [SecurityCritical] + public void Encrypt() + { + Directory.EncryptDecryptDirectoryCore(LongFullName, true, false, PathFormat.LongFullPath); + } + + /// [AlphaFS] Decrypts a directory that was encrypted by the current account using the Encrypt method. + /// + /// + /// + /// + /// + /// + /// to encrypt the directory recursively. only encrypt files and directories in the root of the directory. + [SecurityCritical] + public void Encrypt(bool recursive) + { + Directory.EncryptDecryptDirectoryCore(LongFullName, true, recursive, PathFormat.LongFullPath); + } + + #endregion // Encrypt + + #endregion // AlphaFS + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.EnumerateAlternateDataStreams.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.EnumerateAlternateDataStreams.cs new file mode 100644 index 0000000..4b91dd7 --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.EnumerateAlternateDataStreams.cs @@ -0,0 +1,37 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Collections.Generic; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + /// [AlphaFS] Returns an enumerable collection of instances for the directory. + /// An enumerable collection of instances for the directory. + [SecurityCritical] + public IEnumerable EnumerateAlternateDataStreams() + { + return File.EnumerateAlternateDataStreamsCore(Transaction, LongFullName, PathFormat.LongFullPath); + } + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.EnumerateDirectories.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.EnumerateDirectories.cs new file mode 100644 index 0000000..05b5cee --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.EnumerateDirectories.cs @@ -0,0 +1,138 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region .NET + + /// Returns an enumerable collection of directory information in the current directory. + /// An enumerable collection of directories in the current directory. + /// + /// + /// + /// + /// + /// + [SecurityCritical] + public IEnumerable EnumerateDirectories() + { + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Folders, PathFormat.LongFullPath); + } + + /// Returns an enumerable collection of directory information that matches a specified search pattern. + /// An enumerable collection of directories that matches . + /// + /// + /// + /// + /// + /// + /// + /// The search string to match against the names of directories in path. + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SecurityCritical] + public IEnumerable EnumerateDirectories(string searchPattern) + { + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, searchPattern, DirectoryEnumerationOptions.Folders, PathFormat.LongFullPath); + } + + /// Returns an enumerable collection of directory information that matches a specified search pattern and search subdirectory option. + /// An enumerable collection of directories that matches and . + /// + /// + /// + /// + /// + /// + /// + /// The search string to match against the names of directories in path. + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + [SecurityCritical] + public IEnumerable EnumerateDirectories(string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.Folders | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, searchPattern, options, PathFormat.LongFullPath); + } + + #endregion // .NET + + + + /// [AlphaFS] Returns an enumerable collection of directory information in the current directory. + /// An enumerable collection of directories in the current directory. + /// + /// + /// + /// + /// + /// + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public IEnumerable EnumerateDirectories(DirectoryEnumerationOptions options) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Files; + options |= DirectoryEnumerationOptions.Folders; + + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, Path.WildcardStarMatchAll, options, PathFormat.LongFullPath); + } + + /// Returns an enumerable collection of directory information that matches a specified search pattern. + /// An enumerable collection of directories that matches . + /// + /// + /// + /// + /// + /// + /// + /// The search string to match against the names of directories in path. + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public IEnumerable EnumerateDirectories(string searchPattern, DirectoryEnumerationOptions options) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Files; + options |= DirectoryEnumerationOptions.Folders; + + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, searchPattern, DirectoryEnumerationOptions.Folders | options, PathFormat.LongFullPath); + } + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.EnumerateFileSystemInfos.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.EnumerateFileSystemInfos.cs new file mode 100644 index 0000000..11bc623 --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.EnumerateFileSystemInfos.cs @@ -0,0 +1,136 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region .NET + + /// Returns an enumerable collection of file system information in the current directory. + /// An enumerable collection of file system information in the current directory. + /// + /// + /// + /// + /// + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public IEnumerable EnumerateFileSystemInfos() + { + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath); + } + + /// Returns an enumerable collection of file system information that matches a specified search pattern. + /// An enumerable collection of file system information objects that matches . + /// + /// + /// + /// + /// + /// + /// + /// The search string to match against the names of directories in path. + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public IEnumerable EnumerateFileSystemInfos(string searchPattern) + { + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, searchPattern, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath); + } + + /// Returns an enumerable collection of file system information that matches a specified search pattern and search subdirectory option. + /// An enumerable collection of file system information objects that matches and . + /// + /// + /// + /// + /// + /// + /// + /// The search string to match against the names of directories in path. + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public IEnumerable EnumerateFileSystemInfos(string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.FilesAndFolders | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, searchPattern, options, PathFormat.LongFullPath); + } + + #endregion // .NET + + + + /// [AlphaFS] Returns an enumerable collection of file system information in the current directory. + /// An enumerable collection of file system information in the current directory. + /// + /// + /// + /// + /// + /// + /// flags that specify how the directory is to be enumerated. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public IEnumerable EnumerateFileSystemInfos(DirectoryEnumerationOptions options) + { + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, Path.WildcardStarMatchAll, options, PathFormat.LongFullPath); + } + + /// [AlphaFS] Returns an enumerable collection of file system information that matches a specified search pattern. + /// An enumerable collection of file system information objects that matches . + /// + /// + /// + /// + /// + /// + /// + /// The search string to match against the names of directories in path. + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public IEnumerable EnumerateFileSystemInfos(string searchPattern, DirectoryEnumerationOptions options) + { + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, searchPattern, options, PathFormat.LongFullPath); + } + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.EnumerateFiles.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.EnumerateFiles.cs new file mode 100644 index 0000000..710ee06 --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.EnumerateFiles.cs @@ -0,0 +1,138 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region .NET + + /// Returns an enumerable collection of file information in the current directory. + /// An enumerable collection of the files in the current directory. + /// + /// + /// + /// + /// + /// + [SecurityCritical] + public IEnumerable EnumerateFiles() + { + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Files, PathFormat.LongFullPath); + } + + /// Returns an enumerable collection of file information that matches a search pattern. + /// An enumerable collection of files that matches . + /// + /// + /// + /// + /// + /// + /// + /// The search string to match against the names of directories in path. + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SecurityCritical] + public IEnumerable EnumerateFiles(string searchPattern) + { + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, searchPattern, DirectoryEnumerationOptions.Files, PathFormat.LongFullPath); + } + + /// Returns an enumerable collection of file information that matches a specified search pattern and search subdirectory option. + /// An enumerable collection of files that matches and . + /// + /// + /// + /// + /// + /// + /// + /// The search string to match against the names of directories in path. + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + [SecurityCritical] + public IEnumerable EnumerateFiles(string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.Files | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, searchPattern, options, PathFormat.LongFullPath); + } + + #endregion // .NET + + + + /// Returns an enumerable collection of file information in the current directory. + /// An enumerable collection of the files in the current directory. + /// + /// + /// + /// + /// + /// + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public IEnumerable EnumerateFiles(DirectoryEnumerationOptions options) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Folders; + options |= DirectoryEnumerationOptions.Files; + + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, Path.WildcardStarMatchAll, options, PathFormat.LongFullPath); + } + + /// Returns an enumerable collection of file information that matches a search pattern. + /// An enumerable collection of files that matches . + /// + /// + /// + /// + /// + /// + /// + /// The search string to match against the names of directories in path. + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// flags that specify how the directory is to be enumerated. + [SecurityCritical] + public IEnumerable EnumerateFiles(string searchPattern, DirectoryEnumerationOptions options) + { + // Adhere to the method name. + options &= ~DirectoryEnumerationOptions.Folders; + options |= DirectoryEnumerationOptions.Files; + + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, searchPattern, options, PathFormat.LongFullPath); + } + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.GetAccessControl.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.GetAccessControl.cs new file mode 100644 index 0000000..2f844ea --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.GetAccessControl.cs @@ -0,0 +1,52 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Security; +using System.Security.AccessControl; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region .NET + + /// Gets a object that encapsulates the access control list (ACL) entries for the directory described by the current DirectoryInfo object. + /// A object that encapsulates the access control rules for the directory. + + [SecurityCritical] + public DirectorySecurity GetAccessControl() + { + return File.GetAccessControlCore(true, LongFullName, AccessControlSections.Access | AccessControlSections.Group | AccessControlSections.Owner, PathFormat.LongFullPath); + } + + /// Gets a object that encapsulates the specified type of access control list (ACL) entries for the directory described by the current object. + /// One of the values that specifies the type of access control list (ACL) information to receive. + /// A object that encapsulates the access control rules for the file described by the path parameter. + + [SecurityCritical] + public DirectorySecurity GetAccessControl(AccessControlSections includeSections) + { + return File.GetAccessControlCore(true, LongFullName, includeSections, PathFormat.LongFullPath); + } + + #endregion // .NET + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.GetDirectories.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.GetDirectories.cs new file mode 100644 index 0000000..848f4ea --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.GetDirectories.cs @@ -0,0 +1,110 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Linq; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region .NET + + /// Returns the subdirectories of the current directory. + /// An array of objects. + /// If there are no subdirectories, this method returns an empty array. This method is not recursive. + /// + /// The EnumerateDirectories and GetDirectories methods differ as follows: When you use EnumerateDirectories, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetDirectories, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateDirectories can be more efficient. + /// + /// + /// + /// + /// + /// + /// + [SecurityCritical] + public DirectoryInfo[] GetDirectories() + { + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Folders, PathFormat.LongFullPath).ToArray(); + } + + /// Returns an array of directories in the current matching the given search criteria. + /// An array of type matching . + /// + /// The EnumerateDirectories and GetDirectories methods differ as follows: When you use EnumerateDirectories, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetDirectories, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateDirectories can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The search string to match against the names of directories in path. + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + [SecurityCritical] + public DirectoryInfo[] GetDirectories(string searchPattern) + { + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, searchPattern, DirectoryEnumerationOptions.Folders, PathFormat.LongFullPath).ToArray(); + } + + /// Returns an array of directories in the current matching the given search criteria and using a value to determine whether to search subdirectories. + /// An array of type matching . + /// If there are no subdirectories, or no subdirectories match the searchPattern parameter, this method returns an empty array. + /// + /// The EnumerateDirectories and GetDirectories methods differ as follows: When you use EnumerateDirectories, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetDirectories, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateDirectories can be more efficient. + /// + /// + /// + /// + /// + /// + /// + /// + /// The search string to match against the names of directories in path. + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + [SecurityCritical] + public DirectoryInfo[] GetDirectories(string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.Folders | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, searchPattern, options, PathFormat.LongFullPath).ToArray(); + } + + #endregion // .NET + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.GetFileSystemInfos.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.GetFileSystemInfos.cs new file mode 100644 index 0000000..7bcaa25 --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.GetFileSystemInfos.cs @@ -0,0 +1,124 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region .NET + + /// Returns an array of strongly typed entries representing all the files and subdirectories in a directory. + /// An array of strongly typed entries. + /// + /// For subdirectories, the objects returned by this method can be cast to the derived class . + /// Use the value returned by the property to determine whether the represents a file or a directory. + /// + /// + /// If there are no files or directories in the DirectoryInfo, this method returns an empty array. This method is not recursive. + /// For subdirectories, the FileSystemInfo objects returned by this method can be cast to the derived class DirectoryInfo. + /// Use the FileAttributes value returned by the Attributes property to determine whether the FileSystemInfo represents a file or a directory. + /// + /// + /// + /// + /// + /// + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public FileSystemInfo[] GetFileSystemInfos() + { + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath).ToArray(); + } + + /// Retrieves an array of strongly typed objects representing the files and subdirectories that match the specified search criteria. + /// + /// The search string to match against the names of directories in path. + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// An array of strongly typed entries. + /// + /// For subdirectories, the objects returned by this method can be cast to the derived class . + /// Use the value returned by the property to determine whether the represents a file or a directory. + /// + /// + /// If there are no files or directories in the DirectoryInfo, this method returns an empty array. This method is not recursive. + /// For subdirectories, the FileSystemInfo objects returned by this method can be cast to the derived class DirectoryInfo. + /// Use the FileAttributes value returned by the Attributes property to determine whether the FileSystemInfo represents a file or a directory. + /// + /// + /// + /// + /// + /// + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public FileSystemInfo[] GetFileSystemInfos(string searchPattern) + { + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, searchPattern, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath).ToArray(); + } + + /// Retrieves an array of strongly typed objects representing the files and subdirectories that match the specified search criteria. + /// + /// The search string to match against the names of directories in path. + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + /// An array of strongly typed entries. + /// + /// For subdirectories, the objects returned by this method can be cast to the derived class . + /// Use the value returned by the property to determine whether the represents a file or a directory. + /// + /// + /// If there are no files or directories in the DirectoryInfo, this method returns an empty array. This method is not recursive. + /// For subdirectories, the FileSystemInfo objects returned by this method can be cast to the derived class DirectoryInfo. + /// Use the FileAttributes value returned by the Attributes property to determine whether the FileSystemInfo represents a file or a directory. + /// + /// + /// + /// + /// + /// + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Infos")] + [SecurityCritical] + public FileSystemInfo[] GetFileSystemInfos(string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.FilesAndFolders | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, searchPattern, options, PathFormat.LongFullPath).ToArray(); + } + + #endregion // .NET + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.GetFiles.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.GetFiles.cs new file mode 100644 index 0000000..1c5ce95 --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.GetFiles.cs @@ -0,0 +1,114 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Linq; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region .NET + + /// Returns a file list from the current directory. + /// An array of type . + /// The order of the returned file names is not guaranteed; use the Sort() method if a specific sort order is required. + /// If there are no files in the , this method returns an empty array. + /// + /// The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetFiles, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient. + /// + /// + /// + /// + /// + /// + /// + [SecurityCritical] + public FileInfo[] GetFiles() + { + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Files, PathFormat.LongFullPath).ToArray(); + } + + /// Returns a file list from the current directory matching the given search pattern. + /// + /// The search string to match against the names of directories in path. + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// An array of type . + /// The order of the returned file names is not guaranteed; use the Sort() method if a specific sort order is required. + /// If there are no files in the , this method returns an empty array. + /// + /// The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetFiles, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient. + /// + /// + /// + /// + /// + /// + /// + [SecurityCritical] + public FileInfo[] GetFiles(string searchPattern) + { + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, searchPattern, DirectoryEnumerationOptions.Files, PathFormat.LongFullPath).ToArray(); + } + + /// Returns a file list from the current directory matching the given search pattern and using a value to determine whether to search subdirectories. + /// + /// The search string to match against the names of directories in path. + /// This parameter can contain a combination of valid literal path and wildcard + /// ( and ) characters, but does not support regular expressions. + /// + /// + /// One of the enumeration values that specifies whether the + /// should include only the current directory or should include all subdirectories. + /// + /// An array of type . + /// The order of the returned file names is not guaranteed; use the Sort() method if a specific sort order is required. + /// If there are no files in the , this method returns an empty array. + /// + /// The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of names + /// before the whole collection is returned; when you use GetFiles, you must wait for the whole array of names to be returned before you can access the array. + /// Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient. + /// + /// + /// + /// + /// + /// + /// + [SecurityCritical] + public FileInfo[] GetFiles(string searchPattern, SearchOption searchOption) + { + var options = DirectoryEnumerationOptions.Files | ((searchOption == SearchOption.AllDirectories) ? DirectoryEnumerationOptions.Recursive : 0); + + return Directory.EnumerateFileSystemEntryInfosCore(Transaction, LongFullName, searchPattern, options, PathFormat.LongFullPath).ToArray(); + } + + #endregion // .NET + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Refresh.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Refresh.cs new file mode 100644 index 0000000..90bc626 --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Refresh.cs @@ -0,0 +1,39 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region .NET + + /// Refreshes the state of the object. + [SecurityCritical] + public new void Refresh() + { + base.Refresh(); + } + + #endregion // .NET + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.RefreshEntryInfo.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.RefreshEntryInfo.cs new file mode 100644 index 0000000..e50d1d0 --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.RefreshEntryInfo.cs @@ -0,0 +1,39 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + #region AlphaFS + + /// Refreshes the state of the EntryInfo instance. + [SecurityCritical] + public new void RefreshEntryInfo() + { + base.RefreshEntryInfo(); + } + + #endregion // AlphaFS + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.SetAccessControl.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.SetAccessControl.cs new file mode 100644 index 0000000..8bc5686 --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.SetAccessControl.cs @@ -0,0 +1,49 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.Security; +using System.Security.AccessControl; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + /// Applies access control list (ACL) entries described by a object to the directory described by the current DirectoryInfo object. + /// A object that describes an ACL entry to apply to the directory described by the path parameter. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public void SetAccessControl(DirectorySecurity directorySecurity) + { + File.SetAccessControlCore(LongFullName, null, directorySecurity, AccessControlSections.All, PathFormat.LongFullPath); + } + + /// Applies access control list (ACL) entries described by a object to the directory described by the current DirectoryInfo object. + /// A object that describes an ACL entry to apply to the directory described by the path parameter. + /// One or more of the values that specifies the type of access control list (ACL) information to set. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public void SetAccessControl(DirectorySecurity directorySecurity, AccessControlSections includeSections) + { + File.SetAccessControlCore(LongFullName, null, directorySecurity, includeSections, PathFormat.LongFullPath); + } + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.ToString.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.ToString.cs new file mode 100644 index 0000000..7e4b33a --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.ToString.cs @@ -0,0 +1,33 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + partial class DirectoryInfo + { + /// Returns the original path that was passed by the user. + /// A string that represents this object. + public override string ToString() + { + return DisplayPath; + } + } +} diff --git a/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.cs b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.cs new file mode 100644 index 0000000..d784bc1 --- /dev/null +++ b/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.cs @@ -0,0 +1,203 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Exposes instance methods for creating, moving, and enumerating through directories and subdirectories. This class cannot be inherited. + [SerializableAttribute] + public sealed partial class DirectoryInfo : FileSystemInfo + { + #region Constructors + + #region .NET + + /// Initializes a new instance of the class on the specified path. + /// The path on which to create the . + /// + /// This constructor does not check if a directory exists. This constructor is a placeholder for a string that is used to access the disk in subsequent operations. + /// The path parameter can be a file name, including a file on a Universal Naming Convention (UNC) share. + /// + public DirectoryInfo(string path) : this(null, path, PathFormat.RelativePath) + { + } + + #endregion // .NET + + #region AlphaFS + + /// [AlphaFS] Initializes a new instance of the class on the specified path. + /// The path on which to create the . + /// Indicates the format of the path parameter(s). + /// This constructor does not check if a directory exists. This constructor is a placeholder for a string that is used to access the disk in subsequent operations. + public DirectoryInfo(string path, PathFormat pathFormat) : this(null, path, pathFormat) + { + } + + /// [AlphaFS] Special internal implementation. + /// The transaction. + /// The full path on which to create the . + /// Not used. + /// Not used. + /// This constructor does not check if a directory exists. This constructor is a placeholder for a string that is used to access the disk in subsequent operations. + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "junk1")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "junk2")] + private DirectoryInfo(KernelTransaction transaction, string fullPath, bool junk1, bool junk2) + { + IsDirectory = true; + Transaction = transaction; + + LongFullName = Path.GetLongPathCore(fullPath, GetFullPathOptions.None); + + OriginalPath = Path.GetFileName(fullPath, true); + + FullPath = fullPath; + + DisplayPath = OriginalPath.Length != 2 || OriginalPath[1] != Path.VolumeSeparatorChar ? OriginalPath : Path.CurrentDirectoryPrefix; + } + + #region Transactional + + /// [AlphaFS] Initializes a new instance of the class on the specified path. + /// The transaction. + /// The path on which to create the . + /// This constructor does not check if a directory exists. This constructor is a placeholder for a string that is used to access the disk in subsequent operations. + public DirectoryInfo(KernelTransaction transaction, string path) : this(transaction, path, PathFormat.RelativePath) + { + } + + /// [AlphaFS] Initializes a new instance of the class on the specified path. + /// The transaction. + /// The path on which to create the . + /// Indicates the format of the path parameter(s). + /// This constructor does not check if a directory exists. This constructor is a placeholder for a string that is used to access the disk in subsequent operations. + public DirectoryInfo(KernelTransaction transaction, string path, PathFormat pathFormat) + { + InitializeCore(true, transaction, path, pathFormat); + } + + #endregion // Transactional + + #endregion // AlphaFS + + #endregion // Constructors + + #region Properties + + #region .NET + + #region Exists + + /// Gets a value indicating whether the directory exists. + /// + /// The property returns if any error occurs while trying to determine if the + /// specified directory exists. + /// This can occur in situations that raise exceptions such as passing a directory name with invalid characters or too many + /// characters, + /// a failing or missing disk, or if the caller does not have permission to read the directory. + /// + /// if the directory exists; otherwise, . + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + public override bool Exists + { + [SecurityCritical] + get + { + try + { + if (DataInitialised == -1) + Refresh(); + + FileAttributes attrs = Win32AttributeData.dwFileAttributes; + return DataInitialised == 0 && attrs != (FileAttributes) (-1) && (attrs & FileAttributes.Directory) != 0; + } + catch + { + return false; + } + } + } + + #endregion // Exists + + #region Name + + /// Gets the name of this instance. + /// The directory name. + /// + /// This Name property returns only the name of the directory, such as "Bin". + /// To get the full path, such as "c:\public\Bin", use the FullName property. + /// + public override string Name + { + get + { + // GetDirName() + return FullPath.Length > 3 + ? Path.GetFileName(Path.RemoveTrailingDirectorySeparator(FullPath, false), true) + : FullPath; + } + } + + #endregion // Name + + #region Parent + + /// Gets the parent directory of a specified subdirectory. + /// The parent directory, or null if the path is null or if the file path denotes a root (such as "\", "C:", or * "\\server\share"). + public DirectoryInfo Parent + { + [SecurityCritical] + get + { + string path = FullPath; + + if (path.Length > 3) + path = Path.RemoveTrailingDirectorySeparator(FullPath, false); + + string dirName = Path.GetDirectoryName(path, false); + return dirName == null ? null : new DirectoryInfo(Transaction, dirName, true, true); + } + } + + #endregion // Parent + + #region Root + + /// Gets the root portion of the directory. + /// An object that represents the root of the directory. + public DirectoryInfo Root + { + [SecurityCritical] + get { return new DirectoryInfo(Transaction, Path.GetPathRoot(FullPath, false), PathFormat.RelativePath); } + } + + #endregion // Root + + #endregion // .NET + + #endregion // Properties + } +} diff --git a/AlphaFS/Filesystem/DiskSpaceInfo.cs b/AlphaFS/Filesystem/DiskSpaceInfo.cs new file mode 100644 index 0000000..619673e --- /dev/null +++ b/AlphaFS/Filesystem/DiskSpaceInfo.cs @@ -0,0 +1,265 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Retrieves information about the amount of space that is available on a disk volume, which is the total amount of space, + /// the total amount of free space, and the total amount of free space available to the user that is associated with the calling thread. + /// This class cannot be inherited. + /// + [SerializableAttribute] + [SecurityCritical] + public sealed class DiskSpaceInfo + { + #region Constructor + + /// Initializes a DiskSpaceInfo instance. + /// A valid drive path or drive letter. This can be either uppercase or lowercase, 'a' to 'z' or a network share in the format: \\server\share + /// This is a Lazyloading object; call to populate all properties first before accessing. + [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Utils.IsNullOrWhiteSpace validates arguments.")] + [SecurityCritical] + public DiskSpaceInfo(string drivePath) + { + if (Utils.IsNullOrWhiteSpace(drivePath)) + throw new ArgumentNullException("drivePath"); + + if (drivePath.Length == 1) + DriveName += Path.VolumeSeparatorChar; + else + DriveName = Path.GetPathRoot(drivePath, false); + + if (Utils.IsNullOrWhiteSpace(DriveName)) + throw new ArgumentException("Argument must be a drive letter (\"C\"), RootDir (\"C:\\\") or UNC path (\"\\\\server\\share\")"); + + // MSDN: + // If this parameter is a UNC name, it must include a trailing backslash (for example, "\\MyServer\MyShare\"). + // Furthermore, a drive specification must have a trailing backslash (for example, "C:\"). + // The calling application must have FILE_LIST_DIRECTORY access rights for this directory. + DriveName = Path.AddTrailingDirectorySeparator(DriveName, false); + } + + /// Initializes a DiskSpaceInfo instance. + /// A valid drive path or drive letter. This can be either uppercase or lowercase, 'a' to 'z' or a network share in the format: \\server\share + /// gets both size- and disk cluster information. Get only disk cluster information, Get only size information. + /// Refreshes the state of the object. + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + public DiskSpaceInfo(string drivePath, bool? spaceInfoType, bool refresh, bool continueOnException) : this(drivePath) + { + if (spaceInfoType == null) + _initGetSpaceInfo = _initGetClusterInfo = true; + + else + { + _initGetSpaceInfo = (bool) !spaceInfoType; + _initGetClusterInfo = (bool) spaceInfoType; + } + + _continueOnAccessError = continueOnException; + + if (refresh) + Refresh(); + } + + #endregion // Constructor + + #region Fields + + private readonly bool _initGetClusterInfo = true; + private readonly bool _initGetSpaceInfo = true; + private readonly bool _continueOnAccessError; + + #endregion // Fields + + #region Methods + + #region Refresh + + /// Refreshes the state of the object. + public void Refresh() + { + Reset(); + + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + { + int lastError = (int) Win32Errors.NO_ERROR; + + #region Get size information. + + if (_initGetSpaceInfo) + { + long freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes; + + if (!NativeMethods.GetDiskFreeSpaceEx(DriveName, out freeBytesAvailable, out totalNumberOfBytes, out totalNumberOfFreeBytes)) + lastError = Marshal.GetLastWin32Error(); + + else + { + FreeBytesAvailable = freeBytesAvailable; + TotalNumberOfBytes = totalNumberOfBytes; + TotalNumberOfFreeBytes = totalNumberOfFreeBytes; + } + + if (!_continueOnAccessError && (lastError != Win32Errors.NO_ERROR && lastError != Win32Errors.ERROR_NOT_READY)) + NativeError.ThrowException(DriveName); + } + + #endregion // Get size information. + + #region Get cluster information. + + if (_initGetClusterInfo) + { + int sectorsPerCluster, bytesPerSector, numberOfFreeClusters; + uint totalNumberOfClusters; + + if (!NativeMethods.GetDiskFreeSpace(DriveName, out sectorsPerCluster, out bytesPerSector, out numberOfFreeClusters, out totalNumberOfClusters)) + lastError = Marshal.GetLastWin32Error(); + + else + { + BytesPerSector = bytesPerSector; + NumberOfFreeClusters = numberOfFreeClusters; + SectorsPerCluster = sectorsPerCluster; + TotalNumberOfClusters = totalNumberOfClusters; + } + + if (!_continueOnAccessError && (lastError != Win32Errors.NO_ERROR && lastError != Win32Errors.ERROR_NOT_READY)) + NativeError.ThrowException(DriveName); + } + + #endregion // Get cluster information. + } + } + + #endregion // Refresh + + #region Reset + + /// Initializes all properties to 0. + private void Reset() + { + if (_initGetSpaceInfo) + FreeBytesAvailable = TotalNumberOfBytes = TotalNumberOfFreeBytes = 0; + + if (_initGetClusterInfo) + { + BytesPerSector = NumberOfFreeClusters = SectorsPerCluster = 0; + TotalNumberOfClusters = 0; + } + } + + #endregion // Reset + + #region ToString + /// Returns the drive name. + /// A string that represents this object. + public override string ToString() + { + return DriveName; + } + + #endregion // ToString + + #endregion // Methods + + #region Properties + + /// Indicates the amount of available free space on a drive, formatted as percentage. + public string AvailableFreeSpacePercent + { + get + { + return string.Format(CultureInfo.CurrentCulture, "{0:0.00}%", Utils.PercentCalculate(TotalNumberOfBytes - (TotalNumberOfBytes - TotalNumberOfFreeBytes), 0, TotalNumberOfBytes)); + } + } + + /// Indicates the amount of available free space on a drive, formatted as a unit size. + public string AvailableFreeSpaceUnitSize + { + get { return Utils.UnitSizeToText(TotalNumberOfFreeBytes); } + } + + /// Returns the Clusters size. + public long ClusterSize + { + get { return SectorsPerCluster * BytesPerSector; } + } + + /// Gets the name of a drive. + /// The name of the drive. + /// This property is the name assigned to the drive, such as C:\ or E:\ + public string DriveName { get; private set; } + + /// The total number of bytes on a disk that are available to the user who is associated with the calling thread, formatted as a unit size. + public string TotalSizeUnitSize + { + get { return Utils.UnitSizeToText(TotalNumberOfBytes); } + } + + /// Indicates the amount of used space on a drive, formatted as percentage. + public string UsedSpacePercent + { + get + { + return string.Format(CultureInfo.CurrentCulture, "{0:0.00}%", Utils.PercentCalculate(TotalNumberOfBytes - FreeBytesAvailable, 0, TotalNumberOfBytes)); + } + } + + /// Indicates the amount of used space on a drive, formatted as a unit size. + public string UsedSpaceUnitSize + { + get { return Utils.UnitSizeToText(TotalNumberOfBytes - FreeBytesAvailable); } + } + + /// The total number of free bytes on a disk that are available to the user who is associated with the calling thread. + public long FreeBytesAvailable { get; private set; } + + /// The total number of bytes on a disk that are available to the user who is associated with the calling thread. + public long TotalNumberOfBytes { get; private set; } + + /// The total number of free bytes on a disk. + public long TotalNumberOfFreeBytes { get; private set; } + + /// The number of bytes per sector. + public int BytesPerSector { get; private set; } + + /// The total number of free clusters on the disk that are available to the user who is associated with the calling thread. + public int NumberOfFreeClusters { get; private set; } + + /// The number of sectors per cluster. + public int SectorsPerCluster { get; private set; } + + /// The total number of clusters on the disk that are available to the user who is associated with the calling thread. + /// If per-user disk quotas are in use, this value may be less than the total number of clusters on the disk. + /// + public long TotalNumberOfClusters { get; private set; } + + + #endregion // Properties + } +} diff --git a/AlphaFS/Filesystem/DriveInfo.cs b/AlphaFS/Filesystem/DriveInfo.cs new file mode 100644 index 0000000..6238c5c --- /dev/null +++ b/AlphaFS/Filesystem/DriveInfo.cs @@ -0,0 +1,422 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Provides access to information on a local or remote drive. + /// + /// This class models a drive and provides methods and properties to query for drive information. + /// Use DriveInfo to determine what drives are available, and what type of drives they are. + /// You can also query to determine the capacity and available free space on the drive. + /// + [Serializable] + [SecurityCritical] + public sealed class DriveInfo + { + #region Private Fields + + [NonSerialized] + private readonly VolumeInfo _volumeInfo; + + [NonSerialized] + private readonly DiskSpaceInfo _dsi; + + [NonSerialized] + private bool _initDsie; + + [NonSerialized] + private DriveType? _driveType; + + [NonSerialized] + private string _dosDeviceName; + + [NonSerialized] + private DirectoryInfo _rootDirectory; + + private readonly string _name; + + + #endregion + + #region Constructors + + /// Provides access to information on the specified drive. + /// + /// + /// + /// A valid drive path or drive letter. + /// This can be either uppercase or lowercase, + /// 'a' to 'z' or a network share in the format: \\server\share + /// + [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Utils.IsNullOrWhiteSpace validates arguments.")] + [SecurityCritical] + public DriveInfo(string driveName) + { + if (Utils.IsNullOrWhiteSpace(driveName)) + throw new ArgumentNullException("driveName"); + + if (driveName.Length == 1) + _name += Path.VolumeSeparatorChar; + else + _name = Path.GetPathRoot(driveName, false); + + if (Utils.IsNullOrWhiteSpace(_name)) + throw new ArgumentException("Argument must be a drive letter (\"C\"), RootDir (\"C:\\\") or UNC path (\"\\\\server\\share\")"); + + // If an exception is thrown, the original drivePath is used. + _name = Path.AddTrailingDirectorySeparator(_name, false); + + + // Initiate VolumeInfo() lazyload instance. + _volumeInfo = new VolumeInfo(_name, false, true); + + // Initiate DiskSpaceInfo() lazyload instance. + _dsi = new DiskSpaceInfo(_name, null, false, true); + } + + #endregion // Constructors + + #region Properties + + /// Indicates the amount of available free space on a drive. + /// The amount of free space available on the drive, in bytes. + /// This property indicates the amount of free space available on the drive. Note that this number may be different from the number because this property takes into account disk quotas. + public long AvailableFreeSpace + { + get + { + GetDeviceInfo(3, 0); + return _dsi == null ? 0 : _dsi.FreeBytesAvailable; + } + } + + /// Gets the name of the file system, such as NTFS or FAT32. + /// Use DriveFormat to determine what formatting a drive uses. + public string DriveFormat + { + get { return (string)GetDeviceInfo(0, 1); } + } + + /// Gets the drive type. + /// One of the values. + /// + /// The DriveType property indicates whether a drive is any of: CDRom, Fixed, Unknown, Network, NoRootDirectory, + /// Ram, Removable, or Unknown. Values are listed in the enumeration. + /// + public DriveType DriveType + { + get { return (DriveType)GetDeviceInfo(2, 0); } + } + + /// Gets a value indicating whether a drive is ready. + /// if the drive is ready; otherwise, . + /// + /// IsReady indicates whether a drive is ready. For example, it indicates whether a CD is in a CD drive or whether + /// a removable storage device is ready for read/write operations. If you do not test whether a drive is ready, and + /// it is not ready, querying the drive using DriveInfo will raise an IOException. + /// + /// Do not rely on IsReady() to avoid catching exceptions from other members such as TotalSize, TotalFreeSpace, and DriveFormat. + /// Between the time that your code checks IsReady and then accesses one of the other properties + /// (even if the access occurs immediately after the check), a drive may have been disconnected or a disk may have been removed. + /// + public bool IsReady + { + get { return File.ExistsCore(true, null, Name, PathFormat.LongFullPath); } + } + + + /// Gets the name of the drive. + /// The name of the drive. + /// This property is the name assigned to the drive, such as C:\ or E:\ + public string Name + { + get { return _name; } + } + + /// Gets the root directory of a drive. + /// A DirectoryInfo object that contains the root directory of the drive. + public DirectoryInfo RootDirectory + { + get { return (DirectoryInfo)GetDeviceInfo(2, 1); } + } + + /// Gets the total amount of free space available on a drive. + /// The total free space available on a drive, in bytes. + /// This property indicates the total amount of free space available on the drive, not just what is available to the current user. + public long TotalFreeSpace + { + get + { + GetDeviceInfo(3, 0); + return _dsi == null ? 0 : _dsi.TotalNumberOfFreeBytes; + } + } + + /// Gets the total size of storage space on a drive. + /// The total size of the drive, in bytes. + /// This property indicates the total size of the drive in bytes, not just what is available to the current user. + public long TotalSize + { + get + { + GetDeviceInfo(3, 0); + return _dsi == null ? 0 : _dsi.TotalNumberOfBytes; + } + } + + /// Gets or sets the volume label of a drive. + /// The volume label. + /// + /// The label length is determined by the operating system. For example, NTFS allows a volume label + /// to be up to 32 characters long. Note that is a valid VolumeLabel. + /// + + public string VolumeLabel + { + get { return (string)GetDeviceInfo(0, 2); } + set { Volume.SetVolumeLabel(Name, value); } + } + + /// [AlphaFS] Returns the instance. + public DiskSpaceInfo DiskSpaceInfo + { + get + { + GetDeviceInfo(3, 0); + return _dsi; + } + } + + /// [AlphaFS] The MS-DOS device name. + public string DosDeviceName + { + get { return (string)GetDeviceInfo(1, 0); } + } + + /// [AlphaFS] Indicates if this drive is a SUBST.EXE / DefineDosDevice drive mapping. + public bool IsDosDeviceSubstitute + { + get { return !Utils.IsNullOrWhiteSpace(DosDeviceName) && DosDeviceName.StartsWith(Path.SubstitutePrefix, StringComparison.OrdinalIgnoreCase); } + } + + /// [AlphaFS] Indicates if this drive is a UNC path. + /// Only retrieve this information if we're dealing with a real network share mapping: http://alphafs.codeplex.com/discussions/316583 + public bool IsUnc + { + get { return !IsDosDeviceSubstitute && DriveType == DriveType.Network; } + } + + /// [AlphaFS] Determines whether the specified volume name is a defined volume on the current computer. + public bool IsVolume + { + get { return GetDeviceInfo(0, 0) != null; } + } + + /// [AlphaFS] Contains information about a file-system volume. + /// A VolumeInfo object that contains file-system volume information of the drive. + public VolumeInfo VolumeInfo + { + get { return (VolumeInfo)GetDeviceInfo(0, 0); } + } + + + #endregion // Properties + + #region Methods + + /// Retrieves the drive names of all logical drives on a computer. + /// An array of type that represents the logical drives on a computer. + + [SecurityCritical] + public static DriveInfo[] GetDrives() + { + return Directory.EnumerateLogicalDrivesCore(false, false).ToArray(); + } + + /// Returns a drive name as a string. + /// The name of the drive. + /// This method returns the Name property. + public override string ToString() + { + return _name; + } + + + /// [AlphaFS] Enumerates the drive names of all logical drives on a computer. + /// Retrieve logical drives as known by the Environment. + /// Retrieve only when accessible (IsReady) logical drives. + /// + /// An IEnumerable of type that represents + /// the logical drives on a computer. + /// + [SecurityCritical] + public static IEnumerable EnumerateDrives(bool fromEnvironment, bool isReady) + { + return Directory.EnumerateLogicalDrivesCore(fromEnvironment, isReady); + } + + + /// [AlphaFS] Gets the first available drive letter on the local system. + /// A drive letter as . When no drive letters are available, an exception is thrown. + /// The letters "A" and "B" are reserved for floppy drives and will never be returned by this function. + + public static char GetFreeDriveLetter() + { + return GetFreeDriveLetter(false); + } + + /// Gets an available drive letter on the local system. + /// When get the last available drive letter. When gets the first available drive letter. + /// A drive letter as . When no drive letters are available, an exception is thrown. + /// The letters "A" and "B" are reserved for floppy drives and will never be returned by this function. + + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")] + [SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")] + public static char GetFreeDriveLetter(bool getLastAvailable) + { + IEnumerable freeDriveLetters = "CDEFGHIJKLMNOPQRSTUVWXYZ".Except(Directory.EnumerateLogicalDrivesCore(false, false).Select(d => d.Name[0])); + + try + { + return getLastAvailable ? freeDriveLetters.Last() : freeDriveLetters.First(); + } + catch + { + throw new Exception("There are no drive letters available."); + } + } + + #endregion // Methods + + #region Private Methods + + /// Retrieves information about the file system and volume associated with the specified root file or directorystream. + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + [SecurityCritical] + private object GetDeviceInfo(int type, int mode) + { + try + { + switch (type) + { + #region Volume + + // VolumeInfo properties. + case 0: + if (Utils.IsNullOrWhiteSpace(_volumeInfo.FullPath)) + _volumeInfo.Refresh(); + + switch (mode) + { + case 0: + // IsVolume, VolumeInfo + return _volumeInfo; + + case 1: + // DriveFormat + return _volumeInfo == null ? DriveType.Unknown.ToString() : _volumeInfo.FileSystemName ?? DriveType.Unknown.ToString(); + + case 2: + // VolumeLabel + return _volumeInfo == null ? string.Empty : _volumeInfo.Name ?? string.Empty; + } + break; + + // Volume related. + case 1: + switch (mode) + { + case 0: + // DosDeviceName + + // Do not use ?? expression here. + if (_dosDeviceName == null) + _dosDeviceName = Volume.QueryDosDevice(Name).FirstOrDefault(); + + return _dosDeviceName; + } + break; + + #endregion // Volume + + #region Drive + + // Drive related. + case 2: + switch (mode) + { + case 0: + // DriveType + // Do not use ?? expression here. + if (_driveType == null) + _driveType = Volume.GetDriveType(Name); + + return _driveType; + + case 1: + // RootDirectory + + // Do not use ?? expression here. + if (_rootDirectory == null) + _rootDirectory = new DirectoryInfo(null, Name, PathFormat.RelativePath); + + return _rootDirectory; + } + break; + + // DiskSpaceInfo related. + case 3: + switch (mode) + { + case 0: + // AvailableFreeSpace, TotalFreeSpace, TotalSize, DiskSpaceInfo + if (!_initDsie) + { + _dsi.Refresh(); + _initDsie = true; + } + break; + } + break; + + #endregion // Drive + } + } + catch + { + } + + return type == 0 && mode > 0 ? string.Empty : null; + } + + + #endregion // Private + + } +} diff --git a/AlphaFS/Filesystem/Enumerations/BackupStreamType.cs b/AlphaFS/Filesystem/Enumerations/BackupStreamType.cs new file mode 100644 index 0000000..495f7e1 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/BackupStreamType.cs @@ -0,0 +1,84 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Filesystem +{ + /// The type of the data contained in the backup stream. + public enum BackupStreamType + { + /// This indicates an error. + None = 0, + + /// BACKUP_DATA + /// Standard data. This corresponds to the NTFS $DATA stream type on the default (unnamed) data stream. + /// + Data = 1, + + /// BACKUP_EA_DATA + /// Extended attribute data. This corresponds to the NTFS $EA stream type. + /// + ExtendedAttributesData = 2, + + /// BACKUP_SECURITY_DATA + /// Security descriptor data. + /// + SecurityData = 3, + + /// BACKUP_ALTERNATE_DATA + /// Alternative data streams. This corresponds to the NTFS $DATA stream type on a named data stream. + /// + AlternateData = 4, + + /// BACKUP_LINK + /// Hard link information. This corresponds to the NTFS $FILE_NAME stream type. + /// + Link = 5, + + /// BACKUP_PROPERTY_DATA + /// Property data. + /// + PropertyData = 6, + + /// BACKUP_OBJECT_ID + /// Objects identifiers. This corresponds to the NTFS $OBJECT_ID stream type. + /// + ObjectId = 7, + + /// BACKUP_REPARSE_DATA + /// Reparse points. This corresponds to the NTFS $REPARSE_POINT stream type. + /// + ReparseData = 8, + + /// BACKUP_SPARSE_BLOCK + /// Sparse file. This corresponds to the NTFS $DATA stream type for a sparse file. + /// + SparseBlock = 9, + + /// BACKUP_TXFS_DATA + /// Transactional NTFS (TxF) data stream. + /// + /// Windows Server 2003 and Windows XP: This value is not supported. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Txfs")] + TxfsData = 10 + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/CopyMoveProgressCallbackReason.cs b/AlphaFS/Filesystem/Enumerations/CopyMoveProgressCallbackReason.cs new file mode 100644 index 0000000..1664118 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/CopyMoveProgressCallbackReason.cs @@ -0,0 +1,37 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + /// Used by CopyFileXxx and MoveFileXxx. The reason that was called. + public enum CopyMoveProgressCallbackReason + { + /// CALLBACK_CHUNK_FINISHED + /// Another part of the data file was copied. + /// + ChunkFinished = 0, + + /// CALLBACK_STREAM_SWITCH + /// Another stream was created and is about to be copied. This is the callback reason given when the callback routine is first invoked. + /// + StreamSwitch = 1 + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/CopyMoveProgressResult.cs b/AlphaFS/Filesystem/Enumerations/CopyMoveProgressResult.cs new file mode 100644 index 0000000..8e2fa6d --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/CopyMoveProgressResult.cs @@ -0,0 +1,47 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + /// Used by CopyFileXxx and MoveFileXxx. The function should return one of the following values. + public enum CopyMoveProgressResult + { + /// PROGRESS_CONTINUE + /// Continue the copy operation. + /// + Continue = 0, + + /// PROGRESS_CANCEL + /// Cancel the copy operation and delete the destination file. + /// + Cancel = 1, + + /// PROGRESS_STOP + /// Stop the copy operation. It can be restarted at a later time. + /// + Stop = 2, + + /// PROGRESS_QUIET + /// Continue the copy operation, but stop invoking to report progress. + /// + Quiet = 3 + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/CopyOptions.cs b/AlphaFS/Filesystem/Enumerations/CopyOptions.cs new file mode 100644 index 0000000..1b2d066 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/CopyOptions.cs @@ -0,0 +1,69 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Flags that specify how a file or directory is to be copied. + [Flags] + public enum CopyOptions + { + /// No CopyOptions used, this allows overwriting the file. + None = 0, + + /// COPY_FILE_FAIL_IF_EXISTS + /// The copy operation fails immediately if the target file already exists. + /// + FailIfExists = 1, + + /// COPY_FILE_RESTARTABLE + /// + /// Progress of the copy is tracked in the target file in case the copy fails. The failed copy can be restarted at a later time by specifying the same values + /// forexisting file name and new file name as those used in the call that failed. This can significantly slow down the copy operation as the new file may be + /// flushed multiple times during the copy operation. + /// + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Restartable")] + Restartable = 2, + + /// COPY_FILE_OPEN_SOURCE_FOR_WRITE + /// The file is copied and the original file is opened for write access. + /// + OpenSourceForWrite = 4, + + /// COPY_FILE_ALLOW_DECRYPTED_DESTINATION + /// An attempt to copy an encrypted file will succeed even if the destination copy cannot be encrypted. + /// + AllowDecryptedDestination = 8, + + /// COPY_FILE_COPY_SYMLINK + /// If the source file is a symbolic link, the destination file is also a symbolic link pointing to the same file that the source symbolic link is pointing to. + /// + CopySymbolicLink = 2048, + + /// COPY_FILE_NO_BUFFERING + /// The copy operation is performed using unbuffered I/O, bypassing system I/O cache resources. Recommended for very large file transfers. + /// + NoBuffering = 4096 + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/DeviceGuid.cs b/AlphaFS/Filesystem/Enumerations/DeviceGuid.cs new file mode 100644 index 0000000..288e0ef --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/DeviceGuid.cs @@ -0,0 +1,200 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Filesystem +{ + /// System-Defined Device Interface Classes + /// http://msdn.microsoft.com/en-us/library/windows/hardware/ff541389%28v=vs.85%29.aspx + public enum DeviceGuid + { + #region 1394 and 61883 Devices + + /// The BUS1394_CLASS_GUID device interface class is defined for 1394 bus devices. + [Description("6BDD1FC1-810F-11d0-BEC7-08002BE2092F")] Bus1394, + + /// The GUID_61883_CLASS device interface class is defined for devices in the 61883 device setup class. + [Description("7EBEFBC0-3200-11d2-B4C2-00A0C9697D07")] Guid61883, + + #endregion // 1394 and 61883 Devices + + #region Battery and ACPI devices + + /// The GUID_DEVICE_APPLICATIONLAUNCH_BUTTON device interface class is defined for Advanced Configuration and Power Interface (ACPI) application start buttons. + [Description("629758EE-986E-4D9E-8E47-DE27F8AB054D")] ApplicationLaunchButton, + + /// The GUID_DEVICE_BATTERY device interface class is defined for battery devices. + [Description("72631E54-78A4-11D0-BCF7-00AA00B7B32A")] Battery, + + /// The GUID_DEVICE_LID device interface class is defined for Advanced Configuration and Power Interface (ACPI) lid devices. + [Description("4AFA3D52-74A7-11d0-be5e-00A0C9062857")] Lid, + + /// The GUID_DEVICE_MEMORY device interface class is defined for Advanced Configuration and Power Interface (ACPI) memory devices. + [Description("3FD0F03D-92E0-45FB-B75C-5ED8FFB01021")] Memory, + + /// The GUID_DEVICE_MESSAGE_INDICATOR device interface class is defined for Advanced Configuration and Power Interface (ACPI) message indicator devices. + [Description("CD48A365-FA94-4CE2-A232-A1B764E5D8B4")] MessageIndicator, + + /// The GUID_DEVICE_PROCESSOR device interface class is defined for Advanced Configuration and Power Interface (ACPI) processor devices. + [Description("97FADB10-4E33-40AE-359C-8BEF029DBDD0")] Processor, + + /// The GUID_DEVICE_SYS_BUTTON device interface classis defined for Advanced Configuration and Power Interface (ACPI) system power button devices. + [Description("4AFA3D53-74A7-11d0-be5e-00A0C9062857")] SysButton, + + /// The GUID_DEVICE_THERMAL_ZONE device interface class is defined for Advanced Configuration and Power Interface (ACPI) thermal zone devices. + [Description("4AFA3D51-74A7-11d0-be5e-00A0C9062857")] ThermalZone, + + #endregion // Battery and ACPI devices + + #region Bluetooth Devices + + /// The GUID_BTHPORT_DEVICE_INTERFACE device interface class is defined for Bluetooth radios. + [Description("0850302A-B344-4fda-9BE9-90576B8D46F0")] Bluetooth, + + #endregion // Bluetooth Devices + + #region Display and Image Devices + + /// The GUID_DEVINTERFACE_BRIGHTNESS device interface class is defined for display adapter drivers that operate in the context of the Windows Vista Display Driver Model and support brightness control of monitor child devices. + [Description("FDE5BBA4-B3F9-46FB-BDAA-0728CE3100B4")] Brightness, + + /// The GUID_DEVINTERFACE_DISPLAY_ADAPTER device interface class is defined for display views that are supported by display adapters. + [Description("5B45201D-F2F2-4F3B-85BB-30FF1F953599")] DisplayAdapter, + + /// The GUID_DEVINTERFACE_I2C device interface class is defined for display adapter drivers that operate in the context of the Windows Vista Display Driver Model and perform I2C transactions with monitor child devices. + [Description("2564AA4F-DDDB-4495-B497-6AD4A84163D7")] I2C, + + /// The GUID_DEVINTERFACE_IMAGE device interface class is defined for WIA devices and Still Image (STI) devices, including digital cameras and scanners. + [Description("6BDD1FC6-810F-11D0-BEC7-08002BE2092F")] StillImage, + + /// The GUID_DEVINTERFACE_MONITOR device interface class is defined for monitor devices. + [Description("E6F07B5F-EE97-4a90-B076-33F57BF4EAA7")] Monitor, + + /// The GUID_DEVINTERFACE_OPM device interface class is defined for display adapter drivers that operate in the context of the Windows Vista Display Driver Model and support output protection management (OPM) for monitor child devices. + [Description("BF4672DE-6B4E-4BE4-A325-68A91EA49C09")] OutputProtectionManagement, + + /// The GUID_DEVINTERFACE_VIDEO_OUTPUT_ARRIVAL device interface class is defined for child devices of display devices. + [Description("1AD9E4F0-F88D-4360-BAB9-4C2D55E564CD")] VideoOutputArrival, + + /// The GUID_DISPLAY_DEVICE_ARRIVAL device interface class is defined for display adapters. + [Description("1CA05180-A699-450A-9A0C-DE4FBE3DDD89")] DisplayDeviceArrival, + + #endregion // Display and Image Devices + + #region Interactive Input Devices + + /// The GUID_DEVINTERFACE_HID device interface class is defined for HID collections. + [Description("4D1E55B2-F16F-11CF-88CB-001111000030")] Hid, + + /// The GUID_DEVINTERFACE_KEYBOARD device interface class is defined for keyboard devices. + [Description("4D1E55B2-F16F-11CF-88CB-001111000030")] Keyboard, + + /// The GUID_DEVINTERFACE_MOUSE device interface class is defined for mouse devices. + [Description("378DE44C-56EF-11D1-BC8C-00A0C91405DD")] Mouse, + + #endregion // Interactive Input Devices + + #region Modem Devices + + /// The GUID_DEVINTERFACE_MODEM device interface class is defined for modem devices. + [Description("2C7089AA-2E0E-11D1-B114-00C04FC2AAE4")] Modem, + + #endregion // Modem Devices + + #region Network Devices + + /// The GUID_DEVINTERFACE_NET device interface class is defined for network devices. + [Description("CAC88484-7515-4C03-82E6-71A87ABAC361")] Network, + + #endregion // Network Devices + + #region Serial and Parallel Port Devices + + /// The GUID_DEVINTERFACE_COMPORT device interface class is defined for COM ports. + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "ComPort")] + [Description("86E0D1E0-8089-11D0-9CE4-08003E301F73")] ComPort, + + /// The GUID_DEVINTERFACE_PARALLEL device interface class is defined for parallel ports that support an IEEE 1284-compatible hardware interface. + [Description("97F76EF0-F883-11D0-AF1F-0000F800845C")] Parallel, + + /// The GUID_DEVINTERFACE_PARCLASS device interface class is defined for devices that are attached to a parallel port. + [Description("811FC6A5-F728-11D0-A537-0000F8753ED1")] ParallelClass, + + /// The GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR device interface class is defined for Plug and Play (PnP) serial ports. + [Description("4D36E978-E325-11CE-BFC1-08002BE10318")] SerialEnumBusEnumerator, + + #endregion // Serial and Parallel Port Devices + + #region Storage Devices + + /// The GUID_DEVINTERFACE_CDCHANGER device interface class is defined for CD-ROM changer devices. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cdrom")] + [Description("53F56312-B6BF-11D0-94F2-00A0C91EFB8B")] CdromChanger, + + /// The GUID_DEVINTERFACE_CDROM device interface class is defined for CD-ROM storage devices. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cdrom")] + [Description("53F56308-B6BF-11D0-94F2-00A0C91EFB8B")] Cdrom, + + /// The GUID_DEVINTERFACE_DISK device interface class is defined for hard disk storage devices. + [Description("53F56307-B6BF-11D0-94F2-00A0C91EFB8B")] Disk, + + /// The GUID_DEVINTERFACE_FLOPPY device interface class is defined for floppy disk storage devices. + [Description("53F56311-B6BF-11D0-94F2-00A0C91EFB8B")] Floppy, + + /// The GUID_DEVINTERFACE_MEDIUMCHANGER device interface class is defined for medium changer devices. + [Description("53F56310-B6BF-11D0-94F2-00A0C91EFB8B")] MediumChanger, + + /// The GUID_DEVINTERFACE_PARTITION device interface class is defined for partition devices. + [Description("53F5630A-B6BF-11D0-94F2-00A0C91EFB8B")] Partition, + + /// The GUID_DEVINTERFACE_STORAGEPORT device interface class is defined for storage port devices. + [Description("2ACCFE60-C130-11D2-B082-00A0C91EFB8B")] StoragePort, + + /// The GUID_DEVINTERFACE_TAPE device interface class is defined for tape storage devices. + [Description("53F5630B-B6BF-11D0-94F2-00A0C91EFB8B")] Tape, + + /// The GUID_DEVINTERFACE_VOLUME device interface class is defined for volume devices. + [Description("53F5630D-B6BF-11D0-94F2-00A0C91EFB8B")] Volume, + + /// The GUID_DEVINTERFACE_WRITEONCEDISK device interface class is defined for write-once disk devices. + [Description("53F5630C-B6BF-11D0-94F2-00A0C91EFB8B")] WriteOnceDisk, + + #endregion // Storage Devices + + #region USB Devices + + /// The GUID_DEVINTERFACE_USB_DEVICE device interface class is defined for USB devices that are attached to a USB hub. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Usb")] + [Description("A5DCBF10-6530-11D2-901F-00C04FB951ED")] UsbDevice, + + /// The GUID_DEVINTERFACE_USB_HOST_CONTROLLER device interface class is defined for USB host controller devices. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Usb")] + [Description("3ABF6F2D-71C4-462A-8A92-1E6861E6AF27")] UsbHostController, + + /// The GUID_DEVINTERFACE_USB_HUB device interface class is defined for USB hub devices. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Usb")] + [Description("F18A0E88-C30C-11D0-8815-00A0C906BED8")] UsbHub + + #endregion // USB Devices + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/DiGetClassFlags.cs b/AlphaFS/Filesystem/Enumerations/DiGetClassFlags.cs new file mode 100644 index 0000000..bb74db1 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/DiGetClassFlags.cs @@ -0,0 +1,61 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Specifies control options that filter the device information elements that are added to the device information set. + [Flags] + internal enum SetupDiGetClassDevsExFlags + { + /// DIGCF_DEFAULT + /// Return only the device that is associated with the system default device interface, if one is set, for the specified device interface classes. + /// + Default = 1, // only valid with DIGCF_DEVICEINTERFACE + + /// DIGCF_PRESENT + /// Return only devices that are currently present. + /// + Present = 2, + + /// DIGCF_ALLCLASSES + /// Return a list of installed devices for the specified device setup classes or device interface classes. + /// + AllClasses = 4, + + /// DIGCF_PROFILE + /// Return only devices that are a part of the current hardware profile. + /// + Profile = 8, + + /// DIGCF_DEVICEINTERFACE + /// + /// Return devices that support device interfaces for the specified device interface classes. + /// This flag must be set in the Flags parameter if the Enumerator parameter specifies a Device Instance ID. + /// + /// + DeviceInterface = 16, + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/DirectoryEnumerationOptions.cs b/AlphaFS/Filesystem/Enumerations/DirectoryEnumerationOptions.cs new file mode 100644 index 0000000..fd9ce87 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/DirectoryEnumerationOptions.cs @@ -0,0 +1,62 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace Alphaleonis.Win32.Filesystem +{ + /// [AlphaFS] Directory enumeration options, flags that specify how a directory is to be enumerated. + [Flags] + public enum DirectoryEnumerationOptions + { + /// None (do not use). + None = 0, + + /// Enumerate files only. + Files = 1, + + /// Enumerate directories only. + Folders = 2, + + /// Enumerate files and directories. + FilesAndFolders = Files | Folders, + + /// Return full path as long full path (Unicode format), only valid when return type is . + AsLongPath = 4, + + /// Skip reparse points during directory enumeration. + SkipReparsePoints = 8, + + /// Suppress any Exception that might be thrown as a result from a failure, such as ACLs protected directories or non-accessible reparse points. + ContinueOnException = 16, + + /// Specifies whether to search the current directory, or the current directory and all subdirectories. + Recursive = 32, + + /// Enumerates the directory without querying the short file name, improving overall enumeration speed. + /// This option is enabled by default if supported. This value is not supported until Windows Server 2008 R2 and Windows 7. + BasicSearch = 64, + + /// Enumerates the directory using a larger buffer for directory queries, which can increase performance of the find operation. + /// This option is enabled by default if supported. This value is not supported until Windows Server 2008 R2 and Windows 7. + LargeCache = 128 + } +} diff --git a/AlphaFS/Filesystem/Enumerations/DosDeviceAttributes.cs b/AlphaFS/Filesystem/Enumerations/DosDeviceAttributes.cs new file mode 100644 index 0000000..c14589c --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/DosDeviceAttributes.cs @@ -0,0 +1,60 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +using System; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Defines the controllable aspects of the Volume.DefineDosDevice() method. + [Flags] + public enum DosDeviceAttributes + { + /// DDD_EXACT_MATCH_ON_REMOVE + /// Default. + /// + None = 0, + + /// DDD_RAW_TARGET_PATH + /// Uses the targetPath string as is. Otherwise, it is converted from an MS-DOS path to a path. + /// + RawTargetPath = 1, + + /// DDD_REMOVE_DEFINITION + /// Removes the specified definition for the specified device. + /// To determine which definition to remove, the function walks the list of mappings for the device, looking for a match of targetPath against a prefix of each mapping associated with this device. + /// The first mapping that matches is the one removed, and then the function returns. + /// If targetPath is null or a pointer to a null string, the function will remove the first mapping associated with the device and pop the most recent one pushed.If there is nothing left to pop, the device name will be removed. + /// If this value is not specified, the string pointed to by the targetPath parameter will become the new mapping for this device. + /// + RemoveDefinition = 2, + + /// DDD_EXACT_MATCH_ON_REMOVE + /// If this value is specified along with , the function will use an exact match to determine which mapping to remove. + /// Use this value to ensure that you do not delete something that you did not define. + /// + ExactMatchOnRemove = 4, + + /// DDD_NO_BROADCAST_SYSTEM + /// Do not broadcast the WM_SETTINGCHANGE message. + /// By default, this message is broadcast to notify the shell and applications of the change. + /// + NoBroadcastSystem = 8, + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/EncryptedFileRawMode.cs b/AlphaFS/Filesystem/Enumerations/EncryptedFileRawMode.cs new file mode 100644 index 0000000..a75e013 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/EncryptedFileRawMode.cs @@ -0,0 +1,45 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class NativeMethods + { + /// Indicates the operation to be performed when opening a file using the OpenEncryptedFileRaw. + [Flags] + internal enum EncryptedFileRawMode + { + /// (0) Open the file for export (backup). + CreateForExport = 0, + + /// (1) The file is being opened for import (restore). + CreateForImport = 1, + + /// (2) Import (restore) a directory containing encrypted files. This must be combined with one of the previous two flags to indicate the operation. + CreateForDir = 2, + + /// (4) Overwrite a hidden file on import. + OverwriteHidden = 4 + } + } +} diff --git a/AlphaFS/Filesystem/Enumerations/ErrorMode.cs b/AlphaFS/Filesystem/Enumerations/ErrorMode.cs new file mode 100644 index 0000000..44a6aa3 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/ErrorMode.cs @@ -0,0 +1,48 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Enum for struct ChangeErrorMode. + [Flags] + internal enum ErrorMode + { + /// Use the system default, which is to display all error dialog boxes. + SystemDefault = 0, + + /// The system does not display the critical-error-handler message box. Instead, the system sends the error to the calling process/thread. + FailCriticalErrors = 1, + + /// The system does not display the Windows Error Reporting dialog. + NoGpfaultErrorbox = 2, + + /// The system automatically fixes memory alignment faults and makes them invisible to the application. It does this for the calling process and any descendant processes. This feature is only supported by certain processor architectures. + NoAlignmentFaultExcept = 4, + + /// The system does not display a message box when it fails to find a file. Instead, the error is returned to the calling process/thread. + NoOpenFileErrorbox = 32768 + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/ExtendedFileAttributes.cs b/AlphaFS/Filesystem/Enumerations/ExtendedFileAttributes.cs new file mode 100644 index 0000000..c8e67e4 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/ExtendedFileAttributes.cs @@ -0,0 +1,143 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Specifies how the operating system should open a file. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2217:DoNotMarkEnumsWithFlags")] + [Flags] + public enum ExtendedFileAttributes + { + /// If you pass , the set of attributes is unspecified. explicitly sets no attributes. + None = 0, + + #region FILE_ATTRIBUTE - Attributes applying to any file + + /// The file is read only. Applications can read the file, but cannot write to or delete it. + /// Equals 1 + ReadOnly = FileAttributes.ReadOnly, + + /// The file is hidden. Do not include it in an ordinary directory listing. + /// Equals 2 + Hidden = FileAttributes.Hidden, + + /// The file is part of or used exclusively by an operating system. + /// Equals 4 + System = FileAttributes.System, + + /// The handle that identifies a directory. + /// Equals 16 + Directory = FileAttributes.Directory, + + /// The file should be archived. Applications use this attribute to mark files for backup or removal. + /// Equals 32 + Archive = FileAttributes.Archive, + + /// The file should be archived. Applications use this attribute to mark files for backup or removal. + /// Equals 64 + Device = FileAttributes.Device, + + /// The file does not have other attributes set. This attribute is valid only if used alone. + /// Equals 128 + Normal = FileAttributes.Normal, + + /// The file is being used for temporary storage. + /// Equals 256 + Temporary = FileAttributes.Temporary, + + /// A file that is a sparse file. + /// Equals 512 + SparseFile = FileAttributes.SparseFile, + + /// A file or directory that has an associated reparse point, or a file that is a symbolic link. + /// Equals 1024 + ReparsePoint = FileAttributes.ReparsePoint, + + /// A file or directory that is compressed. For a file, all of the data in the file is compressed. For a directory, compression is the default for newly created files and subdirectories. + /// Equals 2048 + Compressed = FileAttributes.Compressed, + + /// The data of a file is not immediately available. This attribute indicates that file data is physically moved to offline storage. This attribute is used by Remote Storage, the hierarchical storage management software. Applications should not arbitrarily change this attribute. + /// Equals 4096 + Offline = FileAttributes.Offline, + + /// The file or directory is not to be indexed by the content indexing service. + /// Equals 8192 + NotContentIndexed = FileAttributes.NotContentIndexed, + + /// The file or directory is encrypted. For a file, this means that all data in the file is encrypted. For a directory, this means that encryption is the default for newly created files and subdirectories. + /// Equals 16384 + Encrypted = FileOptions.Encrypted, + + #endregion // FILE_ATTRIBUTE - Attributes applying to any file + + /// The directory or user data stream is configured with integrity (only supported on ReFS volumes). It is not included in an ordinary directory listing. The integrity setting persists with the file if it's renamed. If a file is copied the destination file will have integrity set if either the source file or destination directory have integrity set. + /// This flag is not supported until Windows Server 2012. + IntegrityStream = 32768, + + /// The user data stream not to be read by the background data integrity scanner (AKA scrubber). When set on a directory it only provides inheritance. This flag is only supported on Storage Spaces and ReFS volumes. It is not included in an ordinary directory listing. + /// This flag is not supported until Windows Server 2012. + NoScrubData = 131072, + + /// ... + FirstPipeInstance = 524288, + + /// The file data is requested, but it should continue to be located in remote storage. It should not be transported back to local storage. This flag is for use by remote storage systems. + OpenNoRecall = 1048576, + + /// Normal reparse point processing will not occur; an attempt to open the reparse point will be made. When a file is opened, a file handle is returned, whether or not the filter that controls the reparse point is operational. See MSDN documentation for more information. + OpenReparsePoint = 2097152, + + /// Access will occur according to POSIX rules. This includes allowing multiple files with names, differing only in case, for file systems that support that naming. Use care when using this option, because files created with this flag may not be accessible by applications that are written for MS-DOS or 16-bit Windows. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Posix")] + PosixSemantics = 16777216, + + /// The file is being opened or created for a backup or restore operation. The system ensures that the calling process overrides file security checks when the process has SE_BACKUP_NAME and SE_RESTORE_NAME privileges. You must set this flag to obtain a handle to a directory. A directory handle can be passed to some functions instead of a file handle. + BackupSemantics = 33554432, + + /// The file is to be deleted immediately after all of its handles are closed, which includes the specified handle and any other open or duplicated handles. If there are existing open handles to a file, the call fails unless they were all opened with the share mode. Subsequent open requests for the file fail, unless the share mode is specified. + /// Equals 67108864 + DeleteOnClose = FileOptions.DeleteOnClose, + + /// Access is intended to be sequential from beginning to end. The system can use this as a hint to optimize file caching. + /// Equals 134217728 + SequentialScan = FileOptions.SequentialScan, + + /// Access is intended to be random. The system can use this as a hint to optimize file caching. + /// Equals 268435456 + RandomAccess = FileOptions.RandomAccess, + + /// There are strict requirements for successfully working with files opened with the flag, for details see the section on "File Buffering" in the online MSDN documentation. + NoBuffering = 536870912, + + /// The file or device is being opened or created for asynchronous I/O. + /// Equals 1073741824 + Overlapped = FileOptions.Asynchronous, + + /// Write operations will not go through any intermediate cache, they will go directly to disk. + /// Equals .NET -2147483648 + WriteThrough = FileOptions.WriteThrough + } +} diff --git a/AlphaFS/Filesystem/Enumerations/FINDEX_INFO_LEVELS.cs b/AlphaFS/Filesystem/Enumerations/FINDEX_INFO_LEVELS.cs new file mode 100644 index 0000000..40bf4b4 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/FINDEX_INFO_LEVELS.cs @@ -0,0 +1,44 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// FINDEX_INFO_LEVELS Enumeration - Defines values that are used with the FindFirstFileEx function to specify the information level of the returned data. + /// + /// Minimum supported client: Windows XP [desktop apps | Windows Store apps] + /// Minimum supported server: Windows Server 2003 [desktop apps | Windows Store apps] + /// + internal enum FINDEX_INFO_LEVELS + { + /// A standard set of attribute is returned in a structure. + Standard = 0, + + /// The FindFirstFileEx function does not query the short file name, improving overall enumeration speed. + /// This value is not supported until Windows Server 2008 R2 and Windows 7. + Basic = 1 + + ///// This value is used for validation. Supported values are less than this value. + //MaxLevel + } + } +} diff --git a/AlphaFS/Filesystem/Enumerations/FileEncryptionStatus.cs b/AlphaFS/Filesystem/Enumerations/FileEncryptionStatus.cs new file mode 100644 index 0000000..158c8ec --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/FileEncryptionStatus.cs @@ -0,0 +1,58 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Represents the encryption status of the specified file. + public enum FileEncryptionStatus + { + /// The file can be encrypted. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Encryptable")] + Encryptable = 0, + + /// The file is encrypted. + Encrypted = 1, + + /// The file is a system file. System files cannot be encrypted. + SystemFile = 2, + + /// The file is a root directory. Root directories cannot be encrypted. + RootDirectory = 3, + + /// The file is a system directory. System directories cannot be encrypted. + SystemDirectory = 4, + + /// The encryption status is unknown. The file may be encrypted. + Unknown = 5, + + /// The file system does not support file encryption. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Filesystem")] + NoFilesystemSupport = 6, + + /// Reserved for future use. + UserDisallowed = 7, + + /// The file is a read-only file. + ReadOnly = 8 + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/FileInfoByHandleClass.cs b/AlphaFS/Filesystem/Enumerations/FileInfoByHandleClass.cs new file mode 100644 index 0000000..a156e1c --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/FileInfoByHandleClass.cs @@ -0,0 +1,270 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// FILE_INFO_BY_HANDLE_CLASS + /// Identifies the type of file information that GetFileInformationByHandleEx should retrieve or SetFileInformationByHandle should set. + /// + internal enum FileInfoByHandleClass + { + #region FILE_BASIC_INFO + + /// FILE_BASIC_INFO + /// Minimal information for the file should be retrieved or set. Used for file handles. + /// + FileBasicInfo = 0, + + #endregion // FILE_BASIC_INFO + + #region FILE_STANDARD_INFO + + ///// FILE_STANDARD_INFO + ///// Extended information for the file should be retrieved. Used for file handles. + ///// Use only when calling GetFileInformationByHandleEx. + ///// + //FileStandardInfo = 1, + + #endregion // FILE_STANDARD_INFO + + #region FILE_NAME_INFO + + ///// FILE_NAME_INFO + ///// The file name should be retrieved. Used for any handles. + ///// Use only when calling GetFileInformationByHandleEx. + ///// + //FileNameInfo = 2, + + #endregion // FILE_NAME_INFO + + #region FILE_RENAME_INFO + + ///// FILE_RENAME_INFO + ///// The file name should be changed. Used for file handles. + ///// Use only when calling . + ///// + //FileRenameInfo = 3, + + #endregion // FILE_RENAME_INFO + + #region FILE_DISPOSITION_INFO + + ///// FILE_DISPOSITION_INFO + ///// The file should be deleted. Used for any handles. + ///// Use only when calling . + ///// + //FileDispositionInfo = 4, + + #endregion // FILE_DISPOSITION_INFO + + #region FILE_ALLOCATION_INFO + + ///// FILE_ALLOCATION_INFO + ///// The file allocation information should be changed. Used for file handles. + ///// Use only when calling . + ///// + //FileAllocationInfo = 5, + + #endregion // FILE_ALLOCATION_INFO + + #region FILE_END_OF_FILE_INFO + + ///// FILE_END_OF_FILE_INFO + ///// The end of the file should be set. Use only when calling . + ///// + //FileEndOfFileInfo = 6, + + #endregion // FILE_END_OF_FILE_INFO + + #region FILE_STREAM_INFO + + ///// FILE_STREAM_INFO + ///// File stream information for the specified file should be retrieved. Used for any handles. + ///// Use only when calling GetFileInformationByHandleEx. + ///// + //FileStreamInfo = 7, + + #endregion // FILE_STREAM_INFO + + #region FILE_COMPRESSION_INFO + + ///// FILE_COMPRESSION_INFO + ///// File compression information should be retrieved. Used for any handles. + ///// Use only when calling GetFileInformationByHandleEx. + ///// + //FileCompressionInfo = 8, + + #endregion // FILE_COMPRESSION_INFO + + #region FILE_ATTRIBUTE_TAG_INFO + + ///// FILE_ATTRIBUTE_TAG_INFO + ///// File attribute information should be retrieved. Used for any handles. + ///// Use only when calling GetFileInformationByHandleEx. + ///// + //FileAttributeTagInfo = 9, + + #endregion // FILE_ATTRIBUTE_TAG_INFO + + #region FILE_ID_BOTH_DIR_INFO + + /// FILE_ID_BOTH_DIR_INFO + /// Files in the specified directory should be retrieved. Used for directory handles. + /// Use only when calling GetFileInformationByHandleEx. + /// + /// The number of files returned for each call to GetFileInformationByHandleEx + /// depends on the size of the buffer that is passed to the function. + /// Any subsequent calls to GetFileInformationByHandleEx on the same handle + /// will resume the enumeration operation after the last file is returned. + /// + /// + FileIdBothDirectoryInfo = 10, + + #endregion // FILE_ID_BOTH_DIR_INFO + + #region FILE_ID_BOTH_DIR_INFO + + ///// FILE_ID_BOTH_DIR_INFO + ///// Identical to , but forces the enumeration operation to start again from the beginning. + ///// + //FileIdBothDirectoryInfoRestartInfo = 11, + + #endregion // FILE_ID_BOTH_DIR_INFO + + #region FILE_IO_PRIORITY_HINT_INFO + + ///// FILE_IO_PRIORITY_HINT_INFO + ///// Priority hint information should be set.Use only when calling . + ///// + //FileIoPriorityHintInfo = 12, + + #endregion // FILE_IO_PRIORITY_HINT_INFO + + #region FILE_REMOTE_PROTOCOL_INFO + + ///// (13) FILE_REMOTE_PROTOCOL_INFO + ///// File remote protocol information should be retrieved.Use for any handles. + ///// Use only when calling GetFileInformationByHandleEx. + ///// + //FileRemoteProtocolInfo = 13, + + #endregion // FILE_REMOTE_PROTOCOL_INFO + + #region FILE_FULL_DIR_INFO + + ///// (14) FILE_FULL_DIR_INFO + ///// Files in the specified directory should be retrieved. Used for directory handles. + ///// Use only when calling GetFileInformationByHandleEx. + ///// + ///// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: + ///// This value is not supported before Windows 8 and Windows Server 2012 + ///// + ///// + //FileFullDirectoryInfo = 14, + + #endregion // FILE_FULL_DIR_INFO + + #region FILE_FULL_DIR_INFO + + ///// FILE_FULL_DIR_INFO + ///// Identical to , but forces the enumeration operation to start again from the beginning. Use only when calling GetFileInformationByHandleEx. + ///// + ///// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: + ///// This value is not supported before Windows 8 and Windows Server 2012 + ///// + ///// + //FileFullDirectoryRestartInfo = 15, + + #endregion // FILE_FULL_DIR_INFO + + #region FILE_STORAGE_INFO + + ///// FILE_STORAGE_INFO + ///// File storage information should be retrieved. Use for any handles. + ///// Use only when calling GetFileInformationByHandleEx. + ///// + ///// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: + ///// This value is not supported before Windows 8 and Windows Server 2012 + ///// + ///// + //FileStorageInfo = 16, + + #endregion // FILE_STORAGE_INFO + + #region FILE_ALIGNMENT_INFO + + ///// FILE_ALIGNMENT_INFO + ///// File alignment information should be retrieved. Use for any handles. + ///// Use only when calling GetFileInformationByHandleEx. + ///// + ///// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: + ///// This value is not supported before Windows 8 and Windows Server 2012 + ///// + ///// + //FileAlignmentInfo = 17, + + #endregion FILE_ALIGNMENT_INFO + + #region FILE_ID_INFO + + ///// FILE_ID_INFO + ///// File information should be retrieved. Use for any handles. + ///// Use only when calling GetFileInformationByHandleEx. + ///// + ///// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: + ///// This value is not supported before Windows 8 and Windows Server 2012 + ///// + ///// + //FileIdInfo = 18, + + #endregion // FILE_ID_INFO + + #region FILE_ID_EXTD_DIR_INFO + + ///// FILE_ID_EXTD_DIR_INFO + ///// Files in the specified directory should be retrieved. Used for directory handles. + ///// Use only when calling GetFileInformationByHandleEx. + ///// + ///// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: + ///// This value is not supported before Windows 8 and Windows Server 2012 + ///// + ///// + //FileIdExtdDirectoryInfo = 19, + + #endregion // FILE_ID_EXTD_DIR_INFO + + #region FILE_ID_EXTD_DIR_INFO + + ///// FILE_ID_EXTD_DIR_INFO + ///// Identical to , but forces the enumeration operation to start again from the beginning. Use only when calling GetFileInformationByHandleEx. + ///// + ///// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: + ///// This value is not supported before Windows 8 and Windows Server 2012 + ///// + ///// + //FileIdExtdDirectoryRestartInfo = 20 + + #endregion // FILE_ID_EXTD_DIR_INFO + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/FinalPathFormats.cs b/AlphaFS/Filesystem/Enumerations/FinalPathFormats.cs new file mode 100644 index 0000000..8e5feea --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/FinalPathFormats.cs @@ -0,0 +1,45 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Determines the format to convert a path to using + [Flags] + public enum FinalPathFormats + { + /// (FileNameNormalized / VolumeNameDos) Return the normalized drive name. This is the default. + None = 0, + + /// Return the path with a volume GUID path instead of the drive name. + VolumeNameGuid = 1, + + /// Return the path with the volume device path. + VolumeNameNT = 2, + + /// Return the path with no drive information. + VolumeNameNone = 4, + + /// Return the opened file name (not normalized). + FileNameOpened = 8 + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/FindExAdditionalFlags.cs b/AlphaFS/Filesystem/Enumerations/FindExAdditionalFlags.cs new file mode 100644 index 0000000..3b7cdf4 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/FindExAdditionalFlags.cs @@ -0,0 +1,43 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Additional flags that control the search. + [Flags] + internal enum FindExAdditionalFlags + { + /// No additional flags used. + None = 0, + + /// Searches are case-sensitive. + CaseSensitive = 1, + + /// Uses a larger buffer for directory queries, which can increase performance of the find operation. + /// This value is not supported until Windows Server 2008 R2 and Windows 7. + LargeFetch = 2 + } + } +} diff --git a/AlphaFS/Filesystem/Enumerations/FindExSearchOps.cs b/AlphaFS/Filesystem/Enumerations/FindExSearchOps.cs new file mode 100644 index 0000000..c1eda52 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/FindExSearchOps.cs @@ -0,0 +1,57 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// FINDEX_SEARCH_OPS Enumeration - Defines values that are used with the FindFirstFileEx function to specify the type of filtering to perform. + /// + /// Minimum supported client: Windows XP [desktop apps | Windows Store apps] + /// Minimum supported server: Windows Server 2003 [desktop apps | Windows Store apps] + /// + internal enum FINDEX_SEARCH_OPS + { + /// The search for a file that matches a specified file name. + /// The lpSearchFilter parameter of FindFirstFileEx must be NULL when this search operation is used. + /// + SearchNameMatch = 0, + + /// This is an advisory flag. If the file system supports directory filtering, + /// the function searches for a file that matches the specified name and is also a directory. + /// If the file system does not support directory filtering, this flag is silently ignored. + ///   + /// + /// The lpSearchFilter parameter of the FindFirstFileEx function must be NULL when this search value is used. + /// If directory filtering is desired, this flag can be used on all file systems, + /// but because it is an advisory flag and only affects file systems that support it, + /// the application must examine the file attribute data stored in the lpFindFileData parameter + /// of the FindFirstFileEx function to determine whether the function has returned a handle to a directory. + /// + /// + SearchLimitToDirectories = 1, + + /// This filtering type is not available. + /// For more information, see Device Interface Classes. + SearchLimitToDevices = 2 + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/GetFileExInfoLevels.cs b/AlphaFS/Filesystem/Enumerations/GetFileExInfoLevels.cs new file mode 100644 index 0000000..4eb25a6 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/GetFileExInfoLevels.cs @@ -0,0 +1,33 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Defines values that are used with the GetFileAttributesEx and GetFileAttributesTransacted functions to specify the information level of the returned data. + public enum GetFileExInfoLevels + { + /// The GetFileAttributesEx or GetFileAttributesTransacted function retrieves a standard set of attribute information. The data is returned in a WIN32_FILE_ATTRIBUTE_DATA structure. + GetFileExInfoStandard = 0 + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/GetFullPathOptions.cs b/AlphaFS/Filesystem/Enumerations/GetFullPathOptions.cs new file mode 100644 index 0000000..ec6999c --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/GetFullPathOptions.cs @@ -0,0 +1,60 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace Alphaleonis.Win32.Filesystem +{ + /// A bitfield of flags for specifying options for various internal operations that convert paths to full paths. + [Flags] + public enum GetFullPathOptions + { + /// No special options applies. + None = 0, + + /// Remove any trailing whitespace from the path. + TrimEnd = 1, + + /// Add a trailing directory separator to the path (if one does not already exist). + AddTrailingDirectorySeparator = 2, + + /// Remove the trailing directory separator from the path (if one exists). + RemoveTrailingDirectorySeparator = 4, + + /// Return full path as long full path (Unicode format). Not valid for . + AsLongPath = 8, + + /// Prevents any exception from being thrown if a filesystem object does not exist. Not valid for . + ContinueOnNonExist = 16, + + /// Check that the path contains only valid path-characters. + CheckInvalidPathChars = 32, + + /// Also check for wildcard (? and *) characters. + CheckAdditional = 64, + + /// Do not trim the trailing dot or space. + KeepDotOrSpace = 128, + + /// Performs both and checks. + FullCheck = CheckInvalidPathChars | CheckAdditional + } +} diff --git a/AlphaFS/Filesystem/Enumerations/MoveOptions.cs b/AlphaFS/Filesystem/Enumerations/MoveOptions.cs new file mode 100644 index 0000000..c2e4e29 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/MoveOptions.cs @@ -0,0 +1,83 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Used by MoveFileXxx.Flags that specify how a file or directory is to be moved. + [Flags] + public enum MoveOptions + { + /// No MoveOptions used, this fails when the file name already exists. + None = 0, + + /// MOVE_FILE_REPLACE_EXISTSING + /// If the destination file name already exists, the function replaces its contents with the contents of the source file. + /// This value cannot be used if lpNewFileName or lpExistingFileName names a directory. + /// This value cannot be used if either source or destination names a directory. + /// + ReplaceExisting = 1, + + /// MOVE_FILE_COPY_ALLOWED + /// If the file is to be moved to a different volume, the function simulates the move by using the CopyFile and DeleteFile functions. + /// This value cannot be used with . + /// + CopyAllowed = 2, + + /// MOVE_FILE_DELAY_UNTIL_REBOOT + /// + /// The system does not move the file until the operating system is restarted. + /// The system moves the file immediately after AUTOCHK is executed, but before creating any paging files. + /// + /// + /// Consequently, this parameter enables the function to delete paging files from previous startups. + /// This value can only be used if the process is in the context of a user who belongs to the administrators group or the LocalSystem account. + /// + /// This value cannot be used with . + /// + DelayUntilReboot = 4, + + /// MOVE_FILE_WRITE_THROUGH + /// The function does not return until the file has actually been moved on the disk. + /// + /// Setting this value guarantees that a move performed as a copy and delete operation is flushed to disk before the function returns. + /// The flush occurs at the end of the copy operation. + /// + /// This value has no effect if is set. + /// + WriteThrough = 8, + + /// MOVE_FILE_CREATE_HARDLINK + /// Reserved for future use. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hardlink")] + CreateHardlink = 16, + + /// MOVE_FILE_FAIL_IF_NOT_TRACKABLE + /// The function fails if the source file is a link source, but the file cannot be tracked after the move. + /// This situation can occur if the destination is a volume formatted with the FAT file system. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Trackable")] + FailIfNotTrackable = 32 + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/PathFormat.cs b/AlphaFS/Filesystem/Enumerations/PathFormat.cs new file mode 100644 index 0000000..e2c6b60 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/PathFormat.cs @@ -0,0 +1,59 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + /// Indicates the format of a path passed to a method. + /// + /// At some point in code you know the full path of file system objects, e.g.: "C:\Windows". + /// For example, Directory.EnumerateFileSystemEntries() will return all files and directories from a given path. + /// Most likely, some processing will happen on the results of the enum. The file or directory may be passed + /// on to another function. Whenever a file path is required, some performance can be gained. + ///   + /// A path like: "C:\Windows" or "\\server\share" is considered a full path for a directory because it is rooted and has a drive/unc path. + /// If the method supports it, and will skip GetFullPath() + /// calls for path resolving of the object, while also avoiding path validation and checks. + /// Using (default) will always call GetFullPath() and perform path validation and checks. + ///   + /// When working in a loop with thousands of files, will give the best performance. + /// + public enum PathFormat + { + /// The format of the path is automatically detected by the method and internally converted to an extended length path. + /// It can be either a standard (short) full path, an extended length (unicode) full path or a relative path. + /// Example relative path: "Windows". + /// + RelativePath, + + /// The path is a full path in either normal or extended length (UNICODE) format. + /// Internally it will be converted to an extended length (UNICODE) path. + /// Using this option has a very slight performance advantage compared to using . + /// Example full path: "C:\Windows" or "\\server\share". + /// + FullPath, + + /// The path is an extended length path. No additional processing will be done on the path, and it will be used as is. + /// Using this option has a slight performance advantage compared to using . + /// Example long full path: "\\?\C:\Windows" or "\\?\UNC\server\share". + /// + LongFullPath + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/ReparsePointTag.cs b/AlphaFS/Filesystem/Enumerations/ReparsePointTag.cs new file mode 100644 index 0000000..894f460 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/ReparsePointTag.cs @@ -0,0 +1,106 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Enumeration specifying the different reparse point tags. + /// + /// Reparse tags, with the exception of IO_REPARSE_TAG_SYMLINK, are processed on the server and are not processed by a client after transmission over the wire. + /// Clients should treat associated reparse data as opaque data. + /// + public enum ReparsePointTag + { + /// The entry is not a reparse point. + None = 0, + + /// IO_REPARSE_APPXSTREAM + AppXStream = unchecked ((int) 3221225492), + + /// IO_REPARSE_TAG_CSV + Csv = unchecked ((int) 2147483657), + + /// IO_REPARSE_TAG_DRIVER_EXTENDER + /// Used by Home server drive extender. + /// + DriverExtender = unchecked ((int) 2147483653), + + /// IO_REPARSE_TAG_DEDUP + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dedup")] + Dedup = unchecked ((int) 2147483667), + + /// IO_REPARSE_TAG_DFS + /// Used by the DFS filter. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + Dfs = unchecked ((int) 2147483658), + + /// IO_REPARSE_TAG_DFSR + /// Used by the DFS filter. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfsr")] + Dfsr = unchecked ((int) 2147483666), + + /// IO_REPARSE_TAG_FILTER_MANAGER + /// Used by filter manager test harness. + /// + FilterManager = unchecked ((int) 2147483659), + + /// IO_REPARSE_TAG_HSM + /// (Obsolete) Used by legacy Hierarchical Storage Manager Product. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hsm")] + Hsm = unchecked ((int) 3221225476), + + /// IO_REPARSE_TAG_HSM2 + /// (Obsolete) Used by legacy Hierarchical Storage Manager Product. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hsm")] + Hsm2 = unchecked ((int) 2147483654), + + /// IO_REPARSE_TAG_NFS + /// NFS symlinks, Windows 8 / SMB3 and later. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Nfs")] + Nfs = unchecked ((int) 2147483668), + + /// IO_REPARSE_TAG_MOUNT_POINT + /// Used for mount point support. + /// + MountPoint = unchecked ((int) 2684354563), + + /// IO_REPARSE_TAG_SIS + /// Used by single-instance storage (SIS) filter driver. + /// + Sis = unchecked ((int) 2147483655), + + /// IO_REPARSE_TAG_SYMLINK + /// Used for symbolic link support. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sym")] + SymLink = unchecked ((int) 2684354572), + + /// IO_REPARSE_TAG_WIM + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Wim")] + Wim = unchecked ((int) 2147483656) + } +} diff --git a/AlphaFS/Filesystem/Enumerations/STREAM_INFO_LEVELS.cs b/AlphaFS/Filesystem/Enumerations/STREAM_INFO_LEVELS.cs new file mode 100644 index 0000000..44b2a53 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/STREAM_INFO_LEVELS.cs @@ -0,0 +1,40 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Defines values that are used with the FindFirstStreamW function to specify the information level of the returned data. + /// + /// Minimum supported client: Windows Vista [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + internal enum STREAM_INFO_LEVELS + { + /// The FindFirstStreamW function retrieves standard stream information. The data is returned in a structure. + FindStreamInfoStandard = 0, + + /// Used to determine valid enumeration values. All supported enumeration values are less than FindStreamInfoMaxInfoLevel. + FindStreamInfoMaxInfoLevel = 1 + } + } +} diff --git a/AlphaFS/Filesystem/Enumerations/SetupDiGetDeviceRegistryPropertyEnum.cs b/AlphaFS/Filesystem/Enumerations/SetupDiGetDeviceRegistryPropertyEnum.cs new file mode 100644 index 0000000..b8121e1 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/SetupDiGetDeviceRegistryPropertyEnum.cs @@ -0,0 +1,169 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Flags for SetupDiGetDeviceRegistryProperty(). + internal enum SetupDiGetDeviceRegistryPropertyEnum + { + /// SPDRP_DEVICEDESC + /// Represents a description of a device instance. + /// + DeviceDescription = 0, + + /// SPDRP_HARDWAREID + /// Represents the list of hardware identifiers for a device instance. + /// + HardwareId = 1, + + /// SPDRP_COMPATIBLEIDS + /// Represents the list of compatible identifiers for a device instance. + /// + CompatibleIds = 2, + + //SPDRP_UNUSED0 = 0x00000003, + + /// SPDRP_CLASS + /// Represents the name of the service that is installed for a device instance. + /// + Service = 4, + + //SPDRP_UNUSED1 = 0x00000005, + //SPDRP_UNUSED2 = 0x00000006, + + /// SPDRP_CLASS + /// Represents the name of the device setup class that a device instance belongs to. + /// + Class = 7, + + /// SPDRP_CLASSGUID + /// Represents the of the device setup class that a device instance belongs to. + /// + ClassGuid = 8, + + /// SPDRP_DRIVER + /// Represents the registry entry name of the driver key for a device instance. + /// + Driver = 9, + + ///// SPDRP_CONFIGFLAGS + ///// Represents the configuration flags that are set for a device instance. + ///// + //ConfigurationFlags = 10, + + /// SPDRP_MFG + /// Represents the name of the manufacturer of a device instance. + /// + Manufacturer = 11, + + /// SPDRP_FRIENDLYNAME + /// Represents the friendly name of a device instance. + /// + FriendlyName = 12, + + /// SPDRP_LOCATION_INFORMATION + /// Represents the bus-specific physical location of a device instance. + /// + LocationInformation = 13, + + /// SPDRP_PHYSICAL_DEVICE_LOCATION + /// Encapsulates the physical device location information provided by a device's firmware to Windows. + /// + PhysicalDeviceObjectName = 14, + + ///// SPDRP_CAPABILITIES + //// Represents the capabilities of a device instance. + //// + //Capabilities = 15, + + ///// SPDRP_UI_NUMBER - Represents a number for the device instance that can be displayed in a user interface item. + //UiNumber = 16, + + ///// SPDRP_UPPERFILTERS - Represents a list of the service names of the upper-level filter drivers that are installed for a device instance. + //UpperFilters = 17, + + ///// SPDRP_LOWERFILTERS - Represents a list of the service names of the lower-level filter drivers that are installed for a device instance. + //LowerFilters = 18, + + ///// SPDRP_BUSTYPEGUID - Represents the that identifies the bus type of a device instance. + //BusTypeGuid = 19, + + ///// SPDRP_LEGACYBUSTYPE - Represents the legacy bus number of a device instance. + //LegacyBusType = 20, + + ///// SPDRP_BUSNUMBER - Represents the number that identifies the bus instance that a device instance is attached to. + //BusNumber = 21, + + /// SPDRP_ENUMERATOR_NAME + /// Represents the name of the enumerator for a device instance. + /// + EnumeratorName = 22, + + ///// SPDRP_SECURITY - Represents a security descriptor structure for a device instance. + //Security = 23, + + ///// SPDRP_SECURITY_SDS - Represents a security descriptor string for a device instance. + //SecuritySds = 24, + + ///// SPDRP_DEVTYPE - Represents the device type of a device instance. + //DeviceType = 25, + + ///// SPDRP_EXCLUSIVE - Represents a Boolean value that determines whether a device instance can be opened for exclusive use. + //Exclusive = 26, + + ///// SPDRP_CHARACTERISTICS - Represents the characteristics of a device instance. + //Characteristics = 27, + + ///// SPDRP_ADDRESS - Represents the bus-specific address of a device instance. + //Address = 28, + + ///// SPDRP_UI_NUMBER_DESC_FORMAT - Represents a printf-compatible format string that you should use to display the value of the device property for a device instance. + //UiNumberDescriptionFormat = 29, + + ///// SPDRP_DEVICE_POWER_DATA - Represents power information about a device instance. + //DevicePowerData = 30, + + ///// SPDRP_REMOVAL_POLICY - Represents the current removal policy for a device instance. + //RemovalPolicy = 31, + + ///// SPDRP_REMOVAL_POLICY_HW_DEFAULT - Represents the default removal policy for a device instance. + //RemovalPolicyDefault = 32, + + ///// SPDRP_REMOVAL_POLICY_OVERRIDE- Represents the removal policy override for a device instance. + //RemovalPolicyOverride = 33, + + ///// SPDRP_INSTALL_STATE - Represents the installation state of a device instance. + //InstallState = 34, + + /// SPDRP_LOCATION_PATHS + /// Represents the location of a device instance in the device tree. + /// + LocationPaths = 35, + + /// SPDRP_BASE_CONTAINERID + /// Represents the value of the base container identifier (ID) .The Windows Plug and Play (PnP) manager assigns this value to the device node (devnode). + /// + BaseContainerId = 36 + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/StreamAttributes.cs b/AlphaFS/Filesystem/Enumerations/StreamAttributes.cs new file mode 100644 index 0000000..869c55f --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/StreamAttributes.cs @@ -0,0 +1,56 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace Alphaleonis.Win32.Filesystem +{ + /// WIN32_STREAM_ID Attributes of data to facilitate cross-operating system transfer. + [Flags] + public enum StreamAttributes + { + /// STREAM_NORMAL_ATTRIBUTE + /// This backup stream has no special attributes. + /// + None = 0, + + /// STREAM_MODIFIED_WHEN_READ + /// Attribute set if the stream contains data that is modified when read. + /// Allows the backup application to know that verification of data will fail. + /// + ModifiedWhenRead = 1, + + /// STREAM_CONTAINS_SECURITY + /// The backup stream contains security information. + /// This attribute applies only to backup stream of type . + /// + ContainsSecurity = 2, + + /// Reserved. + ContainsProperties = 4, + + /// STREAM_SPARSE_ATTRIBUTE + /// The backup stream is part of a sparse file stream. + /// This attribute applies only to backup stream of type , , and . + /// + Sparse = 8 + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/SymbolicLinkTarget.cs b/AlphaFS/Filesystem/Enumerations/SymbolicLinkTarget.cs new file mode 100644 index 0000000..485a094 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/SymbolicLinkTarget.cs @@ -0,0 +1,34 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + /// Indicates whether the link target is a file or directory. + /// Used by Win32 API CreateSymbolicLink()/CreateSymbolicLinkTransacted() + public enum SymbolicLinkTarget + { + /// The link target is a file. + File = 0, + + /// The link target is a directory. + Directory = 1 + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/SymbolicLinkType.cs b/AlphaFS/Filesystem/Enumerations/SymbolicLinkType.cs new file mode 100644 index 0000000..6559169 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/SymbolicLinkType.cs @@ -0,0 +1,33 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + /// Specifies the type of a symbolic link. + public enum SymbolicLinkType + { + /// The symbolic link is absolute. + Absolute = 0, + + /// The symbolic link is relative. + Relative = 1, + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Enumerations/VolumeInfoAttributes.cs b/AlphaFS/Filesystem/Enumerations/VolumeInfoAttributes.cs new file mode 100644 index 0000000..e9cc092 --- /dev/null +++ b/AlphaFS/Filesystem/Enumerations/VolumeInfoAttributes.cs @@ -0,0 +1,144 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Volume Attributes used by the GetVolumeInfo() function. + [Flags] + internal enum VolumeInfoAttributes + { + /// No VolumeInfo attributes. + None = 0, + + /// FILE_CASE_SENSITIVE_SEARCH + /// The specified volume supports case-sensitive file names. + /// + CaseSensitiveSearch = 1, + + /// FILE_CASE_PRESERVED_NAMES + /// The specified volume supports preserved case of file names when it places a name on disk. + /// + CasePreservedNames = 2, + + /// FILE_UNICODE_ON_DISK + /// The specified volume supports Unicode in file names as they appear on disk. + /// + UnicodeOnDisk = 4, + + /// FILE_PERSISTENT_ACLS + /// + /// The specified volume preserves and enforces access control lists (ACL). + /// For example, the NTFS file system preserves and enforces ACLs, and the FAT file system does not. + /// + /// + PersistentAcls = 8, + + /// FILE_FILE_COMPRESSION + /// The specified volume supports file-based compression. + /// + Compression = 16, + + /// FILE_VOLUME_QUOTAS + /// The specified volume supports disk quotas. + /// + VolumeQuotas = 32, + + /// FILE_SUPPORTS_SPARSE_FILES + /// The specified volume supports sparse files. + /// + SupportsSparseFiles = 64, + + /// FILE_SUPPORTS_REPARSE_POINTS + /// The specified volume supports re-parse points. + /// + SupportsReparsePoints = 128, + + /// (does not appear on MSDN) + SupportsRemoteStorage = 256, + + /// FILE_VOLUME_IS_COMPRESSED + /// The specified volume is a compressed volume, for example, a DoubleSpace volume. + /// + VolumeIsCompressed = 32768, + + /// FILE_SUPPORTS_OBJECT_IDS + /// The specified volume supports object identifiers. + /// + SupportsObjectIds = 65536, + + /// FILE_SUPPORTS_ENCRYPTION + /// The specified volume supports the Encrypted File System (EFS). For more information, see File Encryption. + /// + SupportsEncryption = 131072, + + /// FILE_NAMED_STREAMS + /// The specified volume supports named streams. + /// + NamedStreams = 262144, + + /// FILE_READ_ONLY_VOLUME + /// The specified volume is read-only. + /// + ReadOnlyVolume = 524288, + + /// FILE_SEQUENTIAL_WRITE_ONCE + /// The specified volume is read-only. + /// + SequentialWriteOnce = 1048576, + + /// FILE_SUPPORTS_TRANSACTIONS + /// The specified volume supports transactions.For more information, see About KTM. + /// + SupportsTransactions = 2097152, + + /// FILE_SUPPORTS_HARD_LINKS + /// The specified volume supports hard links. For more information, see Hard Links and Junctions. + /// + /// Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: This value is not supported until Windows Server 2008 R2 and Windows 7. + SupportsHardLinks = 4194304, + + /// FILE_SUPPORTS_EXTENDED_ATTRIBUTES + /// + /// The specified volume supports extended attributes. An extended attribute is a piece of application-specific metadata + /// that an application can associate with a file and is not part of the file's data. + /// + /// + /// Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: This value is not supported until Windows Server 2008 R2 and Windows 7. + SupportsExtendedAttributes = 8388608, + + /// FILE_SUPPORTS_OPEN_BY_FILE_ID + /// The file system supports open by FileID. For more information, see FILE_ID_BOTH_DIR_INFO. + /// + /// Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: This value is not supported until Windows Server 2008 R2 and Windows 7. + SupportsOpenByFileId = 16777216, + + /// FILE_SUPPORTS_USN_JOURNAL + /// The specified volume supports update sequence number (USN) journals. For more information, see Change Journal Records. + /// + /// Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: This value is not supported until Windows Server 2008 R2 and Windows 7. + SupportsUsnJournal = 33554432 + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Exceptions/AlreadyExistsException.cs b/AlphaFS/Filesystem/Exceptions/AlreadyExistsException.cs new file mode 100644 index 0000000..5f67e09 --- /dev/null +++ b/AlphaFS/Filesystem/Exceptions/AlreadyExistsException.cs @@ -0,0 +1,58 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.Serialization; + +namespace Alphaleonis.Win32.Filesystem +{ + /// The exception that is thrown when an attempt to create a directory or file that already exists was made. + [Serializable] + public class AlreadyExistsException : System.IO.IOException + { + private static readonly int s_errorCode = Win32Errors.GetHrFromWin32Error(Win32Errors.ERROR_ALREADY_EXISTS); + + /// Initializes a new instance of the class. + public AlreadyExistsException() : base(Resources.File_Or_Directory_Already_Exists, s_errorCode) + { + } + + /// Initializes a new instance of the class. + /// The message. + public AlreadyExistsException(string message) : base(message, s_errorCode) + { + } + + /// Initializes a new instance of the class. + /// The message. + /// The inner exception. + public AlreadyExistsException(string message, Exception innerException) : base(message, innerException) + { + } + + /// Initializes a new instance of the class. + /// The data for serializing or deserializing the object. + /// The source and destination for the object. + protected AlreadyExistsException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} diff --git a/AlphaFS/Filesystem/Exceptions/DeviceNotReadyException.cs b/AlphaFS/Filesystem/Exceptions/DeviceNotReadyException.cs new file mode 100644 index 0000000..1c4cd44 --- /dev/null +++ b/AlphaFS/Filesystem/Exceptions/DeviceNotReadyException.cs @@ -0,0 +1,62 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.Serialization; + +namespace Alphaleonis.Win32.Filesystem +{ + /// The requested operation could not be completed because the device was not ready. + [Serializable] + public class DeviceNotReadyException : System.IO.IOException + { + private static readonly int s_errorCode = Win32Errors.GetHrFromWin32Error(Win32Errors.ERROR_NOT_READY); + + /// Initializes a new instance of the class. + public DeviceNotReadyException() + : base(Resources.Device_Not_Ready, s_errorCode) + { + } + + /// Initializes a new instance of the class. + /// The message. + public DeviceNotReadyException(string message) + : base(message, s_errorCode) + { + } + + /// Initializes a new instance of the class. + /// The message. + /// The inner exception. + public DeviceNotReadyException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// Initializes a new instance of the class. + /// The data for serializing or deserializing the object. + /// The source and destination for the object. + protected DeviceNotReadyException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} diff --git a/AlphaFS/Filesystem/Exceptions/DirectoryNotEmptyException.cs b/AlphaFS/Filesystem/Exceptions/DirectoryNotEmptyException.cs new file mode 100644 index 0000000..b321980 --- /dev/null +++ b/AlphaFS/Filesystem/Exceptions/DirectoryNotEmptyException.cs @@ -0,0 +1,59 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Globalization; +using System.Runtime.Serialization; + +namespace Alphaleonis.Win32.Filesystem +{ + /// The operation could not be completed because the directory was not empty. + [Serializable] + public class DirectoryNotEmptyException : System.IO.IOException + { + private static readonly int s_errorCode = Win32Errors.GetHrFromWin32Error(Win32Errors.ERROR_DIR_NOT_EMPTY); + + /// Initializes a new instance of the class. + public DirectoryNotEmptyException() : base(string.Format(CultureInfo.CurrentCulture, "({0}) The directory is not empty", Win32Errors.ERROR_DIR_NOT_EMPTY), s_errorCode) + { + } + + /// Initializes a new instance of the class. + /// The message. + public DirectoryNotEmptyException(string message) : base(string.Format(CultureInfo.CurrentCulture, "({0}) The directory is not empty: [{1}]", Win32Errors.ERROR_DIR_NOT_EMPTY, message), s_errorCode) + { + } + + /// Initializes a new instance of the class. + /// The message. + /// The inner exception. + public DirectoryNotEmptyException(string message, Exception innerException) : base(string.Format(CultureInfo.CurrentCulture, "({0}) The directory is not empty: [{1}]", Win32Errors.ERROR_DIR_NOT_EMPTY, message), innerException) + { + } + + /// Initializes a new instance of the class. + /// The data for serializing or deserializing the object. + /// The source and destination for the object. + protected DirectoryNotEmptyException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Exceptions/DirectoryReadOnlyException.cs b/AlphaFS/Filesystem/Exceptions/DirectoryReadOnlyException.cs new file mode 100644 index 0000000..be8bd0f --- /dev/null +++ b/AlphaFS/Filesystem/Exceptions/DirectoryReadOnlyException.cs @@ -0,0 +1,59 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Globalization; +using System.Runtime.Serialization; + +namespace Alphaleonis.Win32.Filesystem +{ + /// The operation could not be completed because the directory is read-only. + [Serializable] + public class DirectoryReadOnlyException : System.IO.IOException + { + private static readonly int s_errorCode = Win32Errors.GetHrFromWin32Error(Win32Errors.ERROR_FILE_READ_ONLY); + + /// Initializes a new instance of the class. + public DirectoryReadOnlyException() : base(string.Format(CultureInfo.CurrentCulture, "({0}) The directory is read-only", Win32Errors.ERROR_FILE_READ_ONLY), s_errorCode) + { + } + + /// Initializes a new instance of the class. + /// The message. + public DirectoryReadOnlyException(string message) : base(string.Format(CultureInfo.CurrentCulture, "({0}) The directory is read-only: [{1}]", Win32Errors.ERROR_FILE_READ_ONLY, message), s_errorCode) + { + } + + /// Initializes a new instance of the class. + /// The message. + /// The inner exception. + public DirectoryReadOnlyException(string message, Exception innerException) : base(string.Format(CultureInfo.CurrentCulture, "({0}) The directory is read-only: [{1}]", Win32Errors.ERROR_FILE_READ_ONLY, message), innerException) + { + } + + /// Initializes a new instance of the class. + /// The data for serializing or deserializing the object. + /// The source and destination for the object. + protected DirectoryReadOnlyException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Exceptions/FileReadOnlyException.cs b/AlphaFS/Filesystem/Exceptions/FileReadOnlyException.cs new file mode 100644 index 0000000..4fb197d --- /dev/null +++ b/AlphaFS/Filesystem/Exceptions/FileReadOnlyException.cs @@ -0,0 +1,57 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Globalization; +using System.Runtime.Serialization; + +namespace Alphaleonis.Win32.Filesystem +{ + /// The operation could not be completed because the file is read-only. + [Serializable] + public class FileReadOnlyException : UnauthorizedAccessException + { + /// Initializes a new instance of the class. + public FileReadOnlyException() : base(string.Format(CultureInfo.CurrentCulture, "({0}) The file is read-only.", Win32Errors.ERROR_FILE_READ_ONLY)) + { + } + + /// Initializes a new instance of the class. + /// The message. + public FileReadOnlyException(string message) : base(string.Format(CultureInfo.CurrentCulture, "({0}) The file is read-only: [{1}]", Win32Errors.ERROR_FILE_READ_ONLY, message)) + { + } + + /// Initializes a new instance of the class. + /// The message. + /// The inner exception. + public FileReadOnlyException(string message, Exception innerException) : base(string.Format(CultureInfo.CurrentCulture, "({0}) The file is read-only: [{1}]", Win32Errors.ERROR_FILE_READ_ONLY, message), innerException) + { + } + + /// Initializes a new instance of the class. + /// The data for serializing or deserializing the object. + /// The source and destination for the object. + protected FileReadOnlyException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Exceptions/InvalidTransactionException.cs b/AlphaFS/Filesystem/Exceptions/InvalidTransactionException.cs new file mode 100644 index 0000000..caa737d --- /dev/null +++ b/AlphaFS/Filesystem/Exceptions/InvalidTransactionException.cs @@ -0,0 +1,59 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.Serialization; + +namespace Alphaleonis.Win32.Filesystem +{ + /// The transaction handle associated with this operation is not valid. + [SerializableAttribute] + public class InvalidTransactionException : TransactionException + { + /// Initializes a new instance of the class. + public InvalidTransactionException() + { + } + + /// Initializes a new instance of the class. + /// The message. + public InvalidTransactionException(string message) + : base(message) + { + } + + /// Initializes a new instance of the class. + /// The message. + /// The inner exception. + public InvalidTransactionException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// Initializes a new instance of the class. + /// The data for serializing or deserializing the object. + /// The source and destination for the object. + protected InvalidTransactionException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Exceptions/NotAReparsePointException.cs b/AlphaFS/Filesystem/Exceptions/NotAReparsePointException.cs new file mode 100644 index 0000000..7124206 --- /dev/null +++ b/AlphaFS/Filesystem/Exceptions/NotAReparsePointException.cs @@ -0,0 +1,62 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.Serialization; + +namespace Alphaleonis.Win32.Filesystem +{ + /// The file or directory was not a reparse point. + [SerializableAttribute] + public class NotAReparsePointException : System.IO.IOException + { + private static readonly int s_errorCode = Win32Errors.GetHrFromWin32Error(Win32Errors.ERROR_NOT_A_REPARSE_POINT); + + /// Initializes a new instance of the class. + public NotAReparsePointException() + : base(Resources.Not_A_Reparse_Point, s_errorCode) + { + } + + /// Initializes a new instance of the class. + /// The message. + public NotAReparsePointException(string message) + : base(message, s_errorCode) + { + } + + /// Initializes a new instance of the class. + /// The message. + /// The inner exception. + public NotAReparsePointException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// Initializes a new instance of the class. + /// The info. + /// The context. + protected NotAReparsePointException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} diff --git a/AlphaFS/Filesystem/Exceptions/TransactionAlreadyAbortedException.cs b/AlphaFS/Filesystem/Exceptions/TransactionAlreadyAbortedException.cs new file mode 100644 index 0000000..a6163ab --- /dev/null +++ b/AlphaFS/Filesystem/Exceptions/TransactionAlreadyAbortedException.cs @@ -0,0 +1,59 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.Serialization; + +namespace Alphaleonis.Win32.Filesystem +{ + /// It is too late to perform the requested operation, since the Transaction has already been aborted. + [SerializableAttribute] + public class TransactionAlreadyAbortedException : TransactionException + { + /// Initializes a new instance of the class. + public TransactionAlreadyAbortedException() + { + } + + /// Initializes a new instance of the class. + /// The message. + public TransactionAlreadyAbortedException(string message) + : base(message) + { + } + + /// Initializes a new instance of the class. + /// The message. + /// The inner exception. + public TransactionAlreadyAbortedException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// Initializes a new instance of the class. + /// The info. + /// The context. + protected TransactionAlreadyAbortedException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Exceptions/TransactionAlreadyCommittedException.cs b/AlphaFS/Filesystem/Exceptions/TransactionAlreadyCommittedException.cs new file mode 100644 index 0000000..99dcbe2 --- /dev/null +++ b/AlphaFS/Filesystem/Exceptions/TransactionAlreadyCommittedException.cs @@ -0,0 +1,59 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.Serialization; + +namespace Alphaleonis.Win32.Filesystem +{ + /// It is too late to perform the requested operation, since the Transaction has already been committed. + [SerializableAttribute] + public class TransactionAlreadyCommittedException : TransactionException + { + /// Initializes a new instance of the class. + public TransactionAlreadyCommittedException() + { + } + + /// Initializes a new instance of the class. + /// The message. + public TransactionAlreadyCommittedException(string message) + : base(message) + { + } + + /// Initializes a new instance of the class. + /// The message. + /// The inner exception. + public TransactionAlreadyCommittedException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// Initializes a new instance of the class. + /// The object that holds the serialized object data. + /// The contextual information about the source or destination. + protected TransactionAlreadyCommittedException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Exceptions/TransactionException.cs b/AlphaFS/Filesystem/Exceptions/TransactionException.cs new file mode 100644 index 0000000..5b17e3c --- /dev/null +++ b/AlphaFS/Filesystem/Exceptions/TransactionException.cs @@ -0,0 +1,59 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.Serialization; + +namespace Alphaleonis.Win32.Filesystem +{ + /// The exception that is thrown when an attempt to create a file or directory that already exists was made. + [SerializableAttribute] + public class TransactionException : SystemException + { + /// Initializes a new instance of the class. + public TransactionException() + { + } + + /// Initializes a new instance of the class. + /// The message. + public TransactionException(string message) + : base(message) + { + } + + /// Initializes a new instance of the class. + /// The message. + /// The inner exception. + public TransactionException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// Initializes a new instance of the class. + /// The data for serializing or deserializing the object. + /// The source and destination for the object. + protected TransactionException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Exceptions/TransactionalConflictException.cs b/AlphaFS/Filesystem/Exceptions/TransactionalConflictException.cs new file mode 100644 index 0000000..81d69c6 --- /dev/null +++ b/AlphaFS/Filesystem/Exceptions/TransactionalConflictException.cs @@ -0,0 +1,59 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.Serialization; + +namespace Alphaleonis.Win32.Filesystem +{ + /// The function attempted to use a name that is reserved for use by another transaction. + [SerializableAttribute] + public class TransactionalConflictException : TransactionException + { + /// Initializes a new instance of the class. + public TransactionalConflictException() + { + } + + /// Initializes a new instance of the class. + /// The message. + public TransactionalConflictException(string message) + : base(message) + { + } + + /// Initializes a new instance of the class. + /// The message. + /// The inner exception. + public TransactionalConflictException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// Initializes a new instance of the class. + /// The info. + /// The context. + protected TransactionalConflictException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Exceptions/UnrecognizedReparsePointException.cs b/AlphaFS/Filesystem/Exceptions/UnrecognizedReparsePointException.cs new file mode 100644 index 0000000..63aec51 --- /dev/null +++ b/AlphaFS/Filesystem/Exceptions/UnrecognizedReparsePointException.cs @@ -0,0 +1,59 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.Serialization; + +namespace Alphaleonis.Win32.Filesystem +{ + /// The function attempted to use a name that is reserved for use by another transaction. + [SerializableAttribute] + public class UnrecognizedReparsePointException : System.IO.IOException + { + /// Initializes a new instance of the class. + public UnrecognizedReparsePointException() + { + } + + /// Initializes a new instance of the class. + /// The message. + public UnrecognizedReparsePointException(string message) + : base(message) + { + } + + /// Initializes a new instance of the class. + /// The message. + /// The inner exception. + public UnrecognizedReparsePointException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// Initializes a new instance of the class. + /// The info. + /// The context. + protected UnrecognizedReparsePointException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Exceptions/UnsupportedRemoteTransactionException.cs b/AlphaFS/Filesystem/Exceptions/UnsupportedRemoteTransactionException.cs new file mode 100644 index 0000000..8566508 --- /dev/null +++ b/AlphaFS/Filesystem/Exceptions/UnsupportedRemoteTransactionException.cs @@ -0,0 +1,59 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.Serialization; + +namespace Alphaleonis.Win32.Filesystem +{ + /// The remote server or share does not support transacted file operations. + [SerializableAttribute] + public class UnsupportedRemoteTransactionException : TransactionException + { + /// Initializes a new instance of the class. + public UnsupportedRemoteTransactionException() + { + } + + /// Initializes a new instance of the class. + /// The message. + public UnsupportedRemoteTransactionException(string message) + : base(message) + { + } + + /// Initializes a new instance of the class. + /// The message. + /// The inner exception. + public UnsupportedRemoteTransactionException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// Initializes a new instance of the class. + /// The object that holds the serialized object data. + /// The contextual information about the source or destination. + protected UnsupportedRemoteTransactionException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/File Class/File.AppendText.cs b/AlphaFS/Filesystem/File Class/File.AppendText.cs new file mode 100644 index 0000000..de62be0 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.AppendText.cs @@ -0,0 +1,194 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region AppendText + + /// + /// Creates a that appends NativeMethods.DefaultFileEncoding encoded text to an existing file, or to a new + /// file if the specified file does not exist. + /// + /// The path to the file to append to. + /// + /// A stream writer that appends NativeMethods.DefaultFileEncoding encoded text to the specified file or to a new file. + /// + [SecurityCritical] + public static StreamWriter AppendText(string path) + { + return AppendTextCore(null, path, NativeMethods.DefaultFileEncoding, PathFormat.RelativePath); + } + + /// + /// Creates a that appends NativeMethods.DefaultFileEncoding encoded text to an existing file, or + /// to a new file if the specified file does not exist. + /// + /// The path to the file to append to. + /// Indicates the format of the path parameter(s). + /// + /// A stream writer that appends NativeMethods.DefaultFileEncoding encoded text to the specified file or to a new file. + /// + [SecurityCritical] + public static StreamWriter AppendText(string path, PathFormat pathFormat) + { + return AppendTextCore(null, path, NativeMethods.DefaultFileEncoding, pathFormat); + } + + /// + /// Creates a that appends NativeMethods.DefaultFileEncoding encoded text to an existing file, or + /// to a new file if the specified file does not exist. + /// + /// The path to the file to append to. + /// The character to use. + /// Indicates the format of the path parameter(s). + /// + /// A stream writer that appends NativeMethods.DefaultFileEncoding encoded text to the specified file or to a new file. + /// + [SecurityCritical] + public static StreamWriter AppendText(string path, Encoding encoding, PathFormat pathFormat) + { + return AppendTextCore(null, path, encoding, pathFormat); + } + + /// + /// Creates a that appends NativeMethods.DefaultFileEncoding encoded text to an existing file, or + /// to a new file if the specified file does not exist. + /// + /// The path to the file to append to. + /// The character to use. + /// + /// A stream writer that appends NativeMethods.DefaultFileEncoding encoded text to the specified file or to a new file. + /// + [SecurityCritical] + public static StreamWriter AppendText(string path, Encoding encoding) + { + return AppendTextCore(null, path, encoding, PathFormat.RelativePath); + } + + #region Transactional + + /// + /// Creates a that appends NativeMethods.DefaultFileEncoding encoded text to an existing file, or + /// to a new file if the specified file does not exist. + /// + /// The transaction. + /// The path to the file to append to. + /// + /// A stream writer that appends NativeMethods.DefaultFileEncoding encoded text to the specified file or to a new file. + /// + [SecurityCritical] + public static StreamWriter AppendTextTransacted(KernelTransaction transaction, string path) + { + return AppendTextCore(transaction, path, NativeMethods.DefaultFileEncoding, PathFormat.RelativePath); + } + + /// + /// Creates a that appends NativeMethods.DefaultFileEncoding encoded text to an existing file, or + /// to a new file if the specified file does not exist. + /// + /// The transaction. + /// The path to the file to append to. + /// Indicates the format of the path parameter(s). + /// + /// A stream writer that appends NativeMethods.DefaultFileEncoding encoded text to the specified file or to a new file. + /// + [SecurityCritical] + public static StreamWriter AppendTextTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return AppendTextCore(transaction, path, NativeMethods.DefaultFileEncoding, pathFormat); + } + + /// + /// Creates a that appends NativeMethods.DefaultFileEncoding encoded text to an existing file, or + /// to a new file if the specified file does not exist. + /// + /// The transaction. + /// The path to the file to append to. + /// The character to use. + /// Indicates the format of the path parameter(s). + /// + /// A stream writer that appends NativeMethods.DefaultFileEncoding encoded text to the specified file or to a new file. + /// + [SecurityCritical] + public static StreamWriter AppendTextTransacted(KernelTransaction transaction, string path, Encoding encoding, PathFormat pathFormat) + { + return AppendTextCore(transaction, path, encoding, pathFormat); + } + + /// + /// Creates a that appends NativeMethods.DefaultFileEncoding encoded text to an existing file, or + /// to a new file if the specified file does not exist. + /// + /// The transaction. + /// The path to the file to append to. + /// The character to use. + /// + /// A stream writer that appends NativeMethods.DefaultFileEncoding encoded text to the specified file or to a new file. + /// + [SecurityCritical] + public static StreamWriter AppendTextTransacted(KernelTransaction transaction, string path, Encoding encoding) + { + return AppendTextCore(transaction, path, encoding, PathFormat.RelativePath); + } + + #endregion // Transacted + + #endregion // AppendText + + #region Internal Methods + + /// Creates a that appends NativeMethods.DefaultFileEncoding encoded text to an existing file, or to a new file if the specified file does not exist. + /// + /// The transaction. + /// The path to the file to append to. + /// The character to use. + /// Indicates the format of the path parameter(s). + /// + /// A stream writer that appends NativeMethods.DefaultFileEncoding encoded text to the specified file or to a new file. + /// + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + internal static StreamWriter AppendTextCore(KernelTransaction transaction, string path, Encoding encoding, PathFormat pathFormat) + { + FileStream fs = OpenCore(transaction, path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, ExtendedFileAttributes.Normal, null, null, pathFormat); + + try + { + fs.Seek(0, SeekOrigin.End); + return new StreamWriter(fs, encoding); + } + catch (IOException) + { + fs.Close(); + throw; + } + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.Compress.cs b/AlphaFS/Filesystem/File Class/File.Compress.cs new file mode 100644 index 0000000..ac88380 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.Compress.cs @@ -0,0 +1,109 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region Compress + + /// [AlphaFS] Compresses a file using NTFS compression. + /// A path that describes a file to compress. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Compress(string path, PathFormat pathFormat) + { + Device.ToggleCompressionCore(false, null, path, true, pathFormat); + } + + /// [AlphaFS] Compresses a file using NTFS compression. + /// A path that describes a file to compress. + [SecurityCritical] + public static void Compress(string path) + { + Device.ToggleCompressionCore(false, null, path, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Compresses a file using NTFS compression. + /// The transaction. + /// A path that describes a file to compress. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void CompressTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + Device.ToggleCompressionCore(false, transaction, path, true, pathFormat); + } + + + /// [AlphaFS] Compresses a file using NTFS compression. + /// The transaction. + /// A path that describes a file to compress. + [SecurityCritical] + public static void CompressTransacted(KernelTransaction transaction, string path) + { + Device.ToggleCompressionCore(false, transaction, path, true, PathFormat.RelativePath); + } + + #endregion + + #region Decompress + + /// [AlphaFS] Decompresses an NTFS compressed file. + /// A path that describes a file to decompress. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Decompress(string path, PathFormat pathFormat) + { + Device.ToggleCompressionCore(false, null, path, false, pathFormat); + } + + /// [AlphaFS] Decompresses an NTFS compressed file. + /// A path that describes a file to decompress. + [SecurityCritical] + public static void Decompress(string path) + { + Device.ToggleCompressionCore(false, null, path, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Decompresses an NTFS compressed file. + /// The transaction. + /// A path that describes a file to decompress. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void DecompressTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + Device.ToggleCompressionCore(false, transaction, path, false, pathFormat); + } + + /// [AlphaFS] Decompresses an NTFS compressed file. + /// The transaction. + /// A path that describes a file to decompress. + [SecurityCritical] + public static void DecompressTransacted(KernelTransaction transaction, string path) + { + Device.ToggleCompressionCore(false, transaction, path, false, PathFormat.RelativePath); + } + + #endregion + } +} diff --git a/AlphaFS/Filesystem/File Class/File.CopyMove.cs b/AlphaFS/Filesystem/File Class/File.CopyMove.cs new file mode 100644 index 0000000..4952e0e --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.CopyMove.cs @@ -0,0 +1,1332 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region Copy + + #region .NET + + /// Copies an existing file to a new file. Overwriting a file of the same name is not allowed. + /// + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to copy. + /// The name of the destination file. This cannot be a directory or an existing file. + [SecurityCritical] + public static void Copy(string sourceFileName, string destinationFileName) + { + CopyMoveCore(false, null, sourceFileName, destinationFileName, false, CopyOptions.FailIfExists, null, null, null, null, PathFormat.RelativePath); + } + + /// Copies an existing file to a new file. Overwriting a file of the same name is allowed. + /// + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// if the destination file should ignoring the read-only and hidden attributes and overwrite; otherwise, . + [SecurityCritical] + public static void Copy(string sourceFileName, string destinationFileName, bool overwrite) + { + CopyMoveCore(false, null, sourceFileName, destinationFileName, false, overwrite ? CopyOptions.None : CopyOptions.FailIfExists, null, null, null, null, PathFormat.RelativePath); + } + + #endregion // .NET + + + #region AlphaFS + + #region Non-Transactional + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is not allowed. + /// + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Copy(string sourceFileName, string destinationFileName, PathFormat pathFormat) + { + CopyMoveCore(false, null, sourceFileName, destinationFileName, false, CopyOptions.FailIfExists, null, null, null, null, pathFormat); + } + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. + /// + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// if the destination file should ignoring the read-only and hidden attributes and overwrite; otherwise, . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Copy(string sourceFileName, string destinationFileName, bool overwrite, PathFormat pathFormat) + { + CopyMoveCore(false, null, sourceFileName, destinationFileName, false, overwrite ? CopyOptions.None : CopyOptions.FailIfExists, null, null, null, null, pathFormat); + } + + #endregion // Non-Transactional + + + #region Transactional + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is not allowed. + /// + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to copy. + /// The name of the destination file. This cannot be a directory or an existing file. + [SecurityCritical] + public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName) + { + CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, CopyOptions.FailIfExists, null, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is not allowed. + /// + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, PathFormat pathFormat) + { + CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, CopyOptions.FailIfExists, null, null, null, null, pathFormat); + } + + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. + /// + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// if the destination file should ignoring the read-only and hidden attributes and overwrite; otherwise, . + [SecurityCritical] + public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, bool overwrite) + { + CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, overwrite ? CopyOptions.None : CopyOptions.FailIfExists, null, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. + /// + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// if the destination file should ignoring the read-only and hidden attributes and overwrite; otherwise, . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, bool overwrite, PathFormat pathFormat) + { + CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, overwrite ? CopyOptions.None : CopyOptions.FailIfExists, null, null, null, null, pathFormat); + } + + #endregion // Transactional + + #endregion // AlphaFS + + #endregion // Copy + + + #region Copy (CopyOptions) + + #region Non-Transactional + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. can be specified. + /// + /// Option is recommended for very large file transfers. + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// that specify how the file is to be copied. This parameter can be . + [SecurityCritical] + public static void Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions) + { + CopyMoveCore(false, null, sourceFileName, destinationFileName, false, copyOptions, null, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. can be specified. + /// + /// Option is recommended for very large file transfers. + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// that specify how the file is to be copied. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, PathFormat pathFormat) + { + CopyMoveCore(false, null, sourceFileName, destinationFileName, false, copyOptions, null, null, null, null, pathFormat); + } + + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. can be specified. + /// + /// Option is recommended for very large file transfers. + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// that specify how the file is to be copied. This parameter can be . + /// if original Timestamps must be preserved, otherwise. + [SecurityCritical] + public static void Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates) + { + CopyMoveCore(false, null, sourceFileName, destinationFileName, preserveDates, copyOptions, null, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. can be specified. + /// + /// Option is recommended for very large file transfers. + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// that specify how the file is to be copied. This parameter can be . + /// if original Timestamps must be preserved, otherwise. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, PathFormat pathFormat) + { + CopyMoveCore(false, null, sourceFileName, destinationFileName, preserveDates, copyOptions, null, null, null, null, pathFormat); + } + + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// A class with details of the Copy action. + /// + /// Option is recommended for very large file transfers. + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// that specify how the file is to be copied. This parameter can be . + /// A callback function that is called each time another portion of the file has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + [SecurityCritical] + public static CopyMoveResult Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData) + { + return CopyMoveCore(false, null, sourceFileName, destinationFileName, false, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// A class with details of the Copy action. + /// + /// Option is recommended for very large file transfers. + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// that specify how the file is to be copied. This parameter can be . + /// A callback function that is called each time another portion of the file has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat) + { + return CopyMoveCore(false, null, sourceFileName, destinationFileName, false, copyOptions, null, progressHandler, userProgressData, null, pathFormat); + } + + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// A class with details of the Copy action. + /// + /// Option is recommended for very large file transfers. + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// that specify how the file is to be copied. This parameter can be . + /// if original Timestamps must be preserved, otherwise. + /// A callback function that is called each time another portion of the file has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + [SecurityCritical] + public static CopyMoveResult Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData) + { + return CopyMoveCore(false, null, sourceFileName, destinationFileName, preserveDates, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// A class with details of the Copy action. + /// + /// Option is recommended for very large file transfers. + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// that specify how the file is to be copied. This parameter can be . + /// if original Timestamps must be preserved, otherwise. + /// A callback function that is called each time another portion of the file has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat) + { + return CopyMoveCore(false, null, sourceFileName, destinationFileName, preserveDates, copyOptions, null, progressHandler, userProgressData, null, pathFormat); + } + + #endregion // Non-Transactional + + + #region Transactional + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. can be specified. + /// + /// Option is recommended for very large file transfers. + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// that specify how the file is to be copied. This parameter can be . + [SecurityCritical] + public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions) + { + CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, copyOptions, null, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. can be specified. + /// + /// Option is recommended for very large file transfers. + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// that specify how the file is to be copied. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, PathFormat pathFormat) + { + CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, copyOptions, null, null, null, null, pathFormat); + } + + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. can be specified. + /// + /// Option is recommended for very large file transfers. + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// that specify how the file is to be copied. This parameter can be . + /// if original Timestamps must be preserved, otherwise. + [SecurityCritical] + public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates) + { + CopyMoveCore(false, transaction, sourceFileName, destinationFileName, preserveDates, copyOptions, null, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. can be specified. + /// + /// Option is recommended for very large file transfers. + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// that specify how the file is to be copied. This parameter can be . + /// if original Timestamps must be preserved, otherwise. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, PathFormat pathFormat) + { + CopyMoveCore(false, transaction, sourceFileName, destinationFileName, preserveDates, copyOptions, null, null, null, null, pathFormat); + } + + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// A class with details of the Copy action. + /// + /// Option is recommended for very large file transfers. + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// that specify how the file is to be copied. This parameter can be . + /// A callback function that is called each time another portion of the file has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + [SecurityCritical] + public static CopyMoveResult CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData) + { + return CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// A class with details of the Copy action. + /// + /// Option is recommended for very large file transfers. + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// that specify how the file is to be copied. This parameter can be . + /// A callback function that is called each time another portion of the file has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat) + { + return CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, copyOptions, null, progressHandler, userProgressData, null, pathFormat); + } + + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// A class with details of the Copy action. + /// + /// Option is recommended for very large file transfers. + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// that specify how the file is to be copied. This parameter can be . + /// if original Timestamps must be preserved, otherwise. + /// A callback function that is called each time another portion of the file has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + [SecurityCritical] + public static CopyMoveResult CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData) + { + return CopyMoveCore(false, transaction, sourceFileName, destinationFileName, preserveDates, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// A class with details of the Copy action. + /// + /// Option is recommended for very large file transfers. + /// The attributes of the original file are retained in the copied file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// The transaction. + /// The file to copy. + /// The name of the destination file. This cannot be a directory. + /// that specify how the file is to be copied. This parameter can be . + /// if original Timestamps must be preserved, otherwise. + /// A callback function that is called each time another portion of the file has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// Indicates the format of the path parameter(s). + /// + /// + /// + /// + /// + /// + /// + [SecurityCritical] + public static CopyMoveResult CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat) + { + return CopyMoveCore(false, transaction, sourceFileName, destinationFileName, preserveDates, copyOptions, null, progressHandler, userProgressData, null, pathFormat); + } + + #endregion // Transactional + + #endregion // Copy (CopyOptions) + + + #region Move + + #region .NET + + /// Moves a specified file to a new location, providing the option to specify a new file name. + /// + /// This method works across disk volumes, and it does not throw an exception if the source and destination are the same. + /// Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an . + /// You cannot use the Move method to overwrite an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The name of the file to move. + /// The new path for the file. + [SecurityCritical] + public static void Move(string sourceFileName, string destinationFileName) + { + CopyMoveCore(false, null, sourceFileName, destinationFileName, false, null, MoveOptions.CopyAllowed, null, null, null, PathFormat.RelativePath); + } + + #endregion // .NET + + #region AlphaFS + + #region Non-Transactional + + /// [AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name. + /// + /// This method works across disk volumes, and it does not throw an exception if the source and destination are the same. + /// Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an . + /// You cannot use the Move method to overwrite an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The name of the file to move. + /// The new path for the file. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Move(string sourceFileName, string destinationFileName, PathFormat pathFormat) + { + CopyMoveCore(false, null, sourceFileName, destinationFileName, false, null, MoveOptions.CopyAllowed, null, null, null, pathFormat); + } + + #endregion // Non-Transactional + + #region Transactional + + /// [AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name. + /// + /// This method works across disk volumes, and it does not throw an exception if the source and destination are the same. + /// Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an . + /// You cannot use the Move method to overwrite an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The name of the file to move. + /// The new path for the file. + [SecurityCritical] + public static void MoveTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName) + { + CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, null, MoveOptions.CopyAllowed, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name. + /// + /// This method works across disk volumes, and it does not throw an exception if the source and destination are the same. + /// Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an . + /// You cannot use the Move method to overwrite an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The name of the file to move. + /// The new path for the file. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void MoveTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, PathFormat pathFormat) + { + CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, null, MoveOptions.CopyAllowed, null, null, null, pathFormat); + } + + #endregion // Transactional + + #endregion // AlphaFS + + #endregion // Move + + + #region Move (MoveOptions) + + #region Non-Transactional + + /// [AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name. + /// + /// This method works across disk volumes, and it does not throw an exception if the source and destination are the same. + /// Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an . + /// You cannot use the Move method to overwrite an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The name of the file to move. + /// The new path for the file. + /// that specify how the file is to be moved. This parameter can be . + [SecurityCritical] + public static void Move(string sourceFileName, string destinationFileName, MoveOptions moveOptions) + { + CopyMoveCore(false, null, sourceFileName, destinationFileName, false, null, moveOptions, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name. + /// + /// This method works across disk volumes, and it does not throw an exception if the source and destination are the same. + /// Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an . + /// You cannot use the Move method to overwrite an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The name of the file to move. + /// The new path for the file. + /// that specify how the file is to be moved. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Move(string sourceFileName, string destinationFileName, MoveOptions moveOptions, PathFormat pathFormat) + { + CopyMoveCore(false, null, sourceFileName, destinationFileName, false, null, moveOptions, null, null, null, pathFormat); + } + + + + /// [AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name. + /// A class with the status of the Move action. + /// + /// This method works across disk volumes, and it does not throw an exception if the source and destination are the same. + /// Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an . + /// You cannot use the Move method to overwrite an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The name of the file to move. + /// The new path for the file. + /// that specify how the file is to be moved. This parameter can be . + /// A callback function that is called each time another portion of the file has been moved. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + [SecurityCritical] + public static CopyMoveResult Move(string sourceFileName, string destinationFileName, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData) + { + return CopyMoveCore(false, null, sourceFileName, destinationFileName, false, null, moveOptions, progressHandler, userProgressData, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name. + /// A class with the status of the Move action. + /// + /// This method works across disk volumes, and it does not throw an exception if the source and destination are the same. + /// Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an . + /// You cannot use the Move method to overwrite an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The name of the file to move. + /// The new path for the file. + /// that specify how the file is to be moved. This parameter can be . + /// A callback function that is called each time another portion of the file has been moved. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult Move(string sourceFileName, string destinationFileName, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat) + { + return CopyMoveCore(false, null, sourceFileName, destinationFileName, false, null, moveOptions, progressHandler, userProgressData, null, pathFormat); + } + + #endregion // Non-Transactional + + #region Transactional + + /// [AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name. + /// + /// This method works across disk volumes, and it does not throw an exception if the source and destination are the same. + /// Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an . + /// You cannot use the Move method to overwrite an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The name of the file to move. + /// The new path for the file. + /// that specify how the file is to be moved. This parameter can be . + [SecurityCritical] + public static void MoveTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, MoveOptions moveOptions) + { + CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, null, moveOptions, null, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name. + /// + /// This method works across disk volumes, and it does not throw an exception if the source and destination are the same. + /// Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an . + /// You cannot use the Move method to overwrite an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The name of the file to move. + /// The new path for the file. + /// that specify how the file is to be moved. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void MoveTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, MoveOptions moveOptions, PathFormat pathFormat) + { + CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, null, moveOptions, null, null, null, pathFormat); + } + + + + /// [AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name. + /// A class with the status of the Move action. + /// + /// This method works across disk volumes, and it does not throw an exception if the source and destination are the same. + /// Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an . + /// You cannot use the Move method to overwrite an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The name of the file to move. + /// The new path for the file. + /// that specify how the file is to be moved. This parameter can be . + /// A callback function that is called each time another portion of the file has been moved. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + [SecurityCritical] + public static CopyMoveResult MoveTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData) + { + return CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, null, moveOptions, progressHandler, userProgressData, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name. + /// A class with the status of the Move action. + /// + /// This method works across disk volumes, and it does not throw an exception if the source and destination are the same. + /// Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an . + /// You cannot use the Move method to overwrite an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The name of the file to move. + /// The new path for the file. + /// that specify how the file is to be moved. This parameter can be . + /// A callback function that is called each time another portion of the file has been moved. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static CopyMoveResult MoveTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat) + { + return CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, null, moveOptions, progressHandler, userProgressData, null, pathFormat); + } + + #endregion // Transactional + + #endregion // Move (MoveOptions) + + + #region Internal Methods + + /// Determine the Copy or Move action. + internal static bool DetermineIsCopy(CopyOptions? copyOptions, MoveOptions? moveOptions) + { + // Determine Copy or Move action. + var isCopy = copyOptions != null; + var isMove = !isCopy && moveOptions != null; + + if ((!isCopy && !isMove) || (isCopy && isMove)) + throw new NotSupportedException(Resources.Cannot_Determine_Copy_Or_Move); + + return isCopy; + } + + + /// Copy/move a Non-/Transacted file or directory including its children to a new location, or can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// A class with the status of the Copy or Move action. + /// + /// Option is recommended for very large file transfers. + /// You cannot use the Move method to overwrite an existing file, unless + /// contains . + /// This Move method works across disk volumes, and it does not throw an exception if the + /// source and destination are the same. + /// Note that if you attempt to replace a file by moving a file of the same name into + /// that directory, you get an IOException. + /// + /// + /// + /// + /// + /// + /// + /// + /// Specifies that and are a file or directory. + /// The transaction. + /// The source directory path. + /// The destination directory path. + /// if original Timestamps must be preserved, otherwise. This parameter is ignored for move operations. + /// that specify how the file is to be copied. This parameter can be . + /// Flags that specify how the file or directory is to be moved. This parameter can be . + /// A callback function that is called each time another portion of the file has been copied/moved. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + [SecurityCritical] + internal static CopyMoveResult CopyMoveCore(bool isFolder, KernelTransaction transaction, string sourceFileName, string destinationFileName, bool preserveDates, CopyOptions? copyOptions, MoveOptions? moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, CopyMoveResult copyMoveResult, PathFormat pathFormat) + { + #region Setup + + var sourceFileNameLp = sourceFileName; + var destFileNameLp = destinationFileName; + var skipPathChecks = pathFormat == PathFormat.LongFullPath; + + + if (!skipPathChecks) + { + Path.CheckSupportedPathFormat(sourceFileName, true, true); + Path.CheckSupportedPathFormat(destinationFileName, true, true); + + sourceFileNameLp = Path.GetExtendedLengthPathCore(transaction, sourceFileName, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator); + destFileNameLp = Path.GetExtendedLengthPathCore(transaction, destinationFileName, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator); + } + + + // MSDN: If this flag is set to TRUE during the copy/move operation, the operation is canceled. + // Otherwise, the copy/move operation will continue to completion. + var cancel = false; + + // Determine Copy or Move action. + var isCopy = DetermineIsCopy(copyOptions, moveOptions); + var isMove = !isCopy; + + + var raiseException = progressHandler == null; + //Task completedTask = null; + + + // Setup callback function for progress notifications. + var routine = progressHandler != null + ? (totalFileSize, totalBytesTransferred, streamSize, streamBytesTransferred, dwStreamNumber, dwCallbackReason, hSourceFile, hDestinationFile, lpData) => + progressHandler(totalFileSize, totalBytesTransferred, streamSize, streamBytesTransferred, dwStreamNumber, dwCallbackReason, userProgressData) + : (NativeMethods.NativeCopyMoveProgressRoutine) null; + + + var cmr = copyMoveResult ?? new CopyMoveResult(sourceFileNameLp, destFileNameLp, false, (int) Win32Errors.ERROR_SUCCESS); + + #endregion // Setup + + + startCopyMove: + + #region Win32 Copy/Move + + var success = transaction == null || !NativeMethods.IsAtLeastWindowsVista + + ? isMove + // MoveFileWithProgress() / MoveFileTransacted() + // 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-04-15: MSDN confirms LongPath usage. + + // CopyFileEx() / CopyFileTransacted() + // 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-04-15: MSDN confirms LongPath usage. + + + // Note: The NativeMethod.MoveFileXxx() methods fail if one of the paths is a UNC path, even though both paths refer to the same volume. + // For example, src = C:\TempSrc and dst = \\localhost\C$\TempDst + + + ? NativeMethods.MoveFileWithProgress(sourceFileNameLp, destFileNameLp, routine, IntPtr.Zero, (MoveOptions) moveOptions) + : NativeMethods.CopyFileEx(sourceFileNameLp, destFileNameLp, routine, IntPtr.Zero, out cancel, (CopyOptions) copyOptions) + + : isMove + ? NativeMethods.MoveFileTransacted(sourceFileNameLp, destFileNameLp, routine, IntPtr.Zero, (MoveOptions) moveOptions, transaction.SafeHandle) + : NativeMethods.CopyFileTransacted(sourceFileNameLp, destFileNameLp, routine, IntPtr.Zero, out cancel, (CopyOptions) copyOptions, transaction.SafeHandle); + + + + + var lastError = (uint) Marshal.GetLastWin32Error(); + if (!success) + { + cmr.ErrorCode = (int) lastError; + + if (lastError == Win32Errors.ERROR_REQUEST_ABORTED) + { + // MSDN: + // + // If lpProgressRoutine returns PROGRESS_CANCEL due to the user canceling the operation, + // CopyFileEx will return zero and GetLastError will return ERROR_REQUEST_ABORTED. + // In this case, the partially copied destination file is deleted. + // + // If lpProgressRoutine returns PROGRESS_STOP due to the user stopping the operation, + // CopyFileEx will return zero and GetLastError will return ERROR_REQUEST_ABORTED. + // In this case, the partially copied destination file is left intact. + + cancel = true; + cmr.IsCanceled = cancel; + } + + else if (raiseException) + { + raiseException: + + #region Win32Errors + + switch (lastError) + { + case Win32Errors.ERROR_FILE_NOT_FOUND: + if (isFolder) + { + lastError = Win32Errors.ERROR_PATH_NOT_FOUND; + goto raiseException; + } + + // File.Copy() + // File.Move() + // MSDN: .NET 3.5+: FileNotFoundException: sourceFileName was not found. + NativeError.ThrowException(lastError, sourceFileNameLp); + break; + + case Win32Errors.ERROR_PATH_NOT_FOUND: + // File.Copy() + // File.Move() + // Directory.Move() + // MSDN: .NET 3.5+: DirectoryNotFoundException: The path specified in sourceFileName or destinationFileName is invalid (for example, it is on an unmapped drive). + NativeError.ThrowException(lastError, sourceFileNameLp); + break; + + case Win32Errors.ERROR_FILE_EXISTS: + // File.Copy() + // Directory.Copy() + NativeError.ThrowException(lastError, destFileNameLp); + break; + + default: + var destExists = ExistsCore(isFolder, transaction, destFileNameLp, PathFormat.LongFullPath); + + // For a number of error codes (sharing violation, path not found, etc) + // we don't know if the problem was with the source or destination file. + + // Check if destination directory already exists. + // Directory.Move() + // MSDN: .NET 3.5+: IOException: destDirName already exists. + if (isFolder && destExists) + NativeError.ThrowException(Win32Errors.ERROR_ALREADY_EXISTS, destFileNameLp); + + if (isMove) + { + // Ensure that the source file or directory exists. + // Directory.Move() + // MSDN: .NET 3.5+: DirectoryNotFoundException: The path specified by sourceDirName is invalid (for example, it is on an unmapped drive). + if (!ExistsCore(isFolder, transaction, sourceFileNameLp, PathFormat.LongFullPath)) + NativeError.ThrowException(isFolder ? Win32Errors.ERROR_PATH_NOT_FOUND : Win32Errors.ERROR_FILE_NOT_FOUND, sourceFileNameLp); + } + + + // Try reading the source file. + var fileNameLp = destFileNameLp; + + if (!isFolder) + { + using (var safeHandle = CreateFileCore(transaction, sourceFileNameLp, ExtendedFileAttributes.Normal, null, FileMode.Open, 0, FileShare.Read, false, PathFormat.LongFullPath)) + if (safeHandle != null && safeHandle.IsInvalid) + fileNameLp = sourceFileNameLp; + } + + if (lastError == Win32Errors.ERROR_ACCESS_DENIED) + { + // File.Copy() + // File.Move() + // MSDN: .NET 3.5+: IOException: An I/O error has occurred. + // Directory exists with the same name as the file. + if (!isFolder && destExists) + NativeError.ThrowException(lastError, string.Format(CultureInfo.CurrentCulture, Resources.Target_File_Is_A_Directory, destFileNameLp)); + + if (isMove) + { + var data = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA(); + FillAttributeInfoCore(transaction, destFileNameLp, ref data, false, true); + + if (data.dwFileAttributes != (FileAttributes) (-1)) + { + if ((data.dwFileAttributes & FileAttributes.ReadOnly) != 0) + { + // MSDN: .NET 3.5+: IOException: The directory specified by path is read-only. + if (((MoveOptions) moveOptions & MoveOptions.ReplaceExisting) != 0) + { + // Reset file system object attributes. + SetAttributesCore(isFolder, transaction, destFileNameLp, FileAttributes.Normal, true, PathFormat.LongFullPath); + + goto startCopyMove; + } + + + // MSDN: .NET 3.5+: UnauthorizedAccessException: destinationFileName is read-only. + // MSDN: Win32 CopyFileXxx: This function fails with ERROR_ACCESS_DENIED if the destination file already exists + // and has the FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_READONLY attribute set. + throw new FileReadOnlyException(destFileNameLp); + } + + + // MSDN: Win32 CopyFileXxx: This function fails with ERROR_ACCESS_DENIED if the destination file already exists + // and has the FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_READONLY attribute set. + if ((data.dwFileAttributes & FileAttributes.Hidden) != 0) + NativeError.ThrowException(lastError, string.Format(CultureInfo.CurrentCulture, Resources.File_Is_Hidden, destFileNameLp)); + } + } + } + + + // MSDN: .NET 3.5+: An I/O error has occurred. + // File.Copy(): IOException: destinationFileName exists and overwrite is false. + // File.Move(): The destination file already exists or sourceFileName was not found. + NativeError.ThrowException(lastError, fileNameLp); + + break; + } + + #endregion // Win32Errors + } + } + + #endregion // Win32 Copy/Move + + + #region Transfer Timestamps + + // Apply original Timestamps if requested. + // MoveFileWithProgress() / MoveFileTransacted() automatically preserve Timestamps. + // File.Copy() + + if (success && preserveDates && isCopy) + { + // Currently preserveDates is only used with files. + var data = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA(); + var dataInitialised = FillAttributeInfoCore(transaction, sourceFileNameLp, ref data, false, true); + + if (dataInitialised == Win32Errors.ERROR_SUCCESS && data.dwFileAttributes != (FileAttributes) (-1)) + SetFsoDateTimeCore(false, transaction, destFileNameLp, DateTime.FromFileTimeUtc(data.ftCreationTime), + DateTime.FromFileTimeUtc(data.ftLastAccessTime), DateTime.FromFileTimeUtc(data.ftLastWriteTime), false, PathFormat.LongFullPath); + } + + #endregion // Transfer Timestamps + + + return cmr; + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.Create.cs b/AlphaFS/Filesystem/File Class/File.Create.cs new file mode 100644 index 0000000..f1f2703 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.Create.cs @@ -0,0 +1,427 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Security; +using Microsoft.Win32.SafeHandles; +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.AccessControl; +using FileStream = System.IO.FileStream; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region Non-Transactional + + /// Creates or overwrites a file in the specified path. + /// The path and name of the file to create. + /// A that provides read/write access to the file specified in . + [SecurityCritical] + public static FileStream Create(string path) + { + return CreateFileStreamCore(null, path, ExtendedFileAttributes.Normal, null, FileMode.Create, FileAccess.ReadWrite, FileShare.None, NativeMethods.DefaultFileBufferSize, PathFormat.RelativePath); + } + + /// Creates or overwrites the specified file. + /// The name of the file. + /// The number of bytes buffered for reads and writes to the file. + /// + /// A with the specified buffer size that provides read/write access to the file specified in + /// . + /// + [SecurityCritical] + public static FileStream Create(string path, int bufferSize) + { + return CreateFileStreamCore(null, path, ExtendedFileAttributes.Normal, null, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize, PathFormat.RelativePath); + } + + /// + /// Creates or overwrites the specified file, specifying a buffer size and a + /// value that describes how to create or overwrite the file. + /// + /// The name of the file. + /// The number of bytes buffered for reads and writes to the file. + /// One of the values that describes how to create or overwrite the file. + /// A new file with the specified buffer size. + [SecurityCritical] + public static FileStream Create(string path, int bufferSize, FileOptions options) + { + return CreateFileStreamCore(null, path, (ExtendedFileAttributes) options, null, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize, PathFormat.RelativePath); + } + + /// + /// Creates or overwrites the specified file, specifying a buffer size and a + /// value that describes how to create or overwrite the file. + /// + /// The name of the file. + /// The number of bytes buffered for reads and writes to the file. + /// One of the values that describes how to create or overwrite the file. + /// + /// One of the values that determines the access control and audit security for the file. + /// + /// A new file with the specified buffer size, file options, and file security. + [SecurityCritical] + public static FileStream Create(string path, int bufferSize, FileOptions options, FileSecurity fileSecurity) + { + return CreateFileStreamCore(null, path, (ExtendedFileAttributes)options, fileSecurity, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize, PathFormat.RelativePath); + } + + /// Creates or overwrites a file in the specified path. + /// The path and name of the file to create. + /// Indicates the format of the path parameter(s). + /// + /// A that provides read/write access to the file specified in + /// . + /// + [SecurityCritical] + public static FileStream Create(string path, PathFormat pathFormat) + { + return CreateFileStreamCore(null, path, ExtendedFileAttributes.Normal, null, FileMode.Create, FileAccess.ReadWrite, FileShare.None, NativeMethods.DefaultFileBufferSize, pathFormat); + } + + /// Creates or overwrites the specified file. + /// The name of the file. + /// The number of bytes buffered for reads and writes to the file. + /// Indicates the format of the path parameter(s). + /// + /// A with the specified buffer size that provides read/write access to the file specified in + /// . + /// + [SecurityCritical] + public static FileStream Create(string path, int bufferSize, PathFormat pathFormat) + { + return CreateFileStreamCore(null, path, ExtendedFileAttributes.Normal, null, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize, pathFormat); + } + + /// + /// Creates or overwrites the specified file, specifying a buffer size and a + /// value that describes how to create or overwrite the file. + /// + /// The name of the file. + /// + /// The number of bytes buffered for reads and writes to the file. + /// + /// + /// One of the values that describes how to create or overwrite the + /// file. + /// + /// Indicates the format of the path parameter(s). + /// A new file with the specified buffer size. + [SecurityCritical] + public static FileStream Create(string path, int bufferSize, FileOptions options, PathFormat pathFormat) + { + return CreateFileStreamCore(null, path, (ExtendedFileAttributes)options, null, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize, pathFormat); + } + + /// + /// Creates or overwrites the specified file, specifying a buffer size and a + /// value that describes how to create or overwrite the file. + /// + /// The name of the file. + /// + /// The number of bytes buffered for reads and writes to the file. + /// + /// + /// One of the values that describes how to create or overwrite the + /// file. + /// + /// + /// One of the values that determines the access control and audit + /// security for the file. + /// + /// Indicates the format of the path parameter(s). + /// + /// A new file with the specified buffer size, file options, and file security. + /// + [SecurityCritical] + public static FileStream Create(string path, int bufferSize, FileOptions options, FileSecurity fileSecurity, PathFormat pathFormat) + { + return CreateFileStreamCore(null, path, (ExtendedFileAttributes)options, fileSecurity, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize, pathFormat); + } + + #endregion // .NET + + #region Transactional + + /// Creates or overwrites a file in the specified path. + /// The transaction. + /// The path and name of the file to create. + /// + /// A that provides read/write access to the file specified in + /// . + /// + [SecurityCritical] + public static FileStream CreateTransacted(KernelTransaction transaction, string path) + { + return CreateFileStreamCore(transaction, path, ExtendedFileAttributes.Normal, null, FileMode.Create, FileAccess.ReadWrite, FileShare.None, NativeMethods.DefaultFileBufferSize, PathFormat.RelativePath); + } + + /// Creates or overwrites the specified file. + /// The transaction. + /// The name of the file. + /// + /// The number of bytes buffered for reads and writes to the file. + /// + /// + /// A with the specified buffer size that provides read/write access + /// to the file specified in . + /// + [SecurityCritical] + public static FileStream CreateTransacted(KernelTransaction transaction, string path, int bufferSize) + { + return CreateFileStreamCore(transaction, path, ExtendedFileAttributes.Normal, null, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize, PathFormat.RelativePath); + } + + /// + /// Creates or overwrites the specified file, specifying a buffer size and a + /// value that describes how to create or overwrite the file. + /// + /// The transaction. + /// The name of the file. + /// The number of bytes buffered for reads and writes to the file. + /// One of the values that describes how to create or overwrite the file. + /// A new file with the specified buffer size. + [SecurityCritical] + public static FileStream CreateTransacted(KernelTransaction transaction, string path, int bufferSize, FileOptions options) + { + return CreateFileStreamCore(transaction, path, (ExtendedFileAttributes)options, null, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize, PathFormat.RelativePath); + } + + /// + /// Creates or overwrites the specified file, specifying a buffer size and a + /// value that describes how to create or overwrite the file. + /// + /// The transaction. + /// The name of the file. + /// The number of bytes buffered for reads and writes to the file. + /// One of the values that describes how to create or overwrite the file. + /// + /// One of the values that determines the access control and audit security for the file. + /// + /// A new file with the specified buffer size, file options, and file security. + [SecurityCritical] + public static FileStream CreateTransacted(KernelTransaction transaction, string path, int bufferSize, FileOptions options, FileSecurity fileSecurity) + { + return CreateFileStreamCore(transaction, path, (ExtendedFileAttributes)options, fileSecurity, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize, PathFormat.RelativePath); + } + + /// Creates or overwrites a file in the specified path. + /// The transaction. + /// The path and name of the file to create. + /// Indicates the format of the path parameter(s). + /// + /// A that provides read/write access to the file specified in + /// . + /// + [SecurityCritical] + public static FileStream CreateTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return CreateFileStreamCore(transaction, path, ExtendedFileAttributes.Normal, null, FileMode.Create, FileAccess.ReadWrite, FileShare.None, NativeMethods.DefaultFileBufferSize, pathFormat); + } + + /// Creates or overwrites the specified file. + /// The transaction. + /// The name of the file. + /// The number of bytes buffered for reads and writes to the file. + /// Indicates the format of the path parameter(s). + /// + /// A with the specified buffer size that provides read/write access to the file specified in + /// . + /// + [SecurityCritical] + public static FileStream CreateTransacted(KernelTransaction transaction, string path, int bufferSize, PathFormat pathFormat) + { + return CreateFileStreamCore(transaction, path, ExtendedFileAttributes.Normal, null, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize, pathFormat); + } + + /// + /// Creates or overwrites the specified file, specifying a buffer size and a + /// value that describes how to create or overwrite the file. + /// + /// The transaction. + /// The name of the file. + /// The number of bytes buffered for reads and writes to the file. + /// One of the values that describes how to create or overwrite the file. + /// Indicates the format of the path parameter(s). + /// A new file with the specified buffer size. + [SecurityCritical] + public static FileStream CreateTransacted(KernelTransaction transaction, string path, int bufferSize, FileOptions options, PathFormat pathFormat) + { + return CreateFileStreamCore(transaction, path, (ExtendedFileAttributes)options, null, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize, pathFormat); + } + + /// + /// Creates or overwrites the specified file, specifying a buffer size and a + /// value that describes how to create or overwrite the file. + /// + /// The transaction. + /// The name of the file. + /// The number of bytes buffered for reads and writes to the file. + /// One of the values that describes how to create or overwrite the file. + /// + /// One of the values that determines the access control and audit security for the file. + /// + /// Indicates the format of the path parameter(s). + /// A new file with the specified buffer size, file options, and file security. + [SecurityCritical] + public static FileStream CreateTransacted(KernelTransaction transaction, string path, int bufferSize, FileOptions options, FileSecurity fileSecurity, PathFormat pathFormat) + { + return CreateFileStreamCore(transaction, path, (ExtendedFileAttributes)options, fileSecurity, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize, pathFormat); + } + + #endregion + + #region Internal + + /// Creates or overwrites a file in the specified path. + /// The transaction. + /// The name of the file. + /// The additional advanced options to create a file. + /// + /// A instance that determines the access control and audit security for the file. + /// + /// The option gives you more precise control over how you want to create a file. + /// + /// The allow you additionally specify to default read/write capability - just write, bypassing any cache. + /// + /// + /// The option controls how you would like to share created file with other requesters. + /// + /// Indicates the format of the parameter. + /// The number of bytes buffered for reads and writes to the file. + /// A that provides read/write access to the file specified in path. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "False positive")] + [SecurityCritical] + internal static FileStream CreateFileStreamCore(KernelTransaction transaction, string path, ExtendedFileAttributes attributes, FileSecurity fileSecurity, FileMode mode, FileAccess access, FileShare share, int bufferSize, PathFormat pathFormat) + { + SafeFileHandle safeHandle = null; + + try + { + safeHandle = CreateFileCore(transaction, path, attributes, fileSecurity, mode, (FileSystemRights) access, share, true, pathFormat); + + return new FileStream(safeHandle, access, bufferSize, (attributes & ExtendedFileAttributes.Overlapped) != 0); + } + catch + { + if (safeHandle != null) + safeHandle.Dispose(); + + throw; + } + } + + /// Creates or opens a file, directory or I/O device. + /// A that provides read/write access to the file or directory specified by . + /// + /// To obtain a directory handle using CreateFile, specify the FILE_FLAG_BACKUP_SEMANTICS flag as part of dwFlagsAndAttributes. + /// The most commonly used I/O devices are as follows: file, file stream, directory, physical disk, volume, console buffer, tape drive, communications resource, mailslot, and pipe. + /// + /// + /// + /// + /// The transaction. + /// The path and name of the file or directory to create. + /// One of the values that describes how to create or overwrite the file or directory. + /// A instance that determines the access control and audit security for the file or directory. + /// A constant that determines how to open or create the file or directory. + /// A constant that determines the access rights to use when creating access and audit rules for the file or directory. + /// A constant that determines how the file or directory will be shared by processes. + /// . + /// Indicates the format of the parameter. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Object needs to be disposed by caller.")] + [SecurityCritical] + 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; + } + } + + #endregion // CreateFileCore + } +} diff --git a/AlphaFS/Filesystem/File Class/File.CreateHardlink.cs b/AlphaFS/Filesystem/File Class/File.CreateHardlink.cs new file mode 100644 index 0000000..197a372 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.CreateHardlink.cs @@ -0,0 +1,129 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region CreateHardlink + + /// [AlphaFS] Establishes a hard link between an existing file and a new file. This function is only supported on the NTFS file system, and only for files, not directories. + /// The name of the new file. This parameter cannot specify the name of a directory. + /// The name of the existing file. This parameter cannot specify the name of a directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hardlink")] + [SecurityCritical] + public static void CreateHardlink(string fileName, string existingFileName, PathFormat pathFormat) + { + CreateHardlinkCore(null, fileName, existingFileName, pathFormat); + } + + /// [AlphaFS] Establishes a hard link between an existing file and a new file. This function is only supported on the NTFS file system, and only for files, not directories. + /// The name of the new file. This parameter cannot specify the name of a directory. + /// The name of the existing file. This parameter cannot specify the name of a directory. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hardlink")] + [SecurityCritical] + public static void CreateHardlink(string fileName, string existingFileName) + { + CreateHardlinkCore(null, fileName, existingFileName, PathFormat.RelativePath); + } + + /// + /// [AlphaFS] Establishes a hard link between an existing file and a new file. This function is only supported on the NTFS file system, + /// and only for files, not directories. + /// + /// The transaction. + /// The name of the new file. This parameter cannot specify the name of a directory. + /// The name of the existing file. This parameter cannot specify the name of a directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hardlink")] + [SecurityCritical] + public static void CreateHardlinkTransacted(KernelTransaction transaction, string fileName, string existingFileName, PathFormat pathFormat) + { + CreateHardlinkCore(transaction, fileName, existingFileName, pathFormat); + } + + /// + /// [AlphaFS] Establishes a hard link between an existing file and a new file. This function is only supported on the NTFS file system, + /// and only for files, not directories. + /// + /// The transaction. + /// The name of the new file. This parameter cannot specify the name of a directory. + /// The name of the existing file. This parameter cannot specify the name of a directory. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hardlink")] + [SecurityCritical] + public static void CreateHardlinkTransacted(KernelTransaction transaction, string fileName, string existingFileName) + { + CreateHardlinkCore(transaction, fileName, existingFileName, PathFormat.RelativePath); + } + + #endregion // CreateHardlink + + #region Internal Methods + + /// Establish a hard link between an existing file and a new file. This function + /// is only supported on the NTFS file system, and only for files, not directories. + /// + /// + /// The transaction. + /// The name of the new file. This parameter cannot specify the name of a directory. + /// The name of the existing file. This parameter cannot specify the name of a directory. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hardlink")] + [SecurityCritical] + internal static void CreateHardlinkCore(KernelTransaction transaction, string fileName, string existingFileName, PathFormat pathFormat) + { + var options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck; + + string fileNameLp = Path.GetExtendedLengthPathCore(transaction, fileName, pathFormat, options); + string existingFileNameLp = Path.GetExtendedLengthPathCore(transaction, existingFileName, pathFormat, options); + + if (!(transaction == null || !NativeMethods.IsAtLeastWindowsVista + + // CreateHardLink() / CreateHardLinkTransacted() + // 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 does not confirm LongPath usage but a Unicode version of this function exists. + + ? NativeMethods.CreateHardLink(fileNameLp, existingFileNameLp, IntPtr.Zero) + : NativeMethods.CreateHardLinkTransacted(fileNameLp, existingFileNameLp, IntPtr.Zero, transaction.SafeHandle))) + { + int lastError = Marshal.GetLastWin32Error(); + switch ((uint)lastError) + { + case Win32Errors.ERROR_INVALID_FUNCTION: + throw new NotSupportedException(Resources.HardLinks_Not_Supported); + + default: + NativeError.ThrowException(lastError, fileNameLp, existingFileName); + break; + } + } + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.CreateSymbolicLink.cs b/AlphaFS/Filesystem/File Class/File.CreateSymbolicLink.cs new file mode 100644 index 0000000..237d77c --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.CreateSymbolicLink.cs @@ -0,0 +1,141 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class File + { + #region CreateSymbolicLink + + /// [AlphaFS] Creates a symbolic link. + /// See to run this method in an elevated state. + /// The name of the target for the symbolic link to be created. + /// The symbolic link to be created. + /// Indicates whether the link target, , is a file or directory. + /// Indicates the format of the path parameter(s). + /// + /// Several Exceptions possible. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "symlink")] + [SecurityCritical] + public static void CreateSymbolicLink(string symlinkFileName, string targetFileName, SymbolicLinkTarget targetType, PathFormat pathFormat) + { + CreateSymbolicLinkCore(null, symlinkFileName, targetFileName, targetType, pathFormat); + } + + /// [AlphaFS] Creates a symbolic link. + /// See to run this method in an elevated state. + /// The name of the target for the symbolic link to be created. + /// The symbolic link to be created. + /// Indicates whether the link target, , is a file or directory. + /// + /// Several Exceptions possible. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "symlink")] + [SecurityCritical] + public static void CreateSymbolicLink(string symlinkFileName, string targetFileName, SymbolicLinkTarget targetType) + { + CreateSymbolicLinkCore(null, symlinkFileName, targetFileName, targetType, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates a symbolic link. + /// See to run this method in an elevated state. + /// The transaction. + /// The name of the target for the symbolic link to be created. + /// The symbolic link to be created. + /// Indicates whether the link target, , is a file or directory. + /// Indicates the format of the path parameter(s). + /// + /// Several Exceptions possible. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "symlink")] + [SecurityCritical] + public static void CreateSymbolicLinkTransacted(KernelTransaction transaction, string symlinkFileName, string targetFileName, SymbolicLinkTarget targetType, PathFormat pathFormat) + { + CreateSymbolicLinkCore(transaction, symlinkFileName, targetFileName, targetType, pathFormat); + } + + + /// [AlphaFS] Creates a symbolic link. + /// See to run this method in an elevated state. + /// The transaction. + /// The name of the target for the symbolic link to be created. + /// The symbolic link to be created. + /// Indicates whether the link target, , is a file or directory. + /// + /// Several Exceptions possible. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "symlink")] + [SecurityCritical] + public static void CreateSymbolicLinkTransacted(KernelTransaction transaction, string symlinkFileName, string targetFileName, SymbolicLinkTarget targetType) + { + CreateSymbolicLinkCore(transaction, symlinkFileName, targetFileName, targetType, PathFormat.RelativePath); + } + + #endregion // CreateSymbolicLink + + #region Internal Methods + + /// Creates a symbolic link. + /// See to run this method in an elevated state. + /// The transaction. + /// The name of the target for the symbolic link to be created. + /// The symbolic link to be created. + /// Indicates whether the link target, , is a file or directory. + /// Indicates the format of the path parameter(s). + /// + /// Several Exceptions possible. + [SecurityCritical] + internal static void CreateSymbolicLinkCore(KernelTransaction transaction, string symlinkFileName, string targetFileName, SymbolicLinkTarget targetType, PathFormat pathFormat) + { + if (!NativeMethods.IsAtLeastWindowsVista) + throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher); + + var options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck; + + string symlinkFileNameLp = Path.GetExtendedLengthPathCore(transaction, symlinkFileName, pathFormat, options); + string targetFileNameRp = Path.GetExtendedLengthPathCore(transaction, targetFileName, pathFormat, options); + + // Don't use long path notation, as it will be empty upon creation. + targetFileNameRp = Path.GetRegularPathCore(targetFileNameRp, GetFullPathOptions.None, false); + + + if (!(transaction == null + + // CreateSymbolicLink() / CreateSymbolicLinkTransacted() + // 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. + // 2014-02-14: MSDN does not confirm LongPath usage but a Unicode version of this function exists. + // 2015-07-17: This function does not support long paths. + + ? NativeMethods.CreateSymbolicLink(symlinkFileNameLp, targetFileNameRp, targetType) + : NativeMethods.CreateSymbolicLinkTransacted(symlinkFileNameLp, targetFileNameRp, targetType, transaction.SafeHandle))) + { + var lastError = Marshal.GetLastWin32Error(); + if (lastError != 0) + NativeError.ThrowException(lastError, symlinkFileNameLp, targetFileNameRp); + } + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.CreateText.cs b/AlphaFS/Filesystem/File Class/File.CreateText.cs new file mode 100644 index 0000000..b73d06f --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.CreateText.cs @@ -0,0 +1,110 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; +using System.Text; +using StreamWriter = System.IO.StreamWriter; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region Public Methods + + /// Creates or opens a file for writing UTF-8 encoded text. + /// The file to be opened for writing. + /// A StreamWriter that writes to the specified file using UTF-8 encoding. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public static StreamWriter CreateText(string path) + { + return CreateTextCore(null, path, NativeMethods.DefaultFileEncoding, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates or opens a file for writing UTF-8 encoded text. + /// The file to be opened for writing. + /// Indicates the format of the path parameter(s). + /// A StreamWriter that writes to the specified file using UTF-8 encoding. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public static StreamWriter CreateText(string path, PathFormat pathFormat) + { + return CreateTextCore(null, path, NativeMethods.DefaultFileEncoding, pathFormat); + } + + /// [AlphaFS] Creates or opens a file for writing encoded text. + /// The file to be opened for writing. + /// The encoding that is applied to the contents of the file. + /// Indicates the format of the path parameter(s). + /// A StreamWriter that writes to the specified file using UTF-8 encoding. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public static StreamWriter CreateText(string path, Encoding encoding, PathFormat pathFormat) + { + return CreateTextCore(null, path, encoding, pathFormat); + } + + /// [AlphaFS] Creates or opens a file for writing UTF-8 encoded text. + /// The transaction. + /// The file to be opened for writing. + /// A StreamWriter that writes to the specified file using UTF-8 encoding. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public static StreamWriter CreateTextTransacted(KernelTransaction transaction, string path) + { + return CreateTextCore(transaction, path, NativeMethods.DefaultFileEncoding, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates or opens a file for writing encoded text. + /// The transaction. + /// The file to be opened for writing. + /// The encoding that is applied to the contents of the file. + /// Indicates the format of the path parameter(s). + /// A StreamWriter that writes to the specified file using UTF-8 encoding. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public static StreamWriter CreateTextTransacted(KernelTransaction transaction, string path, Encoding encoding, PathFormat pathFormat) + { + return CreateTextCore(transaction, path, encoding, pathFormat); + } + + #endregion + + #region Internal Methods + + /// Creates or opens a file for writing encoded text. + /// The transaction. + /// The file to be opened for writing. + /// The applied to the contents of the file. + /// Indicates the format of the path parameter(s). + /// A that writes to the specified file using NativeMethods.DefaultFileBufferSize encoding. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + internal static StreamWriter CreateTextCore(KernelTransaction transaction, string path, Encoding encoding, PathFormat pathFormat) + { + return new StreamWriter(CreateFileStreamCore(transaction, path, ExtendedFileAttributes.SequentialScan, null, FileMode.Create, FileAccess.Write, FileShare.Read, NativeMethods.DefaultFileBufferSize, pathFormat), encoding); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.Delete.cs b/AlphaFS/Filesystem/File Class/File.Delete.cs new file mode 100644 index 0000000..447d1cb --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.Delete.cs @@ -0,0 +1,238 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Globalization; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region Delete + + /// Deletes the specified file. + /// If the file to be deleted does not exist, no exception is thrown. + /// + /// The name of the file to be deleted. Wildcard characters are not supported. + /// + /// + /// + /// + /// + [SecurityCritical] + public static void Delete(string path) + { + DeleteFileCore(null, path, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Deletes the specified file. + /// If the file to be deleted does not exist, no exception is thrown. + /// + /// The name of the file to be deleted. Wildcard characters are not supported. + /// + /// + /// overrides the read only of the file. + /// + /// Indicates the format of the path parameter(s). + /// + /// + /// + /// + [SecurityCritical] + public static void Delete(string path, bool ignoreReadOnly, PathFormat pathFormat) + { + DeleteFileCore(null, path, ignoreReadOnly, pathFormat); + } + + + /// [AlphaFS] Deletes the specified file. + /// If the file to be deleted does not exist, no exception is thrown. + /// + /// The name of the file to be deleted. Wildcard characters are not supported. + /// + /// + /// overrides the read only of the file. + /// + /// + /// + /// + /// + [SecurityCritical] + public static void Delete(string path, bool ignoreReadOnly) + { + DeleteFileCore(null, path, ignoreReadOnly, PathFormat.RelativePath); + } + + #region Transactional + + /// [AlphaFS] Deletes the specified file. + /// If the file to be deleted does not exist, no exception is thrown. + /// The transaction. + /// + /// The name of the file to be deleted. Wildcard characters are not supported. + /// + /// + /// + /// + /// + [SecurityCritical] + public static void DeleteTransacted(KernelTransaction transaction, string path) + { + DeleteFileCore(transaction, path, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Deletes the specified file. + /// The transaction. + /// The name of the file to be deleted. Wildcard characters are not supported. + /// overrides the read only of the file. + /// Indicates the format of the path parameter(s). + /// If the file to be deleted does not exist, no exception is thrown. + /// + /// + /// + /// + [SecurityCritical] + public static void DeleteTransacted(KernelTransaction transaction, string path, bool ignoreReadOnly, PathFormat pathFormat) + { + DeleteFileCore(transaction, path, ignoreReadOnly, pathFormat); + } + + /// [AlphaFS] Deletes the specified file. + /// The transaction. + /// The name of the file to be deleted. Wildcard characters are not supported. + /// overrides the read only of the file. + /// If the file to be deleted does not exist, no exception is thrown. + /// + /// + /// + /// + [SecurityCritical] + public static void DeleteTransacted(KernelTransaction transaction, string path, bool ignoreReadOnly) + { + DeleteFileCore(transaction, path, ignoreReadOnly, PathFormat.RelativePath); + } + + #endregion // Transacted + + #endregion // Delete + + #region Internal Methods + + /// Deletes a Non-/Transacted file. + /// If the file to be deleted does not exist, no exception is thrown. + /// + /// + /// + /// + /// The transaction. + /// The name of the file to be deleted. + /// overrides the read only of the file. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static void DeleteFileCore(KernelTransaction transaction, string path, bool ignoreReadOnly, PathFormat pathFormat) + { + #region Setup + + if (pathFormat == PathFormat.RelativePath) + Path.CheckSupportedPathFormat(path, true, true); + + string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator); + + // If the path points to a symbolic link, the symbolic link is deleted, not the target. + + #endregion // Setup + + startDeleteFile: + + if (!(transaction == null || !NativeMethods.IsAtLeastWindowsVista + + // DeleteFile() / DeleteFileTransacted() + // 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.DeleteFile(pathLp) + : NativeMethods.DeleteFileTransacted(pathLp, transaction.SafeHandle))) + { + int lastError = Marshal.GetLastWin32Error(); + switch ((uint)lastError) + { + case Win32Errors.ERROR_FILE_NOT_FOUND: + // MSDN: .NET 3.5+: If the file to be deleted does not exist, no exception is thrown. + return; + + case Win32Errors.ERROR_PATH_NOT_FOUND: + // MSDN: .NET 3.5+: DirectoryNotFoundException: The specified path is invalid (for example, it is on an unmapped drive). + NativeError.ThrowException(lastError, pathLp); + return; + + case Win32Errors.ERROR_SHARING_VIOLATION: + // MSDN: .NET 3.5+: IOException: The specified file is in use or there is an open handle on the file. + NativeError.ThrowException(lastError, pathLp); + break; + + case Win32Errors.ERROR_ACCESS_DENIED: + var data = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA(); + int dataInitialised = FillAttributeInfoCore(transaction, pathLp, ref data, false, true); + + if (data.dwFileAttributes != (FileAttributes)(-1)) + { + if ((data.dwFileAttributes & FileAttributes.Directory) != 0) + // MSDN: .NET 3.5+: UnauthorizedAccessException: Path is a directory. + throw new UnauthorizedAccessException(string.Format(CultureInfo.CurrentCulture, "({0}) {1}", + Win32Errors.ERROR_INVALID_PARAMETER, string.Format(CultureInfo.CurrentCulture, Resources.Target_File_Is_A_Directory, pathLp))); + + + if ((data.dwFileAttributes & FileAttributes.ReadOnly) != 0) + { + if (ignoreReadOnly) + { + // Reset file attributes. + SetAttributesCore(false, transaction, pathLp, FileAttributes.Normal, true, PathFormat.LongFullPath); + goto startDeleteFile; + } + + // MSDN: .NET 3.5+: UnauthorizedAccessException: Path specified a read-only file. + throw new FileReadOnlyException(pathLp); + } + } + + if (dataInitialised == Win32Errors.ERROR_SUCCESS) + // MSDN: .NET 3.5+: UnauthorizedAccessException: The caller does not have the required permission. + NativeError.ThrowException(lastError, pathLp); + + break; + } + + // MSDN: .NET 3.5+: IOException: + // The specified file is in use. + // There is an open handle on the file, and the operating system is Windows XP or earlier. + + NativeError.ThrowException(lastError, pathLp); + } + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.EncryptDecrypt.cs b/AlphaFS/Filesystem/File Class/File.EncryptDecrypt.cs new file mode 100644 index 0000000..35bbcc5 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.EncryptDecrypt.cs @@ -0,0 +1,120 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Globalization; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region Public Methods + + /// Decrypts a file that was encrypted by the current account using the Encrypt method. + /// A path that describes a file to decrypt. + [SecurityCritical] + public static void Decrypt(string path) + { + EncryptDecryptFileCore(false, path, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Decrypts a file that was encrypted by the current account using the Encrypt method. + /// A path that describes a file to decrypt. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Decrypt(string path, PathFormat pathFormat) + { + EncryptDecryptFileCore(false, path, false, pathFormat); + } + + /// Encrypts a file so that only the account used to encrypt the file can decrypt it. + /// A path that describes a file to encrypt. + [SecurityCritical] + public static void Encrypt(string path) + { + EncryptDecryptFileCore(false, path, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Encrypts a file so that only the account used to encrypt the file can decrypt it. + /// A path that describes a file to encrypt. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void Encrypt(string path, PathFormat pathFormat) + { + EncryptDecryptFileCore(false, path, true, pathFormat); + } + + #endregion + + + + + #region Internal Methods + + /// Decrypts/encrypts a file or directory so that only the account used to encrypt the file can decrypt it. + /// + /// Specifies that is a file or directory. + /// A path that describes a file to encrypt. + /// encrypt, decrypt. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static void EncryptDecryptFileCore(bool isFolder, string path, bool encrypt, PathFormat pathFormat) + { + string pathLp = Path.GetExtendedLengthPathCore(null, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + + // Reset file/directory attributes. + // MSDN: If lpFileName specifies a read-only file, the function fails and GetLastError returns ERROR_FILE_READ_ONLY. + SetAttributesCore(isFolder, null, pathLp, FileAttributes.Normal, true, PathFormat.LongFullPath); + + // EncryptFile() / DecryptFile() + // 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 does not confirm LongPath usage but a Unicode version of this function exists. + + if (!(encrypt + ? NativeMethods.EncryptFile(pathLp) + : NativeMethods.DecryptFile(pathLp, 0))) + { + int lastError = Marshal.GetLastWin32Error(); + switch ((uint)lastError) + { + case Win32Errors.ERROR_ACCESS_DENIED: + string root = Path.GetPathRoot(pathLp, false); + if (!string.Equals("NTFS", new DriveInfo(root).DriveFormat, StringComparison.OrdinalIgnoreCase)) + throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "The drive does not support NTFS encryption: [{0}]", root)); + break; + + default: + if (lastError == Win32Errors.ERROR_FILE_NOT_FOUND && isFolder) + lastError = (int)Win32Errors.ERROR_PATH_NOT_FOUND; + + NativeError.ThrowException(lastError, pathLp); + break; + } + } + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.EncryptedFileRaw.cs b/AlphaFS/Filesystem/File Class/File.EncryptedFileRaw.cs new file mode 100644 index 0000000..faa5492 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.EncryptedFileRaw.cs @@ -0,0 +1,291 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class File + { + #region Export + + /// [AlphaFS] Backs up (export) encrypted files. This is one of a group of Encrypted File System (EFS) functions that is + /// intended to implement backup and restore functionality, while maintaining files in their encrypted state. + /// + /// + /// The file being backed up is not decrypted; it is backed up in its encrypted state. + /// + /// + /// If the caller does not have access to the key for the file, the caller needs + /// to export encrypted files. See + /// . + /// + /// + /// To backup an encrypted file call one of the + /// overloads and specify the file to backup + /// along with the destination stream of the backup data. + /// + /// + /// This function is intended for the backup of only encrypted files; see for backup + /// of unencrypted files. + /// + /// + /// The name of the file to be backed up. + /// The destination stream to which the backup data will be written. + /// + public static void ExportEncryptedFileRaw(string fileName, Stream outputStream) + { + ImportExportEncryptedFileDirectoryRawCore(true, false, outputStream, fileName, PathFormat.RelativePath, false); + } + + /// [AlphaFS] Backs up (export) encrypted files. This is one of a group of Encrypted File System (EFS) functions that is + /// intended to implement backup and restore functionality, while maintaining files in their encrypted state. + /// + /// + /// The file being backed up is not decrypted; it is backed up in its encrypted state. + /// + /// + /// If the caller does not have access to the key for the file, the caller needs + /// to export encrypted files. See + /// . + /// + /// + /// To backup an encrypted file call one of the + /// overloads and specify the file to backup + /// along with the destination stream of the backup data. + /// + /// + /// This function is intended for the backup of only encrypted files; see for backup + /// of unencrypted files. + /// + /// + /// The name of the file to be backed up. + /// The destination stream to which the backup data will be written. + /// The path format of the parameter. + /// + public static void ExportEncryptedFileRaw(string fileName, Stream outputStream, PathFormat pathFormat) + { + ImportExportEncryptedFileDirectoryRawCore(true, false, outputStream, fileName, pathFormat, false); + } + + #endregion // Export + + #region Import + + /// [AlphaFS] Restores (import) encrypted files. This is one of a group of Encrypted File System (EFS) functions that is + /// intended to implement backup and restore functionality, while maintaining files in their encrypted state. + /// + /// + /// If the caller does not have access to the key for the file, the caller needs + /// to restore encrypted files. See + /// . + /// + /// + /// To restore an encrypted file call one of the + /// overloads and specify the file to restore + /// along with the destination stream of the restored data. + /// + /// + /// This function is intended for the restoration of only encrypted files; see for + /// backup of unencrypted files. + /// + /// + /// The stream to read previously backed up data from. + /// The path of the destination file to restore to. + /// + public static void ImportEncryptedFileRaw(Stream inputStream, string destinationFilePath) + { + ImportExportEncryptedFileDirectoryRawCore(false, false, inputStream, destinationFilePath, PathFormat.RelativePath, false); + } + + /// [AlphaFS] Restores (import) encrypted files. This is one of a group of Encrypted File System (EFS) functions that is + /// intended to implement backup and restore functionality, while maintaining files in their encrypted state. + /// + /// + /// If the caller does not have access to the key for the file, the caller needs + /// to restore encrypted files. See + /// . + /// + /// + /// To restore an encrypted file call one of the + /// overloads and specify the file to restore + /// along with the destination stream of the restored data. + /// + /// + /// This function is intended for the restoration of only encrypted files; see for + /// backup of unencrypted files. + /// + /// + /// The stream to read previously backed up data from. + /// The path of the destination file to restore to. + /// The path format of the parameter. + /// + public static void ImportEncryptedFileRaw(Stream inputStream, string destinationFilePath, PathFormat pathFormat) + { + ImportExportEncryptedFileDirectoryRawCore(false, false, inputStream, destinationFilePath, pathFormat, false); + } + + + /// [AlphaFS] Restores (import) encrypted files. This is one of a group of Encrypted File System (EFS) functions that is + /// intended to implement backup and restore functionality, while maintaining files in their encrypted state. + /// + /// + /// If the caller does not have access to the key for the file, the caller needs + /// to restore encrypted files. See + /// . + /// + /// + /// To restore an encrypted file call one of the + /// overloads and specify the file to restore + /// along with the destination stream of the restored data. + /// + /// + /// This function is intended for the restoration of only encrypted files; see for + /// backup of unencrypted files. + /// + /// + /// The stream to read previously backed up data from. + /// The path of the destination file to restore to. + /// If set to a hidden file will be overwritten on import. + /// + public static void ImportEncryptedFileRaw(Stream inputStream, string destinationFilePath, bool overwriteHidden) + { + ImportExportEncryptedFileDirectoryRawCore(false, false, inputStream, destinationFilePath, PathFormat.RelativePath, overwriteHidden); + } + + /// [AlphaFS] Restores (import) encrypted files. This is one of a group of Encrypted File System (EFS) functions that is + /// intended to implement backup and restore functionality, while maintaining files in their encrypted state. + /// + /// + /// If the caller does not have access to the key for the file, the caller needs + /// to restore encrypted files. See + /// . + /// + /// + /// To restore an encrypted file call one of the + /// overloads and specify the file to restore + /// along with the destination stream of the restored data. + /// + /// + /// This function is intended for the restoration of only encrypted files; see for + /// backup of unencrypted files. + /// + /// + /// The stream to read previously backed up data from. + /// The path of the destination file to restore to. + /// If set to a hidden file will be overwritten on import. + /// The path format of the parameter. + /// + public static void ImportEncryptedFileRaw(Stream inputStream, string destinationFilePath, bool overwriteHidden, PathFormat pathFormat) + { + ImportExportEncryptedFileDirectoryRawCore(false, false, inputStream, destinationFilePath, pathFormat, overwriteHidden); + } + + #endregion // Import + + + + + internal static void ImportExportEncryptedFileDirectoryRawCore(bool isExport, bool isFolder, Stream stream, string destinationPath, PathFormat pathFormat, bool overwriteHidden) + { + string destinationPathLp = Path.GetExtendedLengthPathCore(null, destinationPath, pathFormat, GetFullPathOptions.FullCheck | GetFullPathOptions.TrimEnd); + + NativeMethods.EncryptedFileRawMode mode = isExport + ? NativeMethods.EncryptedFileRawMode.CreateForExport + : NativeMethods.EncryptedFileRawMode.CreateForImport; + + if (isFolder) + mode = mode | NativeMethods.EncryptedFileRawMode.CreateForDir; + + if (overwriteHidden) + mode = mode | NativeMethods.EncryptedFileRawMode.OverwriteHidden; + + + // OpenEncryptedFileRaw() + // 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. + // 2015-08-02: MSDN does not confirm LongPath usage but a Unicode version of this function exists. + + SafeEncryptedFileRawHandle context; + var lastError = NativeMethods.OpenEncryptedFileRaw(destinationPathLp, mode, out context); + + try + { + if (lastError != Win32Errors.ERROR_SUCCESS) + NativeError.ThrowException(lastError, destinationPathLp); + + + lastError = isExport + ? NativeMethods.ReadEncryptedFileRaw((pbData, pvCallbackContext, length) => + { + try + { + var data = new byte[length]; + + Marshal.Copy(pbData, data, 0, (int) length); + + stream.Write(data, 0, (int) length); + } + catch (Exception ex) + { + return Marshal.GetHRForException(ex) & NativeMethods.OverflowExceptionBitShift; + } + + return (int) Win32Errors.ERROR_SUCCESS; + + }, IntPtr.Zero, context) + + + : NativeMethods.WriteEncryptedFileRaw((IntPtr pbData, IntPtr pvCallbackContext, ref uint length) => + { + try + { + var data = new byte[length]; + + length = (uint) stream.Read(data, 0, (int) length); + if (length == 0) + return (int) Win32Errors.ERROR_SUCCESS; + + Marshal.Copy(data, 0, pbData, (int) length); + } + catch (Exception ex) + { + return Marshal.GetHRForException(ex) & NativeMethods.OverflowExceptionBitShift; + } + + return (int) Win32Errors.ERROR_SUCCESS; + + }, IntPtr.Zero, context); + + + if (lastError != Win32Errors.ERROR_SUCCESS) + NativeError.ThrowException(lastError, destinationPathLp); + } + finally + { + if (context != null) + context.Dispose(); + } + } + } +} diff --git a/AlphaFS/Filesystem/File Class/File.EnumerateAlternateDataStreams.cs b/AlphaFS/Filesystem/File Class/File.EnumerateAlternateDataStreams.cs new file mode 100644 index 0000000..788a67e --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.EnumerateAlternateDataStreams.cs @@ -0,0 +1,121 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class File + { + /// [AlphaFS] Enumerates the streams of type :$DATA from the specified file. + /// The path to the file to enumerate streams of. + /// The streams of type :$DATA in the specified file. + [SecurityCritical] + public static IEnumerable EnumerateAlternateDataStreams(string path) + { + return EnumerateAlternateDataStreamsCore(null, path, PathFormat.RelativePath); + } + + /// [AlphaFS] Enumerates the streams of type :$DATA from the specified file. + /// The path to the file to enumerate streams of. + /// Indicates the format of the path parameter(s). + /// The streams of type :$DATA in the specified file. + [SecurityCritical] + public static IEnumerable EnumerateAlternateDataStreams(string path, PathFormat pathFormat) + { + return EnumerateAlternateDataStreamsCore(null, path, pathFormat); + } + + /// [AlphaFS] Enumerates the streams of type :$DATA from the specified file. + /// The transaction. + /// The path to the file to enumerate streams of. + /// The streams of type :$DATA in the specified file. + [SecurityCritical] + public static IEnumerable EnumerateAlternateDataStreamsTransacted(KernelTransaction transaction, string path) + { + return EnumerateAlternateDataStreamsCore(transaction, path, PathFormat.RelativePath); + } + + /// [AlphaFS] Enumerates the streams of type :$DATA from the specified file. + /// The transaction. + /// The path to the file to enumerate streams of. + /// Indicates the format of the path parameter(s). + /// The streams of type :$DATA in the specified file. + [SecurityCritical] + public static IEnumerable EnumerateAlternateDataStreamsTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return EnumerateAlternateDataStreamsCore(transaction, path, pathFormat); + } + + + + + #region Internal Methods + + /// [AlphaFS] Enumerates the streams of type :$DATA from the specified file or directory. + /// The transaction. + /// The path to the file or directory to enumerate streams of. + /// Indicates the format of the path parameter(s). + /// The streams of type :$DATA in the specified file or directory. + internal static IEnumerable EnumerateAlternateDataStreamsCore(KernelTransaction transaction, string path, PathFormat pathFormat) + { + using (var buffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(typeof(NativeMethods.WIN32_FIND_STREAM_DATA)))) + { + string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, + GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars | + GetFullPathOptions.CheckAdditional); + + using (SafeFindFileHandle handle = transaction == null + ? NativeMethods.FindFirstStreamW(pathLp, NativeMethods.STREAM_INFO_LEVELS.FindStreamInfoStandard, buffer, 0) + : NativeMethods.FindFirstStreamTransactedW(pathLp, NativeMethods.STREAM_INFO_LEVELS.FindStreamInfoStandard, buffer, 0, transaction.SafeHandle)) + { + int errorCode = Marshal.GetLastWin32Error(); + + if (handle.IsInvalid) + { + if (errorCode == Win32Errors.ERROR_HANDLE_EOF) + yield break; + + NativeError.ThrowException(errorCode); + } + + while (true) + { + yield return new AlternateDataStreamInfo(pathLp, buffer.PtrToStructure(0)); + + if (!NativeMethods.FindNextStreamW(handle, buffer)) + { + int lastError = Marshal.GetLastWin32Error(); + if (lastError == Win32Errors.ERROR_HANDLE_EOF) + break; + + NativeError.ThrowException(lastError, pathLp); + } + } + } + } + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.EnumerateHardlinks.cs b/AlphaFS/Filesystem/File Class/File.EnumerateHardlinks.cs new file mode 100644 index 0000000..e0edb6f --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.EnumerateHardlinks.cs @@ -0,0 +1,170 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region EnumerateHardlinks + + /// [AlphaFS] Creates an enumeration of all the hard links to the specified . + /// The name of the file. + /// Indicates the format of the path parameter(s). + /// An enumerable collection of of all the hard links to the specified + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hardlinks")] + [SecurityCritical] + public static IEnumerable EnumerateHardlinks(string path, PathFormat pathFormat) + { + return EnumerateHardlinksCore(null, path, pathFormat); + } + + /// [AlphaFS] Creates an enumeration of all the hard links to the specified . + /// The name of the file. + /// An enumerable collection of of all the hard links to the specified + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hardlinks")] + [SecurityCritical] + public static IEnumerable EnumerateHardlinks(string path) + { + return EnumerateHardlinksCore(null, path, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates an enumeration of all the hard links to the specified . + /// The transaction. + /// The name of the file. + /// Indicates the format of the path parameter(s). + /// An enumerable collection of of all the hard links to the specified + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hardlinks")] + [SecurityCritical] + public static IEnumerable EnumerateHardlinksTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return EnumerateHardlinksCore(transaction, path, pathFormat); + } + + /// [AlphaFS] Creates an enumeration of all the hard links to the specified . + /// The transaction. + /// The name of the file. + /// An enumerable collection of of all the hard links to the specified + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hardlinks")] + [SecurityCritical] + public static IEnumerable EnumerateHardlinksTransacted(KernelTransaction transaction, string path) + { + return EnumerateHardlinksCore(transaction, path, PathFormat.RelativePath); + } + + #endregion // EnumerateHardlinks + + #region Internal Methods + + /// [AlphaFS] Creates an enumeration of all the hard links to the specified . + /// + /// The transaction. + /// The name of the file. + /// Indicates the format of the path parameter(s). + /// An enumerable collection of of all the hard links to the specified + internal static IEnumerable EnumerateHardlinksCore(KernelTransaction transaction, string path, PathFormat pathFormat) + { + if (!NativeMethods.IsAtLeastWindowsVista) + throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher); + + string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + + // Default buffer length, will be extended if needed, although this should not happen. + uint length = NativeMethods.MaxPathUnicode; + StringBuilder builder = new StringBuilder((int)length); + + + getFindFirstFileName: + + using (SafeFindFileHandle handle = transaction == null + + // FindFirstFileName() / FindFirstFileNameTransacted() + // 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 does not confirm LongPath usage but a Unicode version of this function exists. + + ? NativeMethods.FindFirstFileName(pathLp, 0, out length, builder) + : NativeMethods.FindFirstFileNameTransacted(pathLp, 0, out length, builder, transaction.SafeHandle)) + { + int lastError = Marshal.GetLastWin32Error(); + + if (handle.IsInvalid) + { + handle.Close(); + + switch ((uint) lastError) + { + case Win32Errors.ERROR_MORE_DATA: + builder = new StringBuilder((int) length); + goto getFindFirstFileName; + + default: + // If the function fails, the return value is INVALID_HANDLE_VALUE. + NativeError.ThrowException(lastError, pathLp); + break; + } + } + + yield return builder.ToString(); + + + //length = NativeMethods.MaxPathUnicode; + //builder = new StringBuilder((int)length); + + do + { + while (!NativeMethods.FindNextFileName(handle, out length, builder)) + { + lastError = Marshal.GetLastWin32Error(); + + switch ((uint) lastError) + { + // We've reached the end of the enumeration. + case Win32Errors.ERROR_HANDLE_EOF: + yield break; + + case Win32Errors.ERROR_MORE_DATA: + builder = new StringBuilder((int) length); + continue; + + default: + //If the function fails, the return value is zero (0). + NativeError.ThrowException(lastError); + break; + } + } + + yield return builder.ToString(); + + } while (true); + } + } + + #endregion // Internal Methods + + } +} diff --git a/AlphaFS/Filesystem/File Class/File.Exists.cs b/AlphaFS/Filesystem/File Class/File.Exists.cs new file mode 100644 index 0000000..fa808cd --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.Exists.cs @@ -0,0 +1,228 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region Public Methods + + /// Determines whether the specified file exists. + /// + /// MSDN: .NET 3.5+: Trailing spaces are removed from the end of the + /// parameter before checking whether the directory exists. + /// The Exists method returns if any error occurs while trying to + /// determine if the specified file exists. + /// This can occur in situations that raise exceptions such as passing a file name with + /// invalid characters or too many characters, a failing or missing disk, or if the caller does not have permission to read the + /// file. + /// The Exists method should not be used for path validation, + /// this method merely checks if the file specified in path exists. + /// Passing an invalid path to Exists returns false. + /// Be aware that another process can potentially do something with the file in + /// between the time you call the Exists method and perform another operation on the file, such as Delete. + /// + /// The file to check. + /// + /// Returns if the caller has the required permissions and + /// contains the name of an existing file; otherwise, + /// + /// + [SecurityCritical] + public static bool Exists(string path) + { + return ExistsCore(false, null, path, PathFormat.RelativePath); + } + + /// [AlphaFS] Determines whether the specified file exists. + /// + /// MSDN: .NET 3.5+: Trailing spaces are removed from the end of the + /// parameter before checking whether the directory exists. + /// The Exists method returns if any error occurs while trying to + /// determine if the specified file exists. + /// This can occur in situations that raise exceptions such as passing a file name with + /// invalid characters or too many characters, + /// a failing or missing disk, or if the caller does not have permission to read the + /// file. + /// The Exists method should not be used for path validation, this method merely checks + /// if the file specified in path exists. + /// Passing an invalid path to Exists returns false. + /// Be aware that another process can potentially do something with the file in + /// between the time you call the Exists method and perform another operation on the file, such + /// as Delete. + /// + /// The file to check. + /// Indicates the format of the path parameter(s). + /// + /// Returns if the caller has the required permissions and + /// contains the name of an existing file; otherwise, + /// + /// + [SecurityCritical] + public static bool Exists(string path, PathFormat pathFormat) + { + return ExistsCore(false, null, path, pathFormat); + } + + #region Transactional + + /// + /// [AlphaFS] Determines whether the specified file exists. + /// + /// + /// MSDN: .NET 3.5+: Trailing spaces are removed from the end of the + /// parameter before checking whether the directory exists. + /// The Exists method returns if any error occurs while trying to + /// determine if the specified file exists. + /// This can occur in situations that raise exceptions such as passing a file name with + /// invalid characters or too many characters, + /// a failing or missing disk, or if the caller does not have permission to read the + /// file. + /// The Exists method should not be used for path validation, + /// this method merely checks if the file specified in path exists. + /// Passing an invalid path to Exists returns false. + /// Be aware that another process can potentially do something with the file in + /// between + /// the time you call the Exists method and perform another operation on the file, such + /// as Delete. + /// + /// The transaction. + /// The file to check. + /// + /// Returns if the caller has the required permissions + /// and contains the name of an existing file; otherwise, + /// + /// + [SecurityCritical] + public static bool ExistsTransacted(KernelTransaction transaction, string path) + { + return ExistsCore(false, transaction, path, PathFormat.RelativePath); + } + + /// + /// [AlphaFS] Determines whether the specified file exists. + /// + /// + /// MSDN: .NET 3.5+: Trailing spaces are removed from the end of the + /// parameter before checking whether the directory exists. + /// The Exists method returns if any error occurs while trying to + /// determine if the specified file exists. + /// This can occur in situations that raise exceptions such as passing a file name with + /// invalid characters or too many characters, + /// a failing or missing disk, or if the caller does not have permission to read the + /// file. + /// The Exists method should not be used for path validation, + /// this method merely checks if the file specified in path exists. + /// Passing an invalid path to Exists returns false. + /// Be aware that another process can potentially do something with the file in + /// between + /// the time you call the Exists method and perform another operation on the file, such + /// as Delete. + /// + /// The transaction. + /// The file to check. + /// Indicates the format of the path parameter(s). + /// + /// Returns if the caller has the required permissions + /// and contains the name of an existing file; otherwise, + /// + /// + [SecurityCritical] + public static bool ExistsTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return ExistsCore(false, transaction, path, pathFormat); + } + + #endregion // Transacted + + #endregion + + #region Internal Methods + + /// Determines whether the specified file or directory exists. + /// + /// MSDN: .NET 3.5+: Trailing spaces are removed from the end of the parameter before checking whether + /// the directory exists. + /// The Exists method returns if any error occurs while trying to determine if the specified file + /// exists. + /// This can occur in situations that raise exceptions such as passing a file name with invalid characters or too many characters, + /// + /// a failing or missing disk, or if the caller does not have permission to read the file. + /// The Exists method should not be used for path validation, + /// this method merely checks if the file specified in path exists. + /// Passing an invalid path to Exists returns false. + /// Be aware that another process can potentially do something with the file in between + /// the time you call the Exists method and perform another operation on the file, such as Delete. + /// + /// Specifies that is a file or directory. + /// The transaction. + /// The file to check. + /// Indicates the format of the path parameter(s). + /// + /// Returns if the caller has the required permissions + /// and contains the name of an existing file or directory; otherwise, + /// + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + [SecurityCritical] + internal static bool ExistsCore(bool isFolder, KernelTransaction transaction, string path, PathFormat pathFormat) + { + // Will be caught later and be thrown as an ArgumentException or ArgumentNullException. + // Let's take a shorter route, preventing an Exception from being thrown altogether. + if (Utils.IsNullOrWhiteSpace(path)) + return false; + + + // DriveInfo.IsReady() will fail. + // + //// After normalizing, check whether path ends in directory separator. + //// Otherwise, FillAttributeInfoCore removes it and we may return a false positive. + //string pathRp = Path.GetRegularPathCore(path, true, false, false, false); + + //if (pathRp.Length > 0 && Path.IsDVsc(pathRp[pathRp.Length - 1], false)) + // return false; + + + try + { + string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars | GetFullPathOptions.ContinueOnNonExist); + + var data = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA(); + int dataInitialised = FillAttributeInfoCore(transaction, pathLp, ref data, false, true); + + return (dataInitialised == Win32Errors.ERROR_SUCCESS && + data.dwFileAttributes != (FileAttributes) (-1) && + (isFolder + ? (data.dwFileAttributes & FileAttributes.Directory) != 0 + : (data.dwFileAttributes & FileAttributes.Directory) == 0)); + } + catch + { + return false; + } + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.GetAccessControl.cs b/AlphaFS/Filesystem/File Class/File.GetAccessControl.cs new file mode 100644 index 0000000..7ff60e6 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.GetAccessControl.cs @@ -0,0 +1,255 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.AccessControl; +using Alphaleonis.Win32.Security; +using Microsoft.Win32.SafeHandles; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class File + { + /// Gets a object that encapsulates the access control list (ACL) entries for a specified file. + /// A object that encapsulates the access control rules for the file described by the parameter. + /// + /// + /// + /// The path to a file containing a object that describes the file's access control list (ACL) information. + [SecurityCritical] + public static FileSecurity GetAccessControl(string path) + { + return GetAccessControlCore(false, path, AccessControlSections.Access | AccessControlSections.Group | AccessControlSections.Owner, PathFormat.RelativePath); + } + + /// Gets a object that encapsulates the access control list (ACL) entries for a specified file. + /// A object that encapsulates the access control rules for the file described by the parameter. + /// + /// + /// + /// The path to a file containing a object that describes the file's access control list (ACL) information. + /// One (or more) of the values that specifies the type of access control list (ACL) information to receive. + [SecurityCritical] + public static FileSecurity GetAccessControl(string path, AccessControlSections includeSections) + { + return GetAccessControlCore(false, path, includeSections, PathFormat.RelativePath); + } + + + /// [AlphaFS] Gets a object that encapsulates the access control list (ACL) entries for a specified file. + /// A object that encapsulates the access control rules for the file described by the parameter. + /// + /// + /// + /// The path to a file containing a object that describes the file's access control list (ACL) information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static FileSecurity GetAccessControl(string path, PathFormat pathFormat) + { + return GetAccessControlCore(false, path, AccessControlSections.Access | AccessControlSections.Group | AccessControlSections.Owner, pathFormat); + } + + /// [AlphaFS] Gets a object that encapsulates the access control list (ACL) entries for a specified file. + /// A object that encapsulates the access control rules for the file described by the parameter. + /// + /// + /// + /// The path to a file containing a object that describes the file's access control list (ACL) information. + /// One (or more) of the values that specifies the type of access control list (ACL) information to receive. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static FileSecurity GetAccessControl(string path, AccessControlSections includeSections, PathFormat pathFormat) + { + return GetAccessControlCore(false, path, includeSections, pathFormat); + } + + + /// [AlphaFS] Gets a object that encapsulates the access control list (ACL) entries for a specified file handle. + /// A object that encapsulates the access control rules for the file described by the parameter. + /// + /// + /// + /// A to a file containing a object that describes the file's access control list (ACL) information. + [SecurityCritical] + public static FileSecurity GetAccessControl(SafeFileHandle handle) + { + return GetAccessControlHandleCore(false, false, handle, AccessControlSections.Access | AccessControlSections.Group | AccessControlSections.Owner, SecurityInformation.None); + } + + /// [AlphaFS] Gets a object that encapsulates the access control list (ACL) entries for a specified file handle. + /// A object that encapsulates the access control rules for the file described by the parameter. + /// + /// + /// + /// A to a file containing a object that describes the file's access control list (ACL) information. + /// One (or more) of the values that specifies the type of access control list (ACL) information to receive. + [SecurityCritical] + public static FileSecurity GetAccessControl(SafeFileHandle handle, AccessControlSections includeSections) + { + return GetAccessControlHandleCore(false, false, handle, includeSections, SecurityInformation.None); + } + + + + + /// [AlphaFS] Gets an object for a particular file or directory. + /// An object that encapsulates the access control rules for the file or directory described by the parameter. + /// + /// + /// + /// Generic type parameter. + /// Specifies that is a file or directory. + /// The path to a file/directory containing a / object that describes the file's/directory's access control list (ACL) information. + /// One (or more) of the values that specifies the type of access control list (ACL) information to receive. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Disposing is controlled.")] + [SecurityCritical] + internal static T GetAccessControlCore(bool isFolder, string path, AccessControlSections includeSections, PathFormat pathFormat) + { + SecurityInformation securityInfo = CreateSecurityInformation(includeSections); + + + // We need the SE_SECURITY_NAME privilege enabled to be able to get the SACL descriptor. + // So we enable it here for the remainder of this function. + + PrivilegeEnabler privilege = null; + + if ((includeSections & AccessControlSections.Audit) != 0) + privilege = new PrivilegeEnabler(Privilege.Security); + + using (privilege) + { + IntPtr pSidOwner, pSidGroup, pDacl, pSacl; + SafeGlobalMemoryBufferHandle pSecurityDescriptor; + + string pathLp = Path.GetExtendedLengthPathCore(null, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + + + // Get/SetNamedSecurityInfo does not work with a handle but with a path, hence does not honor the privileges. + // It magically does since Windows Server 2012 / 8 but not in previous OS versions. + + uint lastError = Security.NativeMethods.GetNamedSecurityInfo(pathLp, ObjectType.FileObject, securityInfo, + out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor); + + + // When GetNamedSecurityInfo() fails with ACCESS_DENIED, try again using GetSecurityInfo(). + + if (lastError == Win32Errors.ERROR_ACCESS_DENIED) + using (SafeFileHandle handle = CreateFileCore(null, pathLp, ExtendedFileAttributes.BackupSemantics, null, FileMode.Open, FileSystemRights.Read, FileShare.Read, false, PathFormat.LongFullPath)) + return GetAccessControlHandleCore(true, isFolder, handle, includeSections, securityInfo); + + return GetSecurityDescriptor(lastError, isFolder, pathLp, pSecurityDescriptor); + } + } + + + internal static T GetAccessControlHandleCore(bool internalCall, bool isFolder, SafeFileHandle handle, AccessControlSections includeSections, SecurityInformation securityInfo) + { + if (!internalCall) + securityInfo = CreateSecurityInformation(includeSections); + + + // We need the SE_SECURITY_NAME privilege enabled to be able to get the SACL descriptor. + // So we enable it here for the remainder of this function. + + PrivilegeEnabler privilege = null; + + if (!internalCall && (includeSections & AccessControlSections.Audit) != 0) + privilege = new PrivilegeEnabler(Privilege.Security); + + using (privilege) + { + IntPtr pSidOwner, pSidGroup, pDacl, pSacl; + SafeGlobalMemoryBufferHandle pSecurityDescriptor; + + uint lastError = Security.NativeMethods.GetSecurityInfo(handle, ObjectType.FileObject, securityInfo, + out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor); + + return GetSecurityDescriptor(lastError, isFolder, null, pSecurityDescriptor); + } + } + + + private static SecurityInformation CreateSecurityInformation(AccessControlSections includeSections) + { + var securityInfo = SecurityInformation.None; + + + if ((includeSections & AccessControlSections.Access) != 0) + securityInfo |= SecurityInformation.Dacl; + + if ((includeSections & AccessControlSections.Audit) != 0) + securityInfo |= SecurityInformation.Sacl; + + if ((includeSections & AccessControlSections.Group) != 0) + securityInfo |= SecurityInformation.Group; + + if ((includeSections & AccessControlSections.Owner) != 0) + securityInfo |= SecurityInformation.Owner; + + + return securityInfo; + } + + + private static T GetSecurityDescriptor(uint lastError, bool isFolder, string path, SafeGlobalMemoryBufferHandle securityDescriptor) + { + ObjectSecurity objectSecurity; + + using (securityDescriptor) + { + if (lastError == Win32Errors.ERROR_FILE_NOT_FOUND || lastError == Win32Errors.ERROR_PATH_NOT_FOUND) + lastError = isFolder ? Win32Errors.ERROR_PATH_NOT_FOUND : Win32Errors.ERROR_FILE_NOT_FOUND; + + + // If the function fails, the return value is zero. + if (lastError != Win32Errors.ERROR_SUCCESS) + { + if (!Utils.IsNullOrWhiteSpace(path)) + NativeError.ThrowException(lastError, path); + else + NativeError.ThrowException((int) lastError); + } + + if (!NativeMethods.IsValidHandle(securityDescriptor, false)) + throw new IOException(Resources.Returned_Invalid_Security_Descriptor); + + + uint length = Security.NativeMethods.GetSecurityDescriptorLength(securityDescriptor); + + // Seems not to work: Method .CopyTo: length > Capacity, so an Exception is thrown. + //byte[] managedBuffer = new byte[length]; + //pSecurityDescriptor.CopyTo(managedBuffer, 0, (int) length); + + byte[] managedBuffer = securityDescriptor.ToByteArray(0, (int) length); + + objectSecurity = isFolder ? (ObjectSecurity) new DirectorySecurity() : new FileSecurity(); + objectSecurity.SetSecurityDescriptorBinaryForm(managedBuffer); + } + + return (T) (object) objectSecurity; + } + } +} diff --git a/AlphaFS/Filesystem/File Class/File.GetAttributes.cs b/AlphaFS/Filesystem/File Class/File.GetAttributes.cs new file mode 100644 index 0000000..b58248c --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.GetAttributes.cs @@ -0,0 +1,227 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region GetAttributes + + /// Gets the of the file on the path. + /// The path to the file. + /// The of the file on the path. + [SecurityCritical] + public static FileAttributes GetAttributes(string path) + { + return GetAttributesExCore(null, path, PathFormat.RelativePath, true); + } + + /// [AlphaFS] Gets the of the file on the path. + /// The path to the file. + /// Indicates the format of the path parameter(s). + /// The of the file on the path. + [SecurityCritical] + public static FileAttributes GetAttributes(string path, PathFormat pathFormat) + { + return GetAttributesExCore(null, path, pathFormat, true); + } + + /// [AlphaFS] Gets the of the file on the path. + /// The transaction. + /// The path to the file. + /// The of the file on the path. + [SecurityCritical] + public static FileAttributes GetAttributesTransacted(KernelTransaction transaction, string path) + { + return GetAttributesExCore(transaction, path, PathFormat.RelativePath, true); + } + + /// [AlphaFS] Gets the of the file on the path. + /// The transaction. + /// The path to the file. + /// Indicates the format of the path parameter(s). + /// The of the file on the path. + [SecurityCritical] + public static FileAttributes GetAttributesTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return GetAttributesExCore(transaction, path, pathFormat, true); + } + + #endregion + + #region Internal Methods + + /// Gets the or of the specified file or directory. + /// The or of the specified file or directory. + /// + /// + /// Generic type parameter. + /// The transaction. + /// The path to the file or directory. + /// Indicates the format of the path parameter(s). + /// + [SuppressMessage("Microsoft.Interoperability", "CA1404:CallGetLastErrorImmediatelyAfterPInvoke", Justification = "Marshal.GetLastWin32Error() is manipulated.")] + [SecurityCritical] + internal static T GetAttributesExCore(KernelTransaction transaction, string path, PathFormat pathFormat, bool returnErrorOnNotFound) + { + if (pathFormat == PathFormat.RelativePath) + Path.CheckSupportedPathFormat(path, true, true); + + string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars); + + var data = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA(); + int dataInitialised = FillAttributeInfoCore(transaction, pathLp, ref data, false, returnErrorOnNotFound); + + if (dataInitialised != Win32Errors.ERROR_SUCCESS) + NativeError.ThrowException(dataInitialised, pathLp); + + return (T) (typeof (T) == typeof (FileAttributes) ? (object) data.dwFileAttributes : data); + } + + /// + /// Calls NativeMethods.GetFileAttributesEx to retrieve WIN32_FILE_ATTRIBUTE_DATA. + /// Note that classes should use -1 as the uninitialized state for dataInitialized when relying on this method. + /// + /// No path (null, empty string) checking or normalization is performed. + /// . + /// . + /// [in,out]. + /// . + /// . + /// 0 on success, otherwise a Win32 error code. + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + [SecurityCritical] + internal static int FillAttributeInfoCore(KernelTransaction transaction, string pathLp, ref NativeMethods.WIN32_FILE_ATTRIBUTE_DATA win32AttrData, bool tryagain, bool returnErrorOnNotFound) + { + int dataInitialised = (int)Win32Errors.ERROR_SUCCESS; + + #region Try Again + + // Someone has a handle to the file open, or other error. + if (tryagain) + { + NativeMethods.WIN32_FIND_DATA findData; + + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + { + bool error = false; + + SafeFindFileHandle handle = transaction == null || !NativeMethods.IsAtLeastWindowsVista + + // FindFirstFileEx() / FindFirstFileTransacted() + // 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. + + // A trailing backslash is not allowed. + ? NativeMethods.FindFirstFileEx(Path.RemoveTrailingDirectorySeparator(pathLp, false), NativeMethods.FindexInfoLevels, out findData, NativeMethods.FINDEX_SEARCH_OPS.SearchNameMatch, IntPtr.Zero, NativeMethods.LargeCache) + : NativeMethods.FindFirstFileTransacted(Path.RemoveTrailingDirectorySeparator(pathLp, false), NativeMethods.FindexInfoLevels, out findData, NativeMethods.FINDEX_SEARCH_OPS.SearchNameMatch, IntPtr.Zero, NativeMethods.LargeCache, transaction.SafeHandle); + + try + { + if (handle.IsInvalid) + { + error = true; + dataInitialised = Marshal.GetLastWin32Error(); + + if (dataInitialised == Win32Errors.ERROR_FILE_NOT_FOUND || + dataInitialised == Win32Errors.ERROR_PATH_NOT_FOUND || + dataInitialised == Win32Errors.ERROR_NOT_READY) // Floppy device not ready. + { + if (!returnErrorOnNotFound) + { + // Return default value for backward compatibility + dataInitialised = (int)Win32Errors.ERROR_SUCCESS; + win32AttrData.dwFileAttributes = (FileAttributes)(-1); + } + } + + return dataInitialised; + } + } + finally + { + try + { + if (handle != null) + handle.Close(); + } + catch + { + // If we're already returning an error, don't throw another one. + if (!error) + NativeError.ThrowException(dataInitialised, pathLp); + } + } + } + + // Copy the attribute information. + win32AttrData = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA(findData); + } + + #endregion // Try Again + + else + { + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + { + if (!(transaction == null || !NativeMethods.IsAtLeastWindowsVista + + // GetFileAttributesEx() / GetFileAttributesTransacted() + // 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.GetFileAttributesEx(pathLp, NativeMethods.GetFileExInfoLevels.GetFileExInfoStandard, out win32AttrData) + : NativeMethods.GetFileAttributesTransacted(pathLp, NativeMethods.GetFileExInfoLevels.GetFileExInfoStandard, out win32AttrData, transaction.SafeHandle))) + { + dataInitialised = Marshal.GetLastWin32Error(); + + if (dataInitialised != Win32Errors.ERROR_FILE_NOT_FOUND && + dataInitialised != Win32Errors.ERROR_PATH_NOT_FOUND && + dataInitialised != Win32Errors.ERROR_NOT_READY) // Floppy device not ready. + { + // In case someone latched onto the file. Take the perf hit only for failure. + return FillAttributeInfoCore(transaction, pathLp, ref win32AttrData, true, returnErrorOnNotFound); + } + + if (!returnErrorOnNotFound) + { + // Return default value for backward compbatibility. + dataInitialised = (int)Win32Errors.ERROR_SUCCESS; + win32AttrData.dwFileAttributes = (FileAttributes)(-1); + } + } + } + } + + return dataInitialised; + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.GetChangeTime.cs b/AlphaFS/Filesystem/File Class/File.GetChangeTime.cs new file mode 100644 index 0000000..cd50b43 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.GetChangeTime.cs @@ -0,0 +1,203 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Microsoft.Win32.SafeHandles; +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.AccessControl; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region GetChangeTime + + /// [AlphaFS] Gets the change date and time of the specified file. + /// A structure set to the change date and time for the specified file. This value is expressed in local time. + /// The file for which to obtain creation date and time information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetChangeTime(string path, PathFormat pathFormat) + { + return GetChangeTimeCore(false, null, null, path, false, pathFormat); + } + + + /// [AlphaFS] Gets the change date and time of the specified file. + /// A structure set to the change date and time for the specified file. This value is expressed in local time. + /// The file for which to obtain creation date and time information. + [SecurityCritical] + public static DateTime GetChangeTime(string path) + { + return GetChangeTimeCore(false, null, null, path, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the change date and time of the specified file. + /// A structure set to the change date and time for the specified file. This value is expressed in local time. + /// An open handle to the file or directory from which to retrieve information. + [SecurityCritical] + public static DateTime GetChangeTime(SafeFileHandle safeHandle) + { + return GetChangeTimeCore(false, null, safeHandle, null, false, PathFormat.LongFullPath); + } + + /// [AlphaFS] Gets the change date and time of the specified file. + /// A structure set to the change date and time for the specified file. This value is expressed in local time. + /// The transaction. + /// The file for which to obtain creation date and time information. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetChangeTimeTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return GetChangeTimeCore(false, transaction, null, path, false, pathFormat); + } + + /// [AlphaFS] Gets the change date and time of the specified file. + /// A structure set to the change date and time for the specified file. This value is expressed in local time. + /// The transaction. + /// The file for which to obtain creation date and time information. + [SecurityCritical] + public static DateTime GetChangeTimeTransacted(KernelTransaction transaction, string path) + { + return GetChangeTimeCore(false, transaction, null, path, false, PathFormat.RelativePath); + } + + #endregion // GetChangeTime + + #region GetChangeTimeUtc + + /// [AlphaFS] Gets the change date and time, in Coordinated Universal Time (UTC) format, of the specified file. + /// A structure set to the change date and time for the specified file. This value is expressed in UTC time. + /// The file for which to obtain change date and time information, in Coordinated Universal Time (UTC) format. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetChangeTimeUtc(string path, PathFormat pathFormat) + { + return GetChangeTimeCore(false, null, null, path, true, pathFormat); + } + + /// [AlphaFS] Gets the change date and time, in Coordinated Universal Time (UTC) format, of the specified file. + /// A structure set to the change date and time for the specified file. This value is expressed in UTC time. + /// The file for which to obtain change date and time information, in Coordinated Universal Time (UTC) format. + [SecurityCritical] + public static DateTime GetChangeTimeUtc(string path) + { + return GetChangeTimeCore(false, null, null, path, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the change date and time, in Coordinated Universal Time (UTC) format, of the specified file. + /// A structure set to the change date and time for the specified file. This value is expressed in UTC time. + /// An open handle to the file or directory from which to retrieve information. + [SecurityCritical] + public static DateTime GetChangeTimeUtc(SafeFileHandle safeHandle) + { + return GetChangeTimeCore(false, null, safeHandle, null, true, PathFormat.LongFullPath); + } + + /// [AlphaFS] Gets the change date and time, in Coordinated Universal Time (UTC) format, of the specified file. + /// A structure set to the change date and time for the specified file. This value is expressed in UTC time. + /// The transaction. + /// The file for which to obtain change date and time information, in Coordinated Universal Time (UTC) format. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static DateTime GetChangeTimeUtcTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return GetChangeTimeCore(false, transaction, null, path, true, pathFormat); + } + + /// [AlphaFS] Gets the change date and time, in Coordinated Universal Time (UTC) format, of the specified file. + /// A structure set to the change date and time for the specified file. This value is expressed in UTC time. + /// The transaction. + /// The file for which to obtain change date and time information, in Coordinated Universal Time (UTC) format. + [SecurityCritical] + public static DateTime GetChangeTimeUtcTransacted(KernelTransaction transaction, string path) + { + return GetChangeTimeCore(false, transaction, null, path, true, PathFormat.RelativePath); + } + + #endregion // GetChangeTimeUtc + + #region Internal Methods + + /// Gets the change date and time of the specified file. + /// A structure set to the change date and time for the specified file. This value is expressed in local time. + /// Use either or , not both. + /// + /// + /// + /// Specifies that is a file or directory. + /// The transaction. + /// An open handle to the file or directory from which to retrieve information. + /// The file or directory for which to obtain creation date and time information. + /// gets the Coordinated Universal Time (UTC), gets the local time. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Disposing is under control.")] + [SecurityCritical] + internal static DateTime GetChangeTimeCore(bool isFolder, KernelTransaction transaction, SafeFileHandle safeHandle, string path, bool getUtc, PathFormat pathFormat) + { + if (!NativeMethods.IsAtLeastWindowsVista) + throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher); + + bool callerHandle = safeHandle != null; + if (!callerHandle) + { + if (pathFormat != PathFormat.LongFullPath && Utils.IsNullOrWhiteSpace(path)) + throw new ArgumentNullException("path"); + + string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars); + + safeHandle = CreateFileCore(transaction, pathLp, isFolder ? ExtendedFileAttributes.BackupSemantics : ExtendedFileAttributes.Normal, null, FileMode.Open, FileSystemRights.ReadData, FileShare.ReadWrite, true, PathFormat.LongFullPath); + } + + + try + { + NativeMethods.IsValidHandle(safeHandle); + + using (var safeBuffer = new SafeGlobalMemoryBufferHandle(IntPtr.Size + Marshal.SizeOf(typeof(NativeMethods.FILE_BASIC_INFO)))) + { + NativeMethods.FILE_BASIC_INFO fbi; + + if (!NativeMethods.GetFileInformationByHandleEx_FileBasicInfo(safeHandle, NativeMethods.FileInfoByHandleClass.FileBasicInfo, out fbi, (uint)safeBuffer.Capacity)) + NativeError.ThrowException(Marshal.GetLastWin32Error()); + + safeBuffer.StructureToPtr(fbi, true); + NativeMethods.FILETIME changeTime = safeBuffer.PtrToStructure(0).ChangeTime; + + return getUtc + ? DateTime.FromFileTimeUtc(changeTime) + : DateTime.FromFileTime(changeTime); + } + } + finally + { + // Handle is ours, dispose. + if (!callerHandle && safeHandle != null) + safeHandle.Close(); + } + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.GetCompressedSize.cs b/AlphaFS/Filesystem/File Class/File.GetCompressedSize.cs new file mode 100644 index 0000000..e470195 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.GetCompressedSize.cs @@ -0,0 +1,134 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region GetCompressedSize + + /// [AlphaFS] Retrieves the actual number of bytes of disk storage used to store a specified file. + /// + /// If the file is located on a volume that supports compression and the file is compressed, the value obtained is the compressed size + /// of the specified file. If the file is located on a volume that supports sparse files and the file is a sparse file, the value + /// obtained is the sparse size of the specified file. + /// + /// The name of the file. + /// Indicates the format of the path parameter(s). + /// The actual number of bytes of disk storage used to store the specified file. + [SecurityCritical] + public static long GetCompressedSize(string path, PathFormat pathFormat) + { + return GetCompressedSizeCore(null, path, pathFormat); + } + + /// [AlphaFS] Retrieves the actual number of bytes of disk storage used to store a specified file. + /// + /// If the file is located on a volume that supports compression and the file is compressed, the value obtained is the compressed size + /// of the specified file. If the file is located on a volume that supports sparse files and the file is a sparse file, the value + /// obtained is the sparse size of the specified file. + /// + /// The name of the file. + /// The actual number of bytes of disk storage used to store the specified file. + [SecurityCritical] + public static long GetCompressedSize(string path) + { + return GetCompressedSizeCore(null, path, PathFormat.RelativePath); + } + + /// + /// [AlphaFS] Retrieves the actual number of bytes of disk storage used to store a specified file as part of a transaction. If the file + /// is located on a volume that supports compression and the file is compressed, the value obtained is the compressed size of the + /// specified file. If the file is located on a volume that supports sparse files and the file is a sparse file, the value obtained is + /// the sparse size of the specified file. + /// + /// The transaction. + /// The name of the file. + /// Indicates the format of the path parameter(s). + /// The actual number of bytes of disk storage used to store the specified file. + [SecurityCritical] + public static long GetCompressedSizeTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return GetCompressedSizeCore(transaction, path, pathFormat); + } + + /// + /// [AlphaFS] Retrieves the actual number of bytes of disk storage used to store a specified file as part of a transaction. If the file + /// is located on a volume that supports compression and the file is compressed, the value obtained is the compressed size of the + /// specified file. If the file is located on a volume that supports sparse files and the file is a sparse file, the value obtained is + /// the sparse size of the specified file. + /// + /// The transaction. + /// The name of the file. + /// The actual number of bytes of disk storage used to store the specified file. + [SecurityCritical] + public static long GetCompressedSizeTransacted(KernelTransaction transaction, string path) + { + return GetCompressedSizeCore(transaction, path, PathFormat.RelativePath); + } + + #endregion // GetCompressedSize + + #region Internal Methods + + /// Retrieves the actual number of bytes of disk storage used to store a + /// specified file as part of a transaction. If the file is located on a volume that supports compression and the file is compressed, + /// the value obtained is the compressed size of the specified file. If the file is located on a volume that supports sparse files and + /// the file is a sparse file, the value obtained is the sparse size of the specified file. + /// + /// + /// The transaction. + /// The name of the file. + /// Indicates the format of the path parameter(s). + /// The actual number of bytes of disk storage used to store the specified file. + [SecurityCritical] + internal static long GetCompressedSizeCore(KernelTransaction transaction, string path, PathFormat pathFormat) + { + if (pathFormat != PathFormat.LongFullPath && Utils.IsNullOrWhiteSpace(path)) + throw new ArgumentNullException("path"); + + string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + + uint fileSizeHigh; + uint fileSizeLow = transaction == null || !NativeMethods.IsAtLeastWindowsVista + + // GetCompressedFileSize() / GetCompressedFileSizeTransacted() + // 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 does not confirm LongPath usage but a Unicode version of this function exists. + + ? NativeMethods.GetCompressedFileSize(pathLp, out fileSizeHigh) + : NativeMethods.GetCompressedFileSizeTransacted(pathLp, out fileSizeHigh, transaction.SafeHandle); + + // If the function fails, and lpFileSizeHigh is NULL, the return value is INVALID_FILE_SIZE. + if (fileSizeLow == Win32Errors.ERROR_INVALID_FILE_SIZE && fileSizeHigh == 0) + NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); + + return NativeMethods.ToLong(fileSizeHigh, fileSizeLow); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.GetCreationTime.cs b/AlphaFS/Filesystem/File Class/File.GetCreationTime.cs new file mode 100644 index 0000000..e9029cb --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.GetCreationTime.cs @@ -0,0 +1,184 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region GetCreationTime + + /// Gets the creation date and time of the specified file. + /// The file for which to obtain creation date and time information. + /// + /// A structure set to the creation date and time for the specified file. This value is expressed in + /// local time. + /// + [SecurityCritical] + public static DateTime GetCreationTime(string path) + { + return GetCreationTimeCore(null, path, false, PathFormat.RelativePath).ToLocalTime(); + } + + /// [AlphaFS] Gets the creation date and time of the specified file. + /// The file for which to obtain creation date and time information. + /// Indicates the format of the path parameter(s). + /// + /// A structure set to the creation date and time for the specified file. This value is expressed in + /// local time. + /// + [SecurityCritical] + public static DateTime GetCreationTime(string path, PathFormat pathFormat) + { + return GetCreationTimeCore(null, path, false, pathFormat).ToLocalTime(); + } + + #region Transactional + + /// [AlphaFS] Gets the creation date and time of the specified file. + /// The transaction. + /// The file for which to obtain creation date and time information. + /// + /// A structure set to the creation date and time for the specified file. This value is expressed in + /// local time. + /// + [SecurityCritical] + public static DateTime GetCreationTimeTransacted(KernelTransaction transaction, string path) + { + return GetCreationTimeCore(transaction, path, false, PathFormat.RelativePath).ToLocalTime(); + } + + /// [AlphaFS] Gets the creation date and time of the specified file. + /// The transaction. + /// The file for which to obtain creation date and time information. + /// Indicates the format of the path parameter(s). + /// + /// A structure set to the creation date and time for the specified file. This value is expressed in + /// local time. + /// + [SecurityCritical] + public static DateTime GetCreationTimeTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return GetCreationTimeCore(transaction, path, false, pathFormat).ToLocalTime(); + } + + #endregion // Transacted + + #endregion + + #region GetCreationTimeUtc + + /// Gets the creation date and time, in Coordinated Universal Time (UTC) format, of the specified file. + /// + /// The file for which to obtain creation date and time information, in Coordinated Universal Time (UTC) format. + /// + /// + /// A structure set to the creation date and time for the specified file. This value is expressed in UTC + /// time. + /// + [SecurityCritical] + public static DateTime GetCreationTimeUtc(string path) + { + return GetCreationTimeCore(null, path, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the creation date and time, in Coordinated Universal Time (UTC) format, of the specified file. + /// + /// The file for which to obtain creation date and time information, in Coordinated Universal Time (UTC) format. + /// + /// Indicates the format of the path parameter(s). + /// + /// A structure set to the creation date and time for the specified file. This value is expressed in UTC + /// time. + /// + [SecurityCritical] + public static DateTime GetCreationTimeUtc(string path, PathFormat pathFormat) + { + return GetCreationTimeCore(null, path, true, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Gets the creation date and time, in Coordinated Universal Time (UTC) format, of the specified file. + /// The transaction. + /// + /// The file for which to obtain creation date and time information, in Coordinated Universal Time (UTC) format. + /// + /// + /// A structure set to the creation date and time for the specified file. This value is expressed in UTC + /// time. + /// + [SecurityCritical] + public static DateTime GetCreationTimeUtcTransacted(KernelTransaction transaction, string path) + { + return GetCreationTimeCore(transaction, path, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the creation date and time, in Coordinated Universal Time (UTC) format, of the specified file. + /// The transaction. + /// + /// The file for which to obtain creation date and time information, in Coordinated Universal Time (UTC) format. + /// + /// Indicates the format of the path parameter(s). + /// + /// A structure set to the creation date and time for the specified file. This value is expressed in UTC + /// time. + /// + [SecurityCritical] + public static DateTime GetCreationTimeUtcTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return GetCreationTimeCore(transaction, path, true, pathFormat); + } + + #endregion // Transacted + + #endregion // GetCreationTimeUtc + + #region Internal Methods + + /// + /// [AlphaFS] Gets the creation date and time, in Coordinated Universal Time (UTC) or local time, of the specified file or directory. + /// + /// The transaction. + /// The file or directory for which to obtain creation date and time information. + /// + /// gets the Coordinated Universal Time (UTC), gets the local time. + /// + /// Indicates the format of the path parameter(s). + /// + /// A structure set to the creation date and time for the specified file or directory. Depending on + /// this value is expressed in UTC- or local time. + /// + [SecurityCritical] + internal static DateTime GetCreationTimeCore(KernelTransaction transaction, string path, bool returnUtc, PathFormat pathFormat) + { + NativeMethods.FILETIME creationTime = GetAttributesExCore(transaction, path, pathFormat, false).ftCreationTime; + + return returnUtc + ? DateTime.FromFileTimeUtc(creationTime) + : DateTime.FromFileTime(creationTime); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.GetEncryptionStatus.cs b/AlphaFS/Filesystem/File Class/File.GetEncryptionStatus.cs new file mode 100644 index 0000000..3bdb7dc --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.GetEncryptionStatus.cs @@ -0,0 +1,76 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + /// [AlphaFS] Retrieves the encryption status of the specified file. + /// The name of the file. + /// Indicates the format of the path parameter(s). + /// The of the specified . + [SecurityCritical] + public static FileEncryptionStatus GetEncryptionStatus(string path, PathFormat pathFormat) + { + return GetEncryptionStatusCore(path, pathFormat); + } + + + /// [AlphaFS] Retrieves the encryption status of the specified file. + /// The name of the file. + /// The of the specified . + [SecurityCritical] + public static FileEncryptionStatus GetEncryptionStatus(string path) + { + return GetEncryptionStatusCore(path, PathFormat.RelativePath); + } + + /// Retrieves the encryption status of the specified file. + /// The name of the file. + /// Indicates the format of the path parameter(s). + /// The of the specified . + [SecurityCritical] + internal static FileEncryptionStatus GetEncryptionStatusCore(string path, PathFormat pathFormat) + { + if (pathFormat != PathFormat.LongFullPath && Utils.IsNullOrWhiteSpace(path)) + throw new ArgumentNullException("path"); + + string pathLp = Path.GetExtendedLengthPathCore(null, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + + FileEncryptionStatus status; + + // FileEncryptionStatus() + // 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 does not confirm LongPath usage but a Unicode version of this function exists. + + if (!NativeMethods.FileEncryptionStatus(pathLp, out status)) + NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); + + return status; + } + + } +} diff --git a/AlphaFS/Filesystem/File Class/File.GetFileInfoByHandleC.cs b/AlphaFS/Filesystem/File Class/File.GetFileInfoByHandleC.cs new file mode 100644 index 0000000..de5a585 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.GetFileInfoByHandleC.cs @@ -0,0 +1,46 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Microsoft.Win32.SafeHandles; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + /// [AlphaFS] Retrieves file information for the specified . + /// A connected to the open file from which to retrieve the information. + /// A object containing the requested information. + [SecurityCritical] + public static ByHandleFileInfo GetFileInfoByHandle(SafeFileHandle handle) + { + NativeMethods.IsValidHandle(handle); + + NativeMethods.BY_HANDLE_FILE_INFORMATION info; + + if (!NativeMethods.GetFileInformationByHandle(handle, out info)) + NativeError.ThrowException(Marshal.GetLastWin32Error()); + + return new ByHandleFileInfo(info); + } + } +} diff --git a/AlphaFS/Filesystem/File Class/File.GetFileSystemEntryInfo.cs b/AlphaFS/Filesystem/File Class/File.GetFileSystemEntryInfo.cs new file mode 100644 index 0000000..b30e4ec --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.GetFileSystemEntryInfo.cs @@ -0,0 +1,100 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region GetFileSystemEntry + + /// [AlphaFS] Gets the of the file on the path. + /// The instance of the file or directory. + /// The path to the file or directory. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static FileSystemEntryInfo GetFileSystemEntryInfo(string path, PathFormat pathFormat) + { + return GetFileSystemEntryInfoCore(false, null, path, false, pathFormat); + } + + /// [AlphaFS] Gets the of the file on the path. + /// The instance of the file or directory. + /// The path to the file or directory. + [SecurityCritical] + public static FileSystemEntryInfo GetFileSystemEntryInfo(string path) + { + return GetFileSystemEntryInfoCore(false, null, path, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the of the file on the path. + /// The instance of the file or directory. + /// The transaction. + /// The path to the file or directory. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static FileSystemEntryInfo GetFileSystemEntryInfoTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return GetFileSystemEntryInfoCore(false, transaction, path, false, pathFormat); + } + + /// [AlphaFS] Gets the of the file on the path. + /// The instance of the file or directory. + /// The transaction. + /// The path to the file or directory. + [SecurityCritical] + public static FileSystemEntryInfo GetFileSystemEntryInfoTransacted(KernelTransaction transaction, string path) + { + return GetFileSystemEntryInfoCore(false, transaction, path, false, PathFormat.RelativePath); + } + + #endregion // GetFileSystemEntry + + #region Internal Methods + + /// Gets a FileSystemEntryInfo from a Non-/Transacted directory/file. + /// The instance of the file or directory, or null on Exception when is true. + /// BasicSearch and LargeCache are used by default, if possible. + /// + /// + /// Specifies that is a file or directory. + /// The transaction. + /// The path to the file or directory. + /// + /// true suppress any Exception that might be thrown as a result from a failure, + /// such as ACLs protected directories or non-accessible reparse points. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static FileSystemEntryInfo GetFileSystemEntryInfoCore(bool isFolder, KernelTransaction transaction, string path, bool continueOnException, PathFormat pathFormat) + { + // Enable BasicSearch and LargeCache by default. + var options = DirectoryEnumerationOptions.BasicSearch | DirectoryEnumerationOptions.LargeCache | (continueOnException ? DirectoryEnumerationOptions.ContinueOnException : 0); + + return (new FindFileSystemEntryInfo(isFolder, transaction, path, Path.WildcardStarMatchAll, options, typeof(FileSystemEntryInfo), pathFormat)).Get(); + } + + #endregion // Internal Methods + + } +} diff --git a/AlphaFS/Filesystem/File Class/File.GetHash.cs b/AlphaFS/Filesystem/File Class/File.GetHash.cs new file mode 100644 index 0000000..e509397 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.GetHash.cs @@ -0,0 +1,159 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Globalization; +using System.IO; +using System.Security; +using System.Text; +using Alphaleonis.Win32.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + /// [AlphaFS] Calculates the hash/checksum for the given . + /// The name of the file. + /// One of the values. + [SecurityCritical] + public static string GetHash(string fileFullPath, HashType hashType) + { + return GetHashCore(null, fileFullPath, hashType, PathFormat.RelativePath); + } + + + /// [AlphaFS] Calculates the hash/checksum for the given . + /// The name of the file. + /// One of the values. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static string GetHash(string fileFullPath, HashType hashType, PathFormat pathFormat) + { + return GetHashCore(null, fileFullPath, hashType, pathFormat); + } + + + /// [AlphaFS] Calculates the hash/checksum for the given . + /// The transaction. + /// The name of the file. + /// One of the values. + [SecurityCritical] + public static string GetHash(KernelTransaction transaction, string fileFullPath, HashType hashType) + { + return GetHashCore(transaction, fileFullPath, hashType, PathFormat.RelativePath); + } + + + /// [AlphaFS] Calculates the hash/checksum for the given . + /// The transaction. + /// The name of the file. + /// One of the values. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static string GetHash(KernelTransaction transaction, string fileFullPath, HashType hashType, PathFormat pathFormat) + { + return GetHashCore(transaction, fileFullPath, hashType, pathFormat); + } + + + + + /// [AlphaFS] Calculates the hash/checksum for the given . + /// The transaction. + /// One of the values. + /// The name of the file. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static string GetHashCore(KernelTransaction transaction, string fileFullPath, HashType hashType, PathFormat pathFormat) + { + var options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck; + var fileNameLp = Path.GetExtendedLengthPathCore(transaction, fileFullPath, pathFormat, options); + + byte[] hash = null; + + + using (var fs = OpenCore(transaction, fileNameLp, FileMode.Open, FileAccess.Read, FileShare.Read, ExtendedFileAttributes.Normal, null, null, PathFormat.LongFullPath)) + { + switch (hashType) + { + case HashType.CRC32: + using (var hType = new Crc32()) + hash = hType.ComputeHash(fs); + break; + + + case HashType.CRC64ISO3309: + using (var hType = new Crc64()) + hash = hType.ComputeHash(fs); + break; + + + case HashType.MD5: + using (var hType = System.Security.Cryptography.MD5.Create()) + hash = hType.ComputeHash(fs); + break; + + + case HashType.RIPEMD160: + using (var hType = System.Security.Cryptography.RIPEMD160.Create()) + hash = hType.ComputeHash(fs); + break; + + + case HashType.SHA1: + using (var hType = System.Security.Cryptography.SHA1.Create()) + hash = hType.ComputeHash(fs); + break; + + + case HashType.SHA256: + using (var hType = System.Security.Cryptography.SHA256.Create()) + hash = hType.ComputeHash(fs); + break; + + + case HashType.SHA384: + using (var hType = System.Security.Cryptography.SHA384.Create()) + hash = hType.ComputeHash(fs); + break; + + + case HashType.SHA512: + using (var hType = System.Security.Cryptography.SHA512.Create()) + hash = hType.ComputeHash(fs); + break; + } + } + + + if (null != hash) + { + var sb = new StringBuilder(hash.Length); + + foreach (byte b in hash) + sb.Append(b.ToString("X2", CultureInfo.InvariantCulture)); + + return sb.ToString().ToUpperInvariant(); + } + + return string.Empty; + } + } +} diff --git a/AlphaFS/Filesystem/File Class/File.GetLastAccessTime.cs b/AlphaFS/Filesystem/File Class/File.GetLastAccessTime.cs new file mode 100644 index 0000000..4779752 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.GetLastAccessTime.cs @@ -0,0 +1,180 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region GetLastAccessTime + + /// Gets the date and time that the specified file was last accessed. + /// The file for which to obtain access date and time information. + /// + /// A structure set to the date and time that the specified file was last accessed. This value is + /// expressed in local time. + /// + [SecurityCritical] + public static DateTime GetLastAccessTime(string path) + { + return GetLastAccessTimeCore(null, path, false, PathFormat.RelativePath).ToLocalTime(); + } + + /// [AlphaFS] Gets the date and time that the specified file was last accessed. + /// The file for which to obtain access date and time information. + /// Indicates the format of the path parameter(s). + /// + /// A structure set to the date and time that the specified file was last accessed. This value is + /// expressed in local time. + /// + [SecurityCritical] + public static DateTime GetLastAccessTime(string path, PathFormat pathFormat) + { + return GetLastAccessTimeCore(null, path, false, pathFormat).ToLocalTime(); + } + + + #region Transactional + + /// [AlphaFS] Gets the date and time that the specified file was last accessed. + /// The transaction. + /// The file for which to obtain access date and time information. + /// + /// A structure set to the date and time that the specified file was last accessed. This value is + /// expressed in local time. + /// + [SecurityCritical] + public static DateTime GetLastAccessTimeTransacted(KernelTransaction transaction, string path) + { + return GetLastAccessTimeCore(transaction, path, false, PathFormat.RelativePath).ToLocalTime(); + } + + /// [AlphaFS] Gets the date and time that the specified file was last accessed. + /// The transaction. + /// The file for which to obtain access date and time information. + /// Indicates the format of the path parameter(s). + /// + /// A structure set to the date and time that the specified file was last accessed. This value is + /// expressed in local time. + /// + [SecurityCritical] + public static DateTime GetLastAccessTimeTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return GetLastAccessTimeCore(transaction, path, false, pathFormat).ToLocalTime(); + } + + + #endregion // Transacted + + #endregion + + #region GetLastAccessTimeUtc + + /// Gets the date and time, in coordinated universal time (UTC), that the specified file was last accessed. + /// The file for which to obtain access date and time information. + /// + /// A structure set to the date and time that the specified file was last accessed. This value is + /// expressed in UTC time. + /// + [SecurityCritical] + public static DateTime GetLastAccessTimeUtc(string path) + { + return GetLastAccessTimeCore(null, path, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the date and time, in coordinated universal time (UTC), that the specified file was last accessed. + /// The file for which to obtain access date and time information. + /// Indicates the format of the path parameter(s). + /// + /// A structure set to the date and time that the specified file was last accessed. This value is + /// expressed in UTC time. + /// + [SecurityCritical] + public static DateTime GetLastAccessTimeUtc(string path, PathFormat pathFormat) + { + return GetLastAccessTimeCore(null, path, true, pathFormat); + } + + + #region Transactional + + /// [AlphaFS] Gets the date and time, in coordinated universal time (UTC), that the specified file was last accessed. + /// The transaction. + /// The file for which to obtain access date and time information. + /// + /// A structure set to the date and time that the specified file was last accessed. This value is + /// expressed in UTC time. + /// + [SecurityCritical] + public static DateTime GetLastAccessTimeUtcTransacted(KernelTransaction transaction, string path) + { + return GetLastAccessTimeCore(transaction, path, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets the date and time, in coordinated universal time (UTC), that the specified file was last accessed. + /// The transaction. + /// The file for which to obtain access date and time information. + /// Indicates the format of the path parameter(s). + /// + /// A structure set to the date and time that the specified file was last accessed. This value is + /// expressed in UTC time. + /// + [SecurityCritical] + public static DateTime GetLastAccessTimeUtcTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return GetLastAccessTimeCore(transaction, path, true, pathFormat); + } + + #endregion // Transacted + + #endregion // GetLastAccessTimeUtc + + #region Internal Methods + + /// + /// [AlphaFS] Gets the date and time, in coordinated universal time (UTC) or local time, that the specified file or directory was last + /// accessed. + /// + /// The transaction. + /// The file or directory for which to obtain access date and time information. + /// + /// gets the Coordinated Universal Time (UTC), gets the local time. + /// + /// Indicates the format of the path parameter(s). + /// + /// A structure set to the date and time that the specified file or directory was last accessed. + /// Depending on this value is expressed in UTC- or local time. + /// + [SecurityCritical] + internal static DateTime GetLastAccessTimeCore(KernelTransaction transaction, string path, bool returnUtc, PathFormat pathFormat) + { + NativeMethods.FILETIME lastAccessTime = GetAttributesExCore(transaction, path, pathFormat, false).ftLastAccessTime; + + return returnUtc + ? DateTime.FromFileTimeUtc(lastAccessTime) + : DateTime.FromFileTime(lastAccessTime); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.GetLastWriteTime.cs b/AlphaFS/Filesystem/File Class/File.GetLastWriteTime.cs new file mode 100644 index 0000000..76a4e1d --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.GetLastWriteTime.cs @@ -0,0 +1,188 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region GetLastWriteTime + + /// Gets the date and time that the specified file was last written to. + /// The file for which to obtain write date and time information. + /// + /// A structure set to the date and time that the specified file was last written to. This value is + /// expressed in local time. + /// + [SecurityCritical] + public static DateTime GetLastWriteTime(string path) + { + return GetLastWriteTimeCore(null, path, false, PathFormat.RelativePath).ToLocalTime(); + } + + /// [AlphaFS] Gets the date and time that the specified file was last written to. + /// The file for which to obtain write date and time information. + /// Indicates the format of the path parameter(s). + /// + /// A structure set to the date and time that the specified file was last written to. This value is + /// expressed in local time. + /// + [SecurityCritical] + public static DateTime GetLastWriteTime(string path, PathFormat pathFormat) + { + return GetLastWriteTimeCore(null, path, false, pathFormat).ToLocalTime(); + } + + + #region Transactional + + /// [AlphaFS] Gets the date and time that the specified file was last written to. + /// The transaction. + /// The file for which to obtain write date and time information. + /// + /// A structure set to the date and time that the specified file was last written to. This value is + /// expressed in local time. + /// + [SecurityCritical] + public static DateTime GetLastWriteTimeTransacted(KernelTransaction transaction, string path) + { + return GetLastWriteTimeCore(transaction, path, false, PathFormat.RelativePath).ToLocalTime(); + } + + /// [AlphaFS] Gets the date and time that the specified file was last written to. + /// The transaction. + /// The file for which to obtain write date and time information. + /// Indicates the format of the path parameter(s). + /// + /// A structure set to the date and time that the specified file was last written to. This value is + /// expressed in local time. + /// + [SecurityCritical] + public static DateTime GetLastWriteTimeTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return GetLastWriteTimeCore(transaction, path, false, pathFormat).ToLocalTime(); + } + + + #endregion // Transacted + + + #endregion // GetLastWriteTime + + #region GetLastWriteTimeUtc + + /// Gets the date and time, in coordinated universal time (UTC) time, that the specified file was last written to. + /// The file for which to obtain write date and time information. + /// + /// A structure set to the date and time that the specified file was last written to. This value is + /// expressed in UTC time. + /// + [SecurityCritical] + public static DateTime GetLastWriteTimeUtc(string path) + { + return GetLastWriteTimeCore(null, path, true, PathFormat.RelativePath); + } + + /// + /// [AlphaFS] Gets the date and time, in coordinated universal time (UTC) time, that the specified file was last written to. + /// + /// The file for which to obtain write date and time information. + /// Indicates the format of the path parameter(s). + /// + /// A structure set to the date and time that the specified file was last written to. This value is + /// expressed in UTC time. + /// + [SecurityCritical] + public static DateTime GetLastWriteTimeUtc(string path, PathFormat pathFormat) + { + return GetLastWriteTimeCore(null, path, true, pathFormat); + } + + + #region Transactional + + /// + /// [AlphaFS] Gets the date and time, in coordinated universal time (UTC) time, that the specified file was last written to. + /// + /// The transaction. + /// The file for which to obtain write date and time information. + /// + /// A structure set to the date and time that the specified file was last written to. This value is + /// expressed in UTC time. + /// + [SecurityCritical] + public static DateTime GetLastWriteTimeUtcTransacted(KernelTransaction transaction, string path) + { + return GetLastWriteTimeCore(transaction, path, true, PathFormat.RelativePath); + } + + /// + /// [AlphaFS] Gets the date and time, in coordinated universal time (UTC) time, that the specified file was last written to. + /// + /// The transaction. + /// The file for which to obtain write date and time information. + /// Indicates the format of the path parameter(s). + /// + /// A structure set to the date and time that the specified file was last written to. This value is + /// expressed in UTC time. + /// + [SecurityCritical] + public static DateTime GetLastWriteTimeUtcTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return GetLastWriteTimeCore(transaction, path, true, pathFormat); + } + + #endregion // Transacted + + + #endregion // GetLastWriteTimeUtc + + #region Internal Methods + + /// + /// [AlphaFS] Gets the date and time, in coordinated universal time (UTC) or local time, that the specified file or directory was last + /// written to. + /// + /// The transaction. + /// The file or directory for which to obtain write date and time information. + /// + /// gets the Coordinated Universal Time (UTC), gets the local time. + /// + /// Indicates the format of the path parameter(s). + /// + /// A structure set to the date and time that the specified file or directory was last written to. + /// Depending on this value is expressed in UTC- or local time. + /// + [SecurityCritical] + internal static DateTime GetLastWriteTimeCore(KernelTransaction transaction, string path, bool getUtc, PathFormat pathFormat) + { + NativeMethods.FILETIME lastWriteTime = GetAttributesExCore(transaction, path, pathFormat, false).ftLastWriteTime; + + return getUtc + ? DateTime.FromFileTimeUtc(lastWriteTime) + : DateTime.FromFileTime(lastWriteTime); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.GetLinkTargetInfo.cs b/AlphaFS/Filesystem/File Class/File.GetLinkTargetInfo.cs new file mode 100644 index 0000000..4697547 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.GetLinkTargetInfo.cs @@ -0,0 +1,105 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Microsoft.Win32.SafeHandles; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region GetLinkTargetInfo + + /// [AlphaFS] Gets information about the target of a mount point or symbolic link on an NTFS file system. + /// The path to the reparse point. + /// Indicates the format of the path parameter(s). + /// + /// An instance of or containing information about the symbolic link + /// or mount point pointed to by . + /// + [SecurityCritical] + public static LinkTargetInfo GetLinkTargetInfo(string path, PathFormat pathFormat) + { + return GetLinkTargetInfoCore(null, path, pathFormat); + } + + /// [AlphaFS] Gets information about the target of a mount point or symbolic link on an NTFS file system. + /// The path to the reparse point. + /// + /// An instance of or containing information about the symbolic link + /// or mount point pointed to by . + /// + [SecurityCritical] + public static LinkTargetInfo GetLinkTargetInfo(string path) + { + return GetLinkTargetInfoCore(null, path, PathFormat.RelativePath); + } + + /// [AlphaFS] Gets information about the target of a mount point or symbolic link on an NTFS file system. + /// The transaction. + /// The path to the reparse point. + /// Indicates the format of the path parameter(s). + /// + /// An instance of or containing information about the symbolic link + /// or mount point pointed to by . + /// + [SecurityCritical] + public static LinkTargetInfo GetLinkTargetInfoTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return GetLinkTargetInfoCore(transaction, path, pathFormat); + } + + /// [AlphaFS] Gets information about the target of a mount point or symbolic link on an NTFS file system. + /// The transaction. + /// The path to the reparse point. + /// + /// An instance of or containing information about the symbolic link + /// or mount point pointed to by . + /// + [SecurityCritical] + public static LinkTargetInfo GetLinkTargetInfoTransacted(KernelTransaction transaction, string path) + { + return GetLinkTargetInfoCore(transaction, path, PathFormat.RelativePath); + } + + #endregion // GetLinkTargetInfo + + #region GetLinkTargetInfoCore + + /// Gets information about the target of a mount point or symbolic link on an NTFS file system. + /// The transaction. + /// The path to the reparse point. + /// Indicates the format of the path parameter(s). + /// + /// An instance of or containing information about the symbolic link + /// or mount point pointed to by . + /// + [SecurityCritical] + internal static LinkTargetInfo GetLinkTargetInfoCore(KernelTransaction transaction, string path, PathFormat pathFormat) + { + using (SafeFileHandle safeHandle = CreateFileCore(transaction, path, ExtendedFileAttributes.OpenReparsePoint | ExtendedFileAttributes.BackupSemantics, null, FileMode.Open, 0, FileShare.ReadWrite, true, pathFormat)) + return Device.GetLinkTargetInfoCore(safeHandle); + } + + #endregion // GetLinkTargetInfoCore + } +} diff --git a/AlphaFS/Filesystem/File Class/File.GetSize.cs b/AlphaFS/Filesystem/File Class/File.GetSize.cs new file mode 100644 index 0000000..95ea703 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.GetSize.cs @@ -0,0 +1,125 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Microsoft.Win32.SafeHandles; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; +using System.Security.AccessControl; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region GetSize + + /// [AlphaFS] Retrieves the file size, in bytes to store a specified file. + /// The path to the file. + /// Indicates the format of the path parameter(s). + /// The file size, in bytes. + [SecurityCritical] + public static long GetSize(string path, PathFormat pathFormat) + { + return GetSizeCore(null, null, path, pathFormat); + } + + /// [AlphaFS] Retrieves the file size, in bytes to store a specified file. + /// The path to the file. + /// The file size, in bytes. + [SecurityCritical] + public static long GetSize(string path) + { + return GetSizeCore(null, null, path, PathFormat.RelativePath); + } + + /// [AlphaFS] Retrieves the file size, in bytes to store a specified file. + /// The to the file. + /// The file size, in bytes. + [SecurityCritical] + public static long GetSize(SafeFileHandle handle) + { + return GetSizeCore(null, handle, null, PathFormat.LongFullPath); + } + + /// [AlphaFS] Retrieves the file size, in bytes to store a specified file. + /// The transaction. + /// The path to the file. + /// Indicates the format of the path parameter(s). + /// The number of bytes of disk storage used to store the specified file. + [SecurityCritical] + public static long GetSizeTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return GetSizeCore(transaction, null, path, pathFormat); + } + + /// [AlphaFS] Retrieves the file size, in bytes to store a specified file. + /// The transaction. + /// The path to the file. + /// The number of bytes of disk storage used to store the specified file. + [SecurityCritical] + public static long GetSizeTransacted(KernelTransaction transaction, string path) + { + return GetSizeCore(transaction, null, path, PathFormat.RelativePath); + } + + #endregion // GetSize + + #region Internal Methods + + /// Retrieves the file size, in bytes to store a specified file. + /// Use either or , not both. + /// The transaction. + /// The to the file. + /// The path to the file. + /// Indicates the format of the path parameter(s). + /// The number of bytes of disk storage used to store the specified file. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + internal static long GetSizeCore(KernelTransaction transaction, SafeFileHandle safeHandle, string path, PathFormat pathFormat) + { + bool callerHandle = safeHandle != null; + if (!callerHandle) + { + string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + + safeHandle = CreateFileCore(transaction, pathLp, ExtendedFileAttributes.Normal, null, FileMode.Open, FileSystemRights.ReadData, FileShare.Read, true, PathFormat.LongFullPath); + } + + + long fileSize; + + try + { + NativeMethods.GetFileSizeEx(safeHandle, out fileSize); + } + finally + { + // Handle is ours, dispose. + if (!callerHandle && safeHandle != null) + safeHandle.Close(); + } + + return fileSize; + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.IsLocked.cs b/AlphaFS/Filesystem/File Class/File.IsLocked.cs new file mode 100644 index 0000000..a2f83c9 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.IsLocked.cs @@ -0,0 +1,118 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class File + { + /// [AlphaFS] Determines whether the specified file is in use (locked). + /// Returns if the specified file is in use (locked); otherwise, + /// + /// + /// The file to check. + [SecurityCritical] + public static bool IsLocked(string path) + { + return IsLockedCore(null, path, PathFormat.RelativePath); + } + + /// [AlphaFS] Determines whether the specified file is in use (locked). + /// Returns if the specified file is in use (locked); otherwise, + /// + /// + /// + /// The file to check. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static bool IsLocked(string path, PathFormat pathFormat) + { + return IsLockedCore(null, path, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Determines whether the specified file is in use (locked). + /// Returns if the specified file is in use (locked); otherwise, + /// + /// + /// + /// The transaction. + /// The file to check. + [SecurityCritical] + public static bool IsLockedTransacted(KernelTransaction transaction, string path) + { + return IsLockedCore(transaction, path, PathFormat.RelativePath); + } + + /// [AlphaFS] Determines whether the specified file is in use (locked). + /// Returns if the specified file is in use (locked); otherwise, + /// + /// + /// + /// The transaction. + /// The file to check. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static bool IsLockedTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return IsLockedCore(transaction, path, pathFormat); + } + + #endregion // Transactional + + /// [AlphaFS] Determines whether the specified file is in use (locked). + /// Returns if the specified file is in use (locked); otherwise, + /// + /// + /// + /// The transaction. + /// The file to check. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static bool IsLockedCore(KernelTransaction transaction, string path, PathFormat pathFormat) + { + try + { + // Use FileAccess.Read since FileAccess.ReadWrite always fails when file is read-only. + using (OpenCore(transaction, path, FileMode.Open, FileAccess.Read, FileShare.None, ExtendedFileAttributes.Normal, null, null, pathFormat)) {} + } + catch (IOException ex) + { + int lastError = Marshal.GetHRForException(ex) & NativeMethods.OverflowExceptionBitShift; + if (lastError == Win32Errors.ERROR_SHARING_VIOLATION || lastError == Win32Errors.ERROR_LOCK_VIOLATION) + return true; + + throw; + } + catch (Exception ex) + { + NativeError.ThrowException(Marshal.GetHRForException(ex) & NativeMethods.OverflowExceptionBitShift); + } + + return false; + } + } +} diff --git a/AlphaFS/Filesystem/File Class/File.Open.cs b/AlphaFS/Filesystem/File Class/File.Open.cs new file mode 100644 index 0000000..5f19df6 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.Open.cs @@ -0,0 +1,1016 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Microsoft.Win32.SafeHandles; +using System.IO; +using System.Security; +using System.Security.AccessControl; +using FileStream = System.IO.FileStream; +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class File + { + #region Using FileAccess + + /// Opens a on the specified path with read/write access. + /// The file to open. + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten. + /// A opened in the specified mode and path, with read/write access and not shared. + [SecurityCritical] + public static FileStream Open(string path, FileMode mode) + { + return OpenCore(null, path, mode, mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite, FileShare.None, ExtendedFileAttributes.Normal, null, null, PathFormat.RelativePath); + } + + /// Opens a on the specified path, with the specified mode and access. + /// The file to open. + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten. + /// A value that specifies the operations that can be performed on the file. + /// An unshared that provides access to the specified file, with the specified mode and access. + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileAccess access) + { + return OpenCore(null, path, mode, access, FileShare.None, ExtendedFileAttributes.Normal, null, null, PathFormat.RelativePath); + } + + /// Opens a on the specified path, having the specified mode with read, write, or read/write access and the specified sharing option. + /// The file to open. + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten. + /// A value that specifies the operations that can be performed on the file. + /// A value specifying the type of access other threads have to the file. + /// A on the specified path, having the specified mode with read, write, or read/write access and the specified sharing option. + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share) + { + return OpenCore(null, path, mode, access, share, ExtendedFileAttributes.Normal, null, null, PathFormat.RelativePath); + } + + + /// [AlphaFS] Opens a on the specified path with read/write access. + /// The file to open. + /// + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents + /// of existing files are retained or overwritten. + /// + /// Indicates the format of the path parameter(s). + /// A opened in the specified mode and path, with read/write access and not shared. + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, PathFormat pathFormat) + { + return OpenCore(null, path, mode, mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite, FileShare.None, ExtendedFileAttributes.Normal, null, null, pathFormat); + } + + /// [AlphaFS] Opens a on the specified path, with the specified mode and access. + /// The file to open. + /// + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents + /// of existing files are retained or overwritten. + /// + /// A value that specifies the operations that can be performed on the file. + /// Indicates the format of the path parameter(s). + /// + /// An unshared that provides access to the specified file, with the specified mode and access. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileAccess access, PathFormat pathFormat) + { + return OpenCore(null, path, mode, access, FileShare.None, ExtendedFileAttributes.Normal, null, null, pathFormat); + } + + /// [AlphaFS] Opens a on the specified path, having the specified mode with read, write, or read/write access and the specified sharing option. + /// The file to open. + /// + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents + /// of existing files are retained or overwritten. + /// + /// A value that specifies the operations that can be performed on the file. + /// A value specifying the type of access other threads have to the file. + /// Indicates the format of the path parameter(s). + /// + /// A on the specified path, having the specified mode with read, write, or read/write access and the + /// specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share, PathFormat pathFormat) + { + return OpenCore(null, path, mode, access, share, ExtendedFileAttributes.Normal, null, null, pathFormat); + } + + /// [AlphaFS] Opens a on the specified path, having the specified mode with read, write, or read/write access and the specified sharing option. + /// The file to open. + /// + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents + /// of existing files are retained or overwritten. + /// + /// A value that specifies the operations that can be performed on the file. + /// A value specifying the type of access other threads have to the file. + /// The extended attributes. + /// Indicates the format of the path parameter(s). + /// + /// A on the specified path, having the specified mode with read, write, or read/write access and the + /// specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share, ExtendedFileAttributes extendedAttributes, PathFormat pathFormat) + { + return OpenCore(null, path, mode, access, share, extendedAttributes, null, null, pathFormat); + } + + // New below + + /// [AlphaFS] Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The default buffer size is 4096. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize) + { + return OpenCore(null, path, mode, access, share, ExtendedFileAttributes.Normal, bufferSize, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// Specifies whether to use asynchronous I/O or synchronous I/O. However, note that the + /// underlying operating system might not support asynchronous I/O, so when specifying true, the handle might be + /// opened synchronously depending on the platform. When opened asynchronously, the BeginRead and BeginWrite methods + /// perform better on large reads or writes, but they might be much slower for small reads or writes. If the + /// application is designed to take advantage of asynchronous I/O, set the useAsync parameter to true. Using + /// asynchronous I/O correctly can speed up applications by as much as a factor of 10, but using it without + /// redesigning the application for asynchronous I/O can decrease performance by as much as a factor of 10. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync) + { + return OpenCore(null, path, mode, access, share, ExtendedFileAttributes.Normal | (useAsync ? ExtendedFileAttributes.Overlapped : ExtendedFileAttributes.Normal), bufferSize, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// A value that specifies additional file options. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options) + { + return OpenCore(null, path, mode, access, share, (ExtendedFileAttributes) options, bufferSize, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// The extended attributes specifying additional options. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, ExtendedFileAttributes extendedAttributes) + { + return OpenCore(null, path, mode, access, share, extendedAttributes, bufferSize, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// Indicates the format of the path parameter. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, PathFormat pathFormat) + { + return OpenCore(null, path, mode, access, share, ExtendedFileAttributes.Normal, bufferSize, null, pathFormat); + } + + /// [AlphaFS] Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// Specifies whether to use asynchronous I/O or synchronous I/O. However, note that the + /// underlying operating system might not support asynchronous I/O, so when specifying true, the handle might be + /// opened synchronously depending on the platform. When opened asynchronously, the BeginRead and BeginWrite methods + /// perform better on large reads or writes, but they might be much slower for small reads or writes. If the + /// application is designed to take advantage of asynchronous I/O, set the useAsync parameter to true. Using + /// asynchronous I/O correctly can speed up applications by as much as a factor of 10, but using it without + /// redesigning the application for asynchronous I/O can decrease performance by as much as a factor of 10. + /// Indicates the format of the path parameter. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync, PathFormat pathFormat) + { + return OpenCore(null, path, mode, access, share, ExtendedFileAttributes.Normal | (useAsync ? ExtendedFileAttributes.Overlapped : ExtendedFileAttributes.Normal), bufferSize, null, pathFormat); + } + + /// [AlphaFS] Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// A value that specifies additional file options. + /// Indicates the format of the path parameter. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, PathFormat pathFormat) + { + return OpenCore(null, path, mode, access, share, (ExtendedFileAttributes) options, bufferSize, null, pathFormat); + } + + /// [AlphaFS] Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// The extended attributes specifying additional options. + /// Indicates the format of the path parameter. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, ExtendedFileAttributes extendedAttributes, PathFormat pathFormat) + { + return OpenCore(null, path, mode, access, share, extendedAttributes, bufferSize, null, pathFormat); + } + + #endregion // Using FileAccess + + #region Using FileSystemRights + + /// [AlphaFS] Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// A value that specifies additional file options. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options) + { + return OpenCore(null, path, mode, rights, share, (ExtendedFileAttributes)options, bufferSize, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// Extended attributes specifying additional options. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, ExtendedFileAttributes extendedAttributes) + { + return OpenCore(null, path, mode, rights, share, extendedAttributes, bufferSize, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// A value that specifies additional file options. + /// A value that determines the access control and audit security for the file. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options, FileSecurity security) + { + return OpenCore(null, path, mode, rights, share, (ExtendedFileAttributes)options, bufferSize, security, PathFormat.RelativePath); + } + + /// [AlphaFS] Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// Extended attributes specifying additional options. + /// A value that determines the access control and audit security for the file. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, ExtendedFileAttributes extendedAttributes, FileSecurity security) + { + return OpenCore(null, path, mode, rights, share, extendedAttributes, bufferSize, security, PathFormat.RelativePath); + } + + /// [AlphaFS] Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// A value that specifies additional file options. + /// Indicates the format of the path parameter. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options, PathFormat pathFormat) + { + return OpenCore(null, path, mode, rights, share, (ExtendedFileAttributes) options, bufferSize, null, pathFormat); + } + + /// [AlphaFS] Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// Extended attributes specifying additional options. + /// Indicates the format of the path parameter. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, ExtendedFileAttributes extendedAttributes, PathFormat pathFormat) + { + return OpenCore(null, path, mode, rights, share, extendedAttributes, bufferSize, null, pathFormat); + } + + /// [AlphaFS] Opens a on the specified path using the specified creation mode, access rights and sharing permission, the buffer size, additional file options, access control and audit security. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// A value that specifies additional file options. + /// A value that determines the access control and audit security for the file. + /// Indicates the format of the path parameter. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options, FileSecurity security, PathFormat pathFormat) + { + return OpenCore(null, path, mode, rights, share, (ExtendedFileAttributes) options, bufferSize, security, pathFormat); + } + + /// [AlphaFS] Opens a on the specified path using the specified creation mode, access rights and sharing permission, the buffer size, additional file options, access control and audit security. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// Extended attributes specifying additional options. + /// A value that determines the access control and audit security for the file. + /// Indicates the format of the path parameter. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream Open(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, ExtendedFileAttributes extendedAttributes, FileSecurity security, PathFormat pathFormat) + { + return OpenCore(null, path, mode, rights, share, extendedAttributes, bufferSize, security, pathFormat); + } + + #endregion // Using FileSystemRights + + + #region Transactional + + /// [AlphaFS] (Transacted) Opens a on the specified path with read/write access. + /// The transaction. + /// The file to open. + /// + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents + /// of existing files are retained or overwritten. + /// + /// A opened in the specified mode and path, with read/write access and not shared. + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode) + { + return OpenCore(transaction, path, mode, mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite, FileShare.None, ExtendedFileAttributes.Normal, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path with read/write access. + /// The transaction. + /// The file to open. + /// + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents + /// of existing files are retained or overwritten. + /// + /// Indicates the format of the path parameter(s). + /// A opened in the specified mode and path, with read/write access and not shared. + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, PathFormat pathFormat) + { + return OpenCore(transaction, path, mode, mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite, FileShare.None, ExtendedFileAttributes.Normal, null, null, pathFormat); + } + + #region Using FileAccess + + /// [AlphaFS] (Transacted) Opens a on the specified path, with the specified mode and access. + /// The transaction. + /// The file to open. + /// + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents + /// of existing files are retained or overwritten. + /// + /// A value that specifies the operations that can be performed on the file. + /// + /// An unshared that provides access to the specified file, with the specified mode and access. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileAccess access) + { + return OpenCore(transaction, path, mode, access, FileShare.None, ExtendedFileAttributes.Normal, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path, having the specified mode with read, write, or read/write access and the specified sharing option. + /// The transaction. + /// The file to open. + /// + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents + /// of existing files are retained or overwritten. + /// + /// A value that specifies the operations that can be performed on the file. + /// A value specifying the type of access other threads have to the file. + /// + /// A on the specified path, having the specified mode with read, write, or read/write access and the + /// specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileAccess access, FileShare share) + { + return OpenCore(transaction, path, mode, access, share, ExtendedFileAttributes.Normal, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path, with the specified mode and access. + /// The transaction. + /// The file to open. + /// + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents + /// of existing files are retained or overwritten. + /// + /// A value that specifies the operations that can be performed on the file. + /// Indicates the format of the path parameter(s). + /// + /// An unshared that provides access to the specified file, with the specified mode and access. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileAccess access, PathFormat pathFormat) + { + return OpenCore(transaction, path, mode, access, FileShare.None, ExtendedFileAttributes.Normal, null, null, pathFormat); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path, having the specified mode with read, write, or read/write access and the specified sharing option. + /// The transaction. + /// The file to open. + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten. + /// A value that specifies the operations that can be performed on the file. + /// A value specifying the type of access other threads have to the file. + /// Indicates the format of the path parameter(s). + /// A on the specified path, having the specified mode with read, write, or read/write access and the specified sharing option. + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileAccess access, FileShare share, PathFormat pathFormat) + { + return OpenCore(transaction, path, mode, access, share, ExtendedFileAttributes.Normal, null, null, pathFormat); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path, having the specified mode with read, write, or read/write access and the specified sharing option. + /// The transaction. + /// The file to open. + /// + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents + /// of existing files are retained or overwritten. + /// + /// A value that specifies the operations that can be performed on the file. + /// A value specifying the type of access other threads have to the file. + /// The extended attributes. + /// Indicates the format of the path parameter(s). + /// + /// A on the specified path, having the specified mode with read, write, or read/write access and the + /// specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileAccess access, FileShare share, ExtendedFileAttributes extendedAttributes, PathFormat pathFormat) + { + return OpenCore(transaction, path, mode, access, share, extendedAttributes, null, null, pathFormat); + } + + // New below + + /// [AlphaFS] (Transacted) Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The transaction. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileAccess access, FileShare share, int bufferSize) + { + return OpenCore(transaction, path, mode, access, share, ExtendedFileAttributes.Normal, bufferSize, null, PathFormat.RelativePath); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The transaction. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// Specifies whether to use asynchronous I/O or synchronous I/O. However, note that the + /// underlying operating system might not support asynchronous I/O, so when specifying true, the handle might be + /// opened synchronously depending on the platform. When opened asynchronously, the BeginRead and BeginWrite methods + /// perform better on large reads or writes, but they might be much slower for small reads or writes. If the + /// application is designed to take advantage of asynchronous I/O, set the useAsync parameter to true. Using + /// asynchronous I/O correctly can speed up applications by as much as a factor of 10, but using it without + /// redesigning the application for asynchronous I/O can decrease performance by as much as a factor of 10. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync) + { + return OpenCore(transaction, path, mode, access, share, ExtendedFileAttributes.Normal | (useAsync ? ExtendedFileAttributes.Overlapped : ExtendedFileAttributes.Normal), bufferSize, null, PathFormat.RelativePath); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The transaction. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// A value that specifies additional file options. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options) + { + return OpenCore(transaction, path, mode, access, share, (ExtendedFileAttributes) options, bufferSize, null, PathFormat.RelativePath); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The transaction. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// The extended attributes specifying additional options. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, ExtendedFileAttributes extendedAttributes) + { + return OpenCore(transaction, path, mode, access, share, extendedAttributes, bufferSize, null, PathFormat.RelativePath); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The transaction. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// Indicates the format of the path parameter. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, PathFormat pathFormat) + { + return OpenCore(transaction, path, mode, access, share, ExtendedFileAttributes.Normal, bufferSize, null, pathFormat); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The transaction. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// Specifies whether to use asynchronous I/O or synchronous I/O. However, note that the + /// underlying operating system might not support asynchronous I/O, so when specifying true, the handle might be + /// opened synchronously depending on the platform. When opened asynchronously, the BeginRead and BeginWrite methods + /// perform better on large reads or writes, but they might be much slower for small reads or writes. If the + /// application is designed to take advantage of asynchronous I/O, set the useAsync parameter to true. Using + /// asynchronous I/O correctly can speed up applications by as much as a factor of 10, but using it without + /// redesigning the application for asynchronous I/O can decrease performance by as much as a factor of 10. + /// Indicates the format of the path parameter. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync, PathFormat pathFormat) + { + return OpenCore(transaction, path, mode, access, share, ExtendedFileAttributes.Normal | (useAsync ? ExtendedFileAttributes.Overlapped : ExtendedFileAttributes.Normal), bufferSize, null, pathFormat); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The transaction. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// A value that specifies additional file options. + /// Indicates the format of the path parameter. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, PathFormat pathFormat) + { + return OpenCore(transaction, path, mode, access, share, (ExtendedFileAttributes) options, bufferSize, null, pathFormat); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The transaction. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// The extended attributes specifying additional options. + /// Indicates the format of the path parameter. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, ExtendedFileAttributes extendedAttributes, PathFormat pathFormat) + { + return OpenCore(transaction, path, mode, access, share, extendedAttributes, bufferSize, null, pathFormat); + } + + #endregion // Using FileAccess + + #region Using FileSystemRights + + /// [AlphaFS] (Transacted) Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The transaction. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// A value that specifies additional file options. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options) + { + return OpenCore(transaction, path, mode, rights, share, (ExtendedFileAttributes) options, bufferSize, null, PathFormat.RelativePath); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The transaction. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// Extended attributes specifying additional options. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, ExtendedFileAttributes extendedAttributes) + { + return OpenCore(transaction, path, mode, rights, share, extendedAttributes, bufferSize, null, PathFormat.RelativePath); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The transaction. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// A value that specifies additional file options. + /// A value that determines the access control and audit security for the file. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options, FileSecurity security) + { + return OpenCore(transaction, path, mode, rights, share, (ExtendedFileAttributes) options, bufferSize, security, PathFormat.RelativePath); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The transaction. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// Extended attributes specifying additional options. + /// A value that determines the access control and audit security for the file. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, ExtendedFileAttributes extendedAttributes, FileSecurity security) + { + return OpenCore(transaction, path, mode, rights, share, extendedAttributes, bufferSize, security, PathFormat.RelativePath); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The transaction. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// A value that specifies additional file options. + /// Indicates the format of the path parameter. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options, PathFormat pathFormat) + { + return OpenCore(transaction, path, mode, rights, share, (ExtendedFileAttributes) options, bufferSize, null, pathFormat); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path using the specified creation mode, read/write and sharing permission, and buffer size. + /// The transaction. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// Extended attributes specifying additional options. + /// Indicates the format of the path parameter. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, ExtendedFileAttributes extendedAttributes, PathFormat pathFormat) + { + return OpenCore(transaction, path, mode, rights, share, extendedAttributes, bufferSize, null, pathFormat); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path using the specified creation mode, access rights and sharing permission, the buffer size, additional file options, access control and audit security. + /// The transaction. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// A value that specifies additional file options. + /// A value that determines the access control and audit security for the file. + /// Indicates the format of the path parameter. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options, FileSecurity security, PathFormat pathFormat) + { + return OpenCore(transaction, path, mode, rights, share, (ExtendedFileAttributes) options, bufferSize, security, pathFormat); + } + + /// [AlphaFS] (Transacted) Opens a on the specified path using the specified creation mode, access rights and sharing permission, the buffer size, additional file options, access control and audit security. + /// The transaction. + /// The file to open. + /// A constant that determines how to open or create the file. + /// A value that specifies the operations that can be performed on the + /// file. + /// A constant that determines how the file will be shared by processes. + /// A positive value greater than 0 indicating the buffer size. The + /// default buffer size is 4096. + /// Extended attributes specifying additional options. + /// A value that determines the access control and audit security for the file. + /// Indicates the format of the path parameter. + /// + /// A on the specified path, having the specified mode with read, write, or read/write + /// access and the specified sharing option. + /// + [SecurityCritical] + public static FileStream OpenTransacted(KernelTransaction transaction, string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, ExtendedFileAttributes extendedAttributes, FileSecurity security, PathFormat pathFormat) + { + return OpenCore(transaction, path, mode, rights, share, extendedAttributes, bufferSize, security, pathFormat); + } + + #endregion // Using FileSystemRights + + #endregion // Transacted + + + #region Internal Methods + + /// [AlphaFS] Opens a on the specified path, having the specified mode with read, write, or read/write access, the specified sharing option and additional options specified. + /// The transaction. + /// The file to open. + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten. + /// A value that specifies the operations that can be performed on the file. + /// A value specifying the type of access other threads have to the file. + /// Advanced options for this file. + /// A positive value greater than 0 indicating the buffer size. The default buffer size is 4096. + /// The security. + /// Indicates the format of the path parameter(s). + /// + /// A instance on the specified path, having the specified mode with + /// read, write, or read/write access and the specified sharing option. + /// + internal static FileStream OpenCore(KernelTransaction transaction, string path, FileMode mode, FileAccess access, FileShare share, ExtendedFileAttributes attributes, int? bufferSize, FileSecurity security, PathFormat pathFormat) + { + var rights = access == FileAccess.Read + ? FileSystemRights.Read + : (access == FileAccess.Write ? FileSystemRights.Write : FileSystemRights.Read | FileSystemRights.Write); + + + return OpenCore(transaction, path, mode, rights, share, attributes, bufferSize, security, pathFormat); + } + + /// Opens a on the specified path, having the specified mode with read, write, or read/write access, the specified sharing option and additional options specified. + /// The transaction. + /// The file to open. + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten. + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten along with additional options. + /// A value specifying the type of access other threads have to the file. + /// Advanced options for this file. + /// A positive value greater than 0 indicating the buffer size. The default buffer size is 4096. + /// The security. + /// Indicates the format of the path parameter(s). + /// + /// A instance on the specified path, having the specified mode with + /// read, write, or read/write access and the specified sharing option. + /// + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + internal static FileStream OpenCore(KernelTransaction transaction, string path, FileMode mode, FileSystemRights rights, FileShare share, ExtendedFileAttributes attributes, int? bufferSize, FileSecurity security, PathFormat pathFormat) + { + var access = ((rights & FileSystemRights.ReadData) != 0 ? FileAccess.Read : 0) | + ((rights & FileSystemRights.WriteData) != 0 || (rights & FileSystemRights.AppendData) != 0 + ? FileAccess.Write + : 0); + + + SafeFileHandle safeHandle = null; + + try + { + safeHandle = CreateFileCore(transaction, path, attributes, security, mode, rights, share, true, pathFormat); + + return new FileStream(safeHandle, access, bufferSize ?? NativeMethods.DefaultFileBufferSize, (attributes & ExtendedFileAttributes.Overlapped) != 0); + } + catch + { + if (safeHandle != null) + safeHandle.Dispose(); + + throw; + } + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.OpenBackupRead.cs b/AlphaFS/Filesystem/File Class/File.OpenBackupRead.cs new file mode 100644 index 0000000..6922530 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.OpenBackupRead.cs @@ -0,0 +1,70 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.IO; +using System.Security; +using System.Security.AccessControl; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + /// [AlphaFS] Opens the specified file for reading purposes bypassing security attributes. + /// The file path to open. + /// Indicates the format of the path parameter(s). + /// A on the specified path, having the read-only mode and sharing options. + [SecurityCritical] + public static FileStream OpenBackupRead(string path, PathFormat pathFormat) + { + return OpenCore(null, path, FileMode.Open, FileSystemRights.ReadData, FileShare.None, ExtendedFileAttributes.BackupSemantics | ExtendedFileAttributes.SequentialScan | ExtendedFileAttributes.ReadOnly, null, null, pathFormat); + } + + /// [AlphaFS] Opens the specified file for reading purposes bypassing security attributes. This method is simpler to use then BackupFileStream to read only file's data stream. + /// The file path to open. + /// A on the specified path, having the read-only mode and sharing options. + [SecurityCritical] + public static FileStream OpenBackupRead(string path) + { + return OpenCore(null, path, FileMode.Open, FileSystemRights.ReadData, FileShare.None, ExtendedFileAttributes.BackupSemantics | ExtendedFileAttributes.SequentialScan | ExtendedFileAttributes.ReadOnly, null, null, PathFormat.RelativePath); + } + + /// [AlphaFS] Opens the specified file for reading purposes bypassing security attributes. + /// The transaction. + /// The file path to open. + /// Indicates the format of the path parameter(s). + /// A on the specified path, having the read-only mode and sharing options. + [SecurityCritical] + public static FileStream OpenBackupReadTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return OpenCore(transaction, path, FileMode.Open, FileSystemRights.ReadData, FileShare.None, ExtendedFileAttributes.BackupSemantics | ExtendedFileAttributes.SequentialScan | ExtendedFileAttributes.ReadOnly, null, null, pathFormat); + } + + /// [AlphaFS] Opens the specified file for reading purposes bypassing security attributes. + /// The transaction. + /// The file path to open. + /// A on the specified path, having the read-only mode and sharing options. + [SecurityCritical] + public static FileStream OpenBackupReadTransacted(KernelTransaction transaction, string path) + { + return OpenCore(transaction, path, FileMode.Open, FileSystemRights.ReadData, FileShare.None, ExtendedFileAttributes.BackupSemantics | ExtendedFileAttributes.SequentialScan | ExtendedFileAttributes.ReadOnly, null, null, PathFormat.RelativePath); + } + } +} diff --git a/AlphaFS/Filesystem/File Class/File.OpenRead.cs b/AlphaFS/Filesystem/File Class/File.OpenRead.cs new file mode 100644 index 0000000..1688f6a --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.OpenRead.cs @@ -0,0 +1,86 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.IO; +using System.Security; +using FileStream = System.IO.FileStream; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + /// Opens an existing file for reading. + /// The file to be opened for reading. + /// A read-only on the specified path. + /// + /// This method is equivalent to the (string, FileMode, FileAccess, FileShare) constructor overload with a + /// value of Open, a value of Read and a value of Read. + /// + [SecurityCritical] + public static FileStream OpenRead(string path) + { + return Open(path, FileMode.Open, FileAccess.Read); + } + + /// [AlphaFS] Opens an existing file for reading. + /// The file to be opened for reading. + /// Indicates the format of the path parameter(s). + /// A read-only on the specified path. + /// + /// This method is equivalent to the (string, FileMode, FileAccess, FileShare) constructor overload with a + /// value of Open, a value of Read and a value of Read. + /// + [SecurityCritical] + public static FileStream OpenRead(string path, PathFormat pathFormat) + { + return Open(path, FileMode.Open, FileAccess.Read, pathFormat); + } + + /// [AlphaFS] Opens an existing file for reading. + /// The transaction. + /// The file to be opened for reading. + /// A read-only on the specified path. + /// + /// This method is equivalent to the (string, FileMode, FileAccess, FileShare) constructor overload with a + /// value of Open, a value of Read and a value of Read. + /// + [SecurityCritical] + public static FileStream OpenReadTransacted(KernelTransaction transaction, string path) + { + return OpenTransacted(transaction, path, FileMode.Open, FileAccess.Read); + } + + /// [AlphaFS] Opens an existing file for reading. + /// The transaction. + /// The file to be opened for reading. + /// Indicates the format of the path parameter(s). + /// A read-only on the specified path. + /// + /// This method is equivalent to the (string, FileMode, FileAccess, FileShare) constructor overload with a + /// value of Open, a value of Read and a value of Read. + /// + [SecurityCritical] + public static FileStream OpenReadTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return OpenTransacted(transaction, path, FileMode.Open, FileAccess.Read, pathFormat); + } + } +} diff --git a/AlphaFS/Filesystem/File Class/File.OpenText.cs b/AlphaFS/Filesystem/File Class/File.OpenText.cs new file mode 100644 index 0000000..45ca276 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.OpenText.cs @@ -0,0 +1,128 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + /// Opens an existing UTF-8 encoded text file for reading. + /// The file to be opened for reading. + /// A on the specified path. + /// This method is equivalent to the (String) constructor overload. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public static StreamReader OpenText(string path) + { + return new StreamReader(OpenRead(path), NativeMethods.DefaultFileEncoding); + } + + /// [AlphaFS] Opens an existing UTF-8 encoded text file for reading. + /// The file to be opened for reading. + /// Indicates the format of the path parameter(s). + /// A on the specified path. + /// This method is equivalent to the (String) constructor overload. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public static StreamReader OpenText(string path, PathFormat pathFormat) + { + return new StreamReader(OpenRead(path, pathFormat), NativeMethods.DefaultFileEncoding); + } + + /// [AlphaFS] Opens an existing encoded text file for reading. + /// The file to be opened for reading. + /// The applied to the contents of the file. + /// Indicates the format of the path parameter(s). + /// A on the specified path. + /// This method is equivalent to the (String) constructor overload. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public static StreamReader OpenText(string path, Encoding encoding, PathFormat pathFormat) + { + return new StreamReader(OpenRead(path, pathFormat), encoding); + } + + + /// [AlphaFS] Opens an existing encoded text file for reading. + /// The file to be opened for reading. + /// The applied to the contents of the file. + /// A on the specified path. + /// This method is equivalent to the (String) constructor overload. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public static StreamReader OpenText(string path, Encoding encoding) + { + return new StreamReader(OpenRead(path), encoding); + } + + /// [AlphaFS] Opens an existing UTF-8 encoded text file for reading. + /// The transaction. + /// The file to be opened for reading. + /// A on the specified path. + /// This method is equivalent to the (String) constructor overload. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + public static StreamReader OpenTextTransacted(KernelTransaction transaction, string path) + { + return new StreamReader(OpenReadTransacted(transaction, path), NativeMethods.DefaultFileEncoding); + } + + /// [AlphaFS] Opens an existing UTF-8 encoded text file for reading. + /// The transaction. + /// The file to be opened for reading. + /// Indicates the format of the path parameter(s). + /// A on the specified path. + /// This method is equivalent to the (String) constructor overload. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + public static StreamReader OpenTextTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return new StreamReader(OpenReadTransacted(transaction, path, pathFormat), NativeMethods.DefaultFileEncoding); + } + + /// [AlphaFS] Opens an existing encoded text file for reading. + /// The transaction. + /// The file to be opened for reading. + /// The applied to the contents of the file. + /// Indicates the format of the path parameter(s). + /// A on the specified path. + /// This method is equivalent to the (String) constructor overload. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + public static StreamReader OpenTextTransacted(KernelTransaction transaction, string path, Encoding encoding, PathFormat pathFormat) + { + return new StreamReader(OpenReadTransacted(transaction, path, pathFormat), encoding); + } + + /// [AlphaFS] Opens an existing encoded text file for reading. + /// The transaction. + /// The file to be opened for reading. + /// The applied to the contents of the file. + /// A on the specified path. + /// This method is equivalent to the (String) constructor overload. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + public static StreamReader OpenTextTransacted(KernelTransaction transaction, string path, Encoding encoding) + { + return new StreamReader(OpenReadTransacted(transaction, path), encoding); + } + } +} diff --git a/AlphaFS/Filesystem/File Class/File.OpenWrite.cs b/AlphaFS/Filesystem/File Class/File.OpenWrite.cs new file mode 100644 index 0000000..7e3d140 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.OpenWrite.cs @@ -0,0 +1,73 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + /// Opens an existing file or creates a new file for writing. + /// The file to be opened for writing. + /// An unshared object on the specified path with access. + /// This method is equivalent to the (String, FileMode, FileAccess, FileShare) constructor overload with file mode set to OpenOrCreate, the access set to Write, and the share mode set to None. + [SecurityCritical] + public static FileStream OpenWrite(string path) + { + return Open(path, FileMode.OpenOrCreate, FileAccess.Write); + } + + /// [AlphaFS] Opens an existing file or creates a new file for writing. + /// The file to be opened for writing. + /// Indicates the format of the path parameter(s). + /// An unshared object on the specified path with access. + /// This method is equivalent to the (String, FileMode, FileAccess, FileShare) constructor overload with file mode set to OpenOrCreate, the access set to Write, and the share mode set to None. + [SecurityCritical] + public static FileStream OpenWrite(string path, PathFormat pathFormat) + { + return Open(path, FileMode.OpenOrCreate, FileAccess.Write, pathFormat); + } + + /// [AlphaFS] Opens an existing file or creates a new file for writing. + /// The transaction. + /// The file to be opened for writing. + /// An unshared object on the specified path with access. + /// This method is equivalent to the (String, FileMode, FileAccess, FileShare) constructor overload with file mode set to OpenOrCreate, the access set to Write, and the share mode set to None. + [SecurityCritical] + public static FileStream OpenWriteTransacted(KernelTransaction transaction, string path) + { + return OpenTransacted(transaction, path, FileMode.OpenOrCreate, FileAccess.Write); + } + + /// [AlphaFS] Opens an existing file or creates a new file for writing. + /// The transaction. + /// The file to be opened for writing. + /// Indicates the format of the path parameter(s). + /// An unshared object on the specified path with access. + /// This method is equivalent to the (String, FileMode, FileAccess, FileShare) constructor overload with file mode set to OpenOrCreate, the access set to Write, and the share mode set to None. + [SecurityCritical] + public static FileStream OpenWriteTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return OpenTransacted(transaction, path, FileMode.OpenOrCreate, FileAccess.Write, pathFormat); + } + } +} diff --git a/AlphaFS/Filesystem/File Class/File.ReadAllBytes.cs b/AlphaFS/Filesystem/File Class/File.ReadAllBytes.cs new file mode 100644 index 0000000..47ec283 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.ReadAllBytes.cs @@ -0,0 +1,117 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Globalization; +using System.IO; +using System.Security; +using FileStream = System.IO.FileStream; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region ReadAllBytes + + /// Opens a binary file, reads the contents of the file into a byte array, and then closes the file. + /// The file to open for reading. + /// A byte array containing the contents of the file. + [SecurityCritical] + public static byte[] ReadAllBytes(string path) + { + return ReadAllBytesCore(null, path, PathFormat.RelativePath); + } + + /// [AlphaFS] Opens a binary file, reads the contents of the file into a byte array, and then closes the file. + /// The file to open for reading. + /// Indicates the format of the path parameter(s). + /// A byte array containing the contents of the file. + [SecurityCritical] + public static byte[] ReadAllBytes(string path, PathFormat pathFormat) + { + return ReadAllBytesCore(null, path, pathFormat); + } + + + #region Transactional + + /// [AlphaFS] Opens a binary file, reads the contents of the file into a byte array, and then closes the file. + /// The transaction. + /// The file to open for reading. + /// A byte array containing the contents of the file. + [SecurityCritical] + public static byte[] ReadAllBytesTransacted(KernelTransaction transaction, string path) + { + return ReadAllBytesCore(transaction, path, PathFormat.RelativePath); + } + + /// [AlphaFS] Opens a binary file, reads the contents of the file into a byte array, and then closes the file. + /// The transaction. + /// The file to open for reading. + /// Indicates the format of the path parameter(s). + /// A byte array containing the contents of the file. + [SecurityCritical] + public static byte[] ReadAllBytesTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return ReadAllBytesCore(transaction, path, pathFormat); + } + + #endregion // Transacted + + #endregion // ReadAllBytes + + #region Internal Methods + + /// Opens a binary file, reads the contents of the file into a byte array, and then closes the file. + /// + /// The transaction. + /// The file to open for reading. + /// Indicates the format of the path parameter(s). + /// A byte array containing the contents of the file. + [SecurityCritical] + internal static byte[] ReadAllBytesCore(KernelTransaction transaction, string path, PathFormat pathFormat) + { + byte[] buffer; + + using (FileStream fs = OpenReadTransacted(transaction, path, pathFormat)) + { + int offset = 0; + long length = fs.Length; + + if (length > int.MaxValue) + throw new IOException(string.Format(CultureInfo.CurrentCulture, "File larger than 2GB: [{0}]", path)); + + int count = (int)length; + buffer = new byte[count]; + while (count > 0) + { + int n = fs.Read(buffer, offset, count); + if (n == 0) + throw new IOException("Unexpected end of file found"); + offset += n; + count -= n; + } + } + return buffer; + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.ReadAllLines.cs b/AlphaFS/Filesystem/File Class/File.ReadAllLines.cs new file mode 100644 index 0000000..0633df6 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.ReadAllLines.cs @@ -0,0 +1,148 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Security; +using System.Text; +using StreamReader = System.IO.StreamReader; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region ReadAllLines + + /// Opens a text file, reads all lines of the file, and then closes the file. + /// The file to open for reading. + /// All lines of the file. + [SecurityCritical] + public static string[] ReadAllLines(string path) + { + return ReadAllLinesCore(null, path, NativeMethods.DefaultFileEncoding, PathFormat.RelativePath).ToArray(); + } + + /// Opens a file, reads all lines of the file with the specified encoding, and then closes the file. + /// The file to open for reading. + /// The applied to the contents of the file. + /// All lines of the file. + [SecurityCritical] + public static string[] ReadAllLines(string path, Encoding encoding) + { + return ReadAllLinesCore(null, path, encoding, PathFormat.RelativePath).ToArray(); + } + + /// [AlphaFS] Opens a text file, reads all lines of the file, and then closes the file. + /// The file to open for reading. + /// Indicates the format of the path parameter(s). + /// All lines of the file. + [SecurityCritical] + public static string[] ReadAllLines(string path, PathFormat pathFormat) + { + return ReadAllLinesCore(null, path, NativeMethods.DefaultFileEncoding, pathFormat).ToArray(); + } + + /// [AlphaFS] Opens a file, reads all lines of the file with the specified encoding, and then closes the file. + /// The file to open for reading. + /// The applied to the contents of the file. + /// Indicates the format of the path parameter(s). + /// All lines of the file. + [SecurityCritical] + public static string[] ReadAllLines(string path, Encoding encoding, PathFormat pathFormat) + { + return ReadAllLinesCore(null, path, encoding, pathFormat).ToArray(); + } + + #region Transactional + + /// [AlphaFS] Opens a text file, reads all lines of the file, and then closes the file. + /// The transaction. + /// The file to open for reading. + /// All lines of the file. + [SecurityCritical] + public static string[] ReadAllLinesTransacted(KernelTransaction transaction, string path) + { + return ReadAllLinesCore(transaction, path, NativeMethods.DefaultFileEncoding, PathFormat.RelativePath).ToArray(); + } + + /// [AlphaFS] Opens a file, reads all lines of the file with the specified encoding, and then closes the file. + /// The transaction. + /// The file to open for reading. + /// The applied to the contents of the file. + /// All lines of the file. + [SecurityCritical] + public static string[] ReadAllLinesTransacted(KernelTransaction transaction, string path, Encoding encoding) + { + return ReadAllLinesCore(transaction, path, encoding, PathFormat.RelativePath).ToArray(); + } + + /// [AlphaFS] Opens a text file, reads all lines of the file, and then closes the file. + /// The transaction. + /// The file to open for reading. + /// Indicates the format of the path parameter(s). + /// All lines of the file. + [SecurityCritical] + public static string[] ReadAllLinesTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return ReadAllLinesCore(transaction, path, NativeMethods.DefaultFileEncoding, pathFormat).ToArray(); + } + + /// [AlphaFS] Opens a file, reads all lines of the file with the specified encoding, and then closes the file. + /// The transaction. + /// The file to open for reading. + /// The applied to the contents of the file. + /// Indicates the format of the path parameter(s). + /// All lines of the file. + [SecurityCritical] + public static string[] ReadAllLinesTransacted(KernelTransaction transaction, string path, Encoding encoding, PathFormat pathFormat) + { + return ReadAllLinesCore(transaction, path, encoding, pathFormat).ToArray(); + } + + #endregion // Transacted + + #endregion // ReadAllLines + + #region Internal Methods + + /// Opens a file, read all lines of the file with the specified encoding, and then close the file. + /// The transaction. + /// The file to open for reading. + /// The applied to the contents of the file. + /// Indicates the format of the path parameter(s). + /// An IEnumerable string containing all lines of the file. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + internal static IEnumerable ReadAllLinesCore(KernelTransaction transaction, string path, Encoding encoding, PathFormat pathFormat) + { + using (StreamReader sr = new StreamReader(OpenCore(transaction, path, FileMode.Open, FileAccess.Read, FileShare.Read, ExtendedFileAttributes.SequentialScan, null, null, pathFormat), encoding)) + { + string line; + while ((line = sr.ReadLine()) != null) + yield return line; + } + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.ReadAllText.cs b/AlphaFS/Filesystem/File Class/File.ReadAllText.cs new file mode 100644 index 0000000..938a55a --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.ReadAllText.cs @@ -0,0 +1,143 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; +using System.Text; +using StreamReader = System.IO.StreamReader; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region ReadAllText + + /// Opens a text file, reads all lines of the file, and then closes the file. + /// The file to open for reading. + /// All lines of the file. + [SecurityCritical] + public static string ReadAllText(string path) + { + return ReadAllTextCore(null, path, NativeMethods.DefaultFileEncoding, PathFormat.RelativePath); + } + + /// Opens a file, reads all lines of the file with the specified encoding, and then closes the file. + /// The file to open for reading. + /// The applied to the contents of the file. + /// All lines of the file. + [SecurityCritical] + public static string ReadAllText(string path, Encoding encoding) + { + return ReadAllTextCore(null, path, encoding, PathFormat.RelativePath); + } + + /// [AlphaFS] Opens a text file, reads all lines of the file, and then closes the file. + /// The file to open for reading. + /// Indicates the format of the path parameter(s). + /// All lines of the file. + [SecurityCritical] + public static string ReadAllText(string path, PathFormat pathFormat) + { + return ReadAllTextCore(null, path, NativeMethods.DefaultFileEncoding, pathFormat); + } + + /// [AlphaFS] Opens a file, reads all lines of the file with the specified encoding, and then closes the file. + /// The file to open for reading. + /// The applied to the contents of the file. + /// Indicates the format of the path parameter(s). + /// All lines of the file. + [SecurityCritical] + public static string ReadAllText(string path, Encoding encoding, PathFormat pathFormat) + { + return ReadAllTextCore(null, path, encoding, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Opens a text file, reads all lines of the file, and then closes the file. + /// The transaction. + /// The file to open for reading. + /// All lines of the file. + [SecurityCritical] + public static string ReadAllTextTransacted(KernelTransaction transaction, string path) + { + return ReadAllTextCore(transaction, path, NativeMethods.DefaultFileEncoding, PathFormat.RelativePath); + } + + /// [AlphaFS] Opens a file, reads all lines of the file with the specified encoding, and then closes the file. + /// The transaction. + /// The file to open for reading. + /// The applied to the contents of the file. + /// All lines of the file. + [SecurityCritical] + public static string ReadAllTextTransacted(KernelTransaction transaction, string path, Encoding encoding) + { + return ReadAllTextCore(transaction, path, encoding, PathFormat.RelativePath); + } + + /// [AlphaFS] Opens a text file, reads all lines of the file, and then closes the file. + /// The transaction. + /// The file to open for reading. + /// Indicates the format of the path parameter(s). + /// All lines of the file. + [SecurityCritical] + public static string ReadAllTextTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return ReadAllTextCore(transaction, path, NativeMethods.DefaultFileEncoding, pathFormat); + } + + /// [AlphaFS] Opens a file, reads all lines of the file with the specified encoding, and then closes the file. + /// The transaction. + /// The file to open for reading. + /// The applied to the contents of the file. + /// Indicates the format of the path parameter(s). + /// All lines of the file. + [SecurityCritical] + public static string ReadAllTextTransacted(KernelTransaction transaction, string path, Encoding encoding, PathFormat pathFormat) + { + return ReadAllTextCore(transaction, path, encoding, pathFormat); + } + + #endregion // Transacted + + #endregion // ReadAllText + + #region Internal Methods + + /// Open a file, read all lines of the file with the specified encoding, and then close the file. + /// The transaction. + /// The file to open for reading. + /// The applied to the contents of the file. + /// Indicates the format of the path parameter(s). + /// All lines of the file. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + internal static string ReadAllTextCore(KernelTransaction transaction, string path, Encoding encoding, PathFormat pathFormat) + { + using (StreamReader sr = new StreamReader(OpenCore(transaction, path, FileMode.Open, FileAccess.Read, FileShare.Read, ExtendedFileAttributes.SequentialScan, null, null, pathFormat), encoding)) + return sr.ReadToEnd(); + } + + #endregion // Internal Methods + + } +} diff --git a/AlphaFS/Filesystem/File Class/File.ReadLines.cs b/AlphaFS/Filesystem/File Class/File.ReadLines.cs new file mode 100644 index 0000000..e5ac433 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.ReadLines.cs @@ -0,0 +1,148 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; +using System.Text; +using StreamReader = System.IO.StreamReader; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region ReadLines + + /// Reads the lines of a file. + /// The file to read. + /// All the lines of the file, or the lines that are the result of a query. + [SecurityCritical] + public static IEnumerable ReadLines(string path) + { + return ReadLinesCore(null, path, NativeMethods.DefaultFileEncoding, PathFormat.RelativePath); + } + + /// Read the lines of a file that has a specified encoding. + /// The file to read. + /// The encoding that is applied to the contents of the file. + /// All the lines of the file, or the lines that are the result of a query. + [SecurityCritical] + public static IEnumerable ReadLines(string path, Encoding encoding) + { + return ReadLinesCore(null, path, encoding, PathFormat.RelativePath); + } + + /// [AlphaFS] Reads the lines of a file. + /// The file to read. + /// Indicates the format of the path parameter(s). + /// All the lines of the file, or the lines that are the result of a query. + [SecurityCritical] + public static IEnumerable ReadLines(string path, PathFormat pathFormat) + { + return ReadLinesCore(null, path, NativeMethods.DefaultFileEncoding, pathFormat); + } + + /// [AlphaFS] Read the lines of a file that has a specified encoding. + /// The file to read. + /// The encoding that is applied to the contents of the file. + /// Indicates the format of the path parameter(s). + /// All the lines of the file, or the lines that are the result of a query. + [SecurityCritical] + public static IEnumerable ReadLines(string path, Encoding encoding, PathFormat pathFormat) + { + return ReadLinesCore(null, path, encoding, pathFormat); + } + + + #region Transactional + + /// [AlphaFS] Reads the lines of a file. + /// The transaction. + /// The file to read. + /// All the lines of the file, or the lines that are the result of a query. + [SecurityCritical] + public static IEnumerable ReadLinesTransacted(KernelTransaction transaction, string path) + { + return ReadLinesCore(transaction, path, NativeMethods.DefaultFileEncoding, PathFormat.RelativePath); + } + + /// [AlphaFS] Read the lines of a file that has a specified encoding. + /// The transaction. + /// The file to read. + /// The encoding that is applied to the contents of the file. + /// All the lines of the file, or the lines that are the result of a query. + [SecurityCritical] + public static IEnumerable ReadLinesTransacted(KernelTransaction transaction, string path, Encoding encoding) + { + return ReadLinesCore(transaction, path, encoding, PathFormat.RelativePath); + } + + /// [AlphaFS] Reads the lines of a file. + /// The transaction. + /// The file to read. + /// Indicates the format of the path parameter(s). + /// All the lines of the file, or the lines that are the result of a query. + [SecurityCritical] + public static IEnumerable ReadLinesTransacted(KernelTransaction transaction, string path, PathFormat pathFormat) + { + return ReadLinesCore(transaction, path, NativeMethods.DefaultFileEncoding, pathFormat); + } + + /// [AlphaFS] Read the lines of a file that has a specified encoding. + /// The transaction. + /// The file to read. + /// The encoding that is applied to the contents of the file. + /// Indicates the format of the path parameter(s). + /// All the lines of the file, or the lines that are the result of a query. + [SecurityCritical] + public static IEnumerable ReadLinesTransacted(KernelTransaction transaction, string path, Encoding encoding, PathFormat pathFormat) + { + return ReadLinesCore(transaction, path, encoding, pathFormat); + } + + #endregion // Transacted + + #endregion // ReadLines + + #region Internal Methods + + /// Reads the lines of a file that has a specified encoding. + /// The transaction. + /// The file to read. + /// The encoding that is applied to the contents of the file. + /// Indicates the format of the path parameter(s). + /// All the lines of the file, or the lines that are the result of a query. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + internal static IEnumerable ReadLinesCore(KernelTransaction transaction, string path, Encoding encoding, PathFormat pathFormat) + { + using (StreamReader sr = new StreamReader(OpenCore(transaction, path, FileMode.Open, FileAccess.Read, FileShare.Read, ExtendedFileAttributes.SequentialScan, null, null, pathFormat), encoding)) + { + string line; + while ((line = sr.ReadLine()) != null) + yield return line; + } + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.Replace.cs b/AlphaFS/Filesystem/File Class/File.Replace.cs new file mode 100644 index 0000000..a796509 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.Replace.cs @@ -0,0 +1,182 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.AccessControl; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region Replace + + /// + /// Replaces the contents of a specified file with the contents of another file, deleting the original file, and creating a backup of + /// the replaced file. + /// + /// + /// The Replace method replaces the contents of a specified file with the contents of another file. It also creates a backup of the + /// file that was replaced. + /// + /// + /// If the and are on different volumes, this method will + /// raise an exception. If the is on a different volume from the source file, the backup + /// file will be deleted. + /// + /// + /// Pass null to the parameter if you do not want to create a backup of the file being + /// replaced. + /// + /// The name of a file that replaces the file specified by . + /// The name of the file being replaced. + /// The name of the backup file. + [SecurityCritical] + public static void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName) + { + ReplaceCore(sourceFileName, destinationFileName, destinationBackupFileName, false, PathFormat.RelativePath); + } + + /// + /// Replaces the contents of a specified file with the contents of another file, deleting the original file, and creating a backup of + /// the replaced file and optionally ignores merge errors. + /// + /// + /// The Replace method replaces the contents of a specified file with the contents of another file. It also creates a backup of the + /// file that was replaced. + /// + /// + /// If the and are on different volumes, this method will + /// raise an exception. If the is on a different volume from the source file, the backup + /// file will be deleted. + /// + /// + /// Pass null to the parameter if you do not want to create a backup of the file being + /// replaced. + /// + /// The name of a file that replaces the file specified by . + /// The name of the file being replaced. + /// The name of the backup file. + /// + /// to ignore merge errors (such as attributes and access control lists (ACLs)) from the replaced file to the + /// replacement file; otherwise, . + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "dest")] + [SecurityCritical] + public static void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors) + { + ReplaceCore(sourceFileName, destinationFileName, destinationBackupFileName, ignoreMetadataErrors, PathFormat.RelativePath); + } + + /// + /// [AlphaFS] Replaces the contents of a specified file with the contents of another file, deleting the original file, and creating a + /// backup of the replaced file and optionally ignores merge errors. + /// + /// + /// The Replace method replaces the contents of a specified file with the contents of another file. It also creates a backup of the + /// file that was replaced. + /// + /// + /// If the and are on different volumes, this method will + /// raise an exception. If the is on a different volume from the source file, the backup + /// file will be deleted. + /// + /// + /// Pass null to the parameter if you do not want to create a backup of the file being + /// replaced. + /// + /// The name of a file that replaces the file specified by . + /// The name of the file being replaced. + /// The name of the backup file. + /// + /// to ignore merge errors (such as attributes and access control lists (ACLs)) from the replaced file to the + /// replacement file; otherwise, . + /// + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "dest")] + [SecurityCritical] + public static void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors, PathFormat pathFormat) + { + ReplaceCore(sourceFileName, destinationFileName, destinationBackupFileName, ignoreMetadataErrors, pathFormat); + } + + #endregion // Replace + + #region ReplaceCore + + /// Replaces the contents of a specified file with the contents of another file, deleting + /// the original file, and creating a backup of the replaced file and optionally ignores merge errors. + /// + /// + /// The Replace method replaces the contents of a specified file with the contents of another file. It also creates a backup of the + /// file that was replaced. + /// + /// + /// If the and are on different volumes, this method will + /// raise an exception. If the is on a different volume from the source file, the backup + /// file will be deleted. + /// + /// + /// Pass null to the parameter if you do not want to create a backup of the file being + /// replaced. + /// + /// The name of a file that replaces the file specified by . + /// The name of the file being replaced. + /// The name of the backup file. + /// + /// to ignore merge errors (such as attributes and access control lists (ACLs)) from the replaced file to the + /// replacement file; otherwise, . + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static void ReplaceCore(string sourceFileName, string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors, PathFormat pathFormat) + { + var options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck; + + string sourceFileNameLp = Path.GetExtendedLengthPathCore(null, sourceFileName, pathFormat, options); + string destinationFileNameLp = Path.GetExtendedLengthPathCore(null, destinationFileName, pathFormat, options); + + // Pass null to the destinationBackupFileName parameter if you do not want to create a backup of the file being replaced. + string destinationBackupFileNameLp = destinationBackupFileName == null + ? null + : Path.GetExtendedLengthPathCore(null, destinationBackupFileName, pathFormat, options); + + const int replacefileWriteThrough = 1; + const int replacefileIgnoreMergeErrors = 2; + + FileSystemRights dwReplaceFlags = (FileSystemRights) replacefileWriteThrough; + if (ignoreMetadataErrors) + dwReplaceFlags |= (FileSystemRights) replacefileIgnoreMergeErrors; + + // ReplaceFile() + // 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 does not confirm LongPath usage but a Unicode version of this function exists. + + if (!NativeMethods.ReplaceFile(destinationFileNameLp, sourceFileNameLp, destinationBackupFileNameLp, dwReplaceFlags, IntPtr.Zero, IntPtr.Zero)) + NativeError.ThrowException(Marshal.GetLastWin32Error(), sourceFileNameLp, destinationFileNameLp); + } + + #endregion // ReplaceCore + } +} diff --git a/AlphaFS/Filesystem/File Class/File.SetAccessControl.cs b/AlphaFS/Filesystem/File Class/File.SetAccessControl.cs new file mode 100644 index 0000000..611ad78 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.SetAccessControl.cs @@ -0,0 +1,264 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.AccessControl; +using Alphaleonis.Win32.Security; +using Microsoft.Win32.SafeHandles; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class File + { + /// Applies access control list (ACL) entries described by a FileSecurity object to the specified file. + /// + /// + /// + /// A file to add or remove access control list (ACL) entries from. + /// A object that describes an ACL entry to apply to the file described by the parameter. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static void SetAccessControl(string path, FileSecurity fileSecurity) + { + SetAccessControlCore(path, null, fileSecurity, AccessControlSections.All, PathFormat.RelativePath); + } + + /// Applies access control list (ACL) entries described by a object to the specified directory. + /// + /// + /// + /// A directory to add or remove access control list (ACL) entries from. + /// A object that describes an ACL entry to apply to the directory described by the path parameter. + /// One or more of the values that specifies the type of access control list (ACL) information to set. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static void SetAccessControl(string path, FileSecurity fileSecurity, AccessControlSections includeSections) + { + SetAccessControlCore(path, null, fileSecurity, includeSections, PathFormat.RelativePath); + } + + + /// [AlphaFS] Applies access control list (ACL) entries described by a FileSecurity object to the specified file. + /// + /// + /// + /// A file to add or remove access control list (ACL) entries from. + /// A object that describes an ACL entry to apply to the file described by the parameter. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static void SetAccessControl(string path, FileSecurity fileSecurity, PathFormat pathFormat) + { + SetAccessControlCore(path, null, fileSecurity, AccessControlSections.All, pathFormat); + } + + /// [AlphaFS] Applies access control list (ACL) entries described by a object to the specified directory. + /// + /// + /// + /// A directory to add or remove access control list (ACL) entries from. + /// A object that describes an ACL entry to apply to the directory described by the path parameter. + /// One or more of the values that specifies the type of access control list (ACL) information to set. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static void SetAccessControl(string path, FileSecurity fileSecurity, AccessControlSections includeSections, PathFormat pathFormat) + { + SetAccessControlCore(path, null, fileSecurity, includeSections, pathFormat); + } + + + /// Applies access control list (ACL) entries described by a FileSecurity object to the specified file. + /// + /// + /// + /// A to a file to add or remove access control list (ACL) entries from. + /// A object that describes an ACL entry to apply to the file described by the parameter. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static void SetAccessControl(SafeFileHandle handle, FileSecurity fileSecurity) + { + SetAccessControlCore(null, handle, fileSecurity, AccessControlSections.All, PathFormat.LongFullPath); + } + + /// Applies access control list (ACL) entries described by a FileSecurity object to the specified file. + /// + /// + /// + /// A to a file to add or remove access control list (ACL) entries from. + /// A object that describes an ACL entry to apply to the file described by the parameter. + /// One or more of the values that specifies the type of access control list (ACL) information to set. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public static void SetAccessControl(SafeFileHandle handle, FileSecurity fileSecurity, AccessControlSections includeSections) + { + SetAccessControlCore(null, handle, fileSecurity, includeSections, PathFormat.LongFullPath); + } + + + + + /// [AlphaFS] Applies access control list (ACL) entries described by a / object to the specified file or directory. + /// Use either or , not both. + /// + /// + /// + /// A file/directory to add or remove access control list (ACL) entries from. This parameter This parameter may be . + /// A to add or remove access control list (ACL) entries from. This parameter This parameter may be . + /// A / object that describes an ACL entry to apply to the file/directory described by the / parameter. + /// One or more of the values that specifies the type of access control list (ACL) information to set. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + [SecurityCritical] + internal static void SetAccessControlCore(string path, SafeFileHandle handle, ObjectSecurity objectSecurity, AccessControlSections includeSections, PathFormat pathFormat) + { + if (pathFormat == PathFormat.RelativePath) + Path.CheckSupportedPathFormat(path, true, true); + + if (objectSecurity == null) + throw new ArgumentNullException("objectSecurity"); + + + byte[] managedDescriptor = objectSecurity.GetSecurityDescriptorBinaryForm(); + + using (var safeBuffer = new SafeGlobalMemoryBufferHandle(managedDescriptor.Length)) + { + string pathLp = Path.GetExtendedLengthPathCore(null, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars); + + safeBuffer.CopyFrom(managedDescriptor, 0, managedDescriptor.Length); + + SecurityDescriptorControl control; + uint revision; + + if (!Security.NativeMethods.GetSecurityDescriptorControl(safeBuffer, out control, out revision)) + NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); + + + PrivilegeEnabler privilegeEnabler = null; + + try + { + var securityInfo = SecurityInformation.None; + IntPtr pDacl = IntPtr.Zero; + + if ((includeSections & AccessControlSections.Access) != 0) + { + bool daclDefaulted, daclPresent; + + if (!Security.NativeMethods.GetSecurityDescriptorDacl(safeBuffer, out daclPresent, out pDacl, out daclDefaulted)) + NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); + + if (daclPresent) + { + securityInfo |= SecurityInformation.Dacl; + securityInfo |= (control & SecurityDescriptorControl.DaclProtected) != 0 + ? SecurityInformation.ProtectedDacl + : SecurityInformation.UnprotectedDacl; + } + } + + + IntPtr pSacl = IntPtr.Zero; + + if ((includeSections & AccessControlSections.Audit) != 0) + { + bool saclDefaulted, saclPresent; + + if (!Security.NativeMethods.GetSecurityDescriptorSacl(safeBuffer, out saclPresent, out pSacl, out saclDefaulted)) + NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); + + if (saclPresent) + { + securityInfo |= SecurityInformation.Sacl; + securityInfo |= (control & SecurityDescriptorControl.SaclProtected) != 0 + ? SecurityInformation.ProtectedSacl + : SecurityInformation.UnprotectedSacl; + + privilegeEnabler = new PrivilegeEnabler(Privilege.Security); + } + } + + + IntPtr pOwner = IntPtr.Zero; + + if ((includeSections & AccessControlSections.Owner) != 0) + { + bool ownerDefaulted; + + if (!Security.NativeMethods.GetSecurityDescriptorOwner(safeBuffer, out pOwner, out ownerDefaulted)) + NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); + + if (pOwner != IntPtr.Zero) + securityInfo |= SecurityInformation.Owner; + } + + + IntPtr pGroup = IntPtr.Zero; + + if ((includeSections & AccessControlSections.Group) != 0) + { + bool groupDefaulted; + + if (!Security.NativeMethods.GetSecurityDescriptorGroup(safeBuffer, out pGroup, out groupDefaulted)) + NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); + + if (pGroup != IntPtr.Zero) + securityInfo |= SecurityInformation.Group; + } + + + uint lastError; + + if (!Utils.IsNullOrWhiteSpace(pathLp)) + { + // SetNamedSecurityInfo() + // 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 does not confirm LongPath usage but a Unicode version of this function exists. + + lastError = Security.NativeMethods.SetNamedSecurityInfo(pathLp, ObjectType.FileObject, securityInfo, pOwner, pGroup, pDacl, pSacl); + + if (lastError != Win32Errors.ERROR_SUCCESS) + NativeError.ThrowException(lastError, pathLp); + } + else + { + if (NativeMethods.IsValidHandle(handle)) + { + lastError = Security.NativeMethods.SetSecurityInfo(handle, ObjectType.FileObject, securityInfo, pOwner, pGroup, pDacl, pSacl); + + if (lastError != Win32Errors.ERROR_SUCCESS) + NativeError.ThrowException((int) lastError); + } + } + } + finally + { + if (privilegeEnabler != null) + privilegeEnabler.Dispose(); + } + } + } + } +} diff --git a/AlphaFS/Filesystem/File Class/File.SetAttributes.cs b/AlphaFS/Filesystem/File Class/File.SetAttributes.cs new file mode 100644 index 0000000..d1addd0 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.SetAttributes.cs @@ -0,0 +1,172 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region SetAttributes + + /// Sets the specified of the file or directory on the specified path. + /// + /// Certain file attributes, such as and , can be combined. + /// Other attributes, such as , must be used alone. + /// + /// + /// It is not possible to change the status of a File object using this method. + /// + /// The path to the file or directory. + /// A bitwise combination of the enumeration values. + /// Sets the specified of the file or directory on the specified path. + [SecurityCritical] + public static void SetAttributes(string path, FileAttributes fileAttributes) + { + SetAttributesCore(false, null, path, fileAttributes, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the specified of the file or directory on the specified path. + /// + /// Certain file attributes, such as and , can be combined. + /// Other attributes, such as , must be used alone. + /// + /// + /// It is not possible to change the status of a File object using this method. + /// + /// The path to the file or directory. + /// A bitwise combination of the enumeration values. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetAttributes(string path, FileAttributes fileAttributes, PathFormat pathFormat) + { + SetAttributesCore(false, null, path, fileAttributes, false, pathFormat); + } + + + #region Transactional + + /// [AlphaFS] Sets the specified of the file on the specified path. + /// + /// Certain file attributes, such as and , can be combined. + /// Other attributes, such as , must be used alone. + /// + /// + /// It is not possible to change the status of a File object using this method. + /// + /// The transaction. + /// The path to the file. + /// A bitwise combination of the enumeration values. + [SecurityCritical] + public static void SetAttributesTransacted(KernelTransaction transaction, string path, FileAttributes fileAttributes) + { + SetAttributesCore(false, transaction, path, fileAttributes, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the specified of the file on the specified path. + /// + /// Certain file attributes, such as and , can be combined. + /// Other attributes, such as , must be used alone. + /// + /// + /// It is not possible to change the status of a File object using this method. + /// + /// The transaction. + /// The path to the file. + /// A bitwise combination of the enumeration values. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetAttributesTransacted(KernelTransaction transaction, string path, FileAttributes fileAttributes, PathFormat pathFormat) + { + SetAttributesCore(false, transaction, path, fileAttributes, false, pathFormat); + } + + #endregion // Transacted + + #endregion // SetAttributes + + #region Internal Methods + + /// Sets the attributes for a Non-/Transacted file/directory. + /// + /// Certain file attributes, such as and , can be combined. + /// Other attributes, such as , must be used alone. + /// + /// + /// It is not possible to change the status of a File object using the SetAttributes method. + /// + /// + /// Specifies that is a file or directory. + /// The transaction. + /// The name of the file or directory whose attributes are to be set. + /// + /// The attributes to set for the file or directory. Note that all other values override . + /// + /// + /// does not throw an Exception when the file system object does not exist. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static void SetAttributesCore(bool isFolder, KernelTransaction transaction, string path, FileAttributes fileAttributes, bool continueOnNotExist, PathFormat pathFormat) + { + string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + + if (!(transaction == null || !NativeMethods.IsAtLeastWindowsVista + + // SetFileAttributes() + // 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.SetFileAttributes(pathLp, fileAttributes) + : NativeMethods.SetFileAttributesTransacted(pathLp, fileAttributes, transaction.SafeHandle))) + { + if (continueOnNotExist) + return; + + uint lastError = (uint)Marshal.GetLastWin32Error(); + + switch (lastError) + { + // MSDN: .NET 3.5+: ArgumentException: FileSystemInfo().Attributes + case Win32Errors.ERROR_INVALID_PARAMETER: + throw new ArgumentException(Resources.Invalid_File_Attribute); + + case Win32Errors.ERROR_FILE_NOT_FOUND: + if (isFolder) + lastError = (int)Win32Errors.ERROR_PATH_NOT_FOUND; + + // MSDN: .NET 3.5+: DirectoryNotFoundException: The specified path is invalid, (for example, it is on an unmapped drive). + // MSDN: .NET 3.5+: FileNotFoundException: The file cannot be found. + NativeError.ThrowException(lastError, pathLp); + break; + } + + NativeError.ThrowException(lastError, pathLp); + } + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.SetFileTime.cs b/AlphaFS/Filesystem/File Class/File.SetFileTime.cs new file mode 100644 index 0000000..30862d4 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.SetFileTime.cs @@ -0,0 +1,886 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Security; +using System.Security.AccessControl; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region SetCreationTime + + /// Sets the date and time the file was created. + /// The file for which to set the creation date and time information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in local time. + /// + [SecurityCritical] + public static void SetCreationTime(string path, DateTime creationTime) + { + SetFsoDateTimeCore(false, null, path, creationTime.ToUniversalTime(), null, null, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the date and time the file was created. + /// The file for which to set the creation date and time information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in local time. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetCreationTime(string path, DateTime creationTime, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, null, path, creationTime.ToUniversalTime(), null, null, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time the file was created. + /// The file for which to set the creation date and time information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in local time. + /// + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetCreationTime(string path, DateTime creationTime, bool modifyReparsePoint, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, null, path, creationTime.ToUniversalTime(), null, null, modifyReparsePoint, pathFormat); + } + + + #region Transactional + + /// [AlphaFS] Sets the date and time the file was created. + /// The transaction. + /// The file for which to set the creation date and time information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in local time. + /// + [SecurityCritical] + public static void SetCreationTimeTransacted(KernelTransaction transaction, string path, DateTime creationTime) + { + SetFsoDateTimeCore(false, transaction, path, creationTime.ToUniversalTime(), null, null, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the date and time the file was created. + /// The transaction. + /// The file for which to set the creation date and time information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in local time. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetCreationTimeTransacted(KernelTransaction transaction, string path, DateTime creationTime, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, transaction, path, creationTime.ToUniversalTime(), null, null, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time the file was created. + /// The transaction. + /// The file for which to set the creation date and time information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in local time. + /// + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetCreationTimeTransacted(KernelTransaction transaction, string path, DateTime creationTime, bool modifyReparsePoint, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, transaction, path, creationTime.ToUniversalTime(), null, null, modifyReparsePoint, pathFormat); + } + + + #endregion // Transacted + + #endregion // SetCreationTime + + #region SetCreationTimeUtc + + /// Sets the date and time, in coordinated universal time (UTC), that the file was created. + /// The file for which to set the creation date and time information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in UTC time. + /// + [SecurityCritical] + public static void SetCreationTimeUtc(string path, DateTime creationTimeUtc) + { + SetFsoDateTimeCore(false, null, path, creationTimeUtc, null, null, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the file was created. + /// The file for which to set the creation date and time information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in UTC time. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetCreationTimeUtc(string path, DateTime creationTimeUtc, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, null, path, creationTimeUtc, null, null, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the file was created. + /// The file for which to set the creation date and time information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in UTC time. + /// + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetCreationTimeUtc(string path, DateTime creationTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, null, path, creationTimeUtc, null, null, modifyReparsePoint, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the file was created. + /// The transaction. + /// The file for which to set the creation date and time information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in UTC time. + /// + [SecurityCritical] + public static void SetCreationTimeUtcTransacted(KernelTransaction transaction, string path, DateTime creationTimeUtc) + { + SetFsoDateTimeCore(false, transaction, path, creationTimeUtc, null, null, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the file was created. + /// The transaction. + /// The file for which to set the creation date and time information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in UTC time. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetCreationTimeUtcTransacted(KernelTransaction transaction, string path, DateTime creationTimeUtc, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, transaction, path, creationTimeUtc, null, null, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the file was created. + /// The transaction. + /// The file for which to set the creation date and time information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in UTC time. + /// + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetCreationTimeUtcTransacted(KernelTransaction transaction, string path, DateTime creationTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, transaction, path, creationTimeUtc, null, null, modifyReparsePoint, pathFormat); + } + + #endregion // Transacted + + #endregion // SetCreationTimeUtc + + #region SetLastAccessTime + + /// Sets the date and time that the specified file was last accessed. + /// The file for which to set the access date and time information. + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in local time. + /// + [SecurityCritical] + public static void SetLastAccessTime(string path, DateTime lastAccessTime) + { + SetFsoDateTimeCore(false, null, path, null, lastAccessTime.ToUniversalTime(), null, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the date and time that the specified file was last accessed. + /// The file for which to set the access date and time information. + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in local time. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastAccessTime(string path, DateTime lastAccessTime, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, null, path, null, lastAccessTime.ToUniversalTime(), null, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time that the specified file was last accessed. + /// The file for which to set the access date and time information. + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in local time. + /// + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastAccessTime(string path, DateTime lastAccessTime, bool modifyReparsePoint, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, null, path, null, lastAccessTime.ToUniversalTime(), null, modifyReparsePoint, pathFormat); + } + + + #region Transaction + + /// [AlphaFS] Sets the date and time that the specified file was last accessed. + /// The transaction. + /// The file for which to set the access date and time information. + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in local time. + /// + [SecurityCritical] + public static void SetLastAccessTimeTransacted(KernelTransaction transaction, string path, DateTime lastAccessTime) + { + SetFsoDateTimeCore(false, transaction, path, null, lastAccessTime.ToUniversalTime(), null, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the date and time that the specified file was last accessed. + /// The transaction. + /// The file for which to set the access date and time information. + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in local time. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastAccessTimeTransacted(KernelTransaction transaction, string path, DateTime lastAccessTime, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, transaction, path, null, lastAccessTime.ToUniversalTime(), null, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time that the specified file was last accessed. + /// The transaction. + /// The file for which to set the access date and time information. + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in local time. + /// + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastAccessTimeTransacted(KernelTransaction transaction, string path, DateTime lastAccessTime, bool modifyReparsePoint, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, transaction, path, null, lastAccessTime.ToUniversalTime(), null, modifyReparsePoint, pathFormat); + } + + + #endregion // Transaction + + #endregion // SetLastAccessTime + + #region SetLastAccessTimeUtc + + /// Sets the date and time, in coordinated universal time (UTC), that the specified file was last accessed. + /// The file for which to set the access date and time information. + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in UTC time. + /// + [SecurityCritical] + public static void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc) + { + SetFsoDateTimeCore(false, null, path, null, lastAccessTimeUtc, null, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified file was last accessed. + /// The file for which to set the access date and time information. + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in UTC time. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, null, path, null, lastAccessTimeUtc, null, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified file was last accessed. + /// The file for which to set the access date and time information. + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in UTC time. + /// + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, null, path, null, lastAccessTimeUtc, null, modifyReparsePoint, pathFormat); + } + + + #region Transactional + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified file was last accessed. + /// The transaction. + /// The file for which to set the access date and time information. + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in UTC time. + /// + [SecurityCritical] + public static void SetLastAccessTimeUtcTransacted(KernelTransaction transaction, string path, DateTime lastAccessTimeUtc) + { + SetFsoDateTimeCore(false, transaction, path, null, lastAccessTimeUtc, null, false, PathFormat.RelativePath); + } + + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified file was last accessed. + /// The transaction. + /// The file for which to set the access date and time information. + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in UTC time. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastAccessTimeUtcTransacted(KernelTransaction transaction, string path, DateTime lastAccessTimeUtc, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, transaction, path, null, lastAccessTimeUtc, null, false, pathFormat); + } + + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified file was last accessed. + /// The transaction. + /// The file for which to set the access date and time information. + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in UTC time. + /// + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastAccessTimeUtcTransacted(KernelTransaction transaction, string path, DateTime lastAccessTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, transaction, path, null, lastAccessTimeUtc, null, modifyReparsePoint, pathFormat); + } + + + #endregion // Transacted + + #endregion // SetLastAccessTimeUtc + + #region SetLastWriteTime + + /// Sets the date and time that the specified file was last written to. + /// The file for which to set the date and time information. + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in local time. + /// + [SecurityCritical] + public static void SetLastWriteTime(string path, DateTime lastWriteTime) + { + SetFsoDateTimeCore(false, null, path, null, null, lastWriteTime.ToUniversalTime(), false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the date and time that the specified file was last written to. + /// The file for which to set the date and time information. + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in local time. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastWriteTime(string path, DateTime lastWriteTime, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, null, path, null, null, lastWriteTime.ToUniversalTime(), false, pathFormat); + } + + /// [AlphaFS] Sets the date and time that the specified file was last written to. + /// The file for which to set the date and time information. + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in local time. + /// + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastWriteTime(string path, DateTime lastWriteTime, bool modifyReparsePoint, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, null, path, null, null, lastWriteTime.ToUniversalTime(), modifyReparsePoint, pathFormat); + } + + #region Transactional + + /// [AlphaFS] Sets the date and time that the specified file was last written to. + /// The transaction. + /// The file for which to set the date and time information. + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in local time. + /// + [SecurityCritical] + public static void SetLastWriteTimeTransacted(KernelTransaction transaction, string path, DateTime lastWriteTime) + { + SetFsoDateTimeCore(false, transaction, path, null, null, lastWriteTime.ToUniversalTime(), false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets the date and time that the specified file was last written to. + /// The transaction. + /// The file for which to set the date and time information. + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in local time. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastWriteTimeTransacted(KernelTransaction transaction, string path, DateTime lastWriteTime, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, transaction, path, null, null, lastWriteTime.ToUniversalTime(), false, pathFormat); + } + + /// [AlphaFS] Sets the date and time that the specified file was last written to. + /// The transaction. + /// The file for which to set the date and time information. + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in local time. + /// + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastWriteTimeTransacted(KernelTransaction transaction, string path, DateTime lastWriteTime, bool modifyReparsePoint, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, transaction, path, null, null, lastWriteTime.ToUniversalTime(), modifyReparsePoint, pathFormat); + } + + + #endregion // Transacted + + #endregion // SetLastWriteTime + + #region SetLastWriteTimeUtc + + /// Sets the date and time, in coordinated universal time (UTC), that the specified file was last written to. + /// The file for which to set the date and time information. + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in UTC time. + /// + [SecurityCritical] + public static void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc) + { + SetFsoDateTimeCore(false, null, path, null, null, lastWriteTimeUtc, false, PathFormat.RelativePath); + } + + /// + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified file was last written to. + /// + /// The file for which to set the date and time information. + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in UTC time. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, null, path, null, null, lastWriteTimeUtc, false, pathFormat); + } + + /// + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified file was last written to. + /// + /// The file for which to set the date and time information. + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in UTC time. + /// + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, null, path, null, null, lastWriteTimeUtc, modifyReparsePoint, pathFormat); + } + + #region Transactional + + /// + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified file was last written to. + /// + /// The transaction. + /// The file for which to set the date and time information. + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in UTC time. + /// + [SecurityCritical] + public static void SetLastWriteTimeUtcTransacted(KernelTransaction transaction, string path, DateTime lastWriteTimeUtc) + { + SetFsoDateTimeCore(false, transaction, path, null, null, lastWriteTimeUtc, false, PathFormat.RelativePath); + } + + /// + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified file was last written to. + /// + /// The transaction. + /// The file for which to set the date and time information. + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in UTC time. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastWriteTimeUtcTransacted(KernelTransaction transaction, string path, DateTime lastWriteTimeUtc, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, transaction, path, null, null, lastWriteTimeUtc, false, pathFormat); + } + + /// + /// [AlphaFS] Sets the date and time, in coordinated universal time (UTC), that the specified file was last written to. + /// + /// The transaction. + /// The file for which to set the date and time information. + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in UTC time. + /// + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetLastWriteTimeUtcTransacted(KernelTransaction transaction, string path, DateTime lastWriteTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, transaction, path, null, null, lastWriteTimeUtc, modifyReparsePoint, pathFormat); + } + + + #endregion // Transacted + + + #endregion // SetLastWriteTimeUtc + + #region SetTimestamps + + /// [AlphaFS] Sets all the date and time stamps for the specified file, at once. + /// The file for which to set the dates and times information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in local time. + /// + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in local time. + /// + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in local time. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetTimestamps(string path, DateTime creationTime, DateTime lastAccessTime, DateTime lastWriteTime, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, null, path, creationTime.ToUniversalTime(), lastAccessTime.ToUniversalTime(), lastWriteTime.ToUniversalTime(), false, pathFormat); + } + + /// [AlphaFS] Sets all the date and time stamps for the specified file, at once. + /// The file for which to set the dates and times information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in local time. + /// + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in local time. + /// + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in local time. + /// + [SecurityCritical] + public static void SetTimestamps(string path, DateTime creationTime, DateTime lastAccessTime, DateTime lastWriteTime) + { + SetFsoDateTimeCore(false, null, path, creationTime.ToUniversalTime(), lastAccessTime.ToUniversalTime(), lastWriteTime.ToUniversalTime(), false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets all the date and time stamps for the specified file, at once. + /// The file for which to set the dates and times information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in local time. + /// + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in local time. + /// + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in local time. + /// + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetTimestamps(string path, DateTime creationTime, DateTime lastAccessTime, DateTime lastWriteTime, bool modifyReparsePoint, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, null, path, creationTime.ToUniversalTime(), lastAccessTime.ToUniversalTime(), lastWriteTime.ToUniversalTime(), modifyReparsePoint, pathFormat); + } + + /// [AlphaFS] Sets all the date and time stamps for the specified file, at once. + /// The transaction. + /// The file for which to set the dates and times information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in local time. + /// + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in local time. + /// + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in local time. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetTimestampsTransacted(KernelTransaction transaction, string path, DateTime creationTime, DateTime lastAccessTime, DateTime lastWriteTime, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, transaction, path, creationTime.ToUniversalTime(), lastAccessTime.ToUniversalTime(), lastWriteTime.ToUniversalTime(), false, pathFormat); + } + + /// [AlphaFS] Sets all the date and time stamps for the specified file, at once. + /// The transaction. + /// The file for which to set the dates and times information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in local time. + /// + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in local time. + /// + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in local time. + /// + [SecurityCritical] + public static void SetTimestampsTransacted(KernelTransaction transaction, string path, DateTime creationTime, DateTime lastAccessTime, DateTime lastWriteTime) + { + SetFsoDateTimeCore(false, transaction, path, creationTime.ToUniversalTime(), lastAccessTime.ToUniversalTime(), lastWriteTime.ToUniversalTime(), false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets all the date and time stamps for the specified file, at once. + /// The transaction. + /// The file for which to set the dates and times information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in local time. + /// + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in local time. + /// + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in local time. + /// + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetTimestampsTransacted(KernelTransaction transaction, string path, DateTime creationTime, DateTime lastAccessTime, DateTime lastWriteTime, bool modifyReparsePoint, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, transaction, path, creationTime.ToUniversalTime(), lastAccessTime.ToUniversalTime(), lastWriteTime.ToUniversalTime(), modifyReparsePoint, pathFormat); + } + + #endregion // SetTimestamps + + #region SetTimestampsUtc + + /// [AlphaFS] Sets all the date and time stamps, in coordinated universal time (UTC), for the specified file, at once. + /// The file for which to set the dates and times information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in UTC time. + /// + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in UTC time. + /// + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in UTC time. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetTimestampsUtc(string path, DateTime creationTimeUtc, DateTime lastAccessTimeUtc, DateTime lastWriteTimeUtc, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, null, path, creationTimeUtc, lastAccessTimeUtc, lastWriteTimeUtc, false, pathFormat); + } + + /// [AlphaFS] Sets all the date and time stamps, in coordinated universal time (UTC), for the specified file, at once. + /// The file for which to set the dates and times information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in UTC time. + /// + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in UTC time. + /// + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in UTC time. + /// + [SecurityCritical] + public static void SetTimestampsUtc(string path, DateTime creationTimeUtc, DateTime lastAccessTimeUtc, DateTime lastWriteTimeUtc) + { + SetFsoDateTimeCore(false, null, path, creationTimeUtc, lastAccessTimeUtc, lastWriteTimeUtc, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets all the date and time stamps, in coordinated universal time (UTC), for the specified file, at once. + /// The file for which to set the dates and times information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in UTC time. + /// + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in UTC time. + /// + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in UTC time. + /// + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetTimestampsUtc(string path, DateTime creationTimeUtc, DateTime lastAccessTimeUtc, DateTime lastWriteTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, null, path, creationTimeUtc, lastAccessTimeUtc, lastWriteTimeUtc, modifyReparsePoint, pathFormat); + } + + /// [AlphaFS] Sets all the date and time stamps, in coordinated universal time (UTC), for the specified file, at once. + /// The transaction. + /// The file for which to set the dates and times information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in UTC time. + /// + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in UTC time. + /// + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in UTC time. + /// + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetTimestampsUtcTransacted(KernelTransaction transaction, string path, DateTime creationTimeUtc, DateTime lastAccessTimeUtc, DateTime lastWriteTimeUtc, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, transaction, path, creationTimeUtc, lastAccessTimeUtc, lastWriteTimeUtc, false, pathFormat); + } + + /// [AlphaFS] Sets all the date and time stamps, in coordinated universal time (UTC), for the specified file, at once. + /// The transaction. + /// The file for which to set the dates and times information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in UTC time. + /// + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in UTC time. + /// + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in UTC time. + /// + [SecurityCritical] + public static void SetTimestampsUtcTransacted(KernelTransaction transaction, string path, DateTime creationTimeUtc, DateTime lastAccessTimeUtc, DateTime lastWriteTimeUtc) + { + SetFsoDateTimeCore(false, transaction, path, creationTimeUtc, lastAccessTimeUtc, lastWriteTimeUtc, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Sets all the date and time stamps, in coordinated universal time (UTC), for the specified file, at once. + /// The transaction. + /// The file for which to set the dates and times information. + /// + /// A containing the value to set for the creation date and time of . This value + /// is expressed in UTC time. + /// + /// + /// A containing the value to set for the last access date and time of . This + /// value is expressed in UTC time. + /// + /// + /// A containing the value to set for the last write date and time of . This value + /// is expressed in UTC time. + /// + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void SetTimestampsUtcTransacted(KernelTransaction transaction, string path, DateTime creationTimeUtc, DateTime lastAccessTimeUtc, DateTime lastWriteTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + SetFsoDateTimeCore(false, transaction, path, creationTimeUtc, lastAccessTimeUtc, lastWriteTimeUtc, modifyReparsePoint, pathFormat); + } + + #endregion // SetTimestampsUtc + + #region Internal Methods + + /// Set the date and time, in coordinated universal time (UTC), that the file or directory was created and/or last accessed and/or written to. + /// + /// + /// Specifies that is a file or directory. + /// The transaction. + /// The file or directory for which to set the date and time information. + /// A containing the value to set for the creation date and time of . This value is expressed in UTC time. + /// A containing the value to set for the last access date and time of . This value is expressed in UTC time. + /// A containing the value to set for the last write date and time of . This value is expressed in UTC time. + /// If , the date and time information will apply to the reparse point (symlink or junction) and not the file or directory linked to. No effect if does not refer to a reparse point. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static void SetFsoDateTimeCore(bool isFolder, KernelTransaction transaction, string path, DateTime? creationTimeUtc, DateTime? lastAccessTimeUtc, DateTime? lastWriteTimeUtc, bool modifyReparsePoint, PathFormat pathFormat) + { + // Because we already check here, use false for CreateFileCore() to prevent another check. + if (pathFormat == PathFormat.RelativePath) + Path.CheckSupportedPathFormat(path, false, false); + + var attributes = isFolder ? ExtendedFileAttributes.BackupSemantics : ExtendedFileAttributes.Normal; + + if (modifyReparsePoint) + attributes |= ExtendedFileAttributes.OpenReparsePoint; + + using (var creationTime = SafeGlobalMemoryBufferHandle.FromLong(creationTimeUtc.HasValue ? creationTimeUtc.Value.ToFileTimeUtc() : (long?)null)) + using (var lastAccessTime = SafeGlobalMemoryBufferHandle.FromLong(lastAccessTimeUtc.HasValue ? lastAccessTimeUtc.Value.ToFileTimeUtc() : (long?)null)) + using (var lastWriteTime = SafeGlobalMemoryBufferHandle.FromLong(lastWriteTimeUtc.HasValue ? lastWriteTimeUtc.Value.ToFileTimeUtc() : (long?)null)) + using (var safeHandle = CreateFileCore(transaction, path, attributes, null, FileMode.Open, FileSystemRights.WriteAttributes, FileShare.Delete | FileShare.Write, false, pathFormat)) + if (!NativeMethods.SetFileTime(safeHandle, creationTime, lastAccessTime, lastWriteTime)) + NativeError.ThrowException(path); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.TransferTimestamps.cs b/AlphaFS/Filesystem/File Class/File.TransferTimestamps.cs new file mode 100644 index 0000000..7e54d41 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.TransferTimestamps.cs @@ -0,0 +1,100 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region TransferTimestamps + + /// [AlphaFS] Transfers the date and time stamps for the specified files. + /// This method does not change last access time for the source file. + /// The source file to get the date and time stamps from. + /// The destination file to set the date and time stamps. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void TransferTimestamps(string sourcePath, string destinationPath, PathFormat pathFormat) + { + TransferTimestampsCore(false, null, sourcePath, destinationPath, pathFormat); + } + + /// [AlphaFS] Transfers the date and time stamps for the specified files. + /// This method does not change last access time for the source file. + /// The source file to get the date and time stamps from. + /// The destination file to set the date and time stamps. + [SecurityCritical] + public static void TransferTimestamps(string sourcePath, string destinationPath) + { + TransferTimestampsCore(false, null, sourcePath, destinationPath, PathFormat.RelativePath); + } + + /// [AlphaFS] Transfers the date and time stamps for the specified files. + /// This method does not change last access time for the source file. + /// The transaction. + /// The source file to get the date and time stamps from. + /// The destination file to set the date and time stamps. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void TransferTimestampsTransacted(KernelTransaction transaction, string sourcePath, string destinationPath, PathFormat pathFormat) + { + TransferTimestampsCore(false, transaction, sourcePath, destinationPath, pathFormat); + } + + /// [AlphaFS] Transfers the date and time stamps for the specified files. + /// This method does not change last access time for the source file. + /// The transaction. + /// The source file to get the date and time stamps from. + /// The destination file to set the date and time stamps. + [SecurityCritical] + public static void TransferTimestampsTransacted(KernelTransaction transaction, string sourcePath, string destinationPath) + { + TransferTimestampsCore(false, transaction, sourcePath, destinationPath, PathFormat.RelativePath); + } + + + #endregion // TransferTimestamps + + #region Internal Methods + + /// Transfer the date and time stamps for the specified files and directories. + /// + /// This method does not change last access time for the source file. + /// This method uses BackupSemantics flag to get Timestamp changed for directories. + /// + /// Specifies that and are a file or directory. + /// The transaction. + /// The source path. + /// The destination path. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + internal static void TransferTimestampsCore(bool isFolder, KernelTransaction transaction, string sourcePath, string destinationPath, PathFormat pathFormat) + { + NativeMethods.WIN32_FILE_ATTRIBUTE_DATA attrs = GetAttributesExCore(transaction, sourcePath, pathFormat, true); + + SetFsoDateTimeCore(isFolder, transaction, destinationPath, DateTime.FromFileTimeUtc(attrs.ftCreationTime), DateTime.FromFileTimeUtc(attrs.ftLastAccessTime), DateTime.FromFileTimeUtc(attrs.ftLastWriteTime), false, pathFormat); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.WriteAllBytes.cs b/AlphaFS/Filesystem/File Class/File.WriteAllBytes.cs new file mode 100644 index 0000000..c12c28f --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.WriteAllBytes.cs @@ -0,0 +1,119 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; +using FileStream = System.IO.FileStream; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region WriteAllBytes + + /// + /// Creates a new file, writes the specified byte array to the file, and then closes the file. If the target file already exists, it is + /// overwritten. + /// + /// The file to write to. + /// The bytes to write to the file. + [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "bytes")] + [SecurityCritical] + public static void WriteAllBytes(string path, byte[] bytes) + { + WriteAllBytesCore(null, path, bytes, PathFormat.RelativePath); + } + + /// + /// [AlphaFS] Creates a new file, writes the specified byte array to the file, and then closes the file. If the target file already + /// exists, it is overwritten. + /// + /// The file to write to. + /// The bytes to write to the file. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "bytes")] + [SecurityCritical] + public static void WriteAllBytes(string path, byte[] bytes, PathFormat pathFormat) + { + WriteAllBytesCore(null, path, bytes, pathFormat); + } + + #region Transactional + + /// + /// [AlphaFS] Creates a new file, writes the specified byte array to the file, and then closes the file. If the target file already + /// exists, it is overwritten. + /// + /// The transaction. + /// The file to write to. + /// The bytes to write to the file. + [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "bytes")] + [SecurityCritical] + public static void WriteAllBytesTransacted(KernelTransaction transaction, string path, byte[] bytes) + { + WriteAllBytesCore(transaction, path, bytes, PathFormat.RelativePath); + } + + /// + /// [AlphaFS] Creates a new file, writes the specified byte array to the file, and then closes the file. If the target file already + /// exists, it is overwritten. + /// + /// The transaction. + /// The file to write to. + /// The bytes to write to the file. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "bytes")] + [SecurityCritical] + public static void WriteAllBytesTransacted(KernelTransaction transaction, string path, byte[] bytes, PathFormat pathFormat) + { + WriteAllBytesCore(transaction, path, bytes, pathFormat); + } + + #endregion // Transacted + + #endregion // WriteAllBytes + + #region Internal Methods + + /// Creates a new file as part of a transaction, writes the specified byte array to + /// the file, and then closes the file. If the target file already exists, it is overwritten. + /// + /// + /// The transaction. + /// The file to write to. + /// The bytes to write to the file. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "bytes")] + [SecurityCritical] + internal static void WriteAllBytesCore(KernelTransaction transaction, string path, byte[] bytes, PathFormat pathFormat) + { + if (bytes == null) + throw new ArgumentNullException("bytes"); + + using (FileStream fs = OpenCore(transaction, path, FileMode.Create, FileAccess.Write, FileShare.Read, ExtendedFileAttributes.Normal, null, null, pathFormat)) + fs.Write(bytes, 0, bytes.Length); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/File Class/File.WriteText.cs b/AlphaFS/Filesystem/File Class/File.WriteText.cs new file mode 100644 index 0000000..29be618 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.WriteText.cs @@ -0,0 +1,1009 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; +using System.Security.AccessControl; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class File + { + #region AppendAllLines + + #region .NET + + /// Appends lines to a file, and then closes the file. If the specified file does not exist, this method creates a file, writes the + /// specified lines to the file, and then closes the file. + /// + /// + /// The method creates the file if it doesn't exist, but it doesn't create new directories. Therefore, the value of the path parameter + /// must contain existing directories. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to append the lines to. The file is created if it doesn't already exist. + /// The lines to append to the file. + [SecurityCritical] + public static void AppendAllLines(string path, IEnumerable contents) + { + WriteAppendAllLinesCore(null, path, contents, NativeMethods.DefaultFileEncoding, true, true, PathFormat.RelativePath); + } + + /// Appends lines to a file, and then closes the file. If the specified file does not exist, this method creates a file, writes the + /// specified lines to the file, and then closes the file. + /// + /// + /// The method creates the file if it doesn't exist, but it doesn't create new directories. Therefore, the value of the path parameter + /// must contain existing directories. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to append the lines to. The file is created if it doesn't already exist. + /// The lines to append to the file. + /// The character to use. + [SecurityCritical] + public static void AppendAllLines(string path, IEnumerable contents, Encoding encoding) + { + WriteAppendAllLinesCore(null, path, contents, encoding, true, false, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Appends lines to a file, and then closes the file. If the specified file does not exist, this method creates a file, + /// writes the specified lines to the file, and then closes the file. + /// + /// + /// The method creates the file if it doesn't exist, but it doesn't create new directories. Therefore, the value of the path parameter + /// must contain existing directories. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to append the lines to. The file is created if it doesn't already exist. + /// The lines to append to the file. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void AppendAllLines(string path, IEnumerable contents, PathFormat pathFormat) + { + WriteAppendAllLinesCore(null, path, contents, NativeMethods.DefaultFileEncoding, true, false, pathFormat); + } + + /// [AlphaFS] Appends lines to a file, and then closes the file. If the specified file does not + /// exist, this method creates a file, writes the specified lines to the file, and then closes + /// the file. + /// + /// + /// The method creates the file if it doesn't exist, but it doesn't create new directories. + /// Therefore, the value of the path parameter must contain existing directories. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to append the lines to. The file is created if it doesn't already exist. + /// + /// The lines to append to the file. + /// The character to use. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void AppendAllLines(string path, IEnumerable contents, Encoding encoding, PathFormat pathFormat) + { + WriteAppendAllLinesCore(null, path, contents, encoding, true, false, pathFormat); + } + + #region Transactional + + #region .NET + + /// [AlphaFS] Appends lines to a file, and then closes the file. If the specified file does not exist, this method creates a file, + /// writes the specified lines to the file, and then closes the file. + /// + /// + /// The method creates the file if it doesn't exist, but it doesn't create new directories. Therefore, the value of the path parameter + /// must contain existing directories. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to append the lines to. The file is created if it doesn't already exist. + /// The lines to append to the file. + [SecurityCritical] + public static void AppendAllLinesTransacted(KernelTransaction transaction, string path, IEnumerable contents) + { + WriteAppendAllLinesCore(transaction, path, contents, NativeMethods.DefaultFileEncoding, true, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Appends lines to a file, and then closes the file. If the specified file does not exist, this method creates a file, + /// writes the specified lines to the file, and then closes the file. + /// + /// + /// The method creates the file if it doesn't exist, but it doesn't create new directories. Therefore, the value of the path parameter + /// must contain existing directories. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to append the lines to. The file is created if it doesn't already exist. + /// The lines to append to the file. + /// The character to use. + [SecurityCritical] + public static void AppendAllLinesTransacted(KernelTransaction transaction, string path, IEnumerable contents, Encoding encoding) + { + WriteAppendAllLinesCore(transaction, path, contents, encoding, true, false, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Appends lines to a file, and then closes the file. If the specified file does not exist, this method creates a file, writes the + /// specified lines to the file, and then closes the file. + /// + /// + /// The method creates the file if it doesn't exist, but it doesn't create new directories. Therefore, the value of the path parameter + /// must contain existing directories. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to append the lines to. The file is created if it doesn't already exist. + /// The lines to append to the file. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void AppendAllLinesTransacted(KernelTransaction transaction, string path, IEnumerable contents, PathFormat pathFormat) + { + WriteAppendAllLinesCore(transaction, path, contents, NativeMethods.DefaultFileEncoding, true, false, pathFormat); + } + + /// [AlphaFS] Appends lines to a file, and then closes the file. If the specified file does not exist, this method creates a file, + /// writes the specified lines to the file, and then closes the file. + /// + /// + /// The method creates the file if it doesn't exist, but it doesn't create new directories. Therefore, the value of the path parameter + /// must contain existing directories. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to append the lines to. The file is created if it doesn't already exist. + /// The lines to append to the file. + /// The character to use. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void AppendAllLinesTransacted(KernelTransaction transaction, string path, IEnumerable contents, Encoding encoding, PathFormat pathFormat) + { + WriteAppendAllLinesCore(transaction, path, contents, encoding, true, false, pathFormat); + } + + #endregion // Transactional + + #endregion // AppendAllLines + + #region AppendAllText + + #region .NET + + /// Appends the specified stringto the file, creating the file if it does not already exist. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to append the specified string to. + /// The string to append to the file. + [SecurityCritical] + public static void AppendAllText(string path, string contents) + { + WriteAppendAllLinesCore(null, path, new[] { contents }, NativeMethods.DefaultFileEncoding, true, false, PathFormat.RelativePath); + } + + /// Appends the specified string to the file, creating the file if it does not already exist. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to append the specified string to. + /// The string to append to the file. + /// The character to use. + [SecurityCritical] + public static void AppendAllText(string path, string contents, Encoding encoding) + { + WriteAppendAllLinesCore(null, path, new[] { contents }, encoding, true, false, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Appends the specified stringto the file, creating the file if it does not already exist. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to append the specified string to. + /// The string to append to the file. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void AppendAllText(string path, string contents, PathFormat pathFormat) + { + WriteAppendAllLinesCore(null, path, new[] { contents }, NativeMethods.DefaultFileEncoding, true, false, pathFormat); + } + + /// [AlphaFS] Appends the specified string to the file, creating the file if it does not already exist. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to append the specified string to. + /// The string to append to the file. + /// The character to use. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void AppendAllText(string path, string contents, Encoding encoding, PathFormat pathFormat) + { + WriteAppendAllLinesCore(null, path, new[] { contents }, encoding, true, false, pathFormat); + } + + #region Transactional + + #region .NET + + /// [AlphaFS] Appends the specified stringto the file, creating the file if it does not already exist. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to append the specified string to. + /// The string to append to the file. + [SecurityCritical] + public static void AppendAllTextTransacted(KernelTransaction transaction, string path, string contents) + { + WriteAppendAllLinesCore(transaction, path, new[] { contents }, NativeMethods.DefaultFileEncoding, true, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Appends the specified string to the file, creating the file if it does not already exist. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to append the specified string to. + /// The string to append to the file. + /// The character to use. + [SecurityCritical] + public static void AppendAllTextTransacted(KernelTransaction transaction, string path, string contents, Encoding encoding) + { + WriteAppendAllLinesCore(transaction, path, new[] { contents }, encoding, true, false, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Appends the specified stringto the file, creating the file if it does not already exist. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to append the specified string to. + /// The string to append to the file. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void AppendAllTextTransacted(KernelTransaction transaction, string path, string contents, PathFormat pathFormat) + { + WriteAppendAllLinesCore(transaction, path, new[] { contents }, NativeMethods.DefaultFileEncoding, true, false, pathFormat); + } + + /// [AlphaFS] Appends the specified string to the file, creating the file if it does not already exist. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to append the specified string to. + /// The string to append to the file. + /// The character to use. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void AppendAllTextTransacted(KernelTransaction transaction, string path, string contents, Encoding encoding, PathFormat pathFormat) + { + WriteAppendAllLinesCore(transaction, path, new[] { contents }, encoding, true, false, pathFormat); + } + + #endregion // Transactional + + #endregion // AppendAllText + + #region WriteAllLines + + #region .NET + + /// Creates a new file, writes a collection of strings to the file, and then closes the file. + /// The default behavior of the method is to write out data by using UTF-8 encoding without a byte order mark (BOM). + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to write to. + /// The lines to write to the file. + [SecurityCritical] + public static void WriteAllLines(string path, IEnumerable contents) + { + WriteAppendAllLinesCore(null, path, contents, new UTF8Encoding(false, true), false, true, PathFormat.RelativePath); + } + + /// Creates a new file by using the specified encoding, writes a collection of strings to the file, and then closes the file. + /// The file to write to. + /// The string array to write to the file. + [SecurityCritical] + public static void WriteAllLines(string path, string[] contents) + { + WriteAppendAllLinesCore(null, path, contents, new UTF8Encoding(false, true), false, true, PathFormat.RelativePath); + } + + /// Creates a new file by using the specified encoding, writes a collection of strings to the file, and then closes the file. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to write to. + /// The lines to write to the file. + /// The character to use. + [SecurityCritical] + public static void WriteAllLines(string path, IEnumerable contents, Encoding encoding) + { + WriteAppendAllLinesCore(null, path, contents, encoding, false, true, PathFormat.RelativePath); + } + + /// Creates a new file by using the specified encoding, writes a collection of strings to the file, and then closes the file. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to write to. + /// The string array to write to the file. + /// The character to use. + [SecurityCritical] + public static void WriteAllLines(string path, string[] contents, Encoding encoding) + { + WriteAppendAllLinesCore(null, path, contents, encoding, false, true, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Creates a new file, writes a collection of strings to the file, and then closes the file. + /// The default behavior of the method is to write out data by using UTF-8 encoding without a byte order mark (BOM). + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to write to. + /// The lines to write to the file. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void WriteAllLines(string path, IEnumerable contents, PathFormat pathFormat) + { + WriteAppendAllLinesCore(null, path, contents, new UTF8Encoding(false, true), false, true, pathFormat); + } + + /// [AlphaFS] Creates a new file by using the specified encoding, writes a collection of strings to the file, and then closes the file. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to write to. + /// The string array to write to the file. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void WriteAllLines(string path, string[] contents, PathFormat pathFormat) + { + WriteAppendAllLinesCore(null, path, contents, new UTF8Encoding(false, true), false, true, pathFormat); + } + + /// [AlphaFS] Creates a new file by using the specified encoding, writes a collection of strings to the file, and then closes the file. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to write to. + /// The lines to write to the file. + /// The character to use. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void WriteAllLines(string path, IEnumerable contents, Encoding encoding, PathFormat pathFormat) + { + WriteAppendAllLinesCore(null, path, contents, encoding, false, true, pathFormat); + } + + /// [AlphaFS] Creates a new file by using the specified encoding, writes a collection of strings to the file, and then closes the file. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to write to. + /// The string array to write to the file. + /// The character to use. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void WriteAllLines(string path, string[] contents, Encoding encoding, PathFormat pathFormat) + { + WriteAppendAllLinesCore(null, path, contents, encoding, false, true, pathFormat); + } + + #region Transactional + + #region .NET + + /// [AlphaFS] Creates a new file, writes a collection of strings to the file, and then closes the file. + /// The default behavior of the method is to write out data by using UTF-8 encoding without a byte order mark (BOM). + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to write to. + /// The lines to write to the file. + [SecurityCritical] + public static void WriteAllLinesTransacted(KernelTransaction transaction, string path, IEnumerable contents) + { + WriteAppendAllLinesCore(transaction, path, contents, new UTF8Encoding(false, true), false, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates a new file, writes a collection of strings to the file, and then closes the file. + /// The default behavior of the method is to write out data by using UTF-8 encoding without a byte order mark (BOM). + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to write to. + /// The string array to write to the file. + [SecurityCritical] + public static void WriteAllLinesTransacted(KernelTransaction transaction, string path, string[] contents) + { + WriteAppendAllLinesCore(transaction, path, contents, new UTF8Encoding(false, true), false, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates a new file by using the specified encoding, writes a collection of strings to the file, and then closes the file. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to write to. + /// The lines to write to the file. + /// The character to use. + [SecurityCritical] + public static void WriteAllLinesTransacted(KernelTransaction transaction, string path, IEnumerable contents, Encoding encoding) + { + WriteAppendAllLinesCore(transaction, path, contents, encoding, false, true, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates a new file by using the specified encoding, writes a collection of strings to the file, and then closes the file. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to write to. + /// The string array to write to the file. + /// The character to use. + [SecurityCritical] + public static void WriteAllLinesTransacted(KernelTransaction transaction, string path, string[] contents, Encoding encoding) + { + WriteAppendAllLinesCore(transaction, path, contents, encoding, false, true, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Creates a new file, writes a collection of strings to the file, and then closes the file. + /// The default behavior of the method is to write out data by using UTF-8 encoding without a byte order mark (BOM). + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to write to. + /// The lines to write to the file. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void WriteAllLinesTransacted(KernelTransaction transaction, string path, IEnumerable contents, PathFormat pathFormat) + { + WriteAppendAllLinesCore(transaction, path, contents, new UTF8Encoding(false, true), false, true, pathFormat); + } + + /// [AlphaFS] Creates a new file by using the specified encoding, writes a collection of strings to the file, and then closes the file. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to write to. + /// The string array to write to the file. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void WriteAllLinesTransacted(KernelTransaction transaction, string path, string[] contents, PathFormat pathFormat) + { + WriteAppendAllLinesCore(transaction, path, contents, new UTF8Encoding(false, true), false, true, pathFormat); + } + + /// [AlphaFS] Creates a new file by using the specified encoding, writes a collection of strings to the file, and then closes the file. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to write to. + /// The lines to write to the file. + /// The character to use. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void WriteAllLinesTransacted(KernelTransaction transaction, string path, IEnumerable contents, Encoding encoding, PathFormat pathFormat) + { + WriteAppendAllLinesCore(transaction, path, contents, encoding, false, true, pathFormat); + } + + /// [AlphaFS] Creates a new file by using the specified encoding, writes a collection of strings to the file, and then closes the file. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to write to. + /// The string array to write to the file. + /// The character to use. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void WriteAllLinesTransacted(KernelTransaction transaction, string path, string[] contents, Encoding encoding, PathFormat pathFormat) + { + WriteAppendAllLinesCore(transaction, path, contents, encoding, false, true, pathFormat); + } + + #endregion // Transactional + + #endregion // WriteAllLines + + #region WriteAllText + + #region .NET + + /// Creates a new file, writes the specified string to the file, and then closes the file. If the target file already exists, it is overwritten. + /// This method uses UTF-8 encoding without a Byte-Order Mark (BOM) + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to write to. + /// The string to write to the file. + [SecurityCritical] + public static void WriteAllText(string path, string contents) + { + WriteAppendAllLinesCore(null, path, new[] { contents }, new UTF8Encoding(false, true), false, false, PathFormat.RelativePath); + } + + /// Creates a new file, writes the specified string to the file using the specified encoding, and then closes the file. If the target file already exists, it is overwritten. + /// The file to write to. + /// The string to write to the file. + /// The applied to the contents of the file. + [SecurityCritical] + public static void WriteAllText(string path, string contents, Encoding encoding) + { + WriteAppendAllLinesCore(null, path, new[] { contents }, encoding, false, false, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Creates a new file, writes the specified string to the file, and then closes the file. If the target file already exists, it is overwritten. + /// This method uses UTF-8 encoding without a Byte-Order Mark (BOM) + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to write to. + /// The string to write to the file. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void WriteAllText(string path, string contents, PathFormat pathFormat) + { + WriteAppendAllLinesCore(null, path, new[] { contents }, new UTF8Encoding(false, true), false, false, pathFormat); + } + + /// [AlphaFS] Creates a new file, writes the specified string to the file using the specified encoding, and then closes the file. If the target file already exists, it is overwritten. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The file to write to. + /// The string to write to the file. + /// The applied to the contents of the file. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void WriteAllText(string path, string contents, Encoding encoding, PathFormat pathFormat) + { + WriteAppendAllLinesCore(null, path, new[] { contents }, encoding, false, false, pathFormat); + } + + #region Transactional + + #region .NET + + /// [AlphaFS] Creates a new file as part of a transaction, write the contents to the file, and then closes the file. If the target file already exists, it is overwritten. + /// This method uses UTF-8 encoding without a Byte-Order Mark (BOM) + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to write to. + /// The string to write to the file. + [SecurityCritical] + public static void WriteAllTextTransacted(KernelTransaction transaction, string path, string contents) + { + WriteAppendAllLinesCore(transaction, path, new[] { contents }, new UTF8Encoding(false, true), false, false, PathFormat.RelativePath); + } + + /// [AlphaFS] Creates a new file as part of a transaction, writes the specified string to the file using the specified encoding, and then closes the file. If the target file already exists, it is overwritten. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to write to. + /// The string to write to the file. + /// The applied to the contents of the file. + [SecurityCritical] + public static void WriteAllTextTransacted(KernelTransaction transaction, string path, string contents, Encoding encoding) + { + WriteAppendAllLinesCore(transaction, path, new[] { contents }, encoding, false, false, PathFormat.RelativePath); + } + + #endregion // .NET + + /// [AlphaFS] Creates a new file as part of a transaction, write the contents to the file, and then closes the file. If the target file already exists, it is overwritten. + /// This method uses UTF-8 encoding without a Byte-Order Mark (BOM) + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to write to. + /// The string to write to the file. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void WriteAllTextTransacted(KernelTransaction transaction, string path, string contents, PathFormat pathFormat) + { + WriteAppendAllLinesCore(transaction, path, new[] { contents }, new UTF8Encoding(false, true), false, false, pathFormat); + } + + /// [AlphaFS] Creates a new file as part of a transaction, writes the specified string to the file using the specified encoding, and then closes the file. If the target file already exists, it is overwritten. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to write to. + /// The string to write to the file. + /// The applied to the contents of the file. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public static void WriteAllTextTransacted(KernelTransaction transaction, string path, string contents, Encoding encoding, PathFormat pathFormat) + { + WriteAppendAllLinesCore(transaction, path, new[] { contents }, encoding, false, false, pathFormat); + } + + #endregion // Transactional + + #endregion // WriteAllText + + #region Internal Method + + /// Creates/appends a new file by using the specified encoding, writes a collection of strings to the file, and then closes the file. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The transaction. + /// The file to write to. + /// The lines to write to the file. + /// The character to use. + /// for file Append, for file Write. + /// to a line terminator, to ommit the line terminator. + /// Indicates the format of the path parameter(s). + [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Disposing is controlled.")] + [SecurityCritical] + internal static void WriteAppendAllLinesCore(KernelTransaction transaction, string path, IEnumerable contents, Encoding encoding, bool isAppend, bool addNewLine, PathFormat pathFormat) + { + if (contents == null) + throw new ArgumentNullException("contents"); + + if (encoding == null) + throw new ArgumentNullException("encoding"); + + + using (FileStream stream = OpenCore(transaction, path, (isAppend ? FileMode.OpenOrCreate : FileMode.Create), FileSystemRights.AppendData, FileShare.ReadWrite, ExtendedFileAttributes.Normal, null, null, pathFormat)) + { + if (isAppend) + stream.Seek(0, SeekOrigin.End); + + using (var writer = new StreamWriter(stream, encoding)) + { + if (addNewLine) + foreach (string line in contents) + writer.WriteLine(line); + + else + foreach (string line in contents) + writer.Write(line); + } + } + } + + #endregion // Method + } +} diff --git a/AlphaFS/Filesystem/File Class/File.cs b/AlphaFS/Filesystem/File Class/File.cs new file mode 100644 index 0000000..27ac688 --- /dev/null +++ b/AlphaFS/Filesystem/File Class/File.cs @@ -0,0 +1,34 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Provides static methods for the creation, copying, deletion, moving, and opening of files, and aids in the creation of objects. + /// This class cannot be inherited. + /// + [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")] + public static partial class File + { + // This file only exists for the documentation. + } +} diff --git a/AlphaFS/Filesystem/FileIdBothDirectoryInfo.cs b/AlphaFS/Filesystem/FileIdBothDirectoryInfo.cs new file mode 100644 index 0000000..f9dae48 --- /dev/null +++ b/AlphaFS/Filesystem/FileIdBothDirectoryInfo.cs @@ -0,0 +1,204 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Contains information about files in the specified directory. Used for directory handles. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dir")] + [Serializable] + [SecurityCritical] + public sealed class FileIdBothDirectoryInfo + { + #region Constructor + + #region FileIdBothDirectoryInfo + + internal FileIdBothDirectoryInfo(NativeMethods.FILE_ID_BOTH_DIR_INFO fibdi, string fileName) + { + CreationTimeUtc = DateTime.FromFileTimeUtc(fibdi.CreationTime); + LastAccessTimeUtc = DateTime.FromFileTimeUtc(fibdi.LastAccessTime); + LastWriteTimeUtc = DateTime.FromFileTimeUtc(fibdi.LastWriteTime); + ChangeTimeUtc = DateTime.FromFileTimeUtc(fibdi.ChangeTime); + + AllocationSize = fibdi.AllocationSize; + EndOfFile = fibdi.EndOfFile; + ExtendedAttributesSize = fibdi.EaSize; + + FileAttributes = fibdi.FileAttributes; + FileId = fibdi.FileId; + FileIndex = fibdi.FileIndex; + FileName = fileName; + + // ShortNameLength is the number of bytes in the short name; since we have a unicode string we must divide that by 2. + ShortName = new string(fibdi.ShortName, 0, fibdi.ShortNameLength / 2); + } + + #endregion // FileIdBothDirectoryInfo + + #endregion // Constructor + + #region Properties + + #region AllocationSize + + /// The number of bytes that are allocated for the file. This value is usually a multiple of the sector or cluster size of the underlying physical device. + public long AllocationSize { get; set; } + + #endregion // AllocationSize + + #region ChangeTime + + /// Gets the time this entry was changed. + /// The time this entry was changed. + public DateTime ChangeTime + { + get { return ChangeTimeUtc.ToLocalTime(); } + } + + #endregion // ChangeTime + + #region ChangeTimeUtc + + /// Gets the time, in coordinated universal time (UTC), this entry was changed. + /// The time, in coordinated universal time (UTC), this entry was changed. + public DateTime ChangeTimeUtc { get; set; } + + #endregion // ChangeTimeUtc + + #region CreationTime + + /// Gets the time this entry was created. + /// The time this entry was created. + public DateTime CreationTime + { + get { return CreationTimeUtc.ToLocalTime(); } + } + + #endregion // CreationTime + + #region CreationTimeUtc + + /// Gets the time, in coordinated universal time (UTC), this entry was created. + /// The time, in coordinated universal time (UTC), this entry was created. + public DateTime CreationTimeUtc { get; set; } + + #endregion // CreationTimeUtc + + #region EaSize + + /// The size of the extended attributes for the file. + public int ExtendedAttributesSize { get; set; } + + #endregion // EaSize + + #region EndOfFile + + /// The absolute new end-of-file position as a byte offset from the start of the file to the end of the file. + /// Because this value is zero-based, it actually refers to the first free byte in the file. In other words, EndOfFile is the offset to + /// the byte that immediately follows the last valid byte in the file. + /// + public long EndOfFile { get; set; } + + #endregion // EndOfFile + + #region FileAttributes + + /// The file attributes. + public FileAttributes FileAttributes { get; set; } + + #endregion FileAttributes + + #region FileId + + /// The file ID. + public long FileId { get; set; } + + #endregion // FileId + + #region FileIndex + + /// The byte offset of the file within the parent directory. This member is undefined for file systems, such as NTFS, + /// in which the position of a file within the parent directory is not fixed and can be changed at any time to maintain sort order. + /// + public long FileIndex { get; set; } + + #endregion // FileIndex + + #region FileName + + /// The name of the file. + public string FileName { get; set; } + + #endregion // FileName + + #region LastAccessTime + + /// Gets the time this entry was last accessed. + /// The time this entry was last accessed. + public DateTime LastAccessTime + { + get { return LastAccessTimeUtc.ToLocalTime(); } + } + + #endregion // LastAccessTime + + #region LastAccessTimeUtc + + /// Gets the time, in coordinated universal time (UTC), this entry was last accessed. + /// The time, in coordinated universal time (UTC), this entry was last accessed. + public DateTime LastAccessTimeUtc { get; set; } + + #endregion // LastAccessTimeUtc + + #region LastWriteTime + + /// Gets the time this entry was last modified. + /// The time this entry was last modified. + public DateTime LastWriteTime + { + get { return LastWriteTimeUtc.ToLocalTime(); } + } + + #endregion // LastWriteTime + + #region LastWriteTimeUtc + + /// Gets the time, in coordinated universal time (UTC), this entry was last modified. + /// The time, in coordinated universal time (UTC), this entry was last modified. + public DateTime LastWriteTimeUtc { get; set; } + + #endregion // LastWriteTimeUtc + + #region ShortName + + /// The short 8.3 file naming convention (for example, FILENAME.TXT) name of the file. + public string ShortName { get; set; } + + #endregion // ShortName + + #endregion // Properties + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.AppendText.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.AppendText.cs new file mode 100644 index 0000000..0a3033d --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.AppendText.cs @@ -0,0 +1,51 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.IO; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + #region .NET + + /// Creates a that appends text to the file represented by this instance of the . + /// A new + [SecurityCritical] + public StreamWriter AppendText() + { + return File.AppendTextCore(Transaction, LongFullName, NativeMethods.DefaultFileEncoding, PathFormat.LongFullPath); + } + + /// Creates a that appends text to the file represented by this instance of the . + /// The character to use. + /// A new + [SecurityCritical] + public StreamWriter AppendText(Encoding encoding) + { + return File.AppendTextCore(Transaction, LongFullName, encoding, PathFormat.LongFullPath); + } + + #endregion // .NET + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.Compress.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Compress.cs new file mode 100644 index 0000000..f9db672 --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Compress.cs @@ -0,0 +1,39 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + #region AlphaFS + + /// [AlphaFS] Compresses a file using NTFS compression. + [SecurityCritical] + public void Compress() + { + Device.ToggleCompressionCore(false, Transaction, LongFullName, true, PathFormat.LongFullPath); + } + + #endregion // AlphaFS + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.CopyToMoveTo.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.CopyToMoveTo.cs new file mode 100644 index 0000000..78cbe79 --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.CopyToMoveTo.cs @@ -0,0 +1,631 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + #region CopyTo + + #region .NET + + /// Copies an existing file to a new file, disallowing the overwriting of an existing file. + /// A new instance with a fully qualified path. + /// + /// Use this method to prevent overwriting of an existing file by default. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A new instance with a fully qualified path. + /// + /// + /// + /// + /// + /// + /// + /// The name of the new file to copy to. + [SecurityCritical] + public FileInfo CopyTo(string destinationPath) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, false, CopyOptions.FailIfExists, null, null, null, out destinationPathLp, PathFormat.RelativePath); + return new FileInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + /// Copies an existing file to a new file, allowing the overwriting of an existing file. + /// + /// Use this method to allow or prevent overwriting of an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A new instance with a fully qualified path. + /// + /// + /// + /// + /// + /// + /// + /// The name of the new file to copy to. + /// to allow an existing file to be overwritten; otherwise, . + [SecurityCritical] + public FileInfo CopyTo(string destinationPath, bool overwrite) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, false, overwrite ? CopyOptions.None : CopyOptions.FailIfExists, null, null, null, out destinationPathLp, PathFormat.RelativePath); + return new FileInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + #endregion // .NET + + + #region AlphaFS + + /// [AlphaFS] Copies an existing file to a new file, disallowing the overwriting of an existing file. + /// + /// Use this method to prevent overwriting of an existing file by default. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A new instance with a fully qualified path. + /// + /// + /// + /// + /// + /// + /// + /// The name of the new file to copy to. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public FileInfo CopyTo(string destinationPath, PathFormat pathFormat) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, false, CopyOptions.FailIfExists, null, null, null, out destinationPathLp, pathFormat); + return new FileInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + + + /// [AlphaFS] Copies an existing file to a new file, allowing the overwriting of an existing file. + /// + /// Use this method to allow or prevent overwriting of an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A new instance with a fully qualified path. + /// + /// + /// + /// + /// + /// + /// + /// The name of the new file to copy to. + /// to allow an existing file to be overwritten; otherwise, . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public FileInfo CopyTo(string destinationPath, bool overwrite, PathFormat pathFormat) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, false, overwrite ? CopyOptions.None : CopyOptions.FailIfExists, null, null, null, out destinationPathLp, pathFormat); + return new FileInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + + + /// [AlphaFS] Copies an existing file to a new file, allowing the overwriting of an existing file, can be specified. + /// + /// Option is recommended for very large file transfers. + /// Use this method to allow or prevent overwriting of an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A new instance with a fully qualified path. + /// + /// + /// + /// + /// + /// + /// + /// The name of the new file to copy to. + /// that specify how the file is to be copied. + [SecurityCritical] + public FileInfo CopyTo(string destinationPath, CopyOptions copyOptions) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, false, copyOptions, null, null, null, out destinationPathLp, PathFormat.RelativePath); + return new FileInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + /// [AlphaFS] Copies an existing file to a new file, allowing the overwriting of an existing file, can be specified. + /// + /// Option is recommended for very large file transfers. + /// Use this method to allow or prevent overwriting of an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A new instance with a fully qualified path. + /// + /// + /// + /// + /// + /// + /// + /// The name of the new file to copy to. + /// that specify how the file is to be copied. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public FileInfo CopyTo(string destinationPath, CopyOptions copyOptions, PathFormat pathFormat) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, false, copyOptions, null, null, null, out destinationPathLp, pathFormat); + return new FileInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + + + /// [AlphaFS] Copies an existing file to a new file, allowing the overwriting of an existing file, can be specified. + /// + /// Option is recommended for very large file transfers. + /// Use this method to allow or prevent overwriting of an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A new instance with a fully qualified path. + /// + /// + /// + /// + /// + /// + /// + /// The name of the new file to copy to. + /// that specify how the file is to be copied. + /// if original Timestamps must be preserved, otherwise. + [SecurityCritical] + public FileInfo CopyTo(string destinationPath, CopyOptions copyOptions, bool preserveDates) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, preserveDates, copyOptions, null, null, null, out destinationPathLp, PathFormat.RelativePath); + return new FileInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + /// [AlphaFS] Copies an existing file to a new file, allowing the overwriting of an existing file, can be specified. + /// + /// Option is recommended for very large file transfers. + /// Use this method to allow or prevent overwriting of an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A new instance with a fully qualified path. + /// + /// + /// + /// + /// + /// + /// + /// The name of the new file to copy to. + /// that specify how the file is to be copied. + /// if original Timestamps must be preserved, otherwise. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public FileInfo CopyTo(string destinationPath, CopyOptions copyOptions, bool preserveDates, PathFormat pathFormat) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, preserveDates, copyOptions, null, null, null, out destinationPathLp, pathFormat); + return new FileInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + + + /// [AlphaFS] Copies an existing file to a new file, allowing the overwriting of an existing file, can be specified. + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// Option is recommended for very large file transfers. + /// Use this method to allow or prevent overwriting of an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// + /// The name of the new file to copy to. + /// that specify how the file is to be copied. + /// A callback function that is called each time another portion of the file has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + [SecurityCritical] + public CopyMoveResult CopyTo(string destinationPath, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData) + { + string destinationPathLp; + var cmr = CopyToMoveToCore(destinationPath, false, copyOptions, null, progressHandler, userProgressData, out destinationPathLp, PathFormat.RelativePath); + CopyToMoveToCoreRefresh(destinationPath, destinationPathLp); + return cmr; + } + + /// [AlphaFS] Copies an existing file to a new file, allowing the overwriting of an existing file, can be specified. + /// + /// Option is recommended for very large file transfers. + /// Use this method to allow or prevent overwriting of an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// + /// The name of the new file to copy to. + /// that specify how the file is to be copied. + /// A callback function that is called each time another portion of the file has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public CopyMoveResult CopyTo(string destinationPath, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat) + { + string destinationPathLp; + var cmr = CopyToMoveToCore(destinationPath, false, copyOptions, null, progressHandler, userProgressData, out destinationPathLp, pathFormat); + CopyToMoveToCoreRefresh(destinationPath, destinationPathLp); + return cmr; + } + + + + /// [AlphaFS] Copies an existing file to a new file, allowing the overwriting of an existing file, can be specified. + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// Option is recommended for very large file transfers. + /// Use this method to allow or prevent overwriting of an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// + /// The name of the new file to copy to. + /// that specify how the file is to be copied. + /// if original Timestamps must be preserved, otherwise. + /// A callback function that is called each time another portion of the file has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + [SecurityCritical] + public CopyMoveResult CopyTo(string destinationPath, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData) + { + string destinationPathLp; + var cmr = CopyToMoveToCore(destinationPath, preserveDates, copyOptions, null, progressHandler, userProgressData, out destinationPathLp, PathFormat.RelativePath); + CopyToMoveToCoreRefresh(destinationPath, destinationPathLp); + return cmr; + } + + /// [AlphaFS] Copies an existing file to a new file, allowing the overwriting of an existing file, can be specified. + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// Option is recommended for very large file transfers. + /// Use this method to allow or prevent overwriting of an existing file. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Copy action. + /// + /// + /// + /// + /// + /// + /// + /// The name of the new file to copy to. + /// that specify how the file is to be copied. + /// if original Timestamps must be preserved, otherwise. + /// A callback function that is called each time another portion of the file has been copied. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public CopyMoveResult CopyTo(string destinationPath, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat) + { + string destinationPathLp; + var cmr = CopyToMoveToCore(destinationPath, preserveDates, copyOptions, null, progressHandler, userProgressData, out destinationPathLp, pathFormat); + CopyToMoveToCoreRefresh(destinationPath, destinationPathLp); + return cmr; + } + + #endregion // AlphaFS + + #endregion // CopyTo + + + #region MoveTo + + #region .NET + + /// Moves a specified file to a new location, providing the option to specify a new file name. + /// + /// Use this method to prevent overwriting of an existing file by default. + /// This method works across disk volumes. + /// For example, the file c:\MyFile.txt can be moved to d:\public and renamed NewFile.txt. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with details of the Move action. + /// + /// + /// + /// + /// + /// + /// + /// The path to move the file to, which can specify a different file name. + [SecurityCritical] + public CopyMoveResult MoveTo(string destinationPath) + { + string destinationPathLp; + var copyMoveResult = CopyToMoveToCore(destinationPath, false, null, MoveOptions.CopyAllowed, null, null, out destinationPathLp, PathFormat.RelativePath); + CopyToMoveToCoreRefresh(destinationPath, destinationPathLp); + + return copyMoveResult; + } + + #endregion // .NET + + + #region AlphaFS + + /// [AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name. + /// Returns a new instance with a fully qualified path when successfully moved, + /// + /// Use this method to prevent overwriting of an existing file by default. + /// This method works across disk volumes. + /// For example, the file c:\MyFile.txt can be moved to d:\public and renamed NewFile.txt. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable + /// behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The path to move the file to, which can specify a different file name. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public FileInfo MoveTo(string destinationPath, PathFormat pathFormat) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, false, null, MoveOptions.CopyAllowed, null, null, out destinationPathLp, pathFormat); + return new FileInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + + + /// [AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name, can be specified. + /// Returns a new instance with a fully qualified path when successfully moved, + /// + /// Use this method to allow or prevent overwriting of an existing file. + /// This method works across disk volumes. + /// For example, the file c:\MyFile.txt can be moved to d:\public and renamed NewFile.txt. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable + /// behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The path to move the file to, which can specify a different file name. + /// that specify how the directory is to be moved. This parameter can be . + [SecurityCritical] + public FileInfo MoveTo(string destinationPath, MoveOptions moveOptions) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, false, null, moveOptions, null, null, out destinationPathLp, PathFormat.RelativePath); + return new FileInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + /// [AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name, can be specified. + /// Returns a new instance with a fully qualified path when successfully moved, + /// + /// Use this method to allow or prevent overwriting of an existing file. + /// This method works across disk volumes. + /// For example, the file c:\MyFile.txt can be moved to d:\public and renamed NewFile.txt. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable + /// behavior. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The path to move the file to, which can specify a different file name. + /// that specify how the directory is to be moved. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public FileInfo MoveTo(string destinationPath, MoveOptions moveOptions, PathFormat pathFormat) + { + string destinationPathLp; + CopyToMoveToCore(destinationPath, false, null, moveOptions, null, null, out destinationPathLp, pathFormat); + return new FileInfo(Transaction, destinationPathLp, PathFormat.LongFullPath); + } + + + + /// [AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name, can be specified, + /// and the possibility of notifying the application of its progress through a callback function. + /// + /// Use this method to allow or prevent overwriting of an existing file. + /// This method works across disk volumes. + /// For example, the file c:\MyFile.txt can be moved to d:\public and renamed NewFile.txt. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with the status of the Move action. + /// + /// + /// + /// + /// + /// + /// + /// The path to move the file to, which can specify a different file name. + /// that specify how the directory is to be moved. This parameter can be . + /// A callback function that is called each time another portion of the directory has been moved. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + [SecurityCritical] + public CopyMoveResult MoveTo(string destinationPath, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData) + { + string destinationPathLp; + var cmr = CopyToMoveToCore(destinationPath, false, null, moveOptions, progressHandler, userProgressData, out destinationPathLp, PathFormat.RelativePath); + CopyToMoveToCoreRefresh(destinationPath, destinationPathLp); + return cmr; + } + + /// [AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name, can be specified. + /// + /// Use this method to allow or prevent overwriting of an existing file. + /// This method works across disk volumes. + /// For example, the file c:\MyFile.txt can be moved to d:\public and renamed NewFile.txt. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with the status of the Move action. + /// + /// + /// + /// + /// + /// + /// + /// The path to move the file to, which can specify a different file name. + /// that specify how the directory is to be moved. This parameter can be . + /// A callback function that is called each time another portion of the directory has been moved. This parameter can be . + /// The argument to be passed to the callback function. This parameter can be . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public CopyMoveResult MoveTo(string destinationPath, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat) + { + string destinationPathLp; + var cmr = CopyToMoveToCore(destinationPath, false, null, moveOptions, progressHandler, userProgressData, out destinationPathLp, pathFormat); + CopyToMoveToCoreRefresh(destinationPath, destinationPathLp); + return cmr; + } + + #endregion // AlphaFS + + #endregion // MoveTo + + + #region Internal Methods + + /// Copy/move an existing file to a new file, allowing the overwriting of an existing file. + /// + /// Option is recommended for very large file transfers. + /// Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method. + /// If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior. + /// + /// + /// A class with the status of the Copy or Move action. + /// A full path string to the destination directory + /// if original Timestamps must be preserved, otherwise. + /// This parameter can be . Use to specify how the file is to be copied. + /// This parameter can be . Use that specify how the file is to be moved. + /// This parameter can be . A callback function that is called each time another portion of the file has been copied. + /// This parameter can be . The argument to be passed to the callback function. + /// [out] Returns the retrieved long full path. + /// Indicates the format of the path parameter(s). + /// + /// + /// + /// + /// + /// + [SecurityCritical] + private CopyMoveResult CopyToMoveToCore(string destinationPath, bool preserveDates, CopyOptions? copyOptions, MoveOptions? moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, out string longFullPath, PathFormat pathFormat) + { + var destinationPathLp = Path.GetExtendedLengthPathCore(Transaction, destinationPath, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + + longFullPath = destinationPathLp; + + // Returns false when CopyMoveProgressResult is PROGRESS_CANCEL or PROGRESS_STOP. + return File.CopyMoveCore(false, Transaction, LongFullName, destinationPathLp, preserveDates, copyOptions, moveOptions, progressHandler, userProgressData, null, PathFormat.LongFullPath); + } + + + private void CopyToMoveToCoreRefresh(string destinationPath, string destinationPathLp) + { + LongFullName = destinationPathLp; + FullPath = Path.GetRegularPathCore(destinationPathLp, GetFullPathOptions.None, false); + + OriginalPath = destinationPath; + DisplayPath = Path.GetRegularPathCore(OriginalPath, GetFullPathOptions.None, false); + + _name = Path.GetFileName(destinationPathLp, true); + + // Flush any cached information about the file. + Reset(); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.Create.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Create.cs new file mode 100644 index 0000000..0a36e19 --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Create.cs @@ -0,0 +1,41 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + #region .NET + + /// Creates a file. + /// A new file. + [SecurityCritical] + public FileStream Create() + { + return File.CreateFileStreamCore(Transaction, LongFullName, ExtendedFileAttributes.Normal, null, FileMode.Create, FileAccess.ReadWrite, FileShare.None, NativeMethods.DefaultFileBufferSize, PathFormat.LongFullPath); + } + + #endregion // .NET + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.CreateText.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.CreateText.cs new file mode 100644 index 0000000..492769f --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.CreateText.cs @@ -0,0 +1,43 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + #region .NET + + /// Creates a instance that writes a new text file. + /// A new + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public StreamWriter CreateText() + { + return new StreamWriter(File.CreateFileStreamCore(Transaction, LongFullName, ExtendedFileAttributes.Normal, null, FileMode.Create, FileAccess.ReadWrite, FileShare.None, NativeMethods.DefaultFileBufferSize, PathFormat.LongFullPath), NativeMethods.DefaultFileEncoding); + } + + #endregion // .NET + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.Decompress.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Decompress.cs new file mode 100644 index 0000000..e79b470 --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Decompress.cs @@ -0,0 +1,39 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + #region AlphaFS + + /// [AlphaFS] Decompresses an NTFS compressed file. + [SecurityCritical] + public void Decompress() + { + Device.ToggleCompressionCore(false, Transaction, LongFullName, false, PathFormat.LongFullPath); + } + + #endregion // AlphaFS + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.Decrypt.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Decrypt.cs new file mode 100644 index 0000000..600f8db --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Decrypt.cs @@ -0,0 +1,39 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + #region .NET + + /// Decrypts a file that was encrypted by the current account using the Encrypt method. + [SecurityCritical] + public void Decrypt() + { + File.EncryptDecryptFileCore(false, LongFullName, false, PathFormat.LongFullPath); + } + + #endregion // .NET + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.Delete.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Delete.cs new file mode 100644 index 0000000..122c6b8 --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Delete.cs @@ -0,0 +1,53 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.IO; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + #region .NET + + /// Permanently deletes a file. + /// If the file does not exist, this method does nothing. + /// + /// + public override void Delete() + { + File.DeleteFileCore(Transaction, LongFullName, false, PathFormat.LongFullPath); + } + + #endregion // .NET + + #region AlphaFS + + /// [AlphaFS] Permanently deletes a file. + /// If the file does not exist, this method does nothing. + /// overrides the read only of the file. + public void Delete(bool ignoreReadOnly) + { + File.DeleteFileCore(Transaction, LongFullName, ignoreReadOnly, PathFormat.LongFullPath); + } + + #endregion // AlphaFS + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.Encrypt.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Encrypt.cs new file mode 100644 index 0000000..e26a0a4 --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Encrypt.cs @@ -0,0 +1,39 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + #region .NET + + /// Encrypts a file so that only the account used to encrypt the file can decrypt it. + [SecurityCritical] + public void Encrypt() + { + File.EncryptDecryptFileCore(false, LongFullName, true, PathFormat.LongFullPath); + } + + #endregion // .NET + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.EnumerateAlternateDataStreams.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.EnumerateAlternateDataStreams.cs new file mode 100644 index 0000000..c7202a9 --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.EnumerateAlternateDataStreams.cs @@ -0,0 +1,37 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Collections.Generic; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + /// [AlphaFS] Returns an enumerable collection of instances for the file. + /// An enumerable collection of instances for the file. + [SecurityCritical] + public IEnumerable EnumerateAlternateDataStreams() + { + return File.EnumerateAlternateDataStreamsCore(Transaction, LongFullName, PathFormat.LongFullPath); + } + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.GetAccessControl.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.GetAccessControl.cs new file mode 100644 index 0000000..93ab75f --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.GetAccessControl.cs @@ -0,0 +1,50 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Security; +using System.Security.AccessControl; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + #region .NET + + /// Gets a object that encapsulates the access control list (ACL) entries for the file described by the current object. + /// A FileSecurity object that encapsulates the access control rules for the current file. + [SecurityCritical] + public FileSecurity GetAccessControl() + { + return File.GetAccessControlCore(false, LongFullName, AccessControlSections.Access | AccessControlSections.Group | AccessControlSections.Owner, PathFormat.LongFullPath); + } + + /// Gets a object that encapsulates the specified type of access control list (ACL) entries for the file described by the current FileInfo object. + /// object that encapsulates the specified type of access control list (ACL) entries for the file described by the current FileInfo object. + /// One of the values that specifies which group of access control entries to retrieve. + [SecurityCritical] + public FileSecurity GetAccessControl(AccessControlSections includeSections) + { + return File.GetAccessControlCore(false, LongFullName, includeSections, PathFormat.LongFullPath); + } + + #endregion // .NET + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.GetHash.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.GetHash.cs new file mode 100644 index 0000000..448d794 --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.GetHash.cs @@ -0,0 +1,39 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + #region AlphaFS + + /// [AlphaFS] Calculates the hash/checksum. + /// One of the values. + public string GetHash(HashType hashType) + { + return File.GetHashCore(Transaction, LongFullName, hashType, PathFormat.LongFullPath); + } + + #endregion // AlphaFS + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.Open.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Open.cs new file mode 100644 index 0000000..8930685 --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Open.cs @@ -0,0 +1,89 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.IO; +using System.Security; +using System.Security.AccessControl; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + #region .NET + + /// Opens a file in the specified mode. + /// A file opened in the specified mode, with read/write access and unshared. + /// A constant specifying the mode (for example, Open or Append) in which to open the file. + [SecurityCritical] + public FileStream Open(FileMode mode) + { + return File.OpenCore(Transaction, LongFullName, mode, FileAccess.Read, FileShare.None, ExtendedFileAttributes.Normal, null, null, PathFormat.LongFullPath); + } + + /// Opens a file in the specified mode with read, write, or read/write access. + /// A object opened in the specified mode and access, and unshared. + /// A constant specifying the mode (for example, Open or Append) in which to open the file. + /// A constant specifying whether to open the file with Read, Write, or ReadWrite file access. + [SecurityCritical] + public FileStream Open(FileMode mode, FileAccess access) + { + return File.OpenCore(Transaction, LongFullName, mode, access, FileShare.None, ExtendedFileAttributes.Normal, null, null, PathFormat.LongFullPath); + } + + /// Opens a file in the specified mode with read, write, or read/write access and the specified sharing option. + /// A object opened with the specified mode, access, and sharing options. + /// A constant specifying the mode (for example, Open or Append) in which to open the file. + /// A constant specifying whether to open the file with Read, Write, or ReadWrite file access. + /// A constant specifying the type of access other objects have to this file. + [SecurityCritical] + public FileStream Open(FileMode mode, FileAccess access, FileShare share) + { + return File.OpenCore(Transaction, LongFullName, mode, access, share, ExtendedFileAttributes.Normal, null, null, PathFormat.LongFullPath); + } + + #endregion // .NET + + #region AlphaFS + + /// [AlphaFS] Opens a file in the specified mode with read, write, or read/write access. + /// A object opened in the specified mode and access, and unshared. + /// A constant specifying the mode (for example, Open or Append) in which to open the file. + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten along with additional options. + [SecurityCritical] + public FileStream Open(FileMode mode, FileSystemRights rights) + { + return File.OpenCore(Transaction, LongFullName, mode, rights, FileShare.None, ExtendedFileAttributes.Normal, null, null, PathFormat.LongFullPath); + } + + /// [AlphaFS] Opens a file in the specified mode with read, write, or read/write access and the specified sharing option. + /// A object opened with the specified mode, access, and sharing options. + /// A constant specifying the mode (for example, Open or Append) in which to open the file. + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten along with additional options. + /// A constant specifying the type of access other objects have to this file. + [SecurityCritical] + public FileStream Open(FileMode mode, FileSystemRights rights, FileShare share) + { + return File.OpenCore(Transaction, LongFullName, mode, rights, share, ExtendedFileAttributes.Normal, null, null, PathFormat.LongFullPath); + } + + #endregion // AlphaFS + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.OpenRead.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.OpenRead.cs new file mode 100644 index 0000000..b36478a --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.OpenRead.cs @@ -0,0 +1,38 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + /// Creates a read-only . + /// A new read-only object. + /// This method returns a read-only object with the mode set to Read. + [SecurityCritical] + public FileStream OpenRead() + { + return File.OpenCore(Transaction, LongFullName, FileMode.Open, FileAccess.Read, FileShare.Read, ExtendedFileAttributes.Normal, null, null, PathFormat.LongFullPath); + } + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.OpenText.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.OpenText.cs new file mode 100644 index 0000000..9a1afe8 --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.OpenText.cs @@ -0,0 +1,52 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + /// Creates a with NativeMethods.DefaultFileEncoding encoding that reads from an existing text file. + /// A new with NativeMethods.DefaultFileEncoding encoding. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public StreamReader OpenText() + { + return new StreamReader(File.OpenCore(Transaction, LongFullName, FileMode.Open, FileAccess.Read, FileShare.None, ExtendedFileAttributes.Normal, null, null, PathFormat.LongFullPath), NativeMethods.DefaultFileEncoding); + } + + + /// [AlphaFS] Creates a with that reads from an existing text file. + /// A new with the specified . + /// The applied to the contents of the file. + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + [SecurityCritical] + public StreamReader OpenText(Encoding encoding) + { + return new StreamReader(File.OpenCore(Transaction, LongFullName, FileMode.Open, FileAccess.Read, FileShare.None, ExtendedFileAttributes.Normal, null, null, PathFormat.LongFullPath), encoding); + } + + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.OpenWrite.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.OpenWrite.cs new file mode 100644 index 0000000..9482818 --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.OpenWrite.cs @@ -0,0 +1,41 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + #region .NET + + /// Creates a write-only . + /// A write-only unshared object for a new or existing file. + [SecurityCritical] + public FileStream OpenWrite() + { + return File.OpenCore(Transaction, LongFullName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, ExtendedFileAttributes.Normal, null, null, PathFormat.LongFullPath); + } + + #endregion // .NET + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.Refresh.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Refresh.cs new file mode 100644 index 0000000..6687387 --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Refresh.cs @@ -0,0 +1,39 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + #region .NET + + /// Refreshes the state of the object. + [SecurityCritical] + public new void Refresh() + { + base.Refresh(); + } + + #endregion // .NET + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.RefreshEntryInfo.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.RefreshEntryInfo.cs new file mode 100644 index 0000000..8bc93d6 --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.RefreshEntryInfo.cs @@ -0,0 +1,39 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + #region AlphaFS + + /// Refreshes the state of the EntryInfo instance. + [SecurityCritical] + public new void RefreshEntryInfo() + { + base.RefreshEntryInfo(); + } + + #endregion // AlphaFS + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.Replace.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Replace.cs new file mode 100644 index 0000000..a616d48 --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.Replace.cs @@ -0,0 +1,122 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + #region .NET + + /// Replaces the contents of a specified file with the file described by the current object, deleting the original file, and creating a backup of the replaced file. + /// A object that encapsulates information about the file described by the parameter. + /// + /// The Replace method replaces the contents of a specified file with the contents of the file described by the current + /// object. It also creates a backup of the file that was replaced. Finally, it returns a new + /// object that describes the overwritten file. + /// + /// Pass null to the parameter if you do not want to create a backup of the file being replaced. + /// The name of a file to replace with the current file. + /// The name of a file with which to create a backup of the file described by the parameter. + [SecurityCritical] + public FileInfo Replace(string destinationFileName, string destinationBackupFileName) + { + return Replace(destinationFileName, destinationBackupFileName, false, PathFormat.RelativePath); + } + + /// Replaces the contents of a specified file with the file described by the current object, deleting the original file, and creating a backup of the replaced file. Also specifies whether to ignore merge errors. + /// A object that encapsulates information about the file described by the parameter. + /// + /// The Replace method replaces the contents of a specified file with the contents of the file described by the current + /// object. It also creates a backup of the file that was replaced. Finally, it returns a new + /// object that describes the overwritten file. + /// + /// Pass null to the parameter if you do not want to create a backup of the file being replaced. + /// The name of a file to replace with the current file. + /// The name of a file with which to create a backup of the file described by the parameter. + /// to ignore merge errors (such as attributes and ACLs) from the replaced file to the replacement file; otherwise, . + [SecurityCritical] + public FileInfo Replace(string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors) + { + return Replace(destinationFileName, destinationBackupFileName, ignoreMetadataErrors, PathFormat.RelativePath); + } + + #endregion // .NET + + #region AlphaFS + + /// [AlphaFS] Replaces the contents of a specified file with the file described by the current object, deleting the original file, and creating a backup of the replaced file. Also specifies whether to ignore merge errors. + /// A object that encapsulates information about the file described by the parameter. + /// + /// The Replace method replaces the contents of a specified file with the contents of the file described by the current + /// object. It also creates a backup of the file that was replaced. Finally, it returns a new + /// object that describes the overwritten file. + /// + /// Pass null to the parameter if you do not want to create a backup of the file being replaced. + /// The name of a file to replace with the current file. + /// The name of a file with which to create a backup of the file described by the parameter. + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public FileInfo Replace(string destinationFileName, string destinationBackupFileName, PathFormat pathFormat) + { + var options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck; + + string destinationFileNameLp = Path.GetExtendedLengthPathCore(Transaction, destinationFileName, pathFormat, options); + string destinationBackupFileNameLp = destinationBackupFileName != null + ? Path.GetExtendedLengthPathCore(Transaction, destinationBackupFileName, pathFormat, options) + : null; + + File.ReplaceCore(LongFullName, destinationFileNameLp, destinationBackupFileNameLp, false, PathFormat.LongFullPath); + + return new FileInfo(Transaction, destinationFileNameLp, PathFormat.LongFullPath); + } + + /// [AlphaFS] Replaces the contents of a specified file with the file described by the current object, deleting the original file, and creating a backup of the replaced file. Also specifies whether to ignore merge errors. + /// A object that encapsulates information about the file described by the parameter. + /// + /// The Replace method replaces the contents of a specified file with the contents of the file described by the current + /// object. It also creates a backup of the file that was replaced. Finally, it returns a new + /// object that describes the overwritten file. + /// + /// Pass null to the parameter if you do not want to create a backup of the file being replaced. + /// The name of a file to replace with the current file. + /// The name of a file with which to create a backup of the file described by the parameter. + /// to ignore merge errors (such as attributes and ACLs) from the replaced file to the replacement file; otherwise, . + /// Indicates the format of the path parameter(s). + [SecurityCritical] + public FileInfo Replace(string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors, PathFormat pathFormat) + { + var options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck; + + string destinationFileNameLp = Path.GetExtendedLengthPathCore(Transaction, destinationFileName, pathFormat, options); + string destinationBackupFileNameLp = destinationBackupFileName != null + ? Path.GetExtendedLengthPathCore(Transaction, destinationBackupFileName, pathFormat, options) + : null; + + File.ReplaceCore(LongFullName, destinationFileNameLp, destinationBackupFileNameLp, ignoreMetadataErrors, PathFormat.LongFullPath); + + return new FileInfo(Transaction, destinationFileNameLp, PathFormat.LongFullPath); + } + + #endregion // AlphaFS + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.SetAccessControl.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.SetAccessControl.cs new file mode 100644 index 0000000..6f85888 --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.SetAccessControl.cs @@ -0,0 +1,57 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.Security; +using System.Security.AccessControl; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + /// Applies access control list (ACL) entries described by a FileSecurity object to the file described by the current FileInfo object. + /// + /// The SetAccessControl method applies access control list (ACL) entries to the current file that represents the noninherited ACL + /// list. Use the SetAccessControl method whenever you need to add or remove ACL entries from a file. + /// + /// A object that describes an access control list (ACL) entry to apply to the current file. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public void SetAccessControl(FileSecurity fileSecurity) + { + File.SetAccessControlCore(LongFullName, null, fileSecurity, AccessControlSections.All, PathFormat.LongFullPath); + } + + /// Applies access control list (ACL) entries described by a FileSecurity object to the file described by the current FileInfo object. + /// + /// The SetAccessControl method applies access control list (ACL) entries to the current file that represents the noninherited ACL + /// list. Use the SetAccessControl method whenever you need to add or remove ACL entries from a file. + /// + /// A object that describes an access control list (ACL) entry to apply to the current file. + /// One or more of the values that specifies the type of access control list (ACL) information to set. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + [SecurityCritical] + public void SetAccessControl(FileSecurity fileSecurity, AccessControlSections includeSections) + { + File.SetAccessControlCore(LongFullName, null, fileSecurity, includeSections, PathFormat.LongFullPath); + } + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.ToString.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.ToString.cs new file mode 100644 index 0000000..b826686 --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.ToString.cs @@ -0,0 +1,33 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + partial class FileInfo + { + /// Returns the path as a string. + /// The path. + public override string ToString() + { + return DisplayPath; + } + } +} diff --git a/AlphaFS/Filesystem/FileInfo Class/FileInfo.cs b/AlphaFS/Filesystem/FileInfo Class/FileInfo.cs new file mode 100644 index 0000000..89fa10f --- /dev/null +++ b/AlphaFS/Filesystem/FileInfo Class/FileInfo.cs @@ -0,0 +1,250 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Provides properties and instance methods for the creation, copying, deletion, moving, and opening of files, and aids in the creation of objects. This class cannot be inherited. + [SerializableAttribute] + public sealed partial class FileInfo : FileSystemInfo + { + #region Constructors + + #region .NET + + /// Initializes a new instance of the class, which acts as a wrapper for a file path. + /// The fully qualified name of the new file, or the relative file name. Do not end the path with the directory separator character. + /// This constructor does not check if a file exists. This constructor is a placeholder for a string that is used to access the file in subsequent operations. + public FileInfo(string fileName) : this(null, fileName, PathFormat.RelativePath) + { + } + + #endregion // .NET + + #region AlphaFS + + #region Non-Transactional + + /// [AlphaFS] Initializes a new instance of the class, which acts as a wrapper for a file path. + /// The fully qualified name of the new file, or the relative file name. Do not end the path with the directory separator character. + /// Indicates the format of the path parameter(s). + /// This constructor does not check if a file exists. This constructor is a placeholder for a string that is used to access the file in subsequent operations. + public FileInfo(string fileName, PathFormat pathFormat) : this(null, fileName, pathFormat) + { + } + + #endregion // Non-Transactional + + #region Transactional + + /// [AlphaFS] Initializes a new instance of the class, which acts as a wrapper for a file path. + /// The transaction. + /// The fully qualified name of the new file, or the relative file name. Do not end the path with the directory separator character. + /// This constructor does not check if a file exists. This constructor is a placeholder for a string that is used to access the file in subsequent operations. + public FileInfo(KernelTransaction transaction, string fileName) : this(transaction, fileName, PathFormat.RelativePath) + { + } + + /// [AlphaFS] Initializes a new instance of the class, which acts as a wrapper for a file path. + /// The transaction. + /// The fully qualified name of the new file, or the relative file name. Do not end the path with the directory separator character. + /// Indicates the format of the path parameter(s). + /// This constructor does not check if a file exists. This constructor is a placeholder for a string that is used to access the file in subsequent operations. + public FileInfo(KernelTransaction transaction, string fileName, PathFormat pathFormat) + { + InitializeCore(false, transaction, fileName, pathFormat); + + _name = Path.GetFileName(Path.RemoveTrailingDirectorySeparator(fileName, false), pathFormat != PathFormat.LongFullPath); + } + + #endregion // Transacted + + #endregion // AlphaFS + + #endregion // Constructors + + #region Properties + + #region .NET + + #region Directory + + /// Gets an instance of the parent directory. + /// A object representing the parent directory of this file. + /// To get the parent directory as a string, use the DirectoryName property. + /// + public DirectoryInfo Directory + { + get + { + string dirName = DirectoryName; + return dirName == null ? null : new DirectoryInfo(Transaction, dirName, PathFormat.FullPath); + } + } + + #endregion // Directory + + #region DirectoryName + + /// Gets a string representing the directory's full path. + /// A string representing the directory's full path. + /// + /// To get the parent directory as a DirectoryInfo object, use the Directory property. + /// When first called, FileInfo calls Refresh and caches information about the file. + /// On subsequent calls, you must call Refresh to get the latest copy of the information. + /// + /// + public string DirectoryName + { + [SecurityCritical] get { return Path.GetDirectoryName(FullPath, false); } + } + + #endregion // DirectoryName + + #region Exists + + /// Gets a value indicating whether the file exists. + /// if the file exists; otherwise, . + /// + /// The property returns if any error occurs while trying to determine if the specified file exists. + /// This can occur in situations that raise exceptions such as passing a file name with invalid characters or too many characters, + /// a failing or missing disk, or if the caller does not have permission to read the file. + /// + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + public override bool Exists + { + [SecurityCritical] + get + { + try + { + if (DataInitialised == -1) + Refresh(); + + FileAttributes attrs = Win32AttributeData.dwFileAttributes; + return DataInitialised == 0 && attrs != (FileAttributes) (-1) && (attrs & FileAttributes.Directory) == 0; + } + catch + { + return false; + } + } + } + + #endregion // Exists + + #region IsReadOnly + + /// Gets or sets a value that determines if the current file is read only. + /// if the current file is read only; otherwise, . + /// + /// Use the IsReadOnly property to quickly determine or change whether the current file is read only. + /// When first called, FileInfo calls Refresh and caches information about the file. + /// On subsequent calls, you must call Refresh to get the latest copy of the information. + /// + /// + /// + public bool IsReadOnly + { + get { return EntryInfo == null || EntryInfo.IsReadOnly; } + + set + { + if (value) + Attributes |= FileAttributes.ReadOnly; + else + Attributes &= ~FileAttributes.ReadOnly; + } + } + + #endregion // IsReadOnly + + #region Length + + /// Gets the size, in bytes, of the current file. + /// The size of the current file in bytes. + /// + /// The value of the Length property is pre-cached + /// To get the latest value, call the Refresh method. + /// + /// + /// + [SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] + public long Length + { + [SecurityCritical] + get + { + if (DataInitialised == -1) + { + Win32AttributeData = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA(); + Refresh(); + } + + // MSDN: .NET 3.5+: IOException: Refresh cannot initialize the data. + if (DataInitialised != 0) + NativeError.ThrowException(DataInitialised, LongFullName); + + FileAttributes attrs = Win32AttributeData.dwFileAttributes; + + // MSDN: .NET 3.5+: FileNotFoundException: The file does not exist or the Length property is called for a directory. + if (attrs == (FileAttributes) (-1)) + NativeError.ThrowException(Win32Errors.ERROR_FILE_NOT_FOUND, LongFullName); + + // MSDN: .NET 3.5+: FileNotFoundException: The file does not exist or the Length property is called for a directory. + if ((attrs & FileAttributes.Directory) == FileAttributes.Directory) + NativeError.ThrowException(Win32Errors.ERROR_FILE_NOT_FOUND, string.Format(CultureInfo.CurrentCulture, Resources.Target_File_Is_A_Directory, LongFullName)); + + return Win32AttributeData.FileSize; + } + } + + #endregion // Length + + #region Name + + private string _name; + + /// Gets the name of the file. + /// The name of the file. + /// + /// The name of the file includes the file extension. + /// When first called, calls Refresh and caches information about the file. + /// On subsequent calls, you must call Refresh to get the latest copy of the information. + /// The name of the file includes the file extension. + /// + public override string Name + { + get { return _name; } + } + + #endregion // Name + + #endregion // .NET + + #endregion // Properties + } +} diff --git a/AlphaFS/Filesystem/FileSystemEntryInfo.cs b/AlphaFS/Filesystem/FileSystemEntryInfo.cs new file mode 100644 index 0000000..86c28e3 --- /dev/null +++ b/AlphaFS/Filesystem/FileSystemEntryInfo.cs @@ -0,0 +1,254 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Represents information about a file system entry. + /// This class cannot be inherited. + /// + [SerializableAttribute] + [SecurityCritical] + public sealed class FileSystemEntryInfo + { + /// Initializes a new instance of the class. + /// The NativeMethods.WIN32_FIND_DATA structure. + internal FileSystemEntryInfo(NativeMethods.WIN32_FIND_DATA findData) + { + Win32FindData = findData; + } + + + #region Properties + + /// Gets the 8.3 version of the filename. + /// the 8.3 version of the filename. + public string AlternateFileName + { + get { return Win32FindData.cAlternateFileName; } + } + + + /// Gets the attributes. + /// The attributes. + public FileAttributes Attributes + { + get { return Win32FindData.dwFileAttributes; } + } + + + /// Gets the time this entry was created. + /// The time this entry was created. + public DateTime CreationTime + { + get { return CreationTimeUtc.ToLocalTime(); } + } + + + /// Gets the time, in coordinated universal time (UTC), this entry was created. + /// The time, in coordinated universal time (UTC), this entry was created. + public DateTime CreationTimeUtc + { + get { return DateTime.FromFileTimeUtc(Win32FindData.ftCreationTime); } + } + + + /// Gets the name of the file. + /// The name of the file. + public string FileName + { + get { return Win32FindData.cFileName; } + } + + + /// Gets the size of the file. + /// The size of the file. + public long FileSize + { + get { return NativeMethods.ToLong(Win32FindData.nFileSizeHigh, Win32FindData.nFileSizeLow); } + } + + + private string _fullPath; + + /// The full path of the file system object. + public string FullPath + { + get { return _fullPath; } + set + { + LongFullPath = value; + _fullPath = Path.GetRegularPathCore(LongFullPath, GetFullPathOptions.None, false); + } + } + + + /// Gets a value indicating whether this instance is compressed. + /// if this instance is compressed; otherwise, . + /// + /// It is not possible to change the compression status of a File object by using the SetAttributes method. + /// Instead, you must actually compress the file using either a compression tool or one of the classes in the namespace. + /// + public bool IsCompressed + { + get { return Attributes != (FileAttributes)(-1) && (Attributes & FileAttributes.Compressed) != 0; } + } + + + /// Gets a value indicating whether this instance is hidden, and thus is not included in an ordinary directory listing. + /// if this instance is hidden; otherwise, . + public bool IsHidden + { + get { return Attributes != (FileAttributes)(-1) && (Attributes & FileAttributes.Hidden) != 0; } + } + + + /// Gets a value indicating whether this instance represents a directory. + /// if this instance represents a directory; otherwise, . + public bool IsDirectory + { + get { return Attributes != (FileAttributes)(-1) && (Attributes & FileAttributes.Directory) != 0; } + } + + + /// Gets a value indicating whether this instance is encrypted (EFS). + /// if this instance is encrypted (EFS); otherwise, . + /// + /// For a file, this means that all data in the file is encrypted. + /// For a directory, this means that encryption is the default for newly created files and directories. + /// + public bool IsEncrypted + { + get { return Attributes != (FileAttributes) (-1) && (Attributes & FileAttributes.Encrypted) != 0; } + } + + + /// Gets a value indicating whether this instance is a mount point. + /// if this instance is a mount point; otherwise, . + public bool IsMountPoint + { + get { return ReparsePointTag == ReparsePointTag.MountPoint; } + } + + + /// Gets a value indicating whether this instance is offline. The data of the file is not immediately available. + /// if this instance is offline; otherwise, . + public bool IsOffline + { + get { return Attributes != (FileAttributes)(-1) && (Attributes & FileAttributes.Offline) != 0; } + } + + + /// Gets a value indicating whether this instance is read-only. + /// if this instance is read-only; otherwise, . + public bool IsReadOnly + { + get { return Attributes != (FileAttributes)(-1) && (Attributes & FileAttributes.ReadOnly) != 0; } + } + + + /// Gets a value indicating whether this instance contains a reparse point, which is a block of user-defined data associated with a file or a directory. + /// if this instance contains a reparse point; otherwise, . + public bool IsReparsePoint + { + get { return Attributes != (FileAttributes)(-1) && (Attributes & FileAttributes.ReparsePoint) != 0; } + } + + + /// Gets a value indicating whether this instance is a symbolic link. + /// if this instance is a symbolic link; otherwise, . + public bool IsSymbolicLink + { + get { return ReparsePointTag == ReparsePointTag.SymLink; } + } + + + /// Gets the time this entry was last accessed. + /// The time this entry was last accessed. + public DateTime LastAccessTime + { + get { return LastAccessTimeUtc.ToLocalTime(); } + } + + + /// Gets the time, in coordinated universal time (UTC), this entry was last accessed. + /// The time, in coordinated universal time (UTC), this entry was last accessed. + public DateTime LastAccessTimeUtc + { + get { return DateTime.FromFileTimeUtc(Win32FindData.ftLastAccessTime); } + } + + + /// Gets the time this entry was last modified. + /// The time this entry was last modified. + public DateTime LastWriteTime + { + get { return LastWriteTimeUtc.ToLocalTime(); } + } + + + /// Gets the time, in coordinated universal time (UTC), this entry was last modified. + /// The time, in coordinated universal time (UTC), this entry was last modified. + public DateTime LastWriteTimeUtc + { + get { return DateTime.FromFileTimeUtc(Win32FindData.ftLastWriteTime); } + } + + + private string _longFullPath; + + /// The full path of the file system object in Unicode (LongPath) format. + public string LongFullPath + { + get { return _longFullPath; } + private set { _longFullPath = Path.GetLongPathCore(value, GetFullPathOptions.None); } + } + + + /// Gets the reparse point tag of this entry. + /// The reparse point tag of this entry. + public ReparsePointTag ReparsePointTag + { + get { return IsReparsePoint ? Win32FindData.dwReserved0 : ReparsePointTag.None; } + } + + + /// Gets internal WIN32 FIND Data + internal NativeMethods.WIN32_FIND_DATA Win32FindData { get; private set; } + + #endregion // Properties + + + #region Methods + + /// Returns the of the instance. + /// The instance as a string. + public override string ToString() + { + return FullPath; + } + + #endregion // Methods + } +} diff --git a/AlphaFS/Filesystem/FileSystemInfo.cs b/AlphaFS/Filesystem/FileSystemInfo.cs new file mode 100644 index 0000000..b89f9ee --- /dev/null +++ b/AlphaFS/Filesystem/FileSystemInfo.cs @@ -0,0 +1,643 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Provides the base class for both and objects. + [SerializableAttribute] + [ComVisibleAttribute(true)] + public abstract class FileSystemInfo : MarshalByRefObject + { + #region Methods + + #region .NET + + #region Delete + + /// Deletes a file or directory. + [SecurityCritical] + public abstract void Delete(); + + #endregion // Delete + + #region Refresh + + /// Refreshes the state of the object. + /// + /// FileSystemInfo.Refresh() takes a snapshot of the file from the current file system. + /// Refresh cannot correct the underlying file system even if the file system returns incorrect or outdated information. + /// This can happen on platforms such as Windows 98. + /// Calls must be made to Refresh() before attempting to get the attribute information, or the information will be + /// outdated. + /// + [SecurityCritical] + protected void Refresh() + { + DataInitialised = File.FillAttributeInfoCore(Transaction, LongFullName, ref Win32AttributeData, false, false); + } + + #endregion // Refresh + + #region ToString + + /// Returns a string that represents the current object. + /// + /// ToString is the major formatting method in the .NET Framework. It converts an object to its string representation so that it is + /// suitable for display. + /// + /// A string that represents this instance. + public override string ToString() + { + // "Alphaleonis.Win32.Filesystem.FileSystemInfo" + return GetType().ToString(); + } + + #endregion // ToString + + #region Equality + + /// Determines whether the specified Object is equal to the current Object. + /// Another object to compare to. + /// if the specified Object is equal to the current Object; otherwise, . + public override bool Equals(object obj) + { + if (obj == null || GetType() != obj.GetType()) + return false; + + FileSystemInfo other = obj as FileSystemInfo; + + return other != null && (other.Name != null && + (other.FullName.Equals(FullName, StringComparison.OrdinalIgnoreCase) && + other.Attributes.Equals(Attributes) && + other.CreationTimeUtc.Equals(CreationTimeUtc) && + other.LastWriteTimeUtc.Equals(LastWriteTimeUtc))); + } + + // A random prime number will be picked and added to the HashCode, each time an instance is created. + [NonSerialized] + private readonly int _random = new Random().Next(0, 19); + + [NonSerialized] + private static readonly int[] Primes = { 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919 }; + + /// Serves as a hash function for a particular type. + /// A hash code for the current Object. + public override int GetHashCode() + { + string fullName = FullName; + string name = Name; + + unchecked + { + int hash = Primes[_random]; + + if (!Utils.IsNullOrWhiteSpace(fullName)) + hash = hash * Primes[1] + fullName.GetHashCode(); + + if (!Utils.IsNullOrWhiteSpace(name)) + hash = hash * Primes[1] + name.GetHashCode(); + + hash = hash * Primes[1] + Attributes.GetHashCode(); + hash = hash * Primes[1] + CreationTimeUtc.GetHashCode(); + hash = hash * Primes[1] + LastWriteTimeUtc.GetHashCode(); + + return hash; + } + } + + /// Implements the operator == + /// A. + /// B. + /// The result of the operator. + public static bool operator ==(FileSystemInfo left, FileSystemInfo right) + { + return ReferenceEquals(left, null) && ReferenceEquals(right, null) || + !ReferenceEquals(left, null) && !ReferenceEquals(right, null) && left.Equals(right); + } + + /// Implements the operator != + /// A. + /// B. + /// The result of the operator. + public static bool operator !=(FileSystemInfo left, FileSystemInfo right) + { + return !(left == right); + } + + #endregion // Equality + + #endregion // .NET + + #region AlphaFS + + #region RefreshEntryInfo + + /// Refreshes the state of the EntryInfo instance. + /// + /// FileSystemInfo.RefreshEntryInfo() takes a snapshot of the file from the current file system. + /// Refresh cannot correct the underlying file system even if the file system returns incorrect or outdated information. + /// This can happen on platforms such as Windows 98. + /// Calls must be made to Refresh() before attempting to get the attribute information, or the information will be outdated. + /// + [SecurityCritical] + protected void RefreshEntryInfo() + { + _entryInfo = File.GetFileSystemEntryInfoCore(IsDirectory, Transaction, LongFullName, true, PathFormat.LongFullPath); + + if (_entryInfo == null) + DataInitialised = -1; + else + { + DataInitialised = 0; + Win32AttributeData = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA(_entryInfo.Win32FindData); + } + } + + #endregion // RefreshEntryInfo + + #region Reset + + /// [AlphaFS] Resets the state of the file system object to uninitialized. + internal void Reset() + { + DataInitialised = -1; + } + + #endregion // Reset + + #region InitializeCore + + /// Initializes the specified file name. + /// + /// + /// Specifies that is a file or directory. + /// The transaction. + /// The full path and name of the file. + /// Indicates the format of the path parameter(s). + internal void InitializeCore(bool isFolder, KernelTransaction transaction, string path, PathFormat pathFormat) + { + if (pathFormat == PathFormat.RelativePath) + Path.CheckSupportedPathFormat(path, true, true); + + LongFullName = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | (isFolder ? GetFullPathOptions.RemoveTrailingDirectorySeparator : 0) | GetFullPathOptions.ContinueOnNonExist); + + // (Not on MSDN): .NET 4+ Trailing spaces are removed from the end of the path parameter before creating the FileSystemInfo instance. + + FullPath = Path.GetRegularPathCore(LongFullName, GetFullPathOptions.None, false); + + IsDirectory = isFolder; + Transaction = transaction; + + OriginalPath = FullPath.Length == 2 && (FullPath[1] == Path.VolumeSeparatorChar) + ? Path.CurrentDirectoryPrefix + : path; + + DisplayPath = OriginalPath.Length != 2 || OriginalPath[1] != Path.VolumeSeparatorChar + ? Path.GetRegularPathCore(OriginalPath, GetFullPathOptions.None, false) + : Path.CurrentDirectoryPrefix; + } + + #endregion // InitializeCore + + #endregion // AlphaFS + + #endregion // Methods + + #region Properties + + #region .NET + + #region Attributes + + /// + /// Gets or sets the attributes for the current file or directory. + /// + /// + /// The value of the CreationTime property is pre-cached + /// To get the latest value, call the Refresh method. + /// + /// of the current . + /// + /// + /// + /// + public FileAttributes Attributes + { + [SecurityCritical] + get + { + if (DataInitialised == -1) + { + Win32AttributeData = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA(); + Refresh(); + } + + // MSDN: .NET 3.5+: IOException: Refresh cannot initialize the data. + if (DataInitialised != 0) + NativeError.ThrowException(DataInitialised, LongFullName); + + return Win32AttributeData.dwFileAttributes; + } + + [SecurityCritical] + set + { + File.SetAttributesCore(IsDirectory, Transaction, LongFullName, value, false, PathFormat.LongFullPath); + Reset(); + } + } + + #endregion // Attributes + + #region CreationTime + + /// Gets or sets the creation time of the current file or directory. + /// + /// The value of the CreationTime property is pre-cached To get the latest value, call the Refresh method. + /// This method may return an inaccurate value, because it uses native functions whose values may not be continuously updated by + /// the operating system. + /// If the file described in the FileSystemInfo object does not exist, this property will return + /// 12:00 midnight, January 1, 1601 A.D. (C.E.) Coordinated Universal Time (UTC), adjusted to local time. + /// NTFS-formatted drives may cache file meta-info, such as file creation time, for a short period of time. + /// This process is known as file tunneling. As a result, it may be necessary to explicitly set the creation time of a file if you are + /// overwriting or replacing an existing file. + /// + /// The creation date and time of the current object. + /// + /// + /// + public DateTime CreationTime + { + [SecurityCritical] get { return CreationTimeUtc.ToLocalTime(); } + [SecurityCritical] set { CreationTimeUtc = value.ToUniversalTime(); } + } + + #endregion // CreationTime + + #region CreationTimeUtc + + /// Gets or sets the creation time, in coordinated universal time (UTC), of the current file or directory. + /// + /// The value of the CreationTimeUtc property is pre-cached + /// To get the latest value, call the Refresh method. + /// This method may return an inaccurate value, because it uses native functions + /// whose values may not be continuously updated by the operating system. + /// To get the latest value, call the Refresh method. + /// If the file described in the FileSystemInfo object does not exist, this property will return + /// 12:00 midnight, January 1, 1601 A.D. (C.E.) Coordinated Universal Time (UTC). + /// NTFS-formatted drives may cache file meta-info, such as file creation time, for a short period of time. + /// This process is known as file tunneling. As a result, it may be necessary to explicitly set the creation time + /// of a file if you are overwriting or replacing an existing file. + /// + /// The creation date and time in UTC format of the current object. + /// + /// + /// + [ComVisible(false)] + public DateTime CreationTimeUtc + { + [SecurityCritical] + get + { + if (DataInitialised == -1) + { + Win32AttributeData = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA(); + Refresh(); + } + + // MSDN: .NET 3.5+: IOException: Refresh cannot initialize the data. + if (DataInitialised != 0) + NativeError.ThrowException(DataInitialised, LongFullName); + + return DateTime.FromFileTimeUtc(Win32AttributeData.ftCreationTime); + } + + [SecurityCritical] + set + { + File.SetFsoDateTimeCore(IsDirectory, Transaction, LongFullName, value, null, null, false, PathFormat.LongFullPath); + Reset(); + } + } + + #endregion // CreationTimeUtc + + #region Exists + + /// + /// Gets a value indicating whether the file or directory exists. + /// + /// + /// The property returns if any error occurs while trying to determine if the + /// specified file or directory exists. + /// This can occur in situations that raise exceptions such as passing a directory- or file name with invalid characters or too + /// many characters, + /// a failing or missing disk, or if the caller does not have permission to read the file or directory. + /// + /// if the file or directory exists; otherwise, . + public abstract bool Exists { get; } + + #endregion // Exists + + #region Extension + + /// + /// Gets the string representing the extension part of the file. + /// + /// + /// The Extension property returns the extension, including the period (.). + /// For example, for a file c:\NewFile.txt, this property returns ".txt". + /// + /// A string containing the extension. + public string Extension + { + get { return Path.GetExtension(FullPath, false); } + } + + #endregion // Extension + + #region FullName + + /// + /// Gets the full path of the directory or file. + /// + /// A string containing the full path. + public virtual string FullName + { + [SecurityCritical] + get { return FullPath; } + } + + #endregion // FullName + + #region LastAccessTime + + /// Gets or sets the time the current file or directory was last accessed. + /// + /// The value of the LastAccessTime property is pre-cached + /// To get the latest value, call the Refresh method. + /// This method may return an inaccurate value, because it uses native functions + /// whose values may not be continuously updated by the operating system. + /// If the file described in the FileSystemInfo object does not exist, this property will return + /// 12:00 midnight, January 1, 1601 A.D. (C.E.) Coordinated Universal Time (UTC), adjusted to local time. + /// + /// The time that the current file or directory was last accessed. + /// + /// + public DateTime LastAccessTime + { + [SecurityCritical] get { return LastAccessTimeUtc.ToLocalTime(); } + [SecurityCritical] set { LastAccessTimeUtc = value.ToUniversalTime(); } + } + + #endregion // LastAccessTime + + #region LastAccessTimeUtc + + /// Gets or sets the time, in coordinated universal time (UTC), that the current file or directory was last accessed. + /// + /// The value of the LastAccessTimeUtc property is pre-cached. + /// To get the latest value, call the Refresh method. + /// This method may return an inaccurate value, because it uses native functions + /// whose values may not be continuously updated by the operating system. + /// If the file described in the FileSystemInfo object does not exist, this property will return + /// 12:00 midnight, January 1, 1601 A.D. (C.E.) Coordinated Universal Time (UTC), adjusted to local time. + /// + /// The UTC time that the current file or directory was last accessed. + /// + /// + [ComVisible(false)] + public DateTime LastAccessTimeUtc + { + [SecurityCritical] + get + { + if (DataInitialised == -1) + { + Win32AttributeData = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA(); + Refresh(); + } + + // MSDN: .NET 3.5+: IOException: Refresh cannot initialize the data. + if (DataInitialised != 0) + NativeError.ThrowException(DataInitialised, LongFullName); + + return DateTime.FromFileTimeUtc(Win32AttributeData.ftLastAccessTime); + } + + [SecurityCritical] + set + { + File.SetFsoDateTimeCore(IsDirectory, Transaction, LongFullName, null, value, null, false, PathFormat.LongFullPath); + Reset(); + } + } + + #endregion // LastAccessTimeUtc + + #region LastWriteTime + + /// Gets or sets the time when the current file or directory was last written to. + /// + /// The value of the LastWriteTime property is pre-cached. + /// To get the latest value, call the Refresh method. + /// This method may return an inaccurate value, because it uses native functions + /// whose values may not be continuously updated by the operating system. + /// If the file described in the FileSystemInfo object does not exist, this property will return + /// 12:00 midnight, January 1, 1601 A.D. (C.E.) Coordinated Universal Time (UTC), adjusted to local time. + /// + /// The time the current file was last written. + /// + /// + public DateTime LastWriteTime + { + get { return LastWriteTimeUtc.ToLocalTime(); } + set { LastWriteTimeUtc = value.ToUniversalTime(); } + } + + #endregion // LastWriteTime + + #region LastWriteTimeUtc + + /// Gets or sets the time, in coordinated universal time (UTC), when the current file or directory was last written to. + /// + /// The value of the LastWriteTimeUtc property is pre-cached. To get the latest value, call the Refresh method. + /// This method may return an inaccurate value, because it uses native functions whose values may not be continuously updated by + /// the operating system. + /// If the file described in the FileSystemInfo object does not exist, this property will return 12:00 midnight, January 1, 1601 + /// A.D. (C.E.) Coordinated Universal Time (UTC), adjusted to local time. + /// + /// The UTC time when the current file was last written to. + [ComVisible(false)] + public DateTime LastWriteTimeUtc + { + [SecurityCritical] + get + { + if (DataInitialised == -1) + { + Win32AttributeData = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA(); + Refresh(); + } + + // MSDN: .NET 3.5+: IOException: Refresh cannot initialize the data. + if (DataInitialised != 0) + NativeError.ThrowException(DataInitialised, LongFullName); + + return DateTime.FromFileTimeUtc(Win32AttributeData.ftLastWriteTime); + } + + [SecurityCritical] + set + { + File.SetFsoDateTimeCore(IsDirectory, Transaction, LongFullName, null, null, value, false, PathFormat.LongFullPath); + Reset(); + } + } + + #endregion // LastWriteTimeUtc + + #region Name + + /// + /// For files, gets the name of the file. For directories, gets the name of the last directory in the hierarchy if a hierarchy exists. + /// Otherwise, the Name property gets the name of the directory. + /// + /// + /// For a directory, Name returns only the name of the parent directory, such as Dir, not c:\Dir. + /// For a subdirectory, Name returns only the name of the subdirectory, such as Sub1, not c:\Dir\Sub1. + /// For a file, Name returns only the file name and file name extension, such as MyFile.txt, not c:\Dir\Myfile.txt. + /// + /// + /// A string that is the name of the parent directory, the name of the last directory in the hierarchy, + /// or the name of a file, including the file name extension. + /// + public abstract string Name { get; } + + #endregion // Name + + #endregion // .NET + + #region AlphaFS + + #region DisplayPath + + /// Returns the path as a string. + protected internal string DisplayPath { get; set; } + + #endregion // DisplayPath + + #region EntryInfo + + private FileSystemEntryInfo _entryInfo; + + /// [AlphaFS] Gets the instance of the class. + public FileSystemEntryInfo EntryInfo + { + [SecurityCritical] + get + { + if (_entryInfo == null) + { + Win32AttributeData = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA(); + RefreshEntryInfo(); + } + + // MSDN: .NET 3.5+: IOException: Refresh cannot initialize the data. + if (DataInitialised > 0) + NativeError.ThrowException(DataInitialised, LongFullName); + + return _entryInfo; + } + + internal set + { + _entryInfo = value; + + DataInitialised = value == null ? -1 : 0; + + if (DataInitialised == 0) + Win32AttributeData = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA(_entryInfo.Win32FindData); + } + } + + #endregion // EntryInfo + + #region IsDirectory + + /// [AlphaFS] The initial "IsDirectory" indicator that was passed to the constructor. + protected internal bool IsDirectory { get; set; } + + #endregion // IsDirectory + + #region LongFullName + + /// The full path of the file system object in Unicode (LongPath) format. + protected string LongFullName { get; set; } + + #endregion // LongFullName + + #region Transaction + + /// [AlphaFS] Represents the KernelTransaction that was passed to the constructor. + public KernelTransaction Transaction { get; set; } + + #endregion // Transaction + + #endregion // AlphaFS + + #endregion // Properties + + #region Fields + + // We use this field in conjunction with the Refresh methods, if we succeed + // we store a zero, on failure we store the HResult in it so that we can + // give back a generic error back. + [NonSerialized] internal int DataInitialised = -1; + + // The pre-cached FileSystemInfo information. + [NonSerialized] internal NativeMethods.WIN32_FILE_ATTRIBUTE_DATA Win32AttributeData; + + #region .NET + + /// Represents the fully qualified path of the file or directory. + /// + /// Classes derived from can use the FullPath field + /// to determine the full path of the object being manipulated. + /// + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")] + protected string FullPath; + + /// The path originally specified by the user, whether relative or absolute. + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")] + protected string OriginalPath; + + #endregion // .NET + + #endregion // Fields + } +} diff --git a/AlphaFS/Filesystem/FindFileSystemEntryInfo.cs b/AlphaFS/Filesystem/FindFileSystemEntryInfo.cs new file mode 100644 index 0000000..28601e7 --- /dev/null +++ b/AlphaFS/Filesystem/FindFileSystemEntryInfo.cs @@ -0,0 +1,387 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; +using System.Text.RegularExpressions; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Class that retrieves file system entries (i.e. files and directories) using Win32 API FindFirst()/FindNext(). + [SerializableAttribute] + internal sealed class FindFileSystemEntryInfo + { + private static readonly Regex WildcardMatchAll = new Regex(@"^(\*)+(\.\*+)+$", RegexOptions.IgnoreCase | RegexOptions.Compiled); // special case to recognize *.* or *.** etc + private Regex _nameFilter; + private string _searchPattern = Path.WildcardStarMatchAll; + + + public FindFileSystemEntryInfo(bool isFolder, KernelTransaction transaction, string path, string searchPattern, DirectoryEnumerationOptions options, Type typeOfT, PathFormat pathFormat) + { + Transaction = transaction; + + OriginalInputPath = path; + InputPath = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + IsRelativePath = !Path.IsPathRooted(OriginalInputPath, false); + + // .NET behaviour. + SearchPattern = searchPattern.TrimEnd(Path.TrimEndChars); + + FileSystemObjectType = null; + + ContinueOnException = (options & DirectoryEnumerationOptions.ContinueOnException) != 0; + + AsLongPath = (options & DirectoryEnumerationOptions.AsLongPath) != 0; + + AsString = typeOfT == typeof(string); + AsFileSystemInfo = !AsString && (typeOfT == typeof(FileSystemInfo) || typeOfT.BaseType == typeof(FileSystemInfo)); + + FindExInfoLevel = NativeMethods.IsAtLeastWindows7 && (options & DirectoryEnumerationOptions.BasicSearch) != 0 + ? NativeMethods.FINDEX_INFO_LEVELS.Basic + : NativeMethods.FINDEX_INFO_LEVELS.Standard; + + LargeCache = NativeMethods.IsAtLeastWindows7 && (options & DirectoryEnumerationOptions.LargeCache) != 0 + ? NativeMethods.FindExAdditionalFlags.LargeFetch + : NativeMethods.FindExAdditionalFlags.None; + + IsDirectory = isFolder; + + if (IsDirectory) + { + // Need files or folders to enumerate. + if ((options & DirectoryEnumerationOptions.FilesAndFolders) == 0) + options |= DirectoryEnumerationOptions.FilesAndFolders; + + FileSystemObjectType = (options & DirectoryEnumerationOptions.FilesAndFolders) == DirectoryEnumerationOptions.FilesAndFolders + ? (bool?) null + : (options & DirectoryEnumerationOptions.Folders) != 0; + + Recursive = (options & DirectoryEnumerationOptions.Recursive) != 0; + + SkipReparsePoints = (options & DirectoryEnumerationOptions.SkipReparsePoints) != 0; + } + } + + + + + private void ThrowPossibleException(uint lastError, string pathLp) + { + //Answer + + switch (lastError) + { + case Win32Errors.ERROR_NO_MORE_FILES: + lastError = Win32Errors.NO_ERROR; + break; + + case Win32Errors.ERROR_FILE_NOT_FOUND: + case Win32Errors.ERROR_PATH_NOT_FOUND: + // MSDN: .NET 3.5+: DirectoryNotFoundException: Path is invalid, such as referring to an unmapped drive. + // Directory.Delete() + + lastError = IsDirectory ? (int) Win32Errors.ERROR_PATH_NOT_FOUND : Win32Errors.ERROR_FILE_NOT_FOUND; + break; + + + //case Win32Errors.ERROR_DIRECTORY: + // // MSDN: .NET 3.5+: IOException: path is a file name. + // // Directory.EnumerateDirectories() + // // Directory.EnumerateFiles() + // // Directory.EnumerateFileSystemEntries() + // // Directory.GetDirectories() + // // Directory.GetFiles() + // // Directory.GetFileSystemEntries() + // break; + + //case Win32Errors.ERROR_ACCESS_DENIED: + // // MSDN: .NET 3.5+: UnauthorizedAccessException: The caller does not have the required permission. + // break; + } + + if (lastError != Win32Errors.NO_ERROR) + NativeError.ThrowException(lastError, pathLp); + } + + + private SafeFindFileHandle FindFirstFile(string pathLp, out NativeMethods.WIN32_FIND_DATA win32FindData) + { + var searchOption = null != FileSystemObjectType && (bool)FileSystemObjectType + ? NativeMethods.FINDEX_SEARCH_OPS.SearchLimitToDirectories + : NativeMethods.FINDEX_SEARCH_OPS.SearchNameMatch; + + + var handle = Transaction == null || !NativeMethods.IsAtLeastWindowsVista + + // FindFirstFileEx() / FindFirstFileTransacted() + // 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. + + // A trailing backslash is not allowed. + ? NativeMethods.FindFirstFileEx(Path.RemoveTrailingDirectorySeparator(pathLp, false), FindExInfoLevel, out win32FindData, searchOption, IntPtr.Zero, LargeCache) + : NativeMethods.FindFirstFileTransacted(Path.RemoveTrailingDirectorySeparator(pathLp, false), FindExInfoLevel, out win32FindData, searchOption, IntPtr.Zero, LargeCache, Transaction.SafeHandle); + + var lastError = Marshal.GetLastWin32Error(); + + if (handle.IsInvalid) + { + handle.Close(); + handle = null; + + if (!ContinueOnException) + ThrowPossibleException((uint)lastError, pathLp); + } + + return handle; + } + + + private T NewFileSystemEntryType(bool isFolder, NativeMethods.WIN32_FIND_DATA win32FindData, string fileName, string pathLp) + { + // Determine yield, e.g. don't return files when only folders are requested and vice versa. + if (null != FileSystemObjectType && (!(bool) FileSystemObjectType || !isFolder) && (!(bool) !FileSystemObjectType || isFolder)) + return (T) (object) null; + + // Determine yield. + if (null != fileName && !(_nameFilter == null || (_nameFilter != null && _nameFilter.IsMatch(fileName)))) + return (T) (object) null; + + + var fullPathLp = (IsRelativePath ? OriginalInputPath + Path.DirectorySeparator : pathLp) + (!Utils.IsNullOrWhiteSpace(fileName) ? fileName : string.Empty); + + + // Return object instance FullPath property as string, optionally in long path format. + if (AsString) + return (T) (object) (AsLongPath ? fullPathLp : Path.GetRegularPathCore(fullPathLp, GetFullPathOptions.None, false)); + + + // Make sure the requested file system object type is returned. + // null = Return files and directories. + // true = Return only directories. + // false = Return only files. + + var fsei = new FileSystemEntryInfo(win32FindData) {FullPath = fullPathLp}; + + return AsFileSystemInfo + // Return object instance of type FileSystemInfo. + ? (T) (object) (fsei.IsDirectory + ? (FileSystemInfo) + new DirectoryInfo(Transaction, fsei.LongFullPath, PathFormat.LongFullPath) {EntryInfo = fsei} + : new FileInfo(Transaction, fsei.LongFullPath, PathFormat.LongFullPath) {EntryInfo = fsei}) + + // Return object instance of type FileSystemEntryInfo. + : (T) (object) fsei; + } + + + + + /// Get an enumerator that returns all of the file system objects that match the wildcards that are in any of the directories to be searched. + /// An instance: FileSystemEntryInfo, DirectoryInfo, FileInfo or string (full path). + [SecurityCritical] + public IEnumerable Enumerate() + { + // MSDN: Queue + // Represents a first-in, first-out collection of objects. + // The capacity of a Queue is the number of elements the Queue can hold. + // As elements are added to a Queue, the capacity is automatically increased as required through reallocation. The capacity can be decreased by calling TrimToSize. + // The growth factor is the number by which the current capacity is multiplied when a greater capacity is required. The growth factor is determined when the Queue is constructed. + // The capacity of the Queue will always increase by a minimum value, regardless of the growth factor; a growth factor of 1.0 will not prevent the Queue from increasing in size. + // If the size of the collection can be estimated, specifying the initial capacity eliminates the need to perform a number of resizing operations while adding elements to the Queue. + // This constructor is an O(n) operation, where n is capacity. + + var dirs = new Queue(1000); + dirs.Enqueue(InputPath); + + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + while (dirs.Count > 0) + { + // Removes the object at the beginning of your Queue. + // The algorithmic complexity of this is O(1). It doesn't loop over elements. + + var path = Path.AddTrailingDirectorySeparator(dirs.Dequeue(), false); + var pathLp = path + Path.WildcardStarMatchAll; + NativeMethods.WIN32_FIND_DATA win32FindData; + + using (var handle = FindFirstFile(pathLp, out win32FindData)) + { + if (handle == null && ContinueOnException) + continue; + + do + { + var fileName = win32FindData.cFileName; + + // Skip entries "." and ".." + if (fileName.Equals(Path.CurrentDirectoryPrefix, StringComparison.OrdinalIgnoreCase) || + fileName.Equals(Path.ParentDirectoryPrefix, StringComparison.OrdinalIgnoreCase)) + continue; + + // Skip reparse points here to cleanly separate regular directories from links. + if (SkipReparsePoints && (win32FindData.dwFileAttributes & FileAttributes.ReparsePoint) != 0) + continue; + + + // If object is a folder, add it to the queue for later traversal. + var isFolder = (win32FindData.dwFileAttributes & FileAttributes.Directory) != 0; + + if (Recursive && (win32FindData.dwFileAttributes & FileAttributes.Directory) != 0) + dirs.Enqueue(path + fileName); + + + var res = NewFileSystemEntryType(isFolder, win32FindData, fileName, path); + if (res == null) + continue; + + yield return res; + + + } while (NativeMethods.FindNextFile(handle, out win32FindData)); + + + var lastError = Marshal.GetLastWin32Error(); + + if (!ContinueOnException) + ThrowPossibleException((uint)lastError, pathLp); + } + } + } + + + /// Gets a specific file system object. + /// + /// The return type is based on C# inference. Possible return types are: + /// - (full path), - ( or ), instance + /// or null in case an Exception is raised and is . + /// + [SecurityCritical] + public T Get() + { + NativeMethods.WIN32_FIND_DATA win32FindData; + + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + using (var handle = FindFirstFile(InputPath, out win32FindData)) + return handle == null + ? (T)(object)null + : NewFileSystemEntryType((win32FindData.dwFileAttributes & FileAttributes.Directory) != 0, win32FindData, null, InputPath); + } + + + + + /// Gets or sets the ability to return the object as a instance. + /// returns the object as a instance. + public bool AsFileSystemInfo { get; internal set; } + + + /// Gets or sets the ability to return the full path in long full path format. + /// returns the full path in long full path format, returns the full path in regular path format. + public bool AsLongPath { get; internal set; } + + + /// Gets or sets the ability to return the object instance as a . + /// returns the full path of the object as a + public bool AsString { get; internal set; } + + + /// Gets the value indicating which to use. + public NativeMethods.FINDEX_INFO_LEVELS FindExInfoLevel { get; internal set; } + + + /// Gets or sets the ability to skip on access errors. + /// suppress any Exception that might be thrown as a result from a failure, such as ACLs protected directories or non-accessible reparse points. + public bool ContinueOnException { get; internal set; } + + + /// Gets the file system object type. + /// + /// = Return files and directories. + /// = Return only directories. + /// = Return only files. + /// + public bool? FileSystemObjectType { get; set; } + + + /// Gets or sets if the path is an absolute or relative path. + /// Gets a value indicating whether the specified path string contains absolute or relative path information. + public bool IsRelativePath { get; set; } + + + /// Gets or sets the initial path to the folder. + /// The initial path to the file or folder in long path format. + public string OriginalInputPath { get; internal set; } + + + /// Gets or sets the path to the folder. + /// The path to the file or folder in long path format. + public string InputPath { get; internal set; } + + + /// Gets or sets a value indicating which to use. + /// indicates a folder object, indicates a file object. + public bool IsDirectory { get; internal set; } + + + /// Gets the value indicating which to use. + public NativeMethods.FindExAdditionalFlags LargeCache { get; internal set; } + + + /// Specifies whether the search should include only the current directory or should include all subdirectories. + /// to all subdirectories. + public bool Recursive { get; internal set; } + + + /// Search for file system object-name using a pattern. + /// The path which has wildcard characters, for example, an asterisk () or a question mark (). + [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] + public string SearchPattern + { + get { return _searchPattern; } + + internal set + { + if (null == value) + throw new ArgumentNullException("SearchPattern"); + + _searchPattern = value; + + _nameFilter = _searchPattern == Path.WildcardStarMatchAll || WildcardMatchAll.IsMatch(_searchPattern) + ? null + : new Regex(string.Format(CultureInfo.CurrentCulture, "^{0}$", Regex.Escape(_searchPattern).Replace(@"\*", ".*").Replace(@"\?", ".")), RegexOptions.IgnoreCase | RegexOptions.Compiled); + } + } + + + /// skips ReparsePoints, will follow ReparsePoints. + public bool SkipReparsePoints { get; internal set; } + + + /// Get or sets the KernelTransaction instance. + /// The transaction. + public KernelTransaction Transaction { get; internal set; } + } +} diff --git a/AlphaFS/Filesystem/KernelTransaction.cs b/AlphaFS/Filesystem/KernelTransaction.cs new file mode 100644 index 0000000..0501d4a --- /dev/null +++ b/AlphaFS/Filesystem/KernelTransaction.cs @@ -0,0 +1,159 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.AccessControl; +using System.Security.Permissions; +using System.Transactions; + +namespace Alphaleonis.Win32.Filesystem +{ + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("79427A2B-F895-40e0-BE79-B57DC82ED231")] + [SuppressUnmanagedCodeSecurity] + internal interface IKernelTransaction + { + void GetHandle([Out] out SafeKernelTransactionHandle handle); + } + + /// A KTM transaction object for use with the transacted operations in + public sealed class KernelTransaction : MarshalByRefObject, IDisposable + { + /// Initializes a new instance of the class, internally using the specified . + /// This method allows the usage of methods accepting a with an instance of . + /// + /// The transaction to use for any transactional operations. + [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] + [SecurityCritical] + public KernelTransaction(Transaction transaction) + { + ((IKernelTransaction) TransactionInterop.GetDtcTransaction(transaction)).GetHandle(out _hTrans); + } + + /// Initializes a new instance of the class with a default security descriptor, infinite timeout and no description. + [SecurityCritical] + public KernelTransaction() + : this(0, null) + { + } + + /// Initializes a new instance of the class with a default security descriptor. + /// The time, in milliseconds, when the transaction will be aborted if it has not already reached the prepared state. + /// A user-readable description of the transaction. This parameter may be . + [SecurityCritical] + public KernelTransaction(int timeout, string description) + : this(null, timeout, description) + { + } + + /// Initializes a new instance of the class. + /// The security descriptor. + /// The time, in milliseconds, when the transaction will be aborted if it has not already reached the prepared state. + /// Specify 0 to provide an infinite timeout. + /// A user-readable description of the transaction. This parameter may be . + [SecurityCritical] + 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); + } + } + + /// Requests that the specified transaction be committed. + /// + /// + /// + [SecurityCritical] + public void Commit() + { + if (!NativeMethods.IsAtLeastWindowsVista) + throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher); + + if (!NativeMethods.CommitTransaction(_hTrans)) + CheckTransaction(); + } + + /// Requests that the specified transaction be rolled back. This function is synchronous. + /// + /// + [SecurityCritical] + public void Rollback() + { + if (!NativeMethods.IsAtLeastWindowsVista) + throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher); + + if (!NativeMethods.RollbackTransaction(_hTrans)) + CheckTransaction(); + } + + private static void CheckTransaction() + { + uint error = (uint) Marshal.GetLastWin32Error(); + int hr = Marshal.GetHRForLastWin32Error(); + + switch (error) + { + case Win32Errors.ERROR_TRANSACTION_ALREADY_ABORTED: + throw new TransactionAlreadyAbortedException("Transaction was already aborted", Marshal.GetExceptionForHR(hr)); + + case Win32Errors.ERROR_TRANSACTION_ALREADY_COMMITTED: + throw new TransactionAlreadyAbortedException("Transaction was already committed", Marshal.GetExceptionForHR(hr)); + + default: + Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); + break; + } + } + + /// Gets the safe handle. + /// The safe handle. + public SafeHandle SafeHandle + { + get { return _hTrans; } + } + + private readonly SafeKernelTransactionHandle _hTrans; + + #region IDisposable Members + + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + [SecurityPermissionAttribute(SecurityAction.Demand, UnmanagedCode = true)] + public void Dispose() + { + _hTrans.Close(); + } + + #endregion // IDisposable Members + } +} diff --git a/AlphaFS/Filesystem/LinkTargetInfo.cs b/AlphaFS/Filesystem/LinkTargetInfo.cs new file mode 100644 index 0000000..5e9876a --- /dev/null +++ b/AlphaFS/Filesystem/LinkTargetInfo.cs @@ -0,0 +1,39 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + /// Information about the target of a symbolic link or mount point. + public class LinkTargetInfo + { + internal LinkTargetInfo(string substituteName, string printName) + { + PrintName = printName; + SubstituteName = substituteName; + } + + /// The print name. + public string PrintName { get; private set; } + + /// The substitute name. + public string SubstituteName { get; private set; } + } +} diff --git a/AlphaFS/Filesystem/Native Methods/NativeMethods.BackupStreams.cs b/AlphaFS/Filesystem/Native Methods/NativeMethods.BackupStreams.cs new file mode 100644 index 0000000..0e56e35 --- /dev/null +++ b/AlphaFS/Filesystem/Native Methods/NativeMethods.BackupStreams.cs @@ -0,0 +1,121 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Microsoft.Win32.SafeHandles; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// The BackupRead function can be used to back up a file or directory, including the security information. + /// The function reads data associated with a specified file or directory into a buffer, + /// which can then be written to the backup medium using the WriteFile function. + /// + /// + /// This function is not intended for use in backing up files encrypted under the Encrypted File System. + /// Use ReadEncryptedFileRaw for that purpose. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + /// The file. + /// The buffer. + /// Number of bytes to reads. + /// [out] Number of bytes reads. + /// true to abort. + /// true to process security. + /// [out] The context. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero, indicating that an I/O error occurred. To get extended error information, + /// call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool BackupRead(SafeFileHandle hFile, SafeGlobalMemoryBufferHandle lpBuffer, [MarshalAs(UnmanagedType.U4)] uint nNumberOfBytesToRead, [MarshalAs(UnmanagedType.U4)] out uint lpNumberOfBytesRead, [MarshalAs(UnmanagedType.Bool)] bool bAbort, [MarshalAs(UnmanagedType.Bool)] bool bProcessSecurity, ref IntPtr lpContext); + + + /// The BackupSeek function seeks forward in a data stream initially accessed by using the or + /// function. + /// The function reads data associated with a specified file or directory into a buffer, which can then be written to the backup + /// medium using the WriteFile function. + /// + /// + /// Applications use the BackupSeek function to skip portions of a data stream that cause errors. + /// This function does not seek across stream headers. For example, this function cannot be used to skip the stream name. + /// If an application attempts to seek past the end of a substream, the function fails, the lpdwLowByteSeeked and + /// lpdwHighByteSeeked parameters + /// indicate the actual number of bytes the function seeks, and the file position is placed at the start of the next stream + /// header. + ///   + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + /// The file. + /// The low bytes to seek. + /// The high bytes to seek. + /// [out] The lpdw low bytes seeked. + /// [out] The lpdw high bytes seeked. + /// [out] The context. + /// + /// If the function could seek the requested amount, the function returns a nonzero value. + /// If the function could not seek the requested amount, the function returns zero. To get extended error information, call + /// GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool BackupSeek(SafeFileHandle hFile, [MarshalAs(UnmanagedType.U4)] uint dwLowBytesToSeek, [MarshalAs(UnmanagedType.U4)] uint dwHighBytesToSeek, [MarshalAs(UnmanagedType.U4)] out uint lpdwLowBytesSeeked, [MarshalAs(UnmanagedType.U4)] out uint lpdwHighBytesSeeked, ref IntPtr lpContext); + + + /// The BackupWrite function can be used to restore a file or directory that was backed up using . + /// Use the ReadFile function to get a stream of data from the backup medium, then use BackupWrite to write the data to the + /// specified file or directory. + ///   + /// + /// + /// This function is not intended for use in restoring files encrypted under the Encrypted File System. Use WriteEncryptedFileRaw + /// for that purpose. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + /// The file. + /// The buffer. + /// Number of bytes to writes. + /// [out] Number of bytes writtens. + /// true to abort. + /// true to process security. + /// [out] The context. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero, indicating that an I/O error occurred. To get extended error information, + /// call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool BackupWrite(SafeFileHandle hFile, SafeGlobalMemoryBufferHandle lpBuffer, [MarshalAs(UnmanagedType.U4)] uint nNumberOfBytesToWrite, [MarshalAs(UnmanagedType.U4)] out uint lpNumberOfBytesWritten, [MarshalAs(UnmanagedType.Bool)] bool bAbort, [MarshalAs(UnmanagedType.Bool)] bool bProcessSecurity, ref IntPtr lpContext); + } +} diff --git a/AlphaFS/Filesystem/Native Methods/NativeMethods.Constants.cs b/AlphaFS/Filesystem/Native Methods/NativeMethods.Constants.cs new file mode 100644 index 0000000..6f87972 --- /dev/null +++ b/AlphaFS/Filesystem/Native Methods/NativeMethods.Constants.cs @@ -0,0 +1,67 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + public static readonly bool IsAtLeastWindows7 = OperatingSystem.IsAtLeast(OperatingSystem.EnumOsName.Windows7); + public static readonly bool IsAtLeastWindowsVista = OperatingSystem.IsAtLeast(OperatingSystem.EnumOsName.WindowsVista); + + /// The FindFirstFileEx function does not query the short file name, improving overall enumeration speed. + ///   + /// + /// The data is returned in a structure, + /// and cAlternateFileName member is always a NULL string. + /// This value is not supported until Windows Server 2008 R2 and Windows 7. + /// + /// + public static readonly FINDEX_INFO_LEVELS FindexInfoLevels = IsAtLeastWindows7 ? FINDEX_INFO_LEVELS.Basic : FINDEX_INFO_LEVELS.Standard; + + /// Uses a larger buffer for directory queries, which can increase performance of the find operation. + /// This value is not supported until Windows Server 2008 R2 and Windows 7. + public static readonly FindExAdditionalFlags LargeCache = IsAtLeastWindows7 ? FindExAdditionalFlags.LargeFetch : FindExAdditionalFlags.None; + + /// DefaultFileBufferSize = 4096; Default type buffer size used for reading and writing files. + public const int DefaultFileBufferSize = 4096; + + /// DefaultFileEncoding = Encoding.UTF8; Default type of Encoding used for reading and writing files. + public static readonly Encoding DefaultFileEncoding = Encoding.UTF8; + + /// MaxDirectoryLength = 255 + internal const int MaxDirectoryLength = 255; + + /// MaxPath = 260 + /// The specified path, file name, or both exceed the system-defined maximum length. + /// For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. + /// + internal const int MaxPath = 260; + + /// MaxPathUnicode = 32000 + internal const int MaxPathUnicode = 32000; + + + /// When an exception is raised, bit shifting is needed to prevent: "System.OverflowException: Arithmetic operation resulted in an overflow." + internal const int OverflowExceptionBitShift = 65535; + } +} diff --git a/AlphaFS/Filesystem/Native Methods/NativeMethods.DeviceManagement.cs b/AlphaFS/Filesystem/Native Methods/NativeMethods.DeviceManagement.cs new file mode 100644 index 0000000..c1265ec --- /dev/null +++ b/AlphaFS/Filesystem/Native Methods/NativeMethods.DeviceManagement.cs @@ -0,0 +1,291 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Microsoft.Win32.SafeHandles; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + #region CM_Xxx + + /// The CM_Connect_Machine function creates a connection to a remote machine. + /// + /// Beginning in Windows 8 and Windows Server 2012 functionality to access remote machines has been removed. + /// You cannot access remote machines when running on these versions of Windows. + /// Available in Microsoft Windows 2000 and later versions of Windows. + /// + /// Name of the unc server. + /// [out] The ph machine. + /// + /// If the operation succeeds, the function returns CR_SUCCESS. + /// Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CM_Connect_MachineW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.I4)] + public static extern int CM_Connect_Machine([MarshalAs(UnmanagedType.LPWStr)] string uncServerName, out SafeCmConnectMachineHandle phMachine); + + /// + /// The CM_Get_Device_ID_Ex function retrieves the device instance ID for a specified device instance on a local or a remote machine. + /// + /// + /// Beginning in Windows 8 and Windows Server 2012 functionality to access remote machines has been removed. + /// You cannot access remote machines when running on these versions of Windows. + ///   + /// Available in Microsoft Windows 2000 and later versions of Windows. + /// + /// The dn development instance. + /// The buffer. + /// Length of the buffer. + /// The ul flags. + /// The machine. + /// + /// If the operation succeeds, the function returns CR_SUCCESS. + /// Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CM_Get_Device_ID_ExW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.I4)] + public static extern int CM_Get_Device_ID_Ex([MarshalAs(UnmanagedType.U4)] uint dnDevInst, SafeGlobalMemoryBufferHandle buffer, [MarshalAs(UnmanagedType.U4)] uint bufferLen, [MarshalAs(UnmanagedType.U4)] uint ulFlags, SafeCmConnectMachineHandle hMachine); + + /// + /// The CM_Disconnect_Machine function removes a connection to a remote machine. + /// + /// + /// Beginning in Windows 8 and Windows Server 2012 functionality to access remote machines has been removed. + /// You cannot access remote machines when running on these versions of Windows. + /// SetLastError is set to . + /// Available in Microsoft Windows 2000 and later versions of Windows. + /// + /// The machine. + /// + /// If the operation succeeds, the function returns CR_SUCCESS. + /// Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("setupapi.dll", SetLastError = false, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.I4)] + internal static extern int CM_Disconnect_Machine(IntPtr hMachine); + + /// + /// The CM_Get_Parent_Ex function obtains a device instance handle to the parent node of a specified device node (devnode) in a local + /// or a remote machine's device tree. + /// + /// + /// Beginning in Windows 8 and Windows Server 2012 functionality to access remote machines has been removed. + /// You cannot access remote machines when running on these versions of Windows. + /// Available in Microsoft Windows 2000 and later versions of Windows. + /// + /// [out] The pdn development instance. + /// The dn development instance. + /// The ul flags. + /// The machine. + /// + /// If the operation succeeds, the function returns CR_SUCCESS. + /// Otherwise, it returns one of the CR_-prefixed error codes defined in Cfgmgr32.h. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.I4)] + internal static extern int CM_Get_Parent_Ex([MarshalAs(UnmanagedType.U4)] out uint pdnDevInst, [MarshalAs(UnmanagedType.U4)] uint dnDevInst, [MarshalAs(UnmanagedType.U4)] uint ulFlags, SafeCmConnectMachineHandle hMachine); + + #endregion // CM_Xxx + + #region DeviceIoControl + + /// Sends a control code directly to a specified device driver, causing the corresponding device to perform the corresponding operation. + /// + /// If the operation completes successfully, the return value is nonzero. + /// If the operation fails or is pending, the return value is zero. To get extended error information, call GetLastError. + /// + /// + /// To retrieve a handle to the device, you must call the function with either the name of a device or + /// the name of the driver associated with a device. + /// To specify a device name, use the following format: \\.\DeviceName + /// Minimum supported client: Windows XP + /// Minimum supported server: Windows Server 2003 + /// + /// The device. + /// The i/o control code. + /// Buffer for in data. + /// Size of the in buffer. + /// Buffer for out data. + /// Size of the out buffer. + /// [out] The bytes returned. + /// The overlapped. + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl(SafeFileHandle hDevice, [MarshalAs(UnmanagedType.U4)] uint dwIoControlCode, IntPtr lpInBuffer, [MarshalAs(UnmanagedType.U4)] uint nInBufferSize, SafeGlobalMemoryBufferHandle lpOutBuffer, [MarshalAs(UnmanagedType.U4)] uint nOutBufferSize, [MarshalAs(UnmanagedType.U4)] out uint lpBytesReturned, IntPtr lpOverlapped); + + /// Sends a control code directly to a specified device driver, causing the corresponding device to perform the corresponding operation. + /// + /// If the operation completes successfully, the return value is nonzero. + /// If the operation fails or is pending, the return value is zero. To get extended error information, call GetLastError. + /// + /// + /// To retrieve a handle to the device, you must call the function with either the name of a device or + /// the name of the driver associated with a device. + /// To specify a device name, use the following format: \\.\DeviceName + /// Minimum supported client: Windows XP + /// Minimum supported server: Windows Server 2003 + /// + /// The device. + /// The i/o control code. + /// Buffer for in data. + /// Size of the in buffer. + /// Buffer for out data. + /// Size of the out buffer. + /// [out] The bytes returned. + /// The overlapped. + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl(SafeFileHandle hDevice, [MarshalAs(UnmanagedType.U4)] uint dwIoControlCode, [MarshalAs(UnmanagedType.AsAny)] object lpInBuffer, [MarshalAs(UnmanagedType.U4)] uint nInBufferSize, [MarshalAs(UnmanagedType.AsAny)] [Out] object lpOutBuffer, [MarshalAs(UnmanagedType.U4)] uint nOutBufferSize, [MarshalAs(UnmanagedType.U4)] out uint lpBytesReturned, IntPtr lpOverlapped); + + #endregion // DeviceIoControl + + #region SetupDiXxx + + /// + /// The SetupDiDestroyDeviceInfoList function deletes a device information set and frees all associated memory. + /// + /// + /// SetLastError is set to . + /// Available in Microsoft Windows 2000 and later versions of Windows. + /// + /// Information describing the development. + /// + /// The function returns TRUE if it is successful. + /// Otherwise, it returns FALSE and the logged error can be retrieved with a call to GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("setupapi.dll", SetLastError = false, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool SetupDiDestroyDeviceInfoList(IntPtr hDevInfo); + + /// + /// The SetupDiEnumDeviceInterfaces function enumerates the device interfaces that are contained in a device information set. + /// + /// + /// Repeated calls to this function return an structure for a different device + /// interface. + /// This function can be called repeatedly to get information about interfaces in a device information set that are + /// associated + /// with a particular device information element or that are associated with all device information elements. + /// Available in Microsoft Windows 2000 and later versions of Windows. + /// + /// Information describing the development. + /// Information describing the development. + /// [in,out] Unique identifier for the interface class. + /// Zero-based index of the member. + /// [in,out] Information describing the device interface. + /// + /// SetupDiEnumDeviceInterfaces returns TRUE if the function completed without error. + /// If the function completed with an error, FALSE is returned and the error code for the failure can be retrieved by calling + /// GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool SetupDiEnumDeviceInterfaces(SafeHandle hDevInfo, IntPtr devInfo, ref Guid interfaceClassGuid, [MarshalAs(UnmanagedType.U4)] uint memberIndex, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData); + + /// + /// The SetupDiGetClassDevsEx function returns a handle to a device information set that contains requested device information elements + /// for a local or a remote computer. + /// + /// + /// The caller of SetupDiGetClassDevsEx must delete the returned device information set when it is no longer needed by calling + /// . + /// Available in Microsoft Windows 2000 and later versions of Windows. + /// + /// [in,out] Unique identifier for the class. + /// The enumerator. + /// The parent. + /// The devs ex flags. + /// Set the device information belongs to. + /// Name of the machine. + /// The reserved. + /// + /// If the operation succeeds, SetupDiGetClassDevsEx returns a handle to a device information set that contains all installed + /// devices that matched the supplied parameters. + /// If the operation fails, the function returns INVALID_HANDLE_VALUE. To get extended error information, call + /// GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + internal static extern SafeSetupDiClassDevsExHandle SetupDiGetClassDevsEx(ref Guid classGuid, IntPtr enumerator, IntPtr hwndParent, [MarshalAs(UnmanagedType.U4)] SetupDiGetClassDevsExFlags devsExFlags, IntPtr deviceInfoSet, [MarshalAs(UnmanagedType.LPWStr)] string machineName, IntPtr reserved); + + /// + /// The SetupDiGetDeviceInterfaceDetail function returns details about a device interface. + /// + /// + /// The interface detail returned by this function consists of a device path that can be passed to Win32 functions such as + /// CreateFile. + /// Do not attempt to parse the device path symbolic name. The device path can be reused across system starts. + /// Available in Microsoft Windows 2000 and later versions of Windows. + /// + /// Information describing the development. + /// [in,out] Information describing the device interface. + /// [in,out] Information describing the device interface detail. + /// Size of the device interface detail data. + /// Size of the required. + /// [in,out] Information describing the device information. + /// + /// SetupDiGetDeviceInterfaceDetail returns TRUE if the function completed without error. + /// If the function completed with an error, FALSE is returned and the error code for the failure can be retrieved by calling + /// GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool SetupDiGetDeviceInterfaceDetail(SafeHandle hDevInfo, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData, [MarshalAs(UnmanagedType.U4)] uint deviceInterfaceDetailDataSize, IntPtr requiredSize, ref SP_DEVINFO_DATA deviceInfoData); + + /// + /// The SetupDiGetDeviceRegistryProperty function retrieves a specified Plug and Play device property. + /// + /// Available in Microsoft Windows 2000 and later versions of Windows. + /// Set the device information belongs to. + /// [in,out] Information describing the device information. + /// The property. + /// [out] Type of the property register data. + /// Buffer for property data. + /// Size of the property buffer. + /// Size of the required. + /// + /// SetupDiGetDeviceRegistryProperty returns TRUE if the call was successful. + /// Otherwise, it returns FALSE and the logged error can be retrieved by making a call to GetLastError. + /// SetupDiGetDeviceRegistryProperty returns the ERROR_INVALID_DATA error code if the requested property does not exist for a + /// device or if the property data is not valid. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool SetupDiGetDeviceRegistryProperty(SafeHandle deviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, SetupDiGetDeviceRegistryPropertyEnum property, [MarshalAs(UnmanagedType.U4)] out uint propertyRegDataType, SafeGlobalMemoryBufferHandle propertyBuffer, [MarshalAs(UnmanagedType.U4)] uint propertyBufferSize, IntPtr requiredSize); + + #endregion // SetupDiXxx + } +} diff --git a/AlphaFS/Filesystem/Native Methods/NativeMethods.DirectoryManagement.cs b/AlphaFS/Filesystem/Native Methods/NativeMethods.DirectoryManagement.cs new file mode 100644 index 0000000..0ee7079 --- /dev/null +++ b/AlphaFS/Filesystem/Native Methods/NativeMethods.DirectoryManagement.cs @@ -0,0 +1,208 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// + /// Creates a new directory. + /// If the underlying file system supports security on files and directories, + /// the function applies a specified security descriptor to the new directory. + /// + /// + /// Some file systems, such as the NTFS file system, support compression or encryption for individual files and + /// directories. + /// On volumes formatted for such a file system, a new directory inherits the compression and encryption attributes of its parent + /// directory. + /// An application can obtain a handle to a directory by calling with the FILE_FLAG_BACKUP_SEMANTICS + /// flag set. + /// Minimum supported client: Windows XP [desktop apps | Windows Store apps] + /// Minimum supported server: Windows Server 2003 [desktop apps | Windows Store apps] + /// + /// Full pathname of the file. + /// The security attributes. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateDirectoryW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CreateDirectory([MarshalAs(UnmanagedType.LPWStr)] string lpPathName, [MarshalAs(UnmanagedType.LPStruct)] Security.NativeMethods.SecurityAttributes lpSecurityAttributes); + + /// + /// Creates a new directory with the attributes of a specified template directory. + /// If the underlying file system supports security on files and directories, + /// the function applies a specified security descriptor to the new directory. + /// The new directory retains the other attributes of the specified template directory. + /// + /// + /// The CreateDirectoryEx function allows you to create directories that inherit stream information from other directories. + /// This function is useful, for example, when you are using Macintosh directories, which have a resource stream + /// that is needed to properly identify directory contents as an attribute. + /// Some file systems, such as the NTFS file system, support compression or encryption for individual files and + /// directories. + /// On volumes formatted for such a file system, a new directory inherits the compression and encryption attributes of its parent + /// directory. + /// You can obtain a handle to a directory by calling the function with the FILE_FLAG_BACKUP_SEMANTICS + /// flag set. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + /// Pathname of the template directory. + /// Full pathname of the file. + /// The security attributes. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero (0). To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateDirectoryExW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CreateDirectoryEx([MarshalAs(UnmanagedType.LPWStr)] string lpTemplateDirectory, [MarshalAs(UnmanagedType.LPWStr)] string lpPathName, [MarshalAs(UnmanagedType.LPStruct)] Security.NativeMethods.SecurityAttributes lpSecurityAttributes); + + /// + /// Creates a new directory as a transacted operation, with the attributes of a specified template directory. + /// If the underlying file system supports security on files and directories, + /// the function applies a specified security descriptor to the new directory. + /// The new directory retains the other attributes of the specified template directory. + /// + /// + /// The CreateDirectoryTransacted function allows you to create directories that inherit stream information from other + /// directories. + /// This function is useful, for example, when you are using Macintosh directories, which have a resource stream + /// that is needed to properly identify directory contents as an attribute. + /// Some file systems, such as the NTFS file system, support compression or encryption for individual files and + /// directories. + /// On volumes formatted for such a file system, a new directory inherits the compression and encryption attributes of its parent + /// directory. + /// You can obtain a handle to a directory by calling the function with the + /// FILE_FLAG_BACKUP_SEMANTICS flag set. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + /// Pathname of the template directory. + /// Pathname of the new directory. + /// The security attributes. + /// The transaction. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero (0). To get extended error information, call GetLastError. + /// This function fails with ERROR_EFS_NOT_ALLOWED_IN_TRANSACTION if you try to create a + /// child directory with a parent directory that has encryption disabled. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateDirectoryTransactedW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CreateDirectoryTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpTemplateDirectory, [MarshalAs(UnmanagedType.LPWStr)] string lpNewDirectory, [MarshalAs(UnmanagedType.LPStruct)] Security.NativeMethods.SecurityAttributes lpSecurityAttributes, SafeHandle hTransaction); + + /// + /// Retrieves the current directory for the current process. + /// + /// + /// The RemoveDirectory function marks a directory for deletion on close. + /// Therefore, the directory is not removed until the last handle to the directory is closed. + /// RemoveDirectory removes a directory junction, even if the contents of the target are not empty; + /// the function removes directory junctions regardless of the state of the target object. + /// Minimum supported client: Windows XP [desktop apps | Windows Store apps] + /// Minimum supported server: Windows Server 2003 [desktop apps | Windows Store apps] + /// + /// The length of the buffer for the current directory string, in TCHARs. The buffer length must include room for a terminating null character. + /// + /// A pointer to the buffer that receives the current directory string. This null-terminated string specifies the absolute path to the current directory. + /// To determine the required buffer size, set this parameter to NULL and the nBufferLength parameter to 0. + /// + /// + /// If the function succeeds, the return value specifies the number of characters that are written to the buffer, not including the terminating null character. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Usage", "CA2205:UseManagedEquivalentsOfWin32Api")] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetCurrentDirectoryW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint GetCurrentDirectory([MarshalAs(UnmanagedType.U4)] uint nBufferLength, StringBuilder lpBuffer); + + /// + /// Deletes an existing empty directory. + /// + /// + /// The RemoveDirectory function marks a directory for deletion on close. + /// Therefore, the directory is not removed until the last handle to the directory is closed. + /// RemoveDirectory removes a directory junction, even if the contents of the target are not empty; + /// the function removes directory junctions regardless of the state of the target object. + /// Minimum supported client: Windows XP [desktop apps | Windows Store apps] + /// Minimum supported server: Windows Server 2003 [desktop apps | Windows Store apps] + /// + /// Full pathname of the file. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "RemoveDirectoryW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool RemoveDirectory([MarshalAs(UnmanagedType.LPWStr)] string lpPathName); + + /// + /// Deletes an existing empty directory as a transacted operation. + /// + /// + /// The RemoveDirectoryTransacted function marks a directory for deletion on close. + /// Therefore, the directory is not removed until the last handle to the directory is closed. + /// RemoveDirectory removes a directory junction, even if the contents of the target are not empty; + /// the function removes directory junctions regardless of the state of the target object. + /// Minimum supported client: Windows Vista [desktop apps only] + /// Minimum supported server: Windows Server 2008 [desktop apps only] + /// + /// Full pathname of the file. + /// The transaction. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "RemoveDirectoryTransactedW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool RemoveDirectoryTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpPathName, SafeHandle hTransaction); + + /// + /// Changes the current directory for the current process. + /// + /// + /// The path to the new current directory. This parameter may specify a relative path or a full path. In either case, the full path of the specified directory is calculated and stored as the current directory. + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Usage", "CA2205:UseManagedEquivalentsOfWin32Api")] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "SetCurrentDirectoryW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool SetCurrentDirectory([MarshalAs(UnmanagedType.LPWStr)] string lpPathName); + } +} diff --git a/AlphaFS/Filesystem/Native Methods/NativeMethods.DiskManagement.cs b/AlphaFS/Filesystem/Native Methods/NativeMethods.DiskManagement.cs new file mode 100644 index 0000000..1853217 --- /dev/null +++ b/AlphaFS/Filesystem/Native Methods/NativeMethods.DiskManagement.cs @@ -0,0 +1,84 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// + /// Retrieves information about the specified disk, including the amount of free space on the disk. + /// + /// + /// Symbolic link behavior: If the path points to a symbolic link, the operation is performed on the target. + /// If this parameter is a UNC name, it must include a trailing backslash (for example, "\\MyServer\MyShare\"). + /// Furthermore, a drive specification must have a trailing backslash (for example, "C:\"). + /// The calling application must have FILE_LIST_DIRECTORY access rights for this directory. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + /// Full pathname of the root file. + /// [out] The sectors per cluster. + /// [out] The bytes per sector. + /// [out] Number of free clusters. + /// [out] The total number of clusters. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetDiskFreeSpaceW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetDiskFreeSpace([MarshalAs(UnmanagedType.LPWStr)] string lpRootPathName, [MarshalAs(UnmanagedType.U4)] out int lpSectorsPerCluster, [MarshalAs(UnmanagedType.U4)] out int lpBytesPerSector, [MarshalAs(UnmanagedType.U4)] out int lpNumberOfFreeClusters, [MarshalAs(UnmanagedType.U4)] out uint lpTotalNumberOfClusters); + + /// + /// Retrieves information about the amount of space that is available on a disk volume, which is the total amount of space, + /// the total amount of free space, and the total amount of free space available to the user that is associated with the calling + /// thread. + /// + /// + /// Symbolic link behavior: If the path points to a symbolic link, the operation is performed on the target. + /// The GetDiskFreeSpaceEx function returns zero (0) for lpTotalNumberOfFreeBytes and lpFreeBytesAvailable + /// for all CD requests unless the disk is an unwritten CD in a CD-RW drive. + /// If this parameter is a UNC name, it must include a trailing backslash, for example, "\\MyServer\MyShare\". + /// This parameter does not have to specify the root directory on a disk. + /// The function accepts any directory on a disk. + /// The calling application must have FILE_LIST_DIRECTORY access rights for this directory. + /// Minimum supported client: Windows XP [desktop apps | Windows Store apps] + /// Minimum supported server: Windows Server 2003 [desktop apps | Windows Store apps] + /// + /// Pathname of the directory. + /// [out] The free bytes available. + /// [out] The total number of in bytes. + /// [out] The total number of free in bytes. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero (0). To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetDiskFreeSpaceExW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetDiskFreeSpaceEx([MarshalAs(UnmanagedType.LPWStr)] string lpDirectoryName, [MarshalAs(UnmanagedType.U8)] out long lpFreeBytesAvailable, [MarshalAs(UnmanagedType.U8)] out long lpTotalNumberOfBytes, [MarshalAs(UnmanagedType.U8)] out long lpTotalNumberOfFreeBytes); + } +} diff --git a/AlphaFS/Filesystem/Native Methods/NativeMethods.EncryptedFileRaw.cs b/AlphaFS/Filesystem/Native Methods/NativeMethods.EncryptedFileRaw.cs new file mode 100644 index 0000000..1e94f71 --- /dev/null +++ b/AlphaFS/Filesystem/Native Methods/NativeMethods.EncryptedFileRaw.cs @@ -0,0 +1,62 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + partial class NativeMethods + { + /// Opens an encrypted file in order to backup (export) or restore (import) the file. + /// If the function succeeds, it returns ERROR_SUCCESS. + /// If the function fails, it returns a nonzero error code defined in WinError.h. You can use FormatMessage with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic text description of the error. + /// Minimum supported client: Windows XP Professional [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// The name of the file to be opened. + /// The operation to be performed. + /// [out] The address of a context block that must be presented in subsequent calls to + /// ReadEncryptedFileRaw, WriteEncryptedFileRaw, or CloseEncryptedFileRaw. + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "OpenEncryptedFileRawW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint OpenEncryptedFileRaw([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, EncryptedFileRawMode ulFlags, out SafeEncryptedFileRawHandle pvContext); + + + /// Closes an encrypted file after a backup or restore operation, and frees associated system resources. + /// Minimum supported client: Windows XP Professional [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// A pointer to a system-defined context block. The OpenEncryptedFileRaw function returns the context block. + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + internal static extern void CloseEncryptedFileRaw(IntPtr pvContext); + + + /// Backs up (export) encrypted files. This is one of a group of Encrypted File System (EFS) functions that is intended to implement backup and restore functionality, while maintaining files in their encrypted state. + /// If the function succeeds, it returns ERROR_SUCCESS. + /// If the function fails, it returns a nonzero error code defined in WinError.h. You can use FormatMessage with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic text description of the error. + /// Minimum supported client: Windows XP Professional [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule"), SuppressUnmanagedCodeSecurity] + [DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint ReadEncryptedFileRaw([MarshalAs(UnmanagedType.FunctionPtr)] EncryptedFileRawExportCallback pfExportCallback, IntPtr pvCallbackContext, SafeEncryptedFileRawHandle pvContext); + + + /// Restores (import) encrypted files. This is one of a group of Encrypted File System (EFS) functions that is intended to implement backup and restore functionality, while maintaining files in their encrypted state. + /// If the function succeeds, it returns ERROR_SUCCESS. + /// If the function fails, it returns a nonzero error code defined in WinError.h. You can use FormatMessage with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic text description of the error. + /// Minimum supported client: Windows XP Professional [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint WriteEncryptedFileRaw([MarshalAs(UnmanagedType.FunctionPtr)] EncryptedFileRawImportCallback pfExportCallback, IntPtr pvCallbackContext, SafeEncryptedFileRawHandle pvContext); + + + [SuppressUnmanagedCodeSecurity] + internal delegate int EncryptedFileRawExportCallback(IntPtr pbData, IntPtr pvCallbackContext, uint ulLength); + + [SuppressUnmanagedCodeSecurity] + internal delegate int EncryptedFileRawImportCallback(IntPtr pbData, IntPtr pvCallbackContext, ref uint ulLength); + } +} diff --git a/AlphaFS/Filesystem/Native Methods/NativeMethods.FileManagement.cs b/AlphaFS/Filesystem/Native Methods/NativeMethods.FileManagement.cs new file mode 100644 index 0000000..40bc36b --- /dev/null +++ b/AlphaFS/Filesystem/Native Methods/NativeMethods.FileManagement.cs @@ -0,0 +1,760 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +using Alphaleonis.Win32.Security; +using Microsoft.Win32.SafeHandles; +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.AccessControl; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// + /// Copies an existing file to a new file, notifying the application of its progress through a callback function. + /// + /// + /// This function fails with ERROR_ACCESS_DENIED if the destination file already exists and has the FILE_ATTRIBUTE_HIDDEN or + /// FILE_ATTRIBUTE_READONLY attribute set. + /// This function preserves extended attributes, OLE structured storage, NTFS file system alternate data streams, security + /// resource attributes, and file attributes. + /// Windows 7, Windows Server 2008 R2, Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: + /// Security resource attributes (ATTRIBUTE_SECURITY_INFORMATION) for the existing file are not copied to the new file until + /// Windows 8 and Windows Server 2012. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + /// Filename of the existing file. + /// Filename of the new file. + /// The progress routine. + /// The data. + /// [out] The pb cancel. + /// The copy flags. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CopyFileExW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CopyFileEx([MarshalAs(UnmanagedType.LPWStr)] string lpExistingFileName, [MarshalAs(UnmanagedType.LPWStr)] string lpNewFileName, NativeCopyMoveProgressRoutine lpProgressRoutine, IntPtr lpData, [MarshalAs(UnmanagedType.Bool)] out bool pbCancel, CopyOptions dwCopyFlags); + + /// + /// Copies an existing file to a new file as a transacted operation, notifying the application of its progress through a callback + /// function. + /// + /// + /// This function fails with ERROR_ACCESS_DENIED if the destination file already exists and has the FILE_ATTRIBUTE_HIDDEN or + /// FILE_ATTRIBUTE_READONLY attribute set. + /// This function preserves extended attributes, OLE structured storage, NTFS file system alternate data streams, security + /// resource attributes, and file attributes. + /// Windows 7, Windows Server 2008 R2, Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: + /// Security resource attributes (ATTRIBUTE_SECURITY_INFORMATION) for the existing file are not copied to the new file until + /// Windows 8 and Windows Server 2012. + /// Minimum supported client: Windows Vista [desktop apps only] + /// Minimum supported server: Windows Server 2008 [desktop apps only] + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CopyFileTransactedW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CopyFileTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpExistingFileName, [MarshalAs(UnmanagedType.LPWStr)] string lpNewFileName, NativeCopyMoveProgressRoutine lpProgressRoutine, IntPtr lpData, [MarshalAs(UnmanagedType.Bool)] out bool pbCancel, CopyOptions dwCopyFlags, SafeHandle hTransaction); + + /// + /// Creates or opens a file or I/O device. The most commonly used I/O devices are as follows: file, file stream, directory, physical + /// disk, volume, console buffer, tape drive, communications resource, mailslot, and pipe. + /// + /// Minimum supported client: Windows XP. + /// Minimum supported server: Windows Server 2003. + /// + /// If the function succeeds, the return value is an open handle to the specified file, device, named pipe, or mail slot. If the + /// function fails, the return value is Win32Errors.ERROR_INVALID_HANDLE. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateFileW"), SuppressUnmanagedCodeSecurity] + internal static extern SafeFileHandle CreateFile([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, [MarshalAs(UnmanagedType.U4)] FileSystemRights dwDesiredAccess, [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode, [MarshalAs(UnmanagedType.LPStruct)] Security.NativeMethods.SecurityAttributes lpSecurityAttributes, [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition, [MarshalAs(UnmanagedType.U4)] ExtendedFileAttributes dwFlagsAndAttributes, IntPtr hTemplateFile); + + /// + /// Creates or opens a file or I/O device. The most commonly used I/O devices are as follows: file, file stream, directory, physical + /// disk, volume, console buffer, tape drive, communications resource, mailslot, and pipe. + /// + /// Minimum supported client: Windows Vista [desktop apps only]. + /// Minimum supported server: Windows Server 2008 [desktop apps only]. + /// + /// If the function succeeds, the return value is an open handle to the specified file, device, named pipe, or mail slot. If the + /// function fails, the return value is Win32Errors.ERROR_INVALID_HANDLE". To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateFileTransactedW"), SuppressUnmanagedCodeSecurity] + internal static extern SafeFileHandle CreateFileTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, [MarshalAs(UnmanagedType.U4)] FileSystemRights dwDesiredAccess, [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode, [MarshalAs(UnmanagedType.LPStruct)] Security.NativeMethods.SecurityAttributes lpSecurityAttributes, [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition, [MarshalAs(UnmanagedType.U4)] ExtendedFileAttributes dwFlagsAndAttributes, IntPtr hTemplateFile, SafeHandle hTransaction, IntPtr pusMiniVersion, IntPtr pExtendedParameter); + + /// Creates or opens a named or unnamed file mapping object for a specified file. + /// Minimum supported client: Windows XP. + /// Minimum supported server: Windows Server 2003. + /// + /// If the function succeeds, the return value is a handle to the newly created file mapping object. If the function fails, the return + /// value is . + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Unicode, EntryPoint = "CreateFileMappingW"), SuppressUnmanagedCodeSecurity] + internal static extern SafeFileHandle CreateFileMapping(SafeFileHandle hFile, SafeHandle lpSecurityAttributes, [MarshalAs(UnmanagedType.U4)] uint flProtect, [MarshalAs(UnmanagedType.U4)] uint dwMaximumSizeHigh, [MarshalAs(UnmanagedType.U4)] uint dwMaximumSizeLow, [MarshalAs(UnmanagedType.LPWStr)] string lpName); + + /// + /// Establishes a hard link between an existing file and a new file. This function is only supported on the NTFS file system, and only + /// for files, not directories. + /// + /// Minimum supported client: Windows XP [desktop apps only]. + /// Minimum supported server: Windows Server 2003 [desktop apps only]. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero (0). To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateHardLinkW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CreateHardLink([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, [MarshalAs(UnmanagedType.LPWStr)] string lpExistingFileName, IntPtr lpSecurityAttributes); + + /// + /// Establishes a hard link between an existing file and a new file as a transacted operation. This function is only supported on the + /// NTFS file system, and only for files, not directories. + /// + /// Minimum supported client: Windows Vista [desktop apps only]. + /// Minimum supported server: Windows Server 2008 [desktop apps only]. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero (0). To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateHardLinkTransactedW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CreateHardLinkTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, [MarshalAs(UnmanagedType.LPWStr)] string lpExistingFileName, IntPtr lpSecurityAttributes, SafeHandle hTransaction); + + /// Creates a symbolic link. + /// Minimum supported client: Windows Vista [desktop apps only]. + /// Minimum supported server: Windows Server 2008 [desktop apps only]. + /// + /// The unmanaged prototype contains a return directive because the CreateSymbolicLink API function returns BOOLEAN, a one-byte data type. + /// The default marshaling for bool is four bytes (to allow seamless integration with BOOL return values). + /// If you were to use the default marshaling for BOOLEAN values, it's likely that you will get erroneous results. + /// The return directive forces PInvoke to marshal just one byte of the return value. + /// Source: http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=762&ns=16196 + /// + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero (0). To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateSymbolicLinkW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.I1)] + internal static extern bool CreateSymbolicLink([MarshalAs(UnmanagedType.LPWStr)] string lpSymlinkFileName, [MarshalAs(UnmanagedType.LPWStr)] string lpTargetFileName, [MarshalAs(UnmanagedType.U4)] SymbolicLinkTarget dwFlags); + + /// Creates a symbolic link as a transacted operation. + /// Minimum supported client: Windows Vista [desktop apps only]. + /// Minimum supported server: Windows Server 2008 [desktop apps only]. + /// + /// The unmanaged prototype contains a return directive because the CreateSymbolicLink API function returns BOOLEAN, a one-byte data type. + /// The default marshaling for bool is four bytes (to allow seamless integration with BOOL return values). + /// If you were to use the default marshaling for BOOLEAN values, it's likely that you will get erroneous results. + /// The return directive forces PInvoke to marshal just one byte of the return value. + /// Source: http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=762&ns=16196 + /// + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero (0). To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateSymbolicLinkTransactedW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.I1)] + internal static extern bool CreateSymbolicLinkTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpSymlinkFileName, [MarshalAs(UnmanagedType.LPWStr)] string lpTargetFileName, [MarshalAs(UnmanagedType.U4)] SymbolicLinkTarget dwFlags, SafeHandle hTransaction); + + /// Decrypts an encrypted file or directory. + /// + /// The DecryptFile function requires exclusive access to the file being decrypted, and will fail if another process is using the file. + /// If the file is not encrypted, DecryptFile simply returns a nonzero value, which indicates success. If lpFileName specifies a read- + /// only file, the function fails and GetLastError returns ERROR_FILE_READ_ONLY. If lpFileName specifies a directory that contains a + /// read-only file, the functions succeeds but the directory is not decrypted. + /// + /// Minimum supported client: Windows XP. + /// Minimum supported server: Windows Server 2003. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "DecryptFileW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DecryptFile([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, [MarshalAs(UnmanagedType.U4)] uint dwReserved); + + /// Deletes an existing file. + /// + /// If an application attempts to delete a file that does not exist, the DeleteFile function fails with ERROR_FILE_NOT_FOUND. + /// + /// If the file is a read-only file, the function fails with ERROR_ACCESS_DENIED. + /// + /// If the path points to a symbolic link, the symbolic link is deleted, not the target. To delete a target, you must call CreateFile + /// and specify FILE_FLAG_DELETE_ON_CLOSE. + /// + /// Minimum supported client: Windows XP [desktop apps | Windows Store apps]. + /// Minimum supported server: Windows Server 2003 [desktop apps | Windows Store apps]. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero (0). To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "DeleteFileW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeleteFile([MarshalAs(UnmanagedType.LPWStr)] string lpFileName); + + /// Deletes an existing file as a transacted operation. + /// Minimum supported client: Windows Vista [desktop apps only]. + /// Minimum supported server: Windows Server 2008 [desktop apps only]. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero (0). To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "DeleteFileTransactedW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeleteFileTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, SafeHandle hTransaction); + + /// + /// Encrypts a file or directory. All data streams in a file are encrypted. All new files created in an encrypted directory are + /// encrypted. + /// + /// + /// The EncryptFile function requires exclusive access to the file being encrypted, and will fail if another process is using the file. + /// If the file is already encrypted, EncryptFile simply returns a nonzero value, which indicates success. If the file is compressed, + /// EncryptFile will decompress the file before encrypting it. If lpFileName specifies a read-only file, the function fails and + /// GetLastError returns ERROR_FILE_READ_ONLY. If lpFileName specifies a directory that contains a read-only file, the functions + /// succeeds but the directory is not encrypted. + /// + /// Minimum supported client: Windows XP. + /// Minimum supported server: Windows Server 2003. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "EncryptFileW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool EncryptFile([MarshalAs(UnmanagedType.LPWStr)] string lpFileName); + + /// + /// Disables or enables encryption of the specified directory and the files in it. It does not affect encryption of subdirectories + /// below the indicated directory. + /// + /// + /// EncryptionDisable() disables encryption of directories and files. It does not affect the visibility of files with the + /// FILE_ATTRIBUTE_SYSTEM attribute set. This method will create/change the file "Desktop.ini" and wil set Encryption value: + /// "Disable=0|1". + /// + /// Minimum supported client: Windows XP Professional [desktop apps only]. + /// Minimum supported server: Windows Server 2003 [desktop apps only]. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule"), SuppressUnmanagedCodeSecurity] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool EncryptionDisable([MarshalAs(UnmanagedType.LPWStr)] string dirPath, [MarshalAs(UnmanagedType.Bool)] bool disable); + + /// Retrieves the encryption status of the specified file. + /// Minimum supported client: Windows XP Professional [desktop apps only]. + /// Minimum supported server: Windows Server 2003 [desktop apps only]. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "FileEncryptionStatusW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool FileEncryptionStatus([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, out FileEncryptionStatus lpStatus); + + /// + /// Closes a file search handle opened by the FindFirstFile, FindFirstFileEx, FindFirstFileNameW, FindFirstFileNameTransactedW, + /// FindFirstFileTransacted, FindFirstStreamTransactedW, or FindFirstStreamW functions. + /// + /// Minimum supported client: Windows XP [desktop apps | Windows Store apps]. + /// Minimum supported server: Windows Server 2003 [desktop apps | Windows Store apps]. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule"), SuppressUnmanagedCodeSecurity] + [DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool FindClose(IntPtr hFindFile); + + /// Searches a directory for a file or subdirectory with a name and attributes that match those specified. + /// A trailing backslash is not allowed and will be removed. + /// Minimum supported client: Windows XP [desktop apps | Windows Store apps]. + /// Minimum supported server: Windows Server 2003 [desktop apps | Windows Store apps]. + /// + /// If the function succeeds, the return value is a search handle used in a subsequent call to FindNextFile or FindClose, and the + /// lpFindFileData parameter contains information about the first file or directory found. If the function fails or fails to locate + /// files from the search string in the lpFileName parameter, the return value is INVALID_HANDLE_VALUE and the contents of + /// lpFindFileData are indeterminate. To get extended error information, call the GetLastError function. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "FindFirstFileExW"), SuppressUnmanagedCodeSecurity] + internal static extern SafeFindFileHandle FindFirstFileEx([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, out WIN32_FIND_DATA lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, IntPtr lpSearchFilter, FindExAdditionalFlags dwAdditionalFlags); + + /// + /// Searches a directory for a file or subdirectory with a name that matches a specific name as a transacted operation. + /// + /// A trailing backslash is not allowed and will be removed. + /// Minimum supported client: Windows Vista [desktop apps only]. + /// Minimum supported server: Windows Server 2008 [desktop apps only]. + /// + /// If the function succeeds, the return value is a search handle used in a subsequent call to FindNextFile or FindClose, and the + /// lpFindFileData parameter contains information about the first file or directory found. If the function fails or fails to locate + /// files from the search string in the lpFileName parameter, the return value is INVALID_HANDLE_VALUE and the contents of + /// lpFindFileData are indeterminate. To get extended error information, call the GetLastError function. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "FindFirstFileTransactedW"), SuppressUnmanagedCodeSecurity] + internal static extern SafeFindFileHandle FindFirstFileTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, out WIN32_FIND_DATA lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, IntPtr lpSearchFilter, FindExAdditionalFlags dwAdditionalFlags, SafeHandle hTransaction); + + /// + /// Creates an enumeration of all the hard links to the specified file. The FindFirstFileNameW function returns a handle to the + /// enumeration that can be used on subsequent calls to the FindNextFileNameW function. + /// + /// Minimum supported client: Windows Vista [desktop apps only]. + /// Minimum supported server: Windows Server 2008 [desktop apps only]. + /// + /// If the function succeeds, the return value is a search handle that can be used with the FindNextFileNameW function or closed with + /// the FindClose function. If the function fails, the return value is INVALID_HANDLE_VALUE (0xffffffff). To get extended error + /// information, call the GetLastError function. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "FindFirstFileNameW"), SuppressUnmanagedCodeSecurity] + internal static extern SafeFindFileHandle FindFirstFileName([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, [MarshalAs(UnmanagedType.U4)] uint dwFlags, [MarshalAs(UnmanagedType.U4)] out uint stringLength, StringBuilder linkName); + + /// + /// Creates an enumeration of all the hard links to the specified file as a transacted operation. The function returns a handle to the + /// enumeration that can be used on subsequent calls to the FindNextFileNameW function. + /// + /// Minimum supported client: Windows Vista [desktop apps only]. + /// Minimum supported server: Windows Server 2008 [desktop apps only]. + /// + /// If the function succeeds, the return value is a search handle that can be used with the FindNextFileNameW function or closed with + /// the FindClose function. If the function fails, the return value is INVALID_HANDLE_VALUE (0xffffffff). To get extended error + /// information, call the GetLastError function. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "FindFirstFileNameTransactedW"), SuppressUnmanagedCodeSecurity] + internal static extern SafeFindFileHandle FindFirstFileNameTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, [MarshalAs(UnmanagedType.U4)] uint dwFlags, [MarshalAs(UnmanagedType.U4)] out uint stringLength, StringBuilder linkName, SafeHandle hTransaction); + + /// + /// Continues a file search from a previous call to the FindFirstFile, FindFirstFileEx, or FindFirstFileTransacted functions. + /// + /// Minimum supported client: Windows XP [desktop apps | Windows Store apps]. + /// Minimum supported server: Windows Server 2003 [desktop apps | Windows Store apps]. + /// + /// If the function succeeds, the return value is nonzero and the lpFindFileData parameter contains information about the next file or + /// directory found. If the function fails, the return value is zero and the contents of lpFindFileData are indeterminate. To get + /// extended error information, call the GetLastError function. If the function fails because no more matching files can be found, the + /// GetLastError function returns ERROR_NO_MORE_FILES. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "FindNextFileW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool FindNextFile(SafeFindFileHandle hFindFile, out WIN32_FIND_DATA lpFindFileData); + + /// + /// Continues enumerating the hard links to a file using the handle returned by a successful call to the FindFirstFileName function. + /// + /// Minimum supported client: Windows Vista [desktop apps only]. + /// Minimum supported server: Windows Server 2008 [desktop apps only]. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero (0). To get extended error + /// information, call GetLastError. If no matching files can be found, the GetLastError function returns ERROR_HANDLE_EOF. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "FindNextFileNameW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool FindNextFileName(SafeFindFileHandle hFindStream, [MarshalAs(UnmanagedType.U4)] out uint stringLength, StringBuilder linkName); + + /// Flushes the buffers of a specified file and causes all buffered data to be written to a file. + /// Minimum supported client: Windows XP [desktop apps | Windows Store apps]. + /// Minimum supported server: Windows Server 2003 [desktop apps | Windows Store apps]. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool FlushFileBuffers(SafeFileHandle hFile); + + /// Retrieves the actual number of bytes of disk storage used to store a specified file. + /// Minimum supported client: Windows XP [desktop apps only]. + /// Minimum supported server: Windows Server 2003 [desktop apps only]. + /// + /// If the function succeeds, the return value is the low-order DWORD of the actual number of bytes of disk storage used to store the + /// specified file, and if lpFileSizeHigh is non-NULL, the function puts the high-order DWORD of that actual value into the DWORD + /// pointed to by that parameter. This is the compressed file size for compressed files, the actual file size for noncompressed files. + /// If the function fails, and lpFileSizeHigh is NULL, the return value is INVALID_FILE_SIZE. To get extended error information, call + /// GetLastError. If the return value is INVALID_FILE_SIZE and lpFileSizeHigh is non-NULL, an application must call GetLastError to + /// determine whether the function has succeeded (value is NO_ERROR) or failed (value is other than NO_ERROR). + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetCompressedFileSizeW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint GetCompressedFileSize([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, [MarshalAs(UnmanagedType.U4)] out uint lpFileSizeHigh); + + /// Retrieves the actual number of bytes of disk storage used to store a specified file as a transacted operation. + /// Minimum supported client: Windows Vista [desktop apps only]. + /// Minimum supported server: Windows Server 2008 [desktop apps only]. + /// + /// If the function succeeds, the return value is the low-order DWORD of the actual number of bytes of disk storage used to store the + /// specified file, and if lpFileSizeHigh is non-NULL, the function puts the high-order DWORD of that actual value into the DWORD + /// pointed to by that parameter. This is the compressed file size for compressed files, the actual file size for noncompressed files. + /// If the function fails, and lpFileSizeHigh is NULL, the return value is INVALID_FILE_SIZE. To get extended error information, call + /// GetLastError. If the return value is INVALID_FILE_SIZE and lpFileSizeHigh is non-NULL, an application must call GetLastError to + /// determine whether the function has succeeded (value is NO_ERROR) or failed (value is other than NO_ERROR). + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetCompressedFileSizeTransactedW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint GetCompressedFileSizeTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, [MarshalAs(UnmanagedType.U4)] out uint lpFileSizeHigh, SafeHandle hTransaction); + + /// + /// Retrieves attributes for a specified file or directory. + /// + /// + /// The GetFileAttributes function retrieves file system attribute information. + /// GetFileAttributesEx can obtain other sets of file or directory attribute information. + /// Currently, GetFileAttributesEx retrieves a set of standard attributes that is a superset of the file system attribute + /// information. + /// When the GetFileAttributesEx function is called on a directory that is a mounted folder, it returns the attributes of the directory, + /// not those of the root directory in the volume that the mounted folder associates with the directory. To obtain the attributes of + /// the associated volume, call GetVolumeNameForVolumeMountPoint to obtain the name of the associated volume. Then use the resulting + /// name in a call to GetFileAttributesEx. The results are the attributes of the root directory on the associated volume. + /// Symbolic link behavior: If the path points to a symbolic link, the function returns attributes for the symbolic link. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetFileAttributesExW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetFileAttributesEx([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, [MarshalAs(UnmanagedType.U4)] GetFileExInfoLevels fInfoLevelId, out WIN32_FILE_ATTRIBUTE_DATA lpFileInformation); + + /// Retrieves attributes for a specified file or directory. + /// + /// The GetFileAttributes function retrieves file system attribute information. + /// GetFileAttributesEx can obtain other sets of file or directory attribute information. + /// + /// Currently, GetFileAttributesEx retrieves a set of standard attributes that is a superset of the file system attribute information. + /// When the GetFileAttributesEx function is called on a directory that is a mounted folder, it returns the attributes of the directory, + /// not those of the root directory in the volume that the mounted folder associates with the directory. To obtain the attributes of + /// the associated volume, call GetVolumeNameForVolumeMountPoint to obtain the name of the associated volume. Then use the resulting + /// name in a call to GetFileAttributesEx. The results are the attributes of the root directory on the associated volume. + /// Symbolic link behavior: If the path points to a symbolic link, the function returns attributes for the symbolic link. + /// Transacted Operations + /// If a file is open for modification in a transaction, no other thread can open the file for modification until the transaction + /// is committed. Conversely, if a file is open for modification outside of a transaction, no transacted thread can open the file for + /// modification until the non-transacted handle is closed. If a non-transacted thread has a handle opened to modify a file, a call to + /// GetFileAttributesTransacted for that file will fail with an ERROR_TRANSACTIONAL_CONFLICT error. + /// Minimum supported client: Windows Vista [desktop apps only] + /// Minimum supported server: Windows Server 2008 [desktop apps only] + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetFileAttributesTransactedW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetFileAttributesTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, [MarshalAs(UnmanagedType.U4)] GetFileExInfoLevels fInfoLevelId, out WIN32_FILE_ATTRIBUTE_DATA lpFileInformation, SafeHandle hTransaction); + + /// Retrieves file information for the specified file. + /// + /// If the function succeeds, the return value is nonzero and file information data is contained in the buffer pointed to by the lpByHandleFileInformation parameter. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// + /// Depending on the underlying network features of the operating system and the type of server connected to, + /// the GetFileInformationByHandle function may fail, return partial information, or full information for the given file. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetFileInformationByHandle(SafeFileHandle hFile, [MarshalAs(UnmanagedType.Struct)] out BY_HANDLE_FILE_INFORMATION lpByHandleFileInformation); + + /// + /// Retrieves file information for the specified file. + /// + /// + /// Minimum supported client: Windows Vista [desktop apps | Windows Store apps] + /// Minimum supported server: Windows Server 2008 [desktop apps | Windows Store apps] + /// Redistributable: Windows SDK on Windows Server 2003 and Windows XP. + /// + /// The file. + /// The file information by handle class. + /// Information describing the file. + /// Size of the buffer. + /// + /// If the function succeeds, the return value is nonzero and file information data is contained in the buffer pointed to by the + /// lpByHandleFileInformation parameter. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetFileInformationByHandleEx(SafeFileHandle hFile, [MarshalAs(UnmanagedType.I4)] FileInfoByHandleClass fileInfoByHandleClass, SafeGlobalMemoryBufferHandle lpFileInformation, [MarshalAs(UnmanagedType.U4)] uint dwBufferSize); + + /// Retrieves file information for the specified file. + /// + /// Minimum supported client: Windows Vista [desktop apps | Windows Store apps] + /// Minimum supported server: Windows Server 2008 [desktop apps | Windows Store apps] + /// Redistributable: Windows SDK on Windows Server 2003 and Windows XP. + /// + /// + /// If the function succeeds, the return value is nonzero and file information data is contained in the buffer pointed to by the + /// lpByHandleFileInformation parameter. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// The file. + /// The file information by handle class. + /// Information describing the file. + /// Size of the buffer. + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetFileInformationByHandleEx"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetFileInformationByHandleEx_FileBasicInfo(SafeFileHandle hFile, [MarshalAs(UnmanagedType.I4)] FileInfoByHandleClass fileInfoByHandleClass, [MarshalAs(UnmanagedType.Struct)] out FILE_BASIC_INFO lpFileInformation, [MarshalAs(UnmanagedType.U4)] uint dwBufferSize); + + /// + /// Retrieves the size of the specified file. + /// + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetFileSizeEx(SafeFileHandle hFile, out long lpFileSize); + + /// Retrieves the final path for the specified file. + /// Minimum supported client: Windows Vista [desktop apps only]. + /// Minimum supported server: Windows Server 2008 [desktop apps only]. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetFinalPathNameByHandleW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint GetFinalPathNameByHandle(SafeFileHandle hFile, StringBuilder lpszFilePath, [MarshalAs(UnmanagedType.U4)] uint cchFilePath, FinalPathFormats dwFlags); + + /// + /// Checks whether the specified address is within a memory-mapped file in the address space of the specified process. If so, the + /// function returns the name of the memory-mapped file. + /// + /// Minimum supported client: Windows XP. + /// Minimum supported server: Windows Server 2003. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("psapi.dll", SetLastError = false, CharSet = CharSet.Unicode, EntryPoint = "GetMappedFileNameW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetMappedFileName(IntPtr hProcess, SafeLocalMemoryBufferHandle lpv, StringBuilder lpFilename, [MarshalAs(UnmanagedType.U4)] uint nSize); + + /// Locks the specified file for exclusive access by the calling process. + /// Minimum supported client: Windows XP. + /// Minimum supported server: Windows Server 2003. + /// + /// If the function succeeds, the return value is nonzero (TRUE). If the function fails, the return value is zero (FALSE). To get + /// extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool LockFile(SafeFileHandle hFile, [MarshalAs(UnmanagedType.U4)] uint dwFileOffsetLow, [MarshalAs(UnmanagedType.U4)] uint dwFileOffsetHigh, [MarshalAs(UnmanagedType.U4)] uint nNumberOfBytesToLockLow, [MarshalAs(UnmanagedType.U4)] uint nNumberOfBytesToLockHigh); + + /// Maps a view of a file mapping into the address space of a calling process. + /// Minimum supported client: Windows XP. + /// Minimum supported server: Windows Server 2003. + /// + /// If the function succeeds, the return value is the starting address of the mapped view. If the function fails, the return value is + /// . + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + internal static extern SafeLocalMemoryBufferHandle MapViewOfFile(SafeFileHandle hFileMappingObject, [MarshalAs(UnmanagedType.U4)] uint dwDesiredAccess, [MarshalAs(UnmanagedType.U4)] uint dwFileOffsetHigh, [MarshalAs(UnmanagedType.U4)] uint dwFileOffsetLow, UIntPtr dwNumberOfBytesToMap); + + /// + /// Moves a file or directory, including its children. + /// You can provide a callback function that receives progress notifications. + /// + /// + /// The MoveFileWithProgress function coordinates its operation with the link tracking service, so link sources can be tracked as they are moved. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + /// Filename of the existing file. + /// Filename of the new file. + /// The progress routine. + /// The data. + /// The flags. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "MoveFileWithProgressW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool MoveFileWithProgress([MarshalAs(UnmanagedType.LPWStr)] string lpExistingFileName, [MarshalAs(UnmanagedType.LPWStr)] string lpNewFileName, NativeCopyMoveProgressRoutine lpProgressRoutine, IntPtr lpData, [MarshalAs(UnmanagedType.U4)] MoveOptions dwFlags); + + /// + /// Moves an existing file or a directory, including its children, as a transacted operation. + /// You can provide a callback function that receives progress notifications. + /// + /// + /// Minimum supported client: Windows Vista [desktop apps only] + /// Minimum supported server: Windows Server 2008 [desktop apps only] + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "MoveFileTransactedW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool MoveFileTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpExistingFileName, [MarshalAs(UnmanagedType.LPWStr)] string lpNewFileName, NativeCopyMoveProgressRoutine lpProgressRoutine, IntPtr lpData, [MarshalAs(UnmanagedType.U4)] MoveOptions dwCopyFlags, SafeHandle hTransaction); + + /// An application-defined callback function used with the CopyFileEx, MoveFileTransacted, and MoveFileWithProgress functions. + /// It is called when a portion of a copy or move operation is completed. + /// The LPPROGRESS_ROUTINE type defines a pointer to this callback function. + /// NativeCopyMoveProgressRoutine (NativeCopyMoveProgressRoutine) is a placeholder for the application-defined function name. + /// + [SuppressUnmanagedCodeSecurity] + internal delegate CopyMoveProgressResult NativeCopyMoveProgressRoutine(long totalFileSize, long totalBytesTransferred, long streamSize, long streamBytesTransferred, [MarshalAs(UnmanagedType.U4)] int dwStreamNumber, CopyMoveProgressCallbackReason dwCallbackReason, IntPtr hSourceFile, IntPtr hDestinationFile, IntPtr lpData); + + /// Replaces one file with another file, with the option of creating a backup copy of the original file. The replacement file assumes the name of the replaced file and its identity. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "ReplaceFileW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool ReplaceFile([MarshalAs(UnmanagedType.LPWStr)] string lpReplacedFileName, [MarshalAs(UnmanagedType.LPWStr)] string lpReplacementFileName, [MarshalAs(UnmanagedType.LPWStr)] string lpBackupFileName, FileSystemRights dwReplaceFlags, IntPtr lpExclude, IntPtr lpReserved); + + /// Sets the attributes for a file or directory. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP + /// Minimum supported server: Windows Server 2003 + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [SuppressMessage("Microsoft.Usage", "CA2205:UseManagedEquivalentsOfWin32Api")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "SetFileAttributesW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool SetFileAttributes([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, [MarshalAs(UnmanagedType.U4)] FileAttributes dwFileAttributes); + + /// Sets the attributes for a file or directory as a transacted operation. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows Vista [desktop apps only] + /// Minimum supported server: Windows Server 2008 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "SetFileAttributesTransactedW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool SetFileAttributesTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, [MarshalAs(UnmanagedType.U4)] FileAttributes dwFileAttributes, SafeHandle hTransaction); + + /// Sets the date and time that the specified file or directory was created, last accessed, or last modified. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool SetFileTime(SafeFileHandle hFile, SafeGlobalMemoryBufferHandle lpCreationTime, SafeGlobalMemoryBufferHandle lpLastAccessTime, SafeGlobalMemoryBufferHandle lpLastWriteTime); + + /// Unlocks a region in an open file. Unlocking a region enables other processes to access the region. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP + /// Minimum supported server: Windows Server 2003 + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool UnlockFile(SafeFileHandle hFile, [MarshalAs(UnmanagedType.U4)] uint dwFileOffsetLow, [MarshalAs(UnmanagedType.U4)] uint dwFileOffsetHigh, [MarshalAs(UnmanagedType.U4)] uint nNumberOfBytesToUnlockLow, [MarshalAs(UnmanagedType.U4)] uint nNumberOfBytesToUnlockHigh); + + /// Unmaps a mapped view of a file from the calling process's address space. + /// Minimum supported client: Windows XP. + /// Minimum supported server: Windows Server 2003. + /// The base address. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool UnmapViewOfFile(SafeLocalMemoryBufferHandle lpBaseAddress); + + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + internal static extern SafeFindFileHandle FindFirstStreamTransactedW(string fileName, STREAM_INFO_LEVELS infoLevel, SafeGlobalMemoryBufferHandle lpFindStreamData, int flags, SafeHandle hTransaction); + + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + internal static extern SafeFindFileHandle FindFirstStreamW(string fileName, STREAM_INFO_LEVELS infoLevel, SafeGlobalMemoryBufferHandle lpFindStreamData, int flags); + + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool FindNextStreamW(SafeFindFileHandle handle, SafeGlobalMemoryBufferHandle lpFindStreamData); + } +} diff --git a/AlphaFS/Filesystem/Native Methods/NativeMethods.Handles.cs b/AlphaFS/Filesystem/Native Methods/NativeMethods.Handles.cs new file mode 100644 index 0000000..0a78c2d --- /dev/null +++ b/AlphaFS/Filesystem/Native Methods/NativeMethods.Handles.cs @@ -0,0 +1,52 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Closes an open object handle. + /// + /// The CloseHandle function closes handles to the following objects: + /// Access token, Communications device, Console input, Console screen buffer, Event, File, File mapping, I/O completion port, + /// Job, Mailslot, Memory resource notification, Mutex, Named pipe, Pipe, Process, Semaphore, Thread, Transaction, Waitable + /// timer. + /// SetLastError is set to . + /// Minimum supported client: Windows 2000 Professional [desktop apps | Windows Store apps] + /// Minimum supported server: Windows 2000 Server [desktop apps | Windows Store apps] + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// If the application is running under a debugger, the function will throw an exception if it receives either a handle value + /// that is not valid or a pseudo-handle value.This can happen if you close a handle twice, or if you call CloseHandle on a handle + /// returned by the FindFirstFile function instead of calling the FindClose function. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CloseHandle(IntPtr hObject); + } +} diff --git a/AlphaFS/Filesystem/Native Methods/NativeMethods.KernelTransactions.cs b/AlphaFS/Filesystem/Native Methods/NativeMethods.KernelTransactions.cs new file mode 100644 index 0000000..ba5fc03 --- /dev/null +++ b/AlphaFS/Filesystem/Native Methods/NativeMethods.KernelTransactions.cs @@ -0,0 +1,77 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// + /// Creates a new transaction object. + /// + /// + /// Use the function to close the transaction handle. If the last transaction handle is closed + /// beforea client calls the CommitTransaction function with the transaction handle, then KTM rolls back the transaction. + /// Minimum supported client: Windows Vista + /// Minimum supported server:Windows Server 2008 + /// + /// + /// If the function succeeds, the return value is a handle to the transaction. + /// If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call the GetLastError + /// function. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("ktmw32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + 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); + + /// Requests that the specified transaction be committed. + /// + /// You can commit any transaction handle that has been opened or created using the TRANSACTION_COMMIT permission; any + /// application can commit a transaction, not just the creator. + /// This function can only be called if the transaction is still active, not prepared, pre-prepared, or rolled back. + /// Minimum supported client: Windows Vista + /// Minimum supported server:Windows Server 2008 + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is 0 (zero). To get extended error information, call the GetLastError function. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("ktmw32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CommitTransaction(SafeHandle hTrans); + + /// + /// Requests that the specified transaction be rolled back. This function is synchronous. + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call the GetLastError function. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("ktmw32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool RollbackTransaction(SafeHandle hTrans); + } +} diff --git a/AlphaFS/Filesystem/Native Methods/NativeMethods.PathManagement.cs b/AlphaFS/Filesystem/Native Methods/NativeMethods.PathManagement.cs new file mode 100644 index 0000000..514b182 --- /dev/null +++ b/AlphaFS/Filesystem/Native Methods/NativeMethods.PathManagement.cs @@ -0,0 +1,86 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Retrieves the full path and file name of the specified file or directory. + /// If the function fails for any other reason, the return value is zero. To get extended error information, call GetLastError. + /// The GetFullPathName function is not recommended for multithreaded applications or shared library code. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetFullPathNameW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint GetFullPathName([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, [MarshalAs(UnmanagedType.U4)] uint nBufferLength, StringBuilder lpBuffer, IntPtr lpFilePart); + + /// Retrieves the full path and file name of the specified file or directory as a transacted operation. + /// If the function fails for any other reason, the return value is zero. To get extended error information, call GetLastError. + /// Minimum supported client: Windows Vista [desktop apps only] + /// Minimum supported server: Windows Server 2008 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetFullPathNameTransactedW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint GetFullPathNameTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, [MarshalAs(UnmanagedType.U4)] uint nBufferLength, StringBuilder lpBuffer, IntPtr lpFilePart, SafeHandle hTransaction); + + /// Converts the specified path to its long form. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetLongPathNameW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint GetLongPathName([MarshalAs(UnmanagedType.LPWStr)] string lpszShortPath, StringBuilder lpszLongPath, [MarshalAs(UnmanagedType.U4)] uint cchBuffer); + + /// Converts the specified path to its long form as a transacted operation. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows Vista [desktop apps only] + /// Minimum supported server: Windows Server 2008 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetLongPathNameTransactedW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint GetLongPathNameTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpszShortPath, StringBuilder lpszLongPath, [MarshalAs(UnmanagedType.U4)] uint cchBuffer, SafeHandle hTransaction); + + /// Retrieves the short path form of the specified path. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP + /// Minimum supported server: Windows Server 2003 + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetShortPathNameW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint GetShortPathName([MarshalAs(UnmanagedType.LPWStr)] string lpszLongPath, StringBuilder lpszShortPath, [MarshalAs(UnmanagedType.U4)] uint cchBuffer); + } +} diff --git a/AlphaFS/Filesystem/Native Methods/NativeMethods.Shell32.cs b/AlphaFS/Filesystem/Native Methods/NativeMethods.Shell32.cs new file mode 100644 index 0000000..04908bf --- /dev/null +++ b/AlphaFS/Filesystem/Native Methods/NativeMethods.Shell32.cs @@ -0,0 +1,197 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + #region AssocXxx + + /// Returns a pointer to an IQueryAssociations object. + /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + /// Minimum supported client: Windows 2000 Professional, Windows XP [desktop apps only] + /// Minimum supported server: Windows 2000 Server [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("shlwapi.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint AssocCreate(Guid clsid, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out IQueryAssociations ppv); + + /// Searches for and retrieves a file or protocol association-related string from the registry. + /// Return value Type: HRESULT. Returns a standard COM error value, including the following: S_OK, E_POINTER and S_FALSE. + /// Minimum supported client: Windows 2000 Professional + /// Minimum supported server: Windows 2000 Server + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("shlwapi.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "AssocQueryStringW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint AssocQueryString(Shell32.AssociationAttributes flags, Shell32.AssociationString str, [MarshalAs(UnmanagedType.LPWStr)] string pszAssoc, [MarshalAs(UnmanagedType.LPWStr)] string pszExtra, StringBuilder pszOut, [MarshalAs(UnmanagedType.U4)] out uint pcchOut); + + + #region IQueryAssociations + + internal static readonly Guid ClsidQueryAssociations = new Guid("A07034FD-6CAA-4954-AC3F-97A27216F98A"); + internal const string QueryAssociationsGuid = "C46CA590-3C3F-11D2-BEE6-0000F805CA57"; + + /// Exposes methods that simplify the process of retrieving information stored in the registry in association with defining a file type or protocol and associating it with an application. + [Guid(QueryAssociationsGuid), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [SuppressUnmanagedCodeSecurity] + internal interface IQueryAssociations + { + /// Initializes the IQueryAssociations interface and sets the root key to the appropriate ProgID. + /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + /// Minimum supported client: Windows 2000 Professional, Windows XP [desktop apps only] + /// Minimum supported server: Windows 2000 Server [desktop apps only] + void Init(Shell32.AssociationAttributes flags, [MarshalAs(UnmanagedType.LPWStr)] string pszAssoc, IntPtr hkProgid, IntPtr hwnd); + + //[return: MarshalAs(UnmanagedType.U4)] + //uint Init(Shell32.AssociationAttributes flags, [MarshalAs(UnmanagedType.LPWStr)] string pszAssoc, IntPtr hkProgid, IntPtr hwnd); + + /// Searches for and retrieves a file or protocol association-related string from the registry. + /// A standard COM error value, including the following: S_OK, E_POINTER, S_FALSE + /// Minimum supported client: Windows 2000 Professional, Windows XP [desktop apps only] + /// Minimum supported server: Windows 2000 Server [desktop apps only] + void GetString(Shell32.AssociationAttributes flags, Shell32.AssociationString str, [MarshalAs(UnmanagedType.LPWStr)] string pwszExtra, StringBuilder pwszOut, [MarshalAs(UnmanagedType.I4)] out int pcchOut); + + //[return: MarshalAs(UnmanagedType.U4)] + //void GetString(Shell32.AssociationAttributes flags, Shell32.AssociationString str, [MarshalAs(UnmanagedType.LPWStr)] string pwszExtra, StringBuilder pwszOut, [MarshalAs(UnmanagedType.I4)] out int pcchOut); + + ///// Searches for and retrieves a file or protocol association-related key from the registry. + ///// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + ///// Minimum supported client: Windows 2000 Professional, Windows XP [desktop apps only] + ///// Minimum supported server: Windows 2000 Server [desktop apps only] + //[return: MarshalAs(UnmanagedType.U4)] + //uint GetKey(Shell32.AssociationAttributes flags, Shell32.AssociationKey str, [MarshalAs(UnmanagedType.LPWStr)] string pwszExtra, out UIntPtr phkeyOut); + + ///// Searches for and retrieves file or protocol association-related binary data from the registry. + ///// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + ///// Minimum supported client: Windows 2000 Professional, Windows XP [desktop apps only] + ///// Minimum supported server: Windows 2000 Server [desktop apps only] + //[return: MarshalAs(UnmanagedType.U4)] + //uint GetData(Shell32.AssociationAttributes flags, Shell32.AssociationData data, [MarshalAs(UnmanagedType.LPWStr)] string pwszExtra, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] out byte[] pvOut, [MarshalAs(UnmanagedType.I4)] out int pcbOut); + + ///// This method is not implemented. + //void GetEnum(); + } + + #endregion // IQueryAssociations + + #endregion // AssocXxx + + + #region Path + + /// Determines whether a path to a file system object such as a file or folder is valid. + /// if the file exists; otherwise, . Call GetLastError for extended error information. + /// + /// This function tests the validity of the path. + /// A path specified by Universal Naming Convention (UNC) is limited to a file only; that is, \\server\share\file is permitted. + /// A network share path to a server or server share is not permitted; that is, \\server or \\server\share. + /// This function returns FALSE if a mounted remote drive is out of service. + /// + /// Minimum supported client: Windows 2000 Professional + /// Minimum supported server: Windows 2000 Server + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "PathFileExistsW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool PathFileExists([MarshalAs(UnmanagedType.LPWStr)] string pszPath); + + + /// Converts a file URL to a Microsoft MS-DOS path. + /// Type: HRESULT + /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + /// + /// Minimum supported client: Windows 2000 Professional, Windows XP [desktop apps only] + /// Minimum supported server: Windows 2000 Server [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("shlwapi.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "PathCreateFromUrlW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint PathCreateFromUrl([MarshalAs(UnmanagedType.LPWStr)] string pszUrl, StringBuilder pszPath, [MarshalAs(UnmanagedType.U4)] ref uint pcchPath, [MarshalAs(UnmanagedType.U4)] uint dwFlags); + + + /// Creates a path from a file URL. + /// Type: HRESULT + /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + /// + /// Minimum supported client: Windows Vista [desktop apps only] + /// Minimum supported server: Windows Server 2008 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("shlwapi.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint PathCreateFromUrlAlloc([MarshalAs(UnmanagedType.LPWStr)] string pszIn, out StringBuilder pszPath, [MarshalAs(UnmanagedType.U4)] uint dwFlags); + + + /// Converts a Microsoft MS-DOS path to a canonicalized URL. + /// Type: HRESULT + /// Returns S_FALSE if pszPath is already in URL format. In this case, pszPath will simply be copied to pszUrl. + /// Otherwise, it returns S_OK if successful or a standard COM error value if not. + /// + /// + /// UrlCreateFromPath does not support extended paths. These are paths that include the extended-length path prefix "\\?\". + /// + /// Minimum supported client: Windows 2000 Professional, Windows XP [desktop apps only] + /// Minimum supported server: Windows 2000 Server [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("shlwapi.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "UrlCreateFromPathW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint UrlCreateFromPath([MarshalAs(UnmanagedType.LPWStr)] string pszPath, StringBuilder pszUrl, ref uint pcchUrl, [MarshalAs(UnmanagedType.U4)] uint dwFlags); + + + /// Tests whether a URL is a specified type. + /// + /// Type: BOOL + /// For all but one of the URL types, UrlIs returns if the URL is the specified type, otherwise. + /// If UrlIs is set to , UrlIs will attempt to determine the URL scheme. + /// If the function is able to determine a scheme, it returns , or . + /// + /// Minimum supported client: Windows 2000 Professional, Windows XP [desktop apps only] + /// Minimum supported server: Windows 2000 Server [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("shlwapi.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "UrlIsW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool UrlIs([MarshalAs(UnmanagedType.LPWStr)] string pszUrl, Shell32.UrlType urlIs); + + #endregion // Path + + + /// Destroys an icon and frees any memory the icon occupied. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows 2000 Server [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("user32.dll", SetLastError = false)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DestroyIcon(IntPtr hIcon); + + + /// Retrieves information about an object in the file system, such as a file, folder, directory, or drive root. + /// You should call this function from a background thread. Failure to do so could cause the UI to stop responding. + /// Minimum supported client: Windows 2000 Professional [desktop apps only] + /// Minimum supported server: Windows 2000 Server [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("shell32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "SHGetFileInfoW"), SuppressUnmanagedCodeSecurity] + internal static extern IntPtr ShGetFileInfo([MarshalAs(UnmanagedType.LPWStr)] string pszPath, FileAttributes dwFileAttributes, [MarshalAs(UnmanagedType.Struct)] out Shell32.FileInfo psfi, [MarshalAs(UnmanagedType.U4)] uint cbFileInfo, [MarshalAs(UnmanagedType.U4)] Shell32.FileAttributes uFlags); + } +} diff --git a/AlphaFS/Filesystem/Native Methods/NativeMethods.Utilities.cs b/AlphaFS/Filesystem/Native Methods/NativeMethods.Utilities.cs new file mode 100644 index 0000000..3cd33aa --- /dev/null +++ b/AlphaFS/Filesystem/Native Methods/NativeMethods.Utilities.cs @@ -0,0 +1,136 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Security; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + internal static uint GetHighOrderDword(long highPart) + { + return (uint)((highPart >> 32) & 0xFFFFFFFF); + } + + internal static uint GetLowOrderDword(long lowPart) + { + return (uint)(lowPart & 0xFFFFFFFF); + } + + /// Check is the current handle is not null, not closed and not invalid. + /// The current handle to check. + /// will throw an , will not raise this exception.. + /// on success, otherwise. + /// + internal static bool IsValidHandle(SafeHandle handle, bool throwException = true) + { + if (handle == null || handle.IsClosed || handle.IsInvalid) + { + if (handle != null) + handle.Close(); + + if (throwException) + throw new ArgumentException(Resources.Handle_Is_Invalid); + + return false; + } + + return true; + } + + /// Check is the current handle is not null, not closed and not invalid. + /// The current handle to check. + /// The result of Marshal.GetLastWin32Error() + /// will throw an , will not raise this exception.. + /// on success, otherwise. + /// + internal static bool IsValidHandle(SafeHandle handle, int lastError, bool throwException = true) + { + if (handle == null || handle.IsClosed || handle.IsInvalid) + { + if (handle != null) + handle.Close(); + + if (throwException) + throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.Handle_Is_Invalid_Win32Error, lastError)); + + return false; + } + + return true; + } + + internal static long LuidToLong(Luid luid) + { + ulong high = (((ulong)luid.HighPart) << 32); + ulong low = (((ulong)luid.LowPart) & 0x00000000FFFFFFFF); + return unchecked((long)(high | low)); + } + + internal static Luid LongToLuid(long lluid) + { + return new Luid { HighPart = (uint)(lluid >> 32), LowPart = (uint)(lluid & 0xFFFFFFFF) }; + } + + /// + /// Controls whether the system will handle the specified types of serious errors or whether the process will handle them. + /// + /// + /// Because the error mode is set for the entire process, you must ensure that multi-threaded applications do not set different error- + /// mode attributes. Doing so can lead to inconsistent error handling. + /// + /// Minimum supported client: Windows XP [desktop apps only]. + /// Minimum supported server: Windows Server 2003 [desktop apps only]. + /// The mode. + /// The return value is the previous state of the error-mode bit attributes. + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + private static extern ErrorMode SetErrorMode(ErrorMode uMode); + + /// + /// Controls whether the system will handle the specified types of serious errors or whether the calling thread will handle them. + /// + /// + /// Because the error mode is set for the entire process, you must ensure that multi-threaded applications do not set different error- + /// mode attributes. Doing so can lead to inconsistent error handling. + /// + /// Minimum supported client: Windows 7 [desktop apps only]. + /// Minimum supported server: Windows Server 2008 R2 [desktop apps only]. + /// The new mode. + /// [out] The old mode. + /// The return value is the previous state of the error-mode bit attributes. + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool SetThreadErrorMode(ErrorMode dwNewMode, [MarshalAs(UnmanagedType.U4)] out ErrorMode lpOldMode); + + internal static long ToLong(uint highPart, uint lowPart) + { + return (((long)highPart) << 32) | (((long)lowPart) & 0xFFFFFFFF); + } + } +} diff --git a/AlphaFS/Filesystem/Native Methods/NativeMethods.VolumeManagement.cs b/AlphaFS/Filesystem/Native Methods/NativeMethods.VolumeManagement.cs new file mode 100644 index 0000000..c2576df --- /dev/null +++ b/AlphaFS/Filesystem/Native Methods/NativeMethods.VolumeManagement.cs @@ -0,0 +1,285 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Microsoft.Win32.SafeHandles; +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Defines, redefines, or deletes MS-DOS device names. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "DefineDosDeviceW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DefineDosDevice(DosDeviceAttributes dwFlags, [MarshalAs(UnmanagedType.LPWStr)] string lpDeviceName, [MarshalAs(UnmanagedType.LPWStr)] string lpTargetPath); + + /// Deletes a drive letter or mounted folder. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "DeleteVolumeMountPointW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal extern static bool DeleteVolumeMountPoint([MarshalAs(UnmanagedType.LPWStr)] string lpszVolumeMountPoint); + + /// Retrieves the name of a volume on a computer. FindFirstVolume is used to begin scanning the volumes of a computer. + /// + /// If the function succeeds, the return value is a search handle used in a subsequent call to the FindNextVolume and FindVolumeClose functions. + /// If the function fails to find any volumes, the return value is the INVALID_HANDLE_VALUE error code. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "FindFirstVolumeW"), SuppressUnmanagedCodeSecurity] + internal extern static SafeFindVolumeHandle FindFirstVolume(StringBuilder lpszVolumeName, [MarshalAs(UnmanagedType.U4)] uint cchBufferLength); + + /// Retrieves the name of a mounted folder on the specified volume. FindFirstVolumeMountPoint is used to begin scanning the mounted folders on a volume. + /// + /// If the function succeeds, the return value is a search handle used in a subsequent call to the FindNextVolumeMountPoint and FindVolumeMountPointClose functions. + /// If the function fails to find a mounted folder on the volume, the return value is the INVALID_HANDLE_VALUE error code. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "FindFirstVolumeMountPointW"), SuppressUnmanagedCodeSecurity] + internal extern static SafeFindVolumeMountPointHandle FindFirstVolumeMountPoint([MarshalAs(UnmanagedType.LPWStr)] string lpszRootPathName, StringBuilder lpszVolumeMountPoint, [MarshalAs(UnmanagedType.U4)] uint cchBufferLength); + + /// Continues a volume search started by a call to the FindFirstVolume function. FindNextVolume finds one volume per call. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "FindNextVolumeW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal extern static bool FindNextVolume(SafeFindVolumeHandle hFindVolume, StringBuilder lpszVolumeName, [MarshalAs(UnmanagedType.U4)] uint cchBufferLength); + + /// Continues a mounted folder search started by a call to the FindFirstVolumeMountPoint function. FindNextVolumeMountPoint finds one mounted folder per call. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. If no more mounted folders can be found, the GetLastError function returns the ERROR_NO_MORE_FILES error code. + /// In that case, close the search with the FindVolumeMountPointClose function. + /// + /// Minimum supported client: Windows XP + /// Minimum supported server: Windows Server 2003 + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "FindNextVolumeMountPointW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal extern static bool FindNextVolumeMountPoint(SafeFindVolumeMountPointHandle hFindVolume, StringBuilder lpszVolumeName, [MarshalAs(UnmanagedType.U4)] uint cchBufferLength); + + /// Closes the specified volume search handle. + /// + /// SetLastError is set to . + /// Minimum supported client: Windows XP [desktop apps only]. Minimum supported server: Windows Server 2003 [desktop apps only]. + /// + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal extern static bool FindVolumeClose(IntPtr hFindVolume); + + /// Closes the specified mounted folder search handle. + /// + /// SetLastError is set to . + /// Minimum supported client: Windows XP + /// Minimum supported server: Windows Server 2003 + /// + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal extern static bool FindVolumeMountPointClose(IntPtr hFindVolume); + + /// + /// Determines whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or network drive. + /// To determine whether a drive is a USB-type drive, call and specify the + /// SPDRP_REMOVAL_POLICY property. + /// + /// + /// SMB does not support volume management functions. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + /// Full pathname of the root file. + /// + /// The return value specifies the type of drive, see . + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetDriveTypeW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal extern static DriveType GetDriveType([MarshalAs(UnmanagedType.LPWStr)] string lpRootPathName); + + /// + /// Retrieves a bitmask representing the currently available disk drives. + /// + /// + /// SMB does not support volume management functions. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + /// + /// If the function succeeds, the return value is a bitmask representing the currently available disk drives. + /// Bit position 0 (the least-significant bit) is drive A, bit position 1 is drive B, bit position 2 is drive C, and so on. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint GetLogicalDrives(); + + /// Retrieves information about the file system and volume associated with the specified root directory. + /// + /// If all the requested information is retrieved, the return value is nonzero. + /// If not all the requested information is retrieved, the return value is zero. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// "lpRootPathName" must end with a trailing backslash. + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetVolumeInformationW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal extern static bool GetVolumeInformation([MarshalAs(UnmanagedType.LPWStr)] string lpRootPathName, StringBuilder lpVolumeNameBuffer, [MarshalAs(UnmanagedType.U4)] uint nVolumeNameSize, [MarshalAs(UnmanagedType.U4)] out uint lpVolumeSerialNumber, [MarshalAs(UnmanagedType.U4)] out int lpMaximumComponentLength, [MarshalAs(UnmanagedType.U4)] out VolumeInfoAttributes lpFileSystemAttributes, StringBuilder lpFileSystemNameBuffer, [MarshalAs(UnmanagedType.U4)] uint nFileSystemNameSize); + + /// Retrieves information about the file system and volume associated with the specified file. + /// + /// If all the requested information is retrieved, the return value is nonzero. + /// If not all the requested information is retrieved, the return value is zero. To get extended error information, call GetLastError. + /// + /// To retrieve the current compression state of a file or directory, use FSCTL_GET_COMPRESSION. + /// SMB does not support volume management functions. + /// Minimum supported client: Windows Vista [desktop apps only] + /// Minimum supported server: Windows Server 2008 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetVolumeInformationByHandleW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal extern static bool GetVolumeInformationByHandle(SafeFileHandle hFile, StringBuilder lpVolumeNameBuffer, [MarshalAs(UnmanagedType.U4)] uint nVolumeNameSize, [MarshalAs(UnmanagedType.U4)] out uint lpVolumeSerialNumber, [MarshalAs(UnmanagedType.U4)] out int lpMaximumComponentLength, out VolumeInfoAttributes lpFileSystemAttributes, StringBuilder lpFileSystemNameBuffer, [MarshalAs(UnmanagedType.U4)] uint nFileSystemNameSize); + + /// Retrieves a volume GUID path for the volume that is associated with the specified volume mount point (drive letter, volume GUID path, or mounted folder). + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// Use GetVolumeNameForVolumeMountPoint to obtain a volume GUID path for use with functions such as SetVolumeMountPoint and FindFirstVolumeMountPoint that require a volume GUID path as an input parameter. + /// SMB does not support volume management functions. + /// Mount points aren't supported by ReFS volumes. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetVolumeNameForVolumeMountPointW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetVolumeNameForVolumeMountPoint([MarshalAs(UnmanagedType.LPWStr)] string lpszVolumeMountPoint, StringBuilder lpszVolumeName, [MarshalAs(UnmanagedType.U4)] uint cchBufferLength); + + /// Retrieves the volume mount point where the specified path is mounted. + /// + /// If a specified path is passed, GetVolumePathName returns the path to the volume mount point, which means that it returns the + /// root of the volume where the end point of the specified path is located. + /// For example, assume that you have volume D mounted at C:\Mnt\Ddrive and volume E mounted at "C:\Mnt\Ddrive\Mnt\Edrive". Also + /// assume that you have a file with the path "E:\Dir\Subdir\MyFile". + /// If you pass "C:\Mnt\Ddrive\Mnt\Edrive\Dir\Subdir\MyFile" to GetVolumePathName, it returns the path "C:\Mnt\Ddrive\Mnt\Edrive\". + /// If a network share is specified, GetVolumePathName returns the shortest path for which GetDriveType returns DRIVE_REMOTE, + /// which means that the path is validated as a remote drive that exists, which the current user can access. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetVolumePathNameW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetVolumePathName([MarshalAs(UnmanagedType.LPWStr)] string lpszFileName, StringBuilder lpszVolumePathName, [MarshalAs(UnmanagedType.U4)] uint cchBufferLength); + + /// Retrieves a list of drive letters and mounted folder paths for the specified volume. + /// Minimum supported client: Windows XP. + /// Minimum supported server: Windows Server 2003. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetVolumePathNamesForVolumeNameW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetVolumePathNamesForVolumeName([MarshalAs(UnmanagedType.LPWStr)] string lpszVolumeName, char[] lpszVolumePathNames, [MarshalAs(UnmanagedType.U4)] uint cchBuferLength, [MarshalAs(UnmanagedType.U4)] out uint lpcchReturnLength); + + /// Sets the label of a file system volume. + /// Minimum supported client: Windows XP [desktop apps only]. + /// Minimum supported server: Windows Server 2003 [desktop apps only]. + /// "lpRootPathName" must end with a trailing backslash. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "SetVolumeLabelW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal extern static bool SetVolumeLabel([MarshalAs(UnmanagedType.LPWStr)] string lpRootPathName, [MarshalAs(UnmanagedType.LPWStr)] string lpVolumeName); + + /// Associates a volume with a drive letter or a directory on another volume. + /// Minimum supported client: Windows XP [desktop apps only]. + /// Minimum supported server: Windows Server 2003 [desktop apps only]. + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error + /// information, call GetLastError. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "SetVolumeMountPointW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal extern static bool SetVolumeMountPoint([MarshalAs(UnmanagedType.LPWStr)] string lpszVolumeMountPoint, [MarshalAs(UnmanagedType.LPWStr)] string lpszVolumeName); + + /// Retrieves information about MS-DOS device names. + /// Minimum supported client: Windows XP [desktop apps only]. + /// Minimum supported server: Windows Server 2003 [desktop apps only]. + /// + /// If the function succeeds, the return value is the number of TCHARs stored into the buffer pointed to by lpTargetPath. If the + /// function fails, the return value is zero. To get extended error information, call GetLastError. If the buffer is too small, the + /// function fails and the last error code is ERROR_INSUFFICIENT_BUFFER. + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "QueryDosDeviceW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint QueryDosDevice([MarshalAs(UnmanagedType.LPWStr)] string lpDeviceName, char[] lpTargetPath, [MarshalAs(UnmanagedType.U4)] uint ucchMax); + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Native Structures/BY_HANDLE_FILE_INFORMATION.cs b/AlphaFS/Filesystem/Native Structures/BY_HANDLE_FILE_INFORMATION.cs new file mode 100644 index 0000000..27493de --- /dev/null +++ b/AlphaFS/Filesystem/Native Structures/BY_HANDLE_FILE_INFORMATION.cs @@ -0,0 +1,74 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.IO; +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Contains information that the GetFileInformationByHandle function retrieves. + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct BY_HANDLE_FILE_INFORMATION + { + /// The file attributes. + public readonly FileAttributes dwFileAttributes; + + /// A structure that specifies when a file or directory is created. + public readonly FILETIME ftCreationTime; + + /// A structure. For a file, the structure specifies the last time that a file is read from or written to. + /// For a directory, the structure specifies when the directory is created. + /// For both files and directories, the specified date is correct, but the time of day is always set to midnight. + /// + public readonly FILETIME ftLastAccessTime; + + /// A structure. For a file, the structure specifies the last time that a file is written to. + /// For a directory, the structure specifies when the directory is created. + public readonly FILETIME ftLastWriteTime; + + /// The serial number of the volume that contains a file. + [MarshalAs(UnmanagedType.U4)] + public readonly int dwVolumeSerialNumber; + + /// The high-order part of the file size. + [MarshalAs(UnmanagedType.U4)] + public readonly uint nFileSizeHigh; + + /// The low-order part of the file size. + [MarshalAs(UnmanagedType.U4)] + public readonly uint nFileSizeLow; + + /// The number of links to this file. For the FAT file system this member is always 1. For the NTFS file system, it can be more than 1. + [MarshalAs(UnmanagedType.U4)] + public readonly int nNumberOfLinks; + + /// The high-order part of a unique identifier that is associated with a file. + [MarshalAs(UnmanagedType.U4)] + public readonly uint nFileIndexHigh; + + /// The low-order part of a unique identifier that is associated with a file. + [MarshalAs(UnmanagedType.U4)] + public readonly uint nFileIndexLow; + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Native Structures/FILETIME.cs b/AlphaFS/Filesystem/Native Structures/FILETIME.cs new file mode 100644 index 0000000..1d3a00a --- /dev/null +++ b/AlphaFS/Filesystem/Native Structures/FILETIME.cs @@ -0,0 +1,123 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Represents the number of 100-nanosecond intervals since January 1, 1601. This structure is a 64-bit value. + [SerializableAttribute] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct FILETIME + { + #region Fields + + private readonly uint dwLowDateTime; + private readonly uint dwHighDateTime; + + #endregion // Fields + + #region Methods + + /// Converts a value to long. + public static implicit operator long(FILETIME ft) + { + return ft.ToLong(); + } + + /// Converts a value to long. + [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "long")] + public long ToLong() + { + return NativeMethods.ToLong(dwHighDateTime, dwLowDateTime); + } + + #endregion + + #region Equality + + #region Equals + + /// Determines whether the specified Object is equal to the current Object. + /// Another object to compare to. + /// if the specified Object is equal to the current Object; otherwise, . + public override bool Equals(object obj) + { + if (obj == null || GetType() != obj.GetType()) + return false; + + FILETIME other = obj is FILETIME ? (FILETIME)obj : new FILETIME(); + + return (other.dwHighDateTime.Equals(dwHighDateTime) && + other.dwLowDateTime.Equals(dwLowDateTime)); + } + + #endregion // Equals + + #region GetHashCode + + /// Serves as a hash function for a particular type. + /// A hash code for the current Object. + public override int GetHashCode() + { + unchecked + { + int hash = 17; + hash = hash * 23 + dwHighDateTime.GetHashCode(); + hash = hash * 11 + dwLowDateTime.GetHashCode(); + return hash; + } + } + + #endregion // GetHashCode + + #region == + + /// Implements the operator == + /// A. + /// B. + /// The result of the operator. + public static bool operator ==(FILETIME left, FILETIME right) + { + return left.Equals(right); + } + + #endregion // == + + #region != + /// Implements the operator != + /// A. + /// B. + /// The result of the operator. + public static bool operator !=(FILETIME left, FILETIME right) + { + return !(left == right); + } + + #endregion // != + + #endregion // Equality + } + } +} diff --git a/AlphaFS/Filesystem/Native Structures/FILE_BASIC_INFO.cs b/AlphaFS/Filesystem/Native Structures/FILE_BASIC_INFO.cs new file mode 100644 index 0000000..f3cd7f4 --- /dev/null +++ b/AlphaFS/Filesystem/Native Structures/FILE_BASIC_INFO.cs @@ -0,0 +1,58 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.IO; +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Contains the basic information for a file. Used for file handles. + /// + /// Specifying -1 for , , or + /// indicates that operations on the current handle should not affect the given field. + /// (I.e, specifying -1 for will leave the unaffected by writes performed + /// on the current handle.) + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct FILE_BASIC_INFO + { + /// The time the file was created in format, + /// which is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC). + /// + public FILETIME CreationTime; + + /// The time the file was last accessed in format. + public FILETIME LastAccessTime; + + /// The time the file was last written to in format. + public FILETIME LastWriteTime; + + /// The time the file was changed in format. + public FILETIME ChangeTime; + + /// The file attributes. + /// If this is set to 0 in a structure passed to SetFileInformationByHandle then none of the attributes are changed. + public FileAttributes FileAttributes; + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Native Structures/FILE_ID_BOTH_DIR_INFO.cs b/AlphaFS/Filesystem/Native Structures/FILE_ID_BOTH_DIR_INFO.cs new file mode 100644 index 0000000..3c91a40 --- /dev/null +++ b/AlphaFS/Filesystem/Native Structures/FILE_ID_BOTH_DIR_INFO.cs @@ -0,0 +1,95 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Contains information about files in the specified directory. Used for directory handles. Use only when calling GetFileInformationByHandleEx. + /// + /// The number of files that are returned for each call to GetFileInformationByHandleEx depends on the size of the buffer that is passed to the function. + /// Any subsequent calls to GetFileInformationByHandleEx on the same handle will resume the enumeration operation after the last file is returned. + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct FILE_ID_BOTH_DIR_INFO + { + /// The offset for the next FILE_ID_BOTH_DIR_INFO structure that is returned. Contains zero (0) if no other entries follow this one. + [MarshalAs(UnmanagedType.U4)] + public readonly int NextEntryOffset; + + /// The byte offset of the file within the parent directory. This member is undefined for file systems, such as NTFS, + /// in which the position of a file within the parent directory is not fixed and can be changed at any time to maintain sort order. + /// + [MarshalAs(UnmanagedType.U4)] + public readonly uint FileIndex; + + /// The time that the file was created. + public FILETIME CreationTime; + + /// The time that the file was last accessed. + public FILETIME LastAccessTime; + + /// The time that the file was last written to. + public FILETIME LastWriteTime; + + /// The time that the file was last changed. + public FILETIME ChangeTime; + + /// The absolute new end-of-file position as a byte offset from the start of the file to the end of the file. + /// Because this value is zero-based, it actually refers to the first free byte in the file. + /// In other words, EndOfFile is the offset to the byte that immediately follows the last valid byte in the file. + /// + public readonly long EndOfFile; + + /// The number of bytes that are allocated for the file. This value is usually a multiple of the sector or cluster size of the underlying physical device. + public readonly long AllocationSize; + + /// The file attributes. + public readonly FileAttributes FileAttributes; + + /// The length of the file name. + [MarshalAs(UnmanagedType.U4)] + public readonly uint FileNameLength; + + /// The size of the extended attributes for the file. + [MarshalAs(UnmanagedType.U4)] + public readonly int EaSize; + + /// The length of ShortName. + [MarshalAs(UnmanagedType.U1)] + public readonly byte ShortNameLength; + + /// The short 8.3 file naming convention (for example, "FILENAME.TXT") name of the file. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12, ArraySubType = UnmanagedType.U2)] + public readonly char[] ShortName; + + /// The file ID. + public readonly long FileId; + + /// The first character of the file name string. This is followed in memory by the remainder of the string. + public IntPtr FileName; + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Native Structures/MountPointReparseBuffer.cs b/AlphaFS/Filesystem/Native Structures/MountPointReparseBuffer.cs new file mode 100644 index 0000000..ba03cac --- /dev/null +++ b/AlphaFS/Filesystem/Native Structures/MountPointReparseBuffer.cs @@ -0,0 +1,38 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct MountPointReparseBuffer + { + public readonly ushort SubstituteNameOffset; + public readonly ushort SubstituteNameLength; + public readonly ushort PrintNameOffset; + public readonly ushort PrintNameLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public readonly byte[] data; + } + } +} diff --git a/AlphaFS/Filesystem/Native Structures/ReparseDataBufferHeader.cs b/AlphaFS/Filesystem/Native Structures/ReparseDataBufferHeader.cs new file mode 100644 index 0000000..5c8db1d --- /dev/null +++ b/AlphaFS/Filesystem/Native Structures/ReparseDataBufferHeader.cs @@ -0,0 +1,37 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct ReparseDataBufferHeader + { + [MarshalAs(UnmanagedType.U4)] public readonly ReparsePointTag ReparseTag; + public readonly ushort ReparseDataLength; + public readonly ushort Reserved; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public readonly byte[] data; + } + } +} diff --git a/AlphaFS/Filesystem/Native Structures/SP_DEVICE_INTERFACE_DATA.cs b/AlphaFS/Filesystem/Native Structures/SP_DEVICE_INTERFACE_DATA.cs new file mode 100644 index 0000000..a03a77d --- /dev/null +++ b/AlphaFS/Filesystem/Native Structures/SP_DEVICE_INTERFACE_DATA.cs @@ -0,0 +1,46 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// An SP_DEVICE_INTERFACE_DATA structure defines a device interface in a device information set. + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct SP_DEVICE_INTERFACE_DATA + { + /// The size, in bytes, of the SP_DEVICE_INTERFACE_DATA structure. + [MarshalAs(UnmanagedType.U4)] public uint cbSize; + + /// The GUID for the class to which the device interface belongs. + public readonly Guid InterfaceClassGuid; + + /// Can be one or more of the following: SPINT_ACTIVE (1), SPINT_DEFAULT (2), SPINT_REMOVED (3). + [MarshalAs(UnmanagedType.U4)] public readonly uint Flags; + + /// Reserved. Do not use. + private readonly IntPtr Reserved; + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Native Structures/SP_DEVICE_INTERFACE_DETAIL_DATA.cs b/AlphaFS/Filesystem/Native Structures/SP_DEVICE_INTERFACE_DETAIL_DATA.cs new file mode 100644 index 0000000..0579e77 --- /dev/null +++ b/AlphaFS/Filesystem/Native Structures/SP_DEVICE_INTERFACE_DETAIL_DATA.cs @@ -0,0 +1,39 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// An SP_DEVICE_INTERFACE_DETAIL_DATA structure contains the path for a device interface. + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct SP_DEVICE_INTERFACE_DETAIL_DATA + { + /// The size, in bytes, of the SP_DEVICE_INTERFACE_DETAIL_DATA structure. + [MarshalAs(UnmanagedType.U4)] public uint cbSize; + + /// The device interface path. This path can be passed to Win32 functions such as CreateFile. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MaxPath)] public readonly string DevicePath; + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Native Structures/SP_DEVINFO_DATA.cs b/AlphaFS/Filesystem/Native Structures/SP_DEVINFO_DATA.cs new file mode 100644 index 0000000..927bbf0 --- /dev/null +++ b/AlphaFS/Filesystem/Native Structures/SP_DEVINFO_DATA.cs @@ -0,0 +1,46 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// An SP_DEVINFO_DATA structure defines a device instance that is a member of a device information set. + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct SP_DEVINFO_DATA + { + /// The size, in bytes, of the SP_DEVINFO_DATA structure. + [MarshalAs(UnmanagedType.U4)] public uint cbSize; + + /// The GUID of the device's setup class. + public readonly Guid ClassGuid; + + /// An opaque handle to the device instance (also known as a handle to the devnode). + [MarshalAs(UnmanagedType.U4)] public readonly uint DevInst; + + /// Reserved. For internal use only. + private readonly IntPtr Reserved; + } + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Native Structures/SymbolicLinkReparseBuffer.cs b/AlphaFS/Filesystem/Native Structures/SymbolicLinkReparseBuffer.cs new file mode 100644 index 0000000..90d31a4 --- /dev/null +++ b/AlphaFS/Filesystem/Native Structures/SymbolicLinkReparseBuffer.cs @@ -0,0 +1,39 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct SymbolicLinkReparseBuffer + { + public readonly ushort SubstituteNameOffset; + public readonly ushort SubstituteNameLength; + public readonly ushort PrintNameOffset; + public readonly ushort PrintNameLength; + public readonly SymbolicLinkType Flags; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public readonly byte[] data; + } + } +} diff --git a/AlphaFS/Filesystem/Native Structures/WIN32_FILE_ATTRIBUTE_DATA.cs b/AlphaFS/Filesystem/Native Structures/WIN32_FILE_ATTRIBUTE_DATA.cs new file mode 100644 index 0000000..dfabfc4 --- /dev/null +++ b/AlphaFS/Filesystem/Native Structures/WIN32_FILE_ATTRIBUTE_DATA.cs @@ -0,0 +1,86 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.IO; +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// WIN32_FILE_ATTRIBUTE_DATA structure contains attribute information for a file or directory. The GetFileAttributesEx function uses this structure. + /// + /// Not all file systems can record creation and last access time, and not all file systems record them in the same manner. + /// For example, on the FAT file system, create time has a resolution of 10 milliseconds, write time has a resolution of 2 seconds, + /// and access time has a resolution of 1 day. On the NTFS file system, access time has a resolution of 1 hour. + /// For more information, see File Times. + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct WIN32_FILE_ATTRIBUTE_DATA + { + public WIN32_FILE_ATTRIBUTE_DATA(WIN32_FIND_DATA findData) + { + dwFileAttributes = findData.dwFileAttributes; + ftCreationTime = findData.ftCreationTime; + ftLastAccessTime = findData.ftLastAccessTime; + ftLastWriteTime = findData.ftLastWriteTime; + nFileSizeHigh = findData.nFileSizeHigh; + nFileSizeLow = findData.nFileSizeLow; + } + + /// The file attributes of a file. + [MarshalAs(UnmanagedType.I4)] public FileAttributes dwFileAttributes; + + /// A structure that specifies when a file or directory was created. + /// If the underlying file system does not support creation time, this member is zero. + public readonly FILETIME ftCreationTime; + + /// A structure. + /// For a file, the structure specifies when the file was last read from, written to, or for executable files, run. + /// For a directory, the structure specifies when the directory is created. If the underlying file system does not support last access time, this member is zero. + /// On the FAT file system, the specified date for both files and directories is correct, but the time of day is always set to midnight. + /// + public readonly FILETIME ftLastAccessTime; + + /// A structure. + /// For a file, the structure specifies when the file was last written to, truncated, or overwritten, for example, when WriteFile or SetEndOfFile are used. + /// The date and time are not updated when file attributes or security descriptors are changed. + /// For a directory, the structure specifies when the directory is created. If the underlying file system does not support last write time, this member is zero. + /// + public readonly FILETIME ftLastWriteTime; + + /// The high-order DWORD of the file size. This member does not have a meaning for directories. + /// This value is zero unless the file size is greater than MAXDWORD. + /// The size of the file is equal to (nFileSizeHigh * (MAXDWORD+1)) + nFileSizeLow. + /// + public readonly uint nFileSizeHigh; + + /// The low-order DWORD of the file size. This member does not have a meaning for directories. + public readonly uint nFileSizeLow; + + /// The file size. + public long FileSize + { + get { return ToLong(nFileSizeHigh, nFileSizeLow); } + } + } + } +} diff --git a/AlphaFS/Filesystem/Native Structures/WIN32_FIND_DATA.cs b/AlphaFS/Filesystem/Native Structures/WIN32_FIND_DATA.cs new file mode 100644 index 0000000..b7612fe --- /dev/null +++ b/AlphaFS/Filesystem/Native Structures/WIN32_FIND_DATA.cs @@ -0,0 +1,93 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.IO; +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Contains information about the file that is found by the FindFirstFile, FindFirstFileEx, or FindNextFile function. + /// + /// If a file has a long file name, the complete name appears in the cFileName member, and the 8.3 format truncated version of the name appears + /// in the cAlternateFileName member. Otherwise, cAlternateFileName is empty. If the FindFirstFileEx function was called with a value of FindExInfoBasic + /// in the fInfoLevelId parameter, the cAlternateFileName member will always contain a string value. This remains true for all subsequent calls to the + /// FindNextFile function. As an alternative method of retrieving the 8.3 format version of a file name, you can use the GetShortPathName function. + /// For more information about file names, see File Names, Paths, and Namespaces. + /// + /// + /// Not all file systems can record creation and last access times, and not all file systems record them in the same manner. + /// For example, on the FAT file system, create time has a resolution of 10 milliseconds, write time has a resolution of 2 seconds, + /// and access time has a resolution of 1 day. The NTFS file system delays updates to the last access time for a file by up to 1 hour + /// after the last access. For more information, see File Times. + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + [SerializableAttribute] + internal struct WIN32_FIND_DATA + { + /// The file attributes of a file. + public FileAttributes dwFileAttributes; + + /// A structure that specifies when a file or directory was created. + /// If the underlying file system does not support creation time, this member is zero. + public FILETIME ftCreationTime; + + /// A structure. + /// For a file, the structure specifies when the file was last read from, written to, or for executable files, run. + /// For a directory, the structure specifies when the directory is created. If the underlying file system does not support last access time, this member is zero. + /// On the FAT file system, the specified date for both files and directories is correct, but the time of day is always set to midnight. + /// + public FILETIME ftLastAccessTime; + + /// A structure. + /// For a file, the structure specifies when the file was last written to, truncated, or overwritten, for example, when WriteFile or SetEndOfFile are used. + /// The date and time are not updated when file attributes or security descriptors are changed. + /// For a directory, the structure specifies when the directory is created. If the underlying file system does not support last write time, this member is zero. + /// + public FILETIME ftLastWriteTime; + + /// The high-order DWORD of the file size. This member does not have a meaning for directories. + /// This value is zero unless the file size is greater than MAXDWORD. + /// The size of the file is equal to (nFileSizeHigh * (MAXDWORD+1)) + nFileSizeLow. + /// + public uint nFileSizeHigh; + + /// The low-order DWORD of the file size. This member does not have a meaning for directories. + public uint nFileSizeLow; + + /// If the dwFileAttributes member includes the FILE_ATTRIBUTE_REPARSE_POINT attribute, this member specifies the reparse point tag. + /// Otherwise, this value is undefined and should not be used. + /// + public readonly ReparsePointTag dwReserved0; + + /// Reserved for future use. + private readonly uint dwReserved1; + + /// The name of the file. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MaxPath)] public string cFileName; + + /// An alternative name for the file. This name is in the classic 8.3 file name format. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] public string cAlternateFileName; + } + } +} diff --git a/AlphaFS/Filesystem/Native Structures/WIN32_FIND_STREAM_DATA.cs b/AlphaFS/Filesystem/Native Structures/WIN32_FIND_STREAM_DATA.cs new file mode 100644 index 0000000..4e8c42b --- /dev/null +++ b/AlphaFS/Filesystem/Native Structures/WIN32_FIND_STREAM_DATA.cs @@ -0,0 +1,37 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct WIN32_FIND_STREAM_DATA + { + public long StreamSize; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MaxPath + 36)] + public string cStreamName; + } + } +} diff --git a/AlphaFS/Filesystem/Native Structures/WIN32_STREAM_ID.cs b/AlphaFS/Filesystem/Native Structures/WIN32_STREAM_ID.cs new file mode 100644 index 0000000..cc9b49c --- /dev/null +++ b/AlphaFS/Filesystem/Native Structures/WIN32_STREAM_ID.cs @@ -0,0 +1,51 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Contains stream data. + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)] + [SerializableAttribute] + internal struct WIN32_STREAM_ID + { + /// Type of stream data. + [MarshalAs(UnmanagedType.U4)] + public readonly BackupStreamType dwStreamId; + + /// Attributes of data to facilitate cross-operating system transfer. + [MarshalAs(UnmanagedType.U4)] + public readonly StreamAttributes dwStreamAttributes; + + /// Size of data, in bytes. + [MarshalAs(UnmanagedType.U8)] + public readonly ulong Size; + + /// Length of the name of the alternative data stream, in bytes. + [MarshalAs(UnmanagedType.U4)] + public readonly uint dwStreamNameSize; + } + } +} diff --git a/AlphaFS/Filesystem/Path Class/Path.Combine.cs b/AlphaFS/Filesystem/Path Class/Path.Combine.cs new file mode 100644 index 0000000..5669b35 --- /dev/null +++ b/AlphaFS/Filesystem/Path Class/Path.Combine.cs @@ -0,0 +1,105 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class Path + { + /// Combines an array of strings into a path. + /// The combined paths. + /// + /// + /// An array of parts of the path. + [SecurityCritical] + public static string Combine(params string[] paths) + { + return CombineCore(true, paths); + } + + /// Combines an array of strings into a path. + /// The combined paths. + /// + /// The parameters are not parsed if they have white space. + /// Therefore, if path2 includes white space (for example, " c:\\ "), + /// the Combine method appends path2 to path1 instead of returning only path2. + /// + /// + /// + /// will not check for invalid path characters. + /// An array of parts of the path. + [SecurityCritical] + internal static string CombineCore(bool checkInvalidPathChars, params string[] paths) + { + if (paths == null) + throw new ArgumentNullException("paths"); + + int capacity = 0; + int num = 0; + for (int index = 0, l = paths.Length; index < l; ++index) + { + if (paths[index] == null) + throw new ArgumentNullException("paths"); + + if (paths[index].Length != 0) + { + if (IsPathRooted(paths[index], checkInvalidPathChars)) + { + num = index; + capacity = paths[index].Length; + } + else + capacity += paths[index].Length; + + char ch = paths[index][paths[index].Length - 1]; + + if (!IsDVsc(ch, null)) + ++capacity; + } + } + + var buffer = new StringBuilder(capacity); + for (int index = num; index < paths.Length; ++index) + { + if (paths[index].Length != 0) + { + if (buffer.Length == 0) + buffer.Append(paths[index]); + + else + { + char ch = buffer[buffer.Length - 1]; + + if (!IsDVsc(ch, null)) + buffer.Append(DirectorySeparatorChar); + + buffer.Append(paths[index]); + } + } + } + + return buffer.ToString(); + } + } +} diff --git a/AlphaFS/Filesystem/Path Class/Path.Constants.cs b/AlphaFS/Filesystem/Path Class/Path.Constants.cs new file mode 100644 index 0000000..c5af3d9 --- /dev/null +++ b/AlphaFS/Filesystem/Path Class/Path.Constants.cs @@ -0,0 +1,124 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.Globalization; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class Path + { + /// AltDirectorySeparatorChar = '/' Provides a platform-specific alternate character used to separate directory levels in a path string that reflects a hierarchical file system organization. + public static readonly char AltDirectorySeparatorChar = System.IO.Path.AltDirectorySeparatorChar; + + /// DirectorySeparatorChar = '\' Provides a platform-specific character used to separate directory levels in a path string that reflects a hierarchical file system organization. + public static readonly char DirectorySeparatorChar = System.IO.Path.DirectorySeparatorChar; + + /// PathSeparator = ';' A platform-specific separator character used to separate path strings in environment variables. + public static readonly char PathSeparator = System.IO.Path.PathSeparator; + + /// VolumeSeparatorChar = ':' Provides a platform-specific Volume Separator character. + public static readonly char VolumeSeparatorChar = System.IO.Path.VolumeSeparatorChar; + + /// [AlphaFS] AltDirectorySeparatorChar = "/" Provides a platform-specific alternate string used to separate directory levels in a path string that reflects a hierarchical file system organization. + public static readonly string AltDirectorySeparator = AltDirectorySeparatorChar.ToString(CultureInfo.CurrentCulture); + + /// [AlphaFS] CurrentDirectoryPrefix = '.' Provides a current directory character. + public const char CurrentDirectoryPrefixChar = '.'; + + /// [AlphaFS] CurrentDirectoryPrefix = "." Provides a current directory string. + public static readonly string CurrentDirectoryPrefix = CurrentDirectoryPrefixChar.ToString(CultureInfo.CurrentCulture); + + /// [AlphaFS] DirectorySeparator = "\" Provides a platform-specific string used to separate directory levels in a path string that reflects a hierarchical file system organization. + public static readonly string DirectorySeparator = DirectorySeparatorChar.ToString(CultureInfo.CurrentCulture); + + /// [AlphaFS] ExtensionSeparatorChar = '.' Provides an Extension Separator character. + public const char ExtensionSeparatorChar = '.'; + + /// [AlphaFS] ParentDirectoryPrefix = ".." Provides a parent directory string. + public const string ParentDirectoryPrefix = ".."; + + /// [AlphaFS] StreamSeparator = ':' Provides a platform-specific Stream-name character. + public static readonly char StreamSeparatorChar = System.IO.Path.VolumeSeparatorChar; + + /// [AlphaFS] StreamSeparator = ':' Provides a platform-specific Stream-name character. + public static readonly string StreamSeparator = StreamSeparatorChar.ToString(CultureInfo.CurrentCulture); + + /// [AlphaFS] StreamDataLabel = ':$DATA' Provides a platform-specific Stream :$DATA label. + public static readonly string StreamDataLabel = ":$DATA"; + + /// [AlphaFS] StringTerminatorChar = '\0' String Terminator Suffix. + public const char StringTerminatorChar = '\0'; + + /// [AlphaFS] Characters to trim from the SearchPattern. + internal static readonly char[] TrimEndChars = { (char) 0x9, (char) 0xA, (char) 0xB, (char) 0xC, (char) 0xD, (char) 0x20, (char) 0x85, (char) 0xA0 }; + + /// [AlphaFS] VolumeSeparatorChar = ':' Provides a platform-specific Volume Separator character. + public static readonly string VolumeSeparator = VolumeSeparatorChar.ToString(CultureInfo.CurrentCulture); + + /// [AlphaFS] WildcardStarMatchAll = "*" Provides a match-all-items string. + public const string WildcardStarMatchAll = "*"; + + /// [AlphaFS] WildcardStarMatchAll = '*' Provides a match-all-items character. + public const char WildcardStarMatchAllChar = '*'; + + /// [AlphaFS] WildcardQuestion = "?" Provides a replace-item string. + public const string WildcardQuestion = "?"; + + /// [AlphaFS] WildcardQuestion = '?' Provides a replace-item string. + public const char WildcardQuestionChar = '?'; + + /// [AlphaFS] UncPrefix = "\\" Provides standard Windows Path UNC prefix. + public static readonly string UncPrefix = string.Format(CultureInfo.CurrentCulture, "{0}{0}", DirectorySeparatorChar); + + /// [AlphaFS] LongPathPrefix = "\\?\" Provides standard Windows Long Path prefix. + public static readonly string LongPathPrefix = string.Format(CultureInfo.CurrentCulture, "{0}{1}{2}", UncPrefix, WildcardQuestion, DirectorySeparatorChar); + + /// [AlphaFS] LongPathUncPrefix = "\\?\UNC\" Provides standard Windows Long Path UNC prefix. + public static readonly string LongPathUncPrefix = string.Format(CultureInfo.CurrentCulture, "{0}{1}{2}", LongPathPrefix, "UNC", DirectorySeparatorChar); + + /// [AlphaFS] GlobalRootPrefix = "\\?\GLOBALROOT\" Provides standard Windows Volume prefix. + public static readonly string GlobalRootPrefix = string.Format(CultureInfo.CurrentCulture, "{0}{1}{2}", LongPathPrefix, "GLOBALROOT", DirectorySeparatorChar); + + /// [AlphaFS] MsDosNamespacePrefix = "\\.\" Provides standard logical drive prefix. + public static readonly string LogicalDrivePrefix = string.Format(CultureInfo.CurrentCulture, "{0}{0}.{0}", DirectorySeparatorChar); + + /// [AlphaFS] SubstitutePrefix = "\??\" Provides a SUBST.EXE Path prefix to a Logical Drive. + public static readonly string SubstitutePrefix = string.Format(CultureInfo.CurrentCulture, "{0}{1}{2}{0}", DirectorySeparatorChar, WildcardQuestion, WildcardQuestion); + + /// [AlphaFS] VolumePrefix = "\\?\Volume" Provides standard Windows Volume prefix. + public static readonly string VolumePrefix = string.Format(CultureInfo.CurrentCulture, "{0}{1}", LongPathPrefix, "Volume"); + + /// [AlphaFS] DevicePrefix = "\Device\" Provides standard Windows Device prefix. + public static readonly string DevicePrefix = string.Format(CultureInfo.CurrentCulture, "{0}{1}{0}", DirectorySeparatorChar, "Device"); + + /// [AlphaFS] DosDeviceLanmanPrefix = "\Device\LanmanRedirector\" Provides a MS-Dos Lanman Redirector Path UNC prefix to a network share. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Lanman")] + public static readonly string DosDeviceLanmanPrefix = string.Format(CultureInfo.CurrentCulture, "{0}{1}{2}", DevicePrefix, "LanmanRedirector", DirectorySeparatorChar); + + /// [AlphaFS] DosDeviceMupPrefix = "\Device\Mup\" Provides a MS-Dos Mup Redirector Path UNC prefix to a network share. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Mup")] + public static readonly string DosDeviceMupPrefix = string.Format(CultureInfo.CurrentCulture, "{0}{1}{2}", DevicePrefix, "Mup", DirectorySeparatorChar); + + /// [AlphaFS] DosDeviceUncPrefix = "\??\UNC\" Provides a SUBST.EXE Path UNC prefix to a network share. + public static readonly string DosDeviceUncPrefix = string.Format(CultureInfo.CurrentCulture, "{0}{1}{2}", SubstitutePrefix, "UNC", DirectorySeparatorChar); + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Path Class/Path.GetComponents.cs b/AlphaFS/Filesystem/Path Class/Path.GetComponents.cs new file mode 100644 index 0000000..bad3fc6 --- /dev/null +++ b/AlphaFS/Filesystem/Path Class/Path.GetComponents.cs @@ -0,0 +1,368 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class Path + { + #region ChangeExtension (.NET) + + /// Changes the extension of a path string. + /// The modified path information. + /// + /// The path information to modify. The path cannot contain any of the characters defined in . + /// The new extension (with or without a leading period). Specify to remove an existing extension from path. + [SecurityCritical] + public static string ChangeExtension(string path, string extension) + { + return System.IO.Path.ChangeExtension(path, extension); + } + + #endregion // ChangeExtension (.NET) + + #region GetDirectoryName + + #region .NET + + /// Returns the directory information for the specified path string. + /// + /// Directory information for , or if denotes a root directory or is + /// . + /// Returns if does not contain directory information. + /// + /// + /// The path of a file or directory. + [SecurityCritical] + public static string GetDirectoryName(string path) + { + return GetDirectoryName(path, true); + } + + #endregion // .NET + + #region AlphaFS + + /// [AlphaFS] Returns the directory information for the specified path string. + /// + /// Directory information for , or if denotes a root directory or is + /// . Returns if does not contain directory information. + /// + /// + /// The path of a file or directory. + /// will check for invalid path characters. + [SecurityCritical] + public static string GetDirectoryName(string path, bool checkInvalidPathChars) + { + if (path != null) + { + int rootLength = GetRootLength(path, checkInvalidPathChars); + if (path.Length > rootLength) + { + int length = path.Length; + if (length == rootLength) + return null; + + while (length > rootLength && path[--length] != DirectorySeparatorChar && path[length] != AltDirectorySeparatorChar) { } + + return path.Substring(0, length).Replace(AltDirectorySeparatorChar, DirectorySeparatorChar); + } + } + + return null; + } + + #endregion // AlphaFS + + #endregion // GetDirectoryName + + #region GetDirectoryNameWithoutRoot + + #region AlphaFS + + /// [AlphaFS] Returns the directory information for the specified path string without the root information, for example: "C:\Windows\system32" returns: "Windows". + /// The without the file name part and without the root information (if any), or if is or if denotes a root (such as "\", "C:", or * "\\server\share"). + /// The path. + [SecurityCritical] + public static string GetDirectoryNameWithoutRoot(string path) + { + return GetDirectoryNameWithoutRootTransacted(null, path); + } + + /// [AlphaFS] Returns the directory information for the specified path string without the root information, for example: "C:\Windows\system32" returns: "Windows". + /// The without the file name part and without the root information (if any), or if is or if denotes a root (such as "\", "C:", or * "\\server\share"). + /// The transaction. + /// The path. + [SecurityCritical] + public static string GetDirectoryNameWithoutRootTransacted(KernelTransaction transaction, string path) + { + if (path == null) + return null; + + DirectoryInfo di = Directory.GetParentCore(transaction, path, PathFormat.RelativePath); + return di != null && di.Parent != null ? di.Name : null; + } + + #endregion // AlphaFS + + #endregion // GetDirectoryNameWithoutRoot + + #region GetExtension + + #region .NET + + /// Returns the extension of the specified path string. + /// + /// The extension of the specified path (including the period "."), or null, or . + /// If is null, this method returns null. + /// If does not have extension information, + /// this method returns . + /// + /// + /// + /// The path string from which to get the extension. The path cannot contain any of the characters defined in . + [SecurityCritical] + public static string GetExtension(string path) + { + return GetExtension(path, !Utils.IsNullOrWhiteSpace(path)); + } + + #endregion // .NET + + #region AlphaFS + + /// Returns the extension of the specified path string. + /// + /// The extension of the specified path (including the period "."), or null, or . + /// If is null, this method returns null. + /// If does not have extension information, + /// this method returns . + /// + /// + /// The path string from which to get the extension. The path cannot contain any of the characters defined in . + /// will check for invalid path characters. + [SecurityCritical] + public static string GetExtension(string path, bool checkInvalidPathChars) + { + if (path == null) + return null; + + if (checkInvalidPathChars) + CheckInvalidPathChars(path, false, true); + + int length = path.Length; + int index = length; + while (--index >= 0) + { + char ch = path[index]; + if (ch == ExtensionSeparatorChar) + return index != length - 1 ? path.Substring(index, length - index) : string.Empty; + + if (IsDVsc(ch, null)) + break; + } + + return string.Empty; + } + + #endregion // AlphaFS + + #endregion // GetExtension + + #region GetFileName + + #region .NET + + /// Returns the file name and extension of the specified path string. + /// + /// The characters after the last directory character in . If the last character of is a + /// directory or volume separator character, this method returns string.Empty. If path is null, this method returns null. + /// + /// + /// The path string from which to obtain the file name and extension. The path cannot contain any of the characters defined in . + [SecurityCritical] + public static string GetFileName(string path) + { + return GetFileName(path, true); + } + + #endregion // .NET + + #region AlphaFS + + /// [AlphaFS] Returns the file name and extension of the specified path string. + /// + /// The characters after the last directory character in . If the last character of is a + /// directory or volume separator character, this method returns string.Empty. If path is null, this method returns null. + /// + /// + /// The path string from which to obtain the file name and extension. + /// will check for invalid path characters. + [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Utils.IsNullOrWhiteSpace validates arguments.")] + public static string GetFileName(string path, bool checkInvalidPathChars) + { + if (Utils.IsNullOrWhiteSpace(path)) + return path; + + if (checkInvalidPathChars) + CheckInvalidPathChars(path, false, true); + + int length = path.Length; + int index = length; + while (--index >= 0) + { + char ch = path[index]; + if (IsDVsc(ch, null)) + return path.Substring(index + 1, length - index - 1); + } + + return path; + } + + #endregion // AlphaFS + + #endregion // GetFileName + + #region GetFileNameWithoutExtension + + #region .NET + + /// Returns the file name of the specified path string without the extension. + /// The string returned by GetFileName, minus the last period (.) and all characters following it. + /// + /// The path of the file. The path cannot contain any of the characters defined in . + [SecurityCritical] + public static string GetFileNameWithoutExtension(string path) + { + return GetFileNameWithoutExtension(path, true); + } + + #endregion // .NET + + #region AlphaFS + + /// [AlphaFS] Returns the file name of the specified path string without the extension. + /// The string returned by GetFileName, minus the last period (.) and all characters following it. + /// + /// The path of the file. The path cannot contain any of the characters defined in . + /// will check for invalid path characters. + [SecurityCritical] + public static string GetFileNameWithoutExtension(string path, bool checkInvalidPathChars) + { + path = GetFileName(path, checkInvalidPathChars); + + if (path != null) + { + int i; + return (i = path.LastIndexOf('.')) == -1 ? path : path.Substring(0, i); + } + + return null; + } + + #endregion // AlphaFS + + #endregion // GetFileNameWithoutExtension + + #region GetInvalidFileNameChars (.NET) + + /// Gets an array containing the characters that are not allowed in file names. + /// An array containing the characters that are not allowed in file names. + [SecurityCritical] + public static char[] GetInvalidFileNameChars() + { + return System.IO.Path.GetInvalidFileNameChars(); + } + + #endregion // GetInvalidFileNameChars (.NET) + + #region GetInvalidPathChars (.NET) + + /// Gets an array containing the characters that are not allowed in path names. + /// An array containing the characters that are not allowed in path names. + [SecurityCritical] + public static char[] GetInvalidPathChars() + { + return System.IO.Path.GetInvalidPathChars(); + } + + #endregion // GetInvalidPathChars (.NET) + + #region GetPathRoot + + #region .NET + + /// Gets the root directory information of the specified path. + /// + /// Returns the root directory of , such as "C:\", + /// or if is , + /// or an empty string if does not contain root directory information. + /// + /// + /// The path from which to obtain root directory information. + [SecurityCritical] + public static string GetPathRoot(string path) + { + return GetPathRoot(path, true); + } + + #endregion // .NET + + /// [AlphaFS] Gets the root directory information of the specified path. + /// + /// Returns the root directory of , such as "C:\", + /// or if is , + /// or an empty string if does not contain root directory information. + /// + /// + /// The path from which to obtain root directory information. + /// will check for invalid path characters. + [SecurityCritical] + public static string GetPathRoot(string path, bool checkInvalidPathChars) + { + if (path == null) + return null; + + if (path.Trim().Length == 0) + throw new ArgumentException(Resources.Path_Is_Zero_Length_Or_Only_White_Space, "path"); + + string pathRp = GetRegularPathCore(path, checkInvalidPathChars ? GetFullPathOptions.CheckInvalidPathChars : GetFullPathOptions.None, false); + + var rootLengthPath = GetRootLength(path, false); + var rootLengthPathRp = GetRootLength(pathRp, false); + + // Check if pathRp is an empty string. + if (rootLengthPathRp == 0) + if (path.StartsWith(LongPathPrefix, StringComparison.OrdinalIgnoreCase)) + return GetLongPathCore(path.Substring(0, rootLengthPath), GetFullPathOptions.None); + + if (path.StartsWith(LongPathUncPrefix, StringComparison.OrdinalIgnoreCase)) + return GetLongPathCore(pathRp.Substring(0, rootLengthPathRp), GetFullPathOptions.None); + + return path.Substring(0, rootLengthPath); + } + + #endregion // GetPathRoot + } +} diff --git a/AlphaFS/Filesystem/Path Class/Path.GetFinalPathNameByHandle.cs b/AlphaFS/Filesystem/Path Class/Path.GetFinalPathNameByHandle.cs new file mode 100644 index 0000000..77206eb --- /dev/null +++ b/AlphaFS/Filesystem/Path Class/Path.GetFinalPathNameByHandle.cs @@ -0,0 +1,166 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Security; +using Microsoft.Win32.SafeHandles; +using System; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class Path + { + /// [AlphaFS] Retrieves the final path for the specified file, formatted as . + /// The final path as a string. + /// + /// A final path is the path that is returned when a path is fully resolved. For example, for a symbolic link named "C:\tmp\mydir" that + /// points to "D:\yourdir", the final path would be "D:\yourdir". + /// + /// Then handle to a instance. + [SecurityCritical] + public static string GetFinalPathNameByHandle(SafeFileHandle handle) + { + return GetFinalPathNameByHandleCore(handle, FinalPathFormats.None); + } + + /// [AlphaFS] Retrieves the final path for the specified file, formatted as . + /// The final path as a string. + /// + /// A final path is the path that is returned when a path is fully resolved. For example, for a symbolic link named "C:\tmp\mydir" that + /// points to "D:\yourdir", the final path would be "D:\yourdir". + /// + /// Then handle to a instance. + /// The final path, formatted as + [SecurityCritical] + public static string GetFinalPathNameByHandle(SafeFileHandle handle, FinalPathFormats finalPath) + { + return GetFinalPathNameByHandleCore(handle, finalPath); + } + + /// Retrieves the final path for the specified file, formatted as . + /// The final path as a string. + /// + /// A final path is the path that is returned when a path is fully resolved. For example, for a symbolic link named "C:\tmp\mydir" that + /// points to "D:\yourdir", the final path would be "D:\yourdir". The string that is returned by this function uses the + /// syntax. + /// + /// Then handle to a instance. + /// The final path, formatted as + [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "Alphaleonis.Win32.Filesystem.NativeMethods.GetMappedFileName(System.IntPtr,Alphaleonis.Win32.SafeGlobalMemoryBufferHandle,System.Text.StringBuilder,System.UInt32)")] + [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "Alphaleonis.Win32.Filesystem.NativeMethods.GetMappedFileName(System.IntPtr,Alphaleonis.Win32.Security.SafeLocalMemoryBufferHandle,System.Text.StringBuilder,System.UInt32)")] + [SecurityCritical] + internal static string GetFinalPathNameByHandleCore(SafeFileHandle handle, FinalPathFormats finalPath) + { + NativeMethods.IsValidHandle(handle); + + var buffer = new StringBuilder(NativeMethods.MaxPathUnicode); + + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + { + if (NativeMethods.IsAtLeastWindowsVista) + { + if (NativeMethods.GetFinalPathNameByHandle(handle, buffer, (uint) buffer.Capacity, finalPath) == Win32Errors.ERROR_SUCCESS) + NativeError.ThrowException(Marshal.GetLastWin32Error()); + + return buffer.ToString(); + } + } + + #region Older OperatingSystem + + // Obtaining a File Name From a File Handle + // http://msdn.microsoft.com/en-us/library/aa366789%28VS.85%29.aspx + + // Be careful when using GetFileSizeEx to check the size of hFile handle of an unknown "File" type object. + // This is more towards returning a filename from a file handle. If the handle is a named pipe handle it seems to hang the thread. + // Check for: FileTypes.DiskFile + + // Can't map a 0 byte file. + long fileSizeHi; + if (!NativeMethods.GetFileSizeEx(handle, out fileSizeHi)) + if (fileSizeHi == 0) + return string.Empty; + + + // PAGE_READONLY + // Allows views to be mapped for read-only or copy-on-write access. An attempt to write to a specific region results in an access violation. + // The file handle that the hFile parameter specifies must be created with the GENERIC_READ access right. + // PageReadOnly = 0x02, + using (SafeFileHandle handle2 = NativeMethods.CreateFileMapping(handle, null, 2, 0, 1, null)) + { + NativeMethods.IsValidHandle(handle, Marshal.GetLastWin32Error()); + + // FILE_MAP_READ + // Read = 4 + using (SafeLocalMemoryBufferHandle pMem = NativeMethods.MapViewOfFile(handle2, 4, 0, 0, (UIntPtr)1)) + { + if (NativeMethods.IsValidHandle(pMem, Marshal.GetLastWin32Error())) + if (NativeMethods.GetMappedFileName(Process.GetCurrentProcess().Handle, pMem, buffer, (uint)buffer.Capacity)) + NativeMethods.UnmapViewOfFile(pMem); + } + } + + + // Default output from GetMappedFileName(): "\Device\HarddiskVolumeX\path\filename.ext" + string dosDevice = buffer.Length > 0 ? buffer.ToString() : string.Empty; + + // Select output format. + switch (finalPath) + { + // As-is: "\Device\HarddiskVolumeX\path\filename.ext" + case FinalPathFormats.VolumeNameNT: + return dosDevice; + + // To: "\path\filename.ext" + case FinalPathFormats.VolumeNameNone: + return DosDeviceToDosPath(dosDevice, string.Empty); + + // To: "\\?\Volume{GUID}\path\filename.ext" + case FinalPathFormats.VolumeNameGuid: + string dosPath = DosDeviceToDosPath(dosDevice, null); + if (!Utils.IsNullOrWhiteSpace(dosPath)) + { + string path = GetSuffixedDirectoryNameWithoutRootCore(null, dosPath); + string driveLetter = RemoveTrailingDirectorySeparator(GetPathRoot(dosPath, false), false); + string file = GetFileName(dosPath, true); + + if (!Utils.IsNullOrWhiteSpace(file)) + foreach (string drive in Directory.EnumerateLogicalDrivesCore(false, false).Select(drv => drv.Name).Where(drv => driveLetter.Equals(RemoveTrailingDirectorySeparator(drv, false), StringComparison.OrdinalIgnoreCase))) + return CombineCore(false, Volume.GetUniqueVolumeNameForPath(drive), path, file); + } + + break; + } + + // To: "\\?\C:\path\filename.ext" + return Utils.IsNullOrWhiteSpace(dosDevice) + ? string.Empty + : LongPathPrefix + DosDeviceToDosPath(dosDevice, null); + + #endregion // Older OperatingSystem + } + } +} diff --git a/AlphaFS/Filesystem/Path Class/Path.GetFullPath.cs b/AlphaFS/Filesystem/Path Class/Path.GetFullPath.cs new file mode 100644 index 0000000..a9202d5 --- /dev/null +++ b/AlphaFS/Filesystem/Path Class/Path.GetFullPath.cs @@ -0,0 +1,305 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class Path + { + #region .NET + + /// Returns the absolute path for the specified path string. + /// The fully qualified location of path, such as "C:\MyFile.txt". + /// + /// GetFullPathName merges the name of the current drive and directory with a specified file name to determine the full path and file name of a specified file. + /// It also calculates the address of the file name portion of the full path and file name. + ///   + /// This method does not verify that the resulting path and file name are valid, or that they see an existing file on the associated volume. + /// The .NET Framework does not support direct access to physical disks through paths that are device names, such as "\\.\PHYSICALDRIVE0". + ///   + /// MSDN: Multithreaded applications and shared library code should not use the GetFullPathName function and + /// should avoid using relative path names. The current directory state written by the SetCurrentDirectory function is stored as a global variable in each process, + /// therefore multithreaded applications cannot reliably use this value without possible data corruption from other threads that may also be reading or setting this value. + /// This limitation also applies to the SetCurrentDirectory and GetCurrentDirectory functions. The exception being when the application is guaranteed to be running in a single thread, + /// for example parsing file names from the command line argument string in the main thread prior to creating any additional threads. + /// Using relative path names in multithreaded applications or shared library code can yield unpredictable results and is not supported. + /// + /// + /// + /// + /// The file or directory for which to obtain absolute path information. + [SecurityCritical] + public static string GetFullPath(string path) + { + return GetFullPathTackleCore(null, path, GetFullPathOptions.None); + } + + #endregion // .NET + + + #region AlphaFS + + /// Returns the absolute path for the specified path string. + /// The fully qualified location of path, such as "C:\MyFile.txt". + /// + /// GetFullPathName merges the name of the current drive and directory with a specified file name to determine the full path and file name of a specified file. + /// It also calculates the address of the file name portion of the full path and file name. + ///   + /// This method does not verify that the resulting path and file name are valid, or that they see an existing file on the associated volume. + /// The .NET Framework does not support direct access to physical disks through paths that are device names, such as "\\.\PHYSICALDRIVE0". + ///   + /// MSDN: Multithreaded applications and shared library code should not use the GetFullPathName function and + /// should avoid using relative path names. The current directory state written by the SetCurrentDirectory function is stored as a global variable in each process, + /// therefore multithreaded applications cannot reliably use this value without possible data corruption from other threads that may also be reading or setting this value. + /// This limitation also applies to the SetCurrentDirectory and GetCurrentDirectory functions. The exception being when the application is guaranteed to be running in a single thread, + /// for example parsing file names from the command line argument string in the main thread prior to creating any additional threads. + /// Using relative path names in multithreaded applications or shared library code can yield unpredictable results and is not supported. + /// + /// + /// + /// + /// The file or directory for which to obtain absolute path information. + /// Options for controlling the full path retrieval. + [SecurityCritical] + public static string GetFullPath(string path, GetFullPathOptions options) + { + return GetFullPathTackleCore(null, path, options); + } + + + /// [AlphaFS] Returns the absolute path for the specified path string. + /// The fully qualified location of path, such as "C:\MyFile.txt". + /// + /// GetFullPathName merges the name of the current drive and directory with a specified file name to determine the full path and file name of a specified file. + /// It also calculates the address of the file name portion of the full path and file name. + ///   + /// This method does not verify that the resulting path and file name are valid, or that they see an existing file on the associated volume. + /// The .NET Framework does not support direct access to physical disks through paths that are device names, such as "\\.\PHYSICALDRIVE0". + ///   + /// MSDN: Multithreaded applications and shared library code should not use the GetFullPathName function and + /// should avoid using relative path names. The current directory state written by the SetCurrentDirectory function is stored as a global variable in each process, + /// therefore multithreaded applications cannot reliably use this value without possible data corruption from other threads that may also be reading or setting this value. + /// This limitation also applies to the SetCurrentDirectory and GetCurrentDirectory functions. The exception being when the application is guaranteed to be running in a single thread, + /// for example parsing file names from the command line argument string in the main thread prior to creating any additional threads. + /// Using relative path names in multithreaded applications or shared library code can yield unpredictable results and is not supported. + /// + /// + /// + /// + /// The transaction. + /// The file or directory for which to obtain absolute path information. + [SecurityCritical] + public static string GetFullPathTransacted(KernelTransaction transaction, string path) + { + return GetFullPathTackleCore(transaction, path, GetFullPathOptions.None); + } + + /// [AlphaFS] Returns the absolute path for the specified path string. + /// The fully qualified location of path, such as "C:\MyFile.txt". + /// + /// GetFullPathName merges the name of the current drive and directory with a specified file name to determine the full path and file name of a specified file. + /// It also calculates the address of the file name portion of the full path and file name. + ///   + /// This method does not verify that the resulting path and file name are valid, or that they see an existing file on the associated volume. + /// The .NET Framework does not support direct access to physical disks through paths that are device names, such as "\\.\PHYSICALDRIVE0". + ///   + /// MSDN: Multithreaded applications and shared library code should not use the GetFullPathName function and + /// should avoid using relative path names. The current directory state written by the SetCurrentDirectory function is stored as a global variable in each process, + /// therefore multithreaded applications cannot reliably use this value without possible data corruption from other threads that may also be reading or setting this value. + /// This limitation also applies to the SetCurrentDirectory and GetCurrentDirectory functions. The exception being when the application is guaranteed to be running in a single thread, + /// for example parsing file names from the command line argument string in the main thread prior to creating any additional threads. + /// Using relative path names in multithreaded applications or shared library code can yield unpredictable results and is not supported. + /// + /// + /// + /// + /// The transaction. + /// The file or directory for which to obtain absolute path information. + /// Options for controlling the full path retrieval. + [SecurityCritical] + public static string GetFullPathTransacted(KernelTransaction transaction, string path, GetFullPathOptions options) + { + return GetFullPathTackleCore(transaction, path, options); + } + + #endregion // AlphaFS + + #region Internal Methods + + /// Retrieves the absolute path for the specified string. + /// The fully qualified location of , such as "C:\MyFile.txt". + /// + /// GetFullPathName merges the name of the current drive and directory with a specified file name to determine the full path and file name of a specified file. + /// It also calculates the address of the file name portion of the full path and file name. + ///   + /// This method does not verify that the resulting path and file name are valid, or that they see an existing file on the associated volume. + /// The .NET Framework does not support direct access to physical disks through paths that are device names, such as "\\.\PHYSICALDRIVE0". + ///   + /// MSDN: Multithreaded applications and shared library code should not use the GetFullPathName function and + /// should avoid using relative path names. The current directory state written by the SetCurrentDirectory function is stored as a global variable in each process, + /// therefore multithreaded applications cannot reliably use this value without possible data corruption from other threads that may also be reading or setting this value. + /// This limitation also applies to the SetCurrentDirectory and GetCurrentDirectory functions. The exception being when the application is guaranteed to be running in a single thread, + /// for example parsing file names from the command line argument string in the main thread prior to creating any additional threads. + /// Using relative path names in multithreaded applications or shared library code can yield unpredictable results and is not supported. + /// + /// + /// + /// The transaction. + /// The file or directory for which to obtain absolute path information. + /// Options for controlling the full path retrieval. + [SecurityCritical] + internal static string GetFullPathCore(KernelTransaction transaction, string path, GetFullPathOptions options) + { + if (path != null) + if (path.StartsWith(GlobalRootPrefix, StringComparison.OrdinalIgnoreCase) ||path.StartsWith(VolumePrefix, StringComparison.OrdinalIgnoreCase)) + return path; + + if (options != GetFullPathOptions.None) + { + if ((options & GetFullPathOptions.CheckInvalidPathChars) != 0) + { + var checkAdditional = (options & GetFullPathOptions.CheckAdditional) != 0; + + CheckInvalidPathChars(path, checkAdditional, false); + + // Prevent duplicate checks. + options &= ~GetFullPathOptions.CheckInvalidPathChars; + + if (checkAdditional) + options &= ~GetFullPathOptions.CheckAdditional; + } + + // Do not remove trailing directory separator when path points to a drive like: "C:\" + // Doing so makes path point to the current directory. + + if (path == null || path.Length <= 3 || (!path.StartsWith(LongPathPrefix, StringComparison.OrdinalIgnoreCase) && path[1] != VolumeSeparatorChar)) + options &= ~GetFullPathOptions.RemoveTrailingDirectorySeparator; + } + + + var pathLp = GetLongPathCore(path, options); + uint bufferSize = NativeMethods.MaxPathUnicode; + + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + { + startGetFullPathName: + + var buffer = new StringBuilder((int)bufferSize); + var returnLength = (transaction == null || !NativeMethods.IsAtLeastWindowsVista + + // GetFullPathName() / GetFullPathNameTransacted() + // 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-04-15: MSDN confirms LongPath usage. + + ? NativeMethods.GetFullPathName(pathLp, bufferSize, buffer, IntPtr.Zero) + : NativeMethods.GetFullPathNameTransacted(pathLp, bufferSize, buffer, IntPtr.Zero, transaction.SafeHandle)); + + if (returnLength != Win32Errors.NO_ERROR) + { + if (returnLength > bufferSize) + { + bufferSize = returnLength; + goto startGetFullPathName; + } + } + else + { + if ((options & GetFullPathOptions.ContinueOnNonExist) != 0) + return null; + + NativeError.ThrowException(pathLp); + } + + + var finalFullPath = (options & GetFullPathOptions.AsLongPath) != 0 + ? GetLongPathCore(buffer.ToString(), GetFullPathOptions.None) + : GetRegularPathCore(buffer.ToString(), GetFullPathOptions.None, false); + + + finalFullPath = NormalizePath(finalFullPath, options); + + + if ((options & GetFullPathOptions.KeepDotOrSpace) != 0) + { + if (pathLp.EndsWith(".", StringComparison.OrdinalIgnoreCase)) + finalFullPath += "."; + + var lastChar = pathLp[pathLp.Length - 1]; + if (char.IsWhiteSpace(lastChar)) + finalFullPath += lastChar; + } + + + return finalFullPath; + } + } + + private static string GetFullPathTackleCore(KernelTransaction transaction, string path, GetFullPathOptions options) + { + if (path != null) + { + if (path.StartsWith(GlobalRootPrefix, StringComparison.OrdinalIgnoreCase) || path.StartsWith(VolumePrefix, StringComparison.OrdinalIgnoreCase)) + return path; + + CheckInvalidUncPath(path); + } + + CheckSupportedPathFormat(path, true, true); + + return GetFullPathCore(transaction, path, options); + } + + /// Applies the to + /// with applied . + /// + /// + /// + /// + private static string ApplyFullPathOptions(string path, GetFullPathOptions options) + { + if ((options & GetFullPathOptions.TrimEnd) != 0) + if ((options & GetFullPathOptions.KeepDotOrSpace) == 0) + path = path.TrimEnd(); + + if ((options & GetFullPathOptions.AddTrailingDirectorySeparator) != 0) + path = AddTrailingDirectorySeparator(path, false); + + if ((options & GetFullPathOptions.RemoveTrailingDirectorySeparator) != 0) + path = RemoveTrailingDirectorySeparator(path, false); + + if ((options & GetFullPathOptions.CheckInvalidPathChars) != 0) + CheckInvalidPathChars(path, (options & GetFullPathOptions.CheckAdditional) != 0, false); + + + // Trim leading whitespace. + if ((options & GetFullPathOptions.KeepDotOrSpace) == 0) + path = path.TrimStart(); + + return path; + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/Path Class/Path.SeparatorManipulation.cs b/AlphaFS/Filesystem/Path Class/Path.SeparatorManipulation.cs new file mode 100644 index 0000000..7140a10 --- /dev/null +++ b/AlphaFS/Filesystem/Path Class/Path.SeparatorManipulation.cs @@ -0,0 +1,202 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Globalization; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class Path + { + #region AddTrailingDirectorySeparator + + /// [AlphaFS] Adds a trailing character to the string, when absent. + /// A text string with a trailing character. The function returns when is . + /// A text string to which the trailing is to be added, when absent. + [SecurityCritical] + public static string AddTrailingDirectorySeparator(string path) + { + return AddTrailingDirectorySeparator(path, false); + } + + /// [AlphaFS] Adds a trailing or character to the string, when absent. + /// A text string with a trailing or character. The function returns when is . + /// A text string to which the trailing or is to be added, when absent. + /// If the character will be added instead. + [SecurityCritical] + public static string AddTrailingDirectorySeparator(string path, bool addAlternateSeparator) + { + return path == null + ? null + : (addAlternateSeparator + ? ((!path.EndsWith(AltDirectorySeparatorChar.ToString(CultureInfo.CurrentCulture), StringComparison.OrdinalIgnoreCase)) + ? path + AltDirectorySeparatorChar + : path) + + : ((!path.EndsWith(DirectorySeparatorChar.ToString(CultureInfo.CurrentCulture), StringComparison.OrdinalIgnoreCase)) + ? path + DirectorySeparatorChar + : path)); + } + + #endregion // AddTrailingDirectorySeparator + + #region RemoveTrailingDirectorySeparator + + /// [AlphaFS] Removes the trailing character from the string, when present. + /// A text string where the trailing character has been removed. The function returns when is . + /// A text string from which the trailing is to be removed, when present. + [SecurityCritical] + public static string RemoveTrailingDirectorySeparator(string path) + { + return path == null ? null : path.TrimEnd(DirectorySeparatorChar, AltDirectorySeparatorChar); + } + + /// [AlphaFS] Removes the trailing or character from the string, when present. + /// A text string where the trailing or character has been removed. The function returns when is . + /// A text string from which the trailing or is to be removed, when present. + /// If the trailing character will be removed instead. + [SecurityCritical] + public static string RemoveTrailingDirectorySeparator(string path, bool removeAlternateSeparator) + { + return path == null + ? null + : path.TrimEnd(removeAlternateSeparator ? AltDirectorySeparatorChar : DirectorySeparatorChar); + } + + #endregion // RemoveTrailingDirectorySeparator + + #region GetSuffixedDirectoryName + + /// [AlphaFS] Returns the directory information for the specified with a trailing character. + /// + /// The suffixed directory information for the specified with a trailing character, + /// or if is or if denotes a root (such as "\", "C:", or * "\\server\share"). + /// + /// This method is similar to calling Path.GetDirectoryName() + Path.AddTrailingDirectorySeparator() + /// The path. + [SecurityCritical] + public static string GetSuffixedDirectoryName(string path) + { + return GetSuffixedDirectoryNameCore(null, path); + } + + /// [AlphaFS] Returns the directory information for the specified with a trailing character. + /// + /// The suffixed directory information for the specified with a trailing character, + /// or if is or if denotes a root (such as "\", "C:", or * "\\server\share"). + /// + /// This method is similar to calling Path.GetDirectoryName() + Path.AddTrailingDirectorySeparator() + /// The transaction. + /// The path. + [SecurityCritical] + public static string GetSuffixedDirectoryNameTransacted(KernelTransaction transaction, string path) + { + return GetSuffixedDirectoryNameCore(transaction, path); + } + + #endregion // GetSuffixedDirectoryName + + #region GetSuffixedDirectoryNameWithoutRoot + + /// [AlphaFS] Returns the directory information for the specified without the root and with a trailing character. + /// + /// The directory information for the specified without the root and with a trailing character, + /// or if is or if is . + /// + /// The path. + [SecurityCritical] + public static string GetSuffixedDirectoryNameWithoutRoot(string path) + { + return GetSuffixedDirectoryNameWithoutRootCore(null, path); + } + + /// [AlphaFS] Returns the directory information for the specified without the root and with a trailing character. + /// + /// The directory information for the specified without the root and with a trailing character, + /// or if is or if is . + /// + /// The transaction. + /// The path. + [SecurityCritical] + public static string GetSuffixedDirectoryNameWithoutRootTransacted(KernelTransaction transaction, string path) + { + return GetSuffixedDirectoryNameWithoutRootCore(transaction, path); + } + + #endregion // GetSuffixedDirectoryNameWithoutRoot + + #region Internal Methods + + /// Returns the directory information for the specified with a trailing character. + /// + /// The suffixed directory information for the specified with a trailing character, + /// or if is or if denotes a root (such as "\", "C:", or * "\\server\share"). + /// + /// This method is similar to calling Path.GetDirectoryName() + Path.AddTrailingDirectorySeparator() + /// The transaction. + /// The path. + [SecurityCritical] + private static string GetSuffixedDirectoryNameCore(KernelTransaction transaction, string path) + { + DirectoryInfo di = Directory.GetParentCore(transaction, path, PathFormat.RelativePath); + + return di != null && di.Parent != null && di.Name != null + ? AddTrailingDirectorySeparator(CombineCore(false, di.Parent.FullName, di.Name), false) + : null; + } + + /// Returns the directory information for the specified without the root and with a trailing character. + /// + /// The directory information for the specified without the root and with a trailing character, + /// or if is or if is . + /// + /// The transaction. + /// The path. + [SecurityCritical] + private static string GetSuffixedDirectoryNameWithoutRootCore(KernelTransaction transaction, string path) + { + DirectoryInfo di = Directory.GetParentCore(transaction, path, PathFormat.RelativePath); + + if (di == null || di.Parent == null) + return null; + + DirectoryInfo tmp = di; + string suffixedDirectoryNameWithoutRoot; + + do + { + suffixedDirectoryNameWithoutRoot = tmp.DisplayPath.Replace(di.Root.ToString(), string.Empty); + + if (tmp.Parent != null) + tmp = di.Parent.Parent; + + } while (tmp != null && tmp.Root.Parent != null && tmp.Parent != null && !Utils.IsNullOrWhiteSpace(tmp.Parent.ToString())); + + return Utils.IsNullOrWhiteSpace(suffixedDirectoryNameWithoutRoot) + ? null + : AddTrailingDirectorySeparator(suffixedDirectoryNameWithoutRoot.TrimStart(DirectorySeparatorChar), false); + // TrimStart() for network-drive, like: C$ + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/Path Class/Path.ShortLongConversions.cs b/AlphaFS/Filesystem/Path Class/Path.ShortLongConversions.cs new file mode 100644 index 0000000..5209d0c --- /dev/null +++ b/AlphaFS/Filesystem/Path Class/Path.ShortLongConversions.cs @@ -0,0 +1,273 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class Path + { + #region GetLongPath + + /// Makes an extended long path from the specified by prefixing . + /// The prefixed with a , the minimum required full path is: "C:\". + /// This method does not verify that the resulting path and file name are valid, or that they see an existing file on the associated volume. + /// + /// + /// The path to the file or directory, this can also be an UNC path. + [SecurityCritical] + public static string GetLongPath(string path) + { + return GetLongPathCore(path, GetFullPathOptions.None); + } + + #endregion // GetLongPath + + #region GetLongFrom83ShortPath + + /// [AlphaFS] Converts the specified existing path to its regular long form. + /// An existing path to a folder or file. + /// The regular full path. + [SecurityCritical] + public static string GetLongFrom83ShortPath(string path) + { + return GetLongShort83PathCore(null, path, false); + } + + /// [AlphaFS] Converts the specified existing path to its regular long form. + /// The transaction. + /// An existing path to a folder or file. + /// The regular full path. + [SecurityCritical] + public static string GetLongFrom83ShortPathTransacted(KernelTransaction transaction, string path) + { + return GetLongShort83PathCore(transaction, path, false); + } + + #endregion // GetLongFrom83ShortPath + + #region GetRegularPath + + /// [AlphaFS] Gets the regular path from long prefixed one. i.e.: "\\?\C:\Temp\file.txt" to C:\Temp\file.txt" or: "\\?\UNC\Server\share\file.txt" to "\\Server\share\file.txt". + /// Regular form path string. + /// This method does not handle paths with volume names, eg. \\?\Volume{GUID}\Folder\file.txt. + /// The path. + [SecurityCritical] + public static string GetRegularPath(string path) + { + return GetRegularPathCore(path, GetFullPathOptions.CheckInvalidPathChars, false); + } + + #endregion // GetRegularPath + + #region GetShort83Path + + /// [AlphaFS] Retrieves the short path form of the specified path. + /// A path that has the 8.3 path form. + /// Will fail on NTFS volumes with disabled 8.3 name generation. + /// The path must actually exist to be able to get the short path name. + /// An existing path to a folder or file. + [SecurityCritical] + public static string GetShort83Path(string path) + { + return GetLongShort83PathCore(null, path, true); + } + + /// [AlphaFS] Retrieves the short path form of the specified path. + /// A path that has the 8.3 path form. + /// Will fail on NTFS volumes with disabled 8.3 name generation. + /// The path must actually exist to be able to get the short path name. + /// The transaction. + /// An existing path to a folder or file. + [SecurityCritical] + public static string GetShort83PathTransacted(KernelTransaction transaction, string path) + { + return GetLongShort83PathCore(transaction, path, true); + } + + #endregion // GetShort83Path + + #region IsLongPath + + /// [AlphaFS] Determines whether the specified path starts with a or . + /// if the specified path has a long path (UNC) prefix, otherwise. + /// The path to the file or directory. + [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Utils.IsNullOrWhiteSpace validates arguments.")] + [SecurityCritical] + public static bool IsLongPath(string path) + { + return !Utils.IsNullOrWhiteSpace(path) && path.StartsWith(LongPathPrefix, StringComparison.OrdinalIgnoreCase); + } + + #endregion // IsLongPath + + #region Internals Methods + + /// Makes an extended long path from the specified by prefixing . + /// The prefixed with a , the minimum required full path is: "C:\". + /// This method does not verify that the resulting path and file name are valid, or that they see an existing file on the associated volume. + /// + /// + /// The path to the file or directory, this can also be an UNC path. + /// Options for controlling the full path retrieval. + [SecurityCritical] + internal static string GetLongPathCore(string path, GetFullPathOptions options) + { + if (path == null) + throw new ArgumentNullException("path"); + + if (path.Length == 0 || Utils.IsNullOrWhiteSpace(path)) + throw new ArgumentException(Resources.Path_Is_Zero_Length_Or_Only_White_Space, "path"); + + if (options != GetFullPathOptions.None) + path = ApplyFullPathOptions(path, options); + + // ".", "C:" + if (path.Length <= 2 || + path.StartsWith(LongPathPrefix, StringComparison.OrdinalIgnoreCase) || + path.StartsWith(LogicalDrivePrefix, StringComparison.OrdinalIgnoreCase)) + return path; + + if (path.StartsWith(UncPrefix, StringComparison.OrdinalIgnoreCase)) + return LongPathUncPrefix + path.Substring(UncPrefix.Length); + + // Don't use char.IsLetter() here as that can be misleading. + // The only valid drive letters are: a-z and A-Z. + char c = path[0]; + return IsPathRooted(path, false) && ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) + ? LongPathPrefix + path + : path; + } + + /// Retrieves the short path form, or the regular long form of the specified . + /// If is , a path of the 8.3 form otherwise the regular long form. + /// + /// Will fail on NTFS volumes with disabled 8.3 name generation. + /// The path must actually exist to be able to get the short- or long path name. + /// + /// The transaction. + /// An existing path to a folder or file. + /// to retrieve the short path form, to retrieve the regular long form from the 8.3 . + [SecurityCritical] + private static string GetLongShort83PathCore(KernelTransaction transaction, string path, bool getShort) + { + string pathLp = GetFullPathCore(transaction, path, GetFullPathOptions.AsLongPath | GetFullPathOptions.FullCheck); + + var buffer = new StringBuilder(); + uint actualLength = getShort ? NativeMethods.GetShortPathName(pathLp, null, 0) : (uint) path.Length; + + while (actualLength > buffer.Capacity) + { + buffer = new StringBuilder((int)actualLength); + actualLength = getShort + + // GetShortPathName() + // 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. + // 2014-01-29: MSDN confirms LongPath usage. + + ? NativeMethods.GetShortPathName(pathLp, buffer, (uint)buffer.Capacity) + : transaction == null || !NativeMethods.IsAtLeastWindowsVista + + // GetLongPathName() + // 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. + // 2014-01-29: MSDN confirms LongPath usage. + + ? NativeMethods.GetLongPathName(pathLp, buffer, (uint)buffer.Capacity) + : NativeMethods.GetLongPathNameTransacted(pathLp, buffer, (uint)buffer.Capacity, transaction.SafeHandle); + + if (actualLength == Win32Errors.ERROR_SUCCESS) + NativeError.ThrowException(pathLp); + } + + return GetRegularPathCore(buffer.ToString(), GetFullPathOptions.None, false); + } + + /// Gets the regular path from a long path. + /// + /// Returns the regular form of a long . + /// For example: "\\?\C:\Temp\file.txt" to: "C:\Temp\file.txt", or: "\\?\UNC\Server\share\file.txt" to: "\\Server\share\file.txt". + /// + /// + /// MSDN: String.TrimEnd Method notes to Callers: http://msdn.microsoft.com/en-us/library/system.string.trimend%28v=vs.110%29.aspx + /// + /// + /// + /// The path. + /// Options for controlling the full path retrieval. + /// When , throws an . + [SecurityCritical] + internal static string GetRegularPathCore(string path, GetFullPathOptions options, bool allowEmpty) + { + if (path == null) + throw new ArgumentNullException("path"); + + if (!allowEmpty && (path.Length == 0 || Utils.IsNullOrWhiteSpace(path))) + throw new ArgumentException(Resources.Path_Is_Zero_Length_Or_Only_White_Space, "path"); + + if (options != GetFullPathOptions.None) + path = ApplyFullPathOptions(path, options); + + return path.StartsWith(GlobalRootPrefix, StringComparison.OrdinalIgnoreCase) + || path.StartsWith(VolumePrefix, StringComparison.OrdinalIgnoreCase) + || !path.StartsWith(LongPathPrefix, StringComparison.OrdinalIgnoreCase) + ? path + : (path.StartsWith(LongPathUncPrefix, StringComparison.OrdinalIgnoreCase) + ? UncPrefix + path.Substring(LongPathUncPrefix.Length) + : path.Substring(LongPathPrefix.Length)); + } + + /// Gets the path as a long full path. + /// The path as an extended length path. + /// + /// The transaction. + /// Full pathname of the source path to convert. + /// The path format to use. + /// Options for controlling the operation. Note that on .NET 3.5 the TrimEnd option has no effect. + internal static string GetExtendedLengthPathCore(KernelTransaction transaction, string sourcePath, PathFormat pathFormat, GetFullPathOptions options) + { + switch (pathFormat) + { + case PathFormat.LongFullPath: + return sourcePath; + + case PathFormat.FullPath: + return GetLongPathCore(sourcePath, GetFullPathOptions.None); + + case PathFormat.RelativePath: +#if NET35 + // .NET 3.5 the TrimEnd option has no effect. + options = options & ~GetFullPathOptions.TrimEnd; +#endif + return GetFullPathCore(transaction, sourcePath, GetFullPathOptions.AsLongPath | options); + + default: + throw new ArgumentException("Invalid value for " + typeof(PathFormat).Name + ": " + pathFormat); + } + } + + #endregion // Internals Methods + } +} diff --git a/AlphaFS/Filesystem/Path Class/Path.Temporary.cs b/AlphaFS/Filesystem/Path Class/Path.Temporary.cs new file mode 100644 index 0000000..552de97 --- /dev/null +++ b/AlphaFS/Filesystem/Path Class/Path.Temporary.cs @@ -0,0 +1,77 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class Path + { + #region GetRandomFileName (.NET) + + /// Returns a random folder name or file name. + /// A random folder name or file name. + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")] + [SecurityCritical] + public static string GetRandomFileName() + { + return System.IO.Path.GetRandomFileName(); + } + + #endregion // GetRandomFileName (.NET) + + #region GetTempFileName (.NET) + + /// Creates a uniquely named, zero-byte temporary file on disk and returns the full path of that file. + /// The full path of the temporary file. + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")] + [SecurityCritical] + public static string GetTempFileName() + { + return System.IO.Path.GetTempFileName(); + } + + #endregion // GetTempFileName (.NET) + + #region GetTempPath (.NET) + + /// Returns the path of the current user's temporary folder. + /// The path to the temporary folder, ending with a backslash. + [SecurityCritical] + public static string GetTempPath() + { + return System.IO.Path.GetTempPath(); + } + + /// [AlphaFS] Returns the path of the current user's temporary folder. + /// The folder name to append to the temporary folder. + /// The path to the temporary folder, combined with . + [SecurityCritical] + public static string GetTempPath(string combinePath) + { + string tempPath = GetTempPath(); + return !Utils.IsNullOrWhiteSpace(combinePath) ? CombineCore(false, tempPath, combinePath) : tempPath; + } + + #endregion // GetTempPath (.NET) + } +} diff --git a/AlphaFS/Filesystem/Path Class/Path.UncPaths.cs b/AlphaFS/Filesystem/Path Class/Path.UncPaths.cs new file mode 100644 index 0000000..6575c65 --- /dev/null +++ b/AlphaFS/Filesystem/Path Class/Path.UncPaths.cs @@ -0,0 +1,234 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Network; +using System; +using System.Globalization; +using System.IO; +using System.Net.NetworkInformation; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class Path + { + #region GetMappedConnectionName + + /// [AlphaFS] Gets the connection name of the locally mapped drive. + /// The server and share as: \\servername\sharename. + /// + /// + /// + /// + /// The local path with drive name. + [SecurityCritical] + public static string GetMappedConnectionName(string path) + { + return Host.GetRemoteNameInfoCore(path, true).lpConnectionName; + } + + #endregion // GetMappedConnectionName + + #region GetMappedUncName + + /// [AlphaFS] Gets the network share name from the locally mapped path. + /// The network share connection name of . + /// + /// + /// + /// + /// The local path with drive name. + [SecurityCritical] + public static string GetMappedUncName(string path) + { + return Host.GetRemoteNameInfoCore(path, true).lpUniversalName; + } + + #endregion // GetMappedUncName + + #region IsUncPath + + /// [AlphaFS] Determines if a path string is a valid Universal Naming Convention (UNC) path. + /// if the specified path is a Universal Naming Convention (UNC) path, otherwise. + /// The path to check. + [SecurityCritical] + public static bool IsUncPath(string path) + { + return IsUncPathCore(path, false, true); + } + + /// [AlphaFS] Determines if a path string is a valid Universal Naming Convention (UNC) path, optionally skip invalid path character check. + /// if the specified path is a Universal Naming Convention (UNC) path, otherwise. + /// The path to check. + /// will check for invalid path characters. + [SecurityCritical] + public static bool IsUncPath(string path, bool checkInvalidPathChars) + { + return IsUncPathCore(path, false, checkInvalidPathChars); + } + + #endregion // IsUncPath + + #region LocalToUnc + + /// [AlphaFS] Converts a local path to a network share path. + /// A Local path, e.g.: "C:\Windows" will be returned as: "\\MachineName\C$\Windows". + /// If a logical drive points to a network share path, the share path will be returned instead. + /// + /// On successful conversion a UNC path is returned. + /// If the conversion fails, is returned. + /// If is an empty string or , is returned. + /// + /// + /// + /// + /// A local path, e.g.: "C:\Windows". + [SecurityCritical] + public static string LocalToUnc(string localPath) + { + return LocalToUncCore(localPath, false, false, false); + } + + /// [AlphaFS] Converts a local path to a network share path, optionally returning it in a long path format. + /// A Local path, e.g.: "C:\Windows" will be returned as: "\\MachineName\C$\Windows". + /// If a logical drive points to a network share path, the share path will be returned instead. + /// + /// On successful conversion a UNC path is returned. + /// If the conversion fails, is returned. + /// If is an empty string or , is returned. + /// + /// + /// + /// + /// A local path, e.g.: "C:\Windows". + /// returns the path in long path (Unicode) format, when returns the path as a regular path. + [SecurityCritical] + public static string LocalToUnc(string localPath, bool asLongPath) + { + return LocalToUncCore(localPath, asLongPath, false, false); + } + + /// [AlphaFS] Converts a local path to a network share path, optionally returning it in a long path format and the ability to add or remove a trailing backslash. + /// A Local path, e.g.: "C:\Windows" will be returned as: "\\MachineName\C$\Windows". + /// If a logical drive points to a network share path, the share path will be returned instead. + /// + /// On successful conversion a UNC path is returned. + /// If the conversion fails, is returned. + /// If is an empty string or , is returned. + /// + /// + /// + /// + /// A local path, e.g.: "C:\Windows". + /// returns the path in long path (Unicode) format, when returns the path as a regular path. + /// adds a trailing character to , when absent. + /// removes the trailing character from , when present. + [SecurityCritical] + public static string LocalToUnc(string localPath, bool asLongPath, bool addTrailingDirectorySeparator, bool removeTrailingDirectorySeparator) + { + return LocalToUncCore(localPath, asLongPath, addTrailingDirectorySeparator, removeTrailingDirectorySeparator); + } + + #endregion // LocalToUnc + + #region Internal Methods + + /// [AlphaFS] Determines if a path string is a valid Universal Naming Convention (UNC) path, optionally skip invalid path character check. + /// if the specified path is a Universal Naming Convention (UNC) path, otherwise. + /// The path to check. + /// When indicates that is already in regular path format. + /// will check for invalid path characters. + [SecurityCritical] + internal static bool IsUncPathCore(string path, bool isRegularPath, bool checkInvalidPathChars) + { + if (!isRegularPath) + path = GetRegularPathCore(path, checkInvalidPathChars ? GetFullPathOptions.CheckInvalidPathChars : 0, false); + + else if (checkInvalidPathChars) + CheckInvalidPathChars(path, false, false); + + Uri uri; + return Uri.TryCreate(path, UriKind.Absolute, out uri) && uri.IsUnc; + } + + /// Converts a local path to a network share path. + /// A Local path, e.g.: "C:\Windows" will be returned as: "\\MachineName\C$\Windows". + /// If a logical drive points to a network share path, the share path will be returned instead. + /// + /// On successful conversion a UNC path is returned. + /// If the conversion fails, is returned. + /// If is an empty string or , is returned. + /// + /// + /// + /// + /// A local path, e.g.: "C:\Windows". + /// returns the path in long path (Unicode) format, when returns the path as a regular path. + /// adds a trailing character to , when absent. + /// removes the trailing character from , when present. + [SecurityCritical] + internal static string LocalToUncCore(string localPath, bool asLongPath, bool addTrailingDirectorySeparator, bool removeTrailingDirectorySeparator) + { + if (Utils.IsNullOrWhiteSpace(localPath)) + return null; + + localPath = GetRegularPathCore(localPath, GetFullPathOptions.CheckInvalidPathChars, false); + + + if (!IsUncPathCore(localPath, true, false)) + { + if (localPath[0] == CurrentDirectoryPrefixChar || !IsPathRooted(localPath, false)) + localPath = GetFullPathCore(null, localPath, GetFullPathOptions.None); + + string drive = GetPathRoot(localPath, false); + + if (Utils.IsNullOrWhiteSpace(drive)) + return localPath; + + Network.NativeMethods.REMOTE_NAME_INFO unc = Host.GetRemoteNameInfoCore(drive, true); + + if (!Utils.IsNullOrWhiteSpace(unc.lpConnectionName)) + // Only leave trailing backslash if "localPath" also ends with backslash. + return localPath.EndsWith(DirectorySeparator, StringComparison.OrdinalIgnoreCase) + ? AddTrailingDirectorySeparator(unc.lpConnectionName, false) + : RemoveTrailingDirectorySeparator(unc.lpConnectionName, false); + + // Split: localDrive[0] = "C", localDrive[1] = "\Windows" + string[] localDrive = localPath.Split(VolumeSeparatorChar); + + // Return: "\\MachineName\C$\Windows" + localPath = string.Format(CultureInfo.CurrentCulture, "{0}{1}{2}${3}", Host.GetUncName(), DirectorySeparatorChar, localDrive[0], localDrive[1]); + } + + + // Only leave trailing backslash if "localPath" also ends with backslash. + addTrailingDirectorySeparator = addTrailingDirectorySeparator || + (localPath.EndsWith(DirectorySeparator, StringComparison.OrdinalIgnoreCase) && !removeTrailingDirectorySeparator); + + var options = (addTrailingDirectorySeparator ? GetFullPathOptions.AddTrailingDirectorySeparator : 0) | + (removeTrailingDirectorySeparator ? GetFullPathOptions.RemoveTrailingDirectorySeparator : 0); + + return asLongPath ? GetLongPathCore(localPath, options) : localPath; + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/Path Class/Path.ValidationAndChecks.cs b/AlphaFS/Filesystem/Path Class/Path.ValidationAndChecks.cs new file mode 100644 index 0000000..2d426e9 --- /dev/null +++ b/AlphaFS/Filesystem/Path Class/Path.ValidationAndChecks.cs @@ -0,0 +1,614 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + public static partial class Path + { + #region HasExtension (.NET) + + /// Determines whether a path includes a file name extension. + /// if the characters that follow the last directory separator (\\ or /) or volume separator (:) in the path include a period (.) followed by one or more characters; otherwise, . + /// + /// The path to search for an extension. The path cannot contain any of the characters defined in . + [SecurityCritical] + public static bool HasExtension(string path) + { + return System.IO.Path.HasExtension(path); + } + + #endregion // HasExtension (.NET) + + #region IsPathRooted + + #region .NET + + /// Gets a value indicating whether the specified path string contains absolute or relative path information. + /// if contains a root; otherwise, . + /// + /// The IsPathRooted method returns if the first character is a directory separator character such as + /// , or if the path starts with a drive letter and colon (). + /// For example, it returns true for path strings such as "\\MyDir\\MyFile.txt", "C:\\MyDir", or "C:MyDir". + /// It returns for path strings such as "MyDir". + /// + /// This method does not verify that the path or file name exists. + /// + /// + /// The path to test. The path cannot contain any of the characters defined in . + [SecurityCritical] + public static bool IsPathRooted(string path) + { + return IsPathRooted(path, true); + } + + #endregion // .NET + + /// [AlphaFS] Gets a value indicating whether the specified path string contains absolute or relative path information. + /// if contains a root; otherwise, . + /// + /// The IsPathRooted method returns true if the first character is a directory separator character such as + /// , or if the path starts with a drive letter and colon (). + /// For example, it returns for path strings such as "\\MyDir\\MyFile.txt", "C:\\MyDir", or "C:MyDir". + /// It returns for path strings such as "MyDir". + /// + /// This method does not verify that the path or file name exists. + /// + /// + /// The path to test. The path cannot contain any of the characters defined in . + /// will check for invalid path characters. + [SecurityCritical] + public static bool IsPathRooted(string path, bool checkInvalidPathChars) + { + if (path != null) + { + if (checkInvalidPathChars) + CheckInvalidPathChars(path, false, true); + + var length = path.Length; + + if ((length >= 1 && IsDVsc(path[0], false)) || + (length >= 2 && IsDVsc(path[1], true))) + return true; + } + + return false; + } + + #endregion // IsPathRooted + + #region IsValidName + + /// [AlphaFS] Check if file or folder name has any invalid characters. + /// + /// File or folder name. + /// if name contains any invalid characters. Otherwise + public static bool IsValidName(string name) + { + if (name == null) + throw new ArgumentNullException("name"); + + return name.IndexOfAny(GetInvalidFileNameChars()) < 0; + } + + #endregion // IsValidName + + #region Internal Methods + + internal static void CheckInvalidUncPath(string path) + { + // Tackle: Path.GetFullPath(@"\\\\.txt"), but exclude "." which is the current directory. + if (!IsLongPath(path) && path.StartsWith(UncPrefix, StringComparison.OrdinalIgnoreCase)) + { + var tackle = GetRegularPathCore(path, GetFullPathOptions.None, false).TrimStart(DirectorySeparatorChar, AltDirectorySeparatorChar); + + if (tackle.Length >= 2 && tackle[0] == CurrentDirectoryPrefixChar) + throw new ArgumentException(Resources.UNC_Path_Should_Match_Format); + } + } + + /// Checks that the given path format is supported. + /// + /// + /// A path to the file or directory. + /// Checks that the path contains only valid path-characters. + /// . + internal static void CheckSupportedPathFormat(string path, bool checkInvalidPathChars, bool checkAdditional) + { + if (Utils.IsNullOrWhiteSpace(path) || path.Length < 2) + return; + + var regularPath = GetRegularPathCore(path, GetFullPathOptions.None, false); + + var isArgumentException = (regularPath[0] == VolumeSeparatorChar); + var throwException = (isArgumentException || (regularPath.Length >= 2 && regularPath.IndexOf(VolumeSeparatorChar, 2) != -1)); + + if (throwException) + { + if (isArgumentException) + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Unsupported_Path_Format, regularPath)); + + throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Resources.Unsupported_Path_Format, regularPath)); + } + + if (checkInvalidPathChars) + CheckInvalidPathChars(path, checkAdditional, false); + } + + /// Checks that the path contains only valid path-characters. + /// + /// + /// A path to the file or directory. + /// also checks for ? and * characters. + /// When , throws an . + [SecurityCritical] + private static void CheckInvalidPathChars(string path, bool checkAdditional, bool allowEmpty) + { + if (path == null) + throw new ArgumentNullException("path"); + + if (!allowEmpty && (path.Length == 0 || Utils.IsNullOrWhiteSpace(path))) + throw new ArgumentException(Resources.Path_Is_Zero_Length_Or_Only_White_Space, "path"); + + // Will fail on a Unicode path. + var pathRp = GetRegularPathCore(path, GetFullPathOptions.None, allowEmpty); + + + // Handle "Path.GlobalRootPrefix" and "Path.VolumePrefix". + if (pathRp.StartsWith(GlobalRootPrefix, StringComparison.OrdinalIgnoreCase)) + pathRp = pathRp.Replace(GlobalRootPrefix, string.Empty); + + if (pathRp.StartsWith(VolumePrefix, StringComparison.OrdinalIgnoreCase)) + pathRp = pathRp.Replace(VolumePrefix, string.Empty); + + + for (int index = 0, l = pathRp.Length; index < l; ++index) + { + int num = pathRp[index]; + switch (num) + { + case 34: // " (quote) + case 60: // < (less than) + case 62: // > (greater than) + case 124: // | (pipe) + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Illegal_Characters_In_Path, (char) num), pathRp); + + default: + // 32: space + if (num >= 32 && (!checkAdditional || num != WildcardQuestionChar && num != WildcardStarMatchAllChar)) + continue; + + goto case 34; + } + } + } + + /// Tranlates DosDevicePath, Volume GUID. For example: "\Device\HarddiskVolumeX\path\filename.ext" can translate to: "\path\filename.ext" or: "\\?\Volume{GUID}\path\filename.ext". + /// A translated dos path. + /// A DosDevicePath, for example: \Device\HarddiskVolumeX\path\filename.ext. + /// Alternate path/device text, usually string.Empty or . + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + [SecurityCritical] + private static string DosDeviceToDosPath(string dosDevice, string deviceReplacement) + { + if (Utils.IsNullOrWhiteSpace(dosDevice)) + return string.Empty; + + foreach (var drive in Directory.EnumerateLogicalDrivesCore(false, false).Select(drv => drv.Name)) + { + try + { + var path = RemoveTrailingDirectorySeparator(drive, false); + foreach (var devNt in Volume.QueryDosDevice(path).Where(dosDevice.StartsWith)) + return dosDevice.Replace(devNt, deviceReplacement ?? path); + } + catch + { + } + } + return string.Empty; + } + + [SecurityCritical] + internal static int GetRootLength(string path, bool checkInvalidPathChars) + { + if (checkInvalidPathChars) + CheckInvalidPathChars(path, false, false); + + var index = 0; + var length = path.Length; + + if (length >= 1 && IsDVsc(path[0], false)) + { + index = 1; + if (length >= 2 && IsDVsc(path[1], false)) + { + index = 2; + var num = 2; + + while (index < length && (!IsDVsc(path[index], false) || --num > 0)) + ++index; + } + } + else if (length >= 2 && IsDVsc(path[1], true)) + { + index = 2; + if (length >= 3 && IsDVsc(path[2], false)) + ++index; + } + + return index; + } + + /// Check if is a directory- and/or volume-separator character. + /// if is a separator character. + /// The character to check. + /// + /// If , checks for all separator characters: , + /// and + /// If , only checks for: and + /// If only checks for: + /// + [SecurityCritical] + internal static bool IsDVsc(char c, bool? checkSeparatorChar) + { + return checkSeparatorChar == null + + // Check for all separator characters. + ? c == DirectorySeparatorChar || c == AltDirectorySeparatorChar || c == VolumeSeparatorChar + + // Check for some separator characters. + : ((bool)checkSeparatorChar + ? c == VolumeSeparatorChar + : c == DirectorySeparatorChar || c == AltDirectorySeparatorChar); + } + + + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + private static string NormalizePath(string path, GetFullPathOptions options) + { + var newBuffer = new StringBuilder(NativeMethods.MaxPathUnicode); + var index = 0; + uint numSpaces = 0; + uint numDots = 0; + var fixupDirectorySeparator = false; + + // Number of significant chars other than potentially suppressible + // dots and spaces since the last directory or volume separator char + uint numSigChars = 0; + + var lastSigChar = -1; // Index of last significant character. + + // Whether this segment of the path (not the complete path) started + // with a volume separator char. Reject "c:...". + var startedWithVolumeSeparator = false; + var firstSegment = true; + var lastDirectorySeparatorPos = 0; + + // LEGACY: This code is here for backwards compatibility reasons. It + // ensures that \\foo.cs\bar.cs stays \\foo.cs\bar.cs instead of being + // turned into \foo.cs\bar.cs. + if (path.Length > 0 && (path[0] == DirectorySeparatorChar || path[0] == AltDirectorySeparatorChar)) + { + newBuffer.Append('\\'); + index++; + lastSigChar = 0; + } + + // Normalize the string, stripping out redundant dots, spaces, and slashes. + while (index < path.Length) + { + var currentChar = path[index]; + + // We handle both directory separators and dots specially. For + // directory separators, we consume consecutive appearances. + // For dots, we consume all dots beyond the second in + // succession. All other characters are added as is. In + // addition we consume all spaces after the last other char + // in a directory name up until the directory separator. + + if (currentChar == DirectorySeparatorChar || currentChar == AltDirectorySeparatorChar) + { + // If we have a path like "123.../foo", remove the trailing dots. + // However, if we found "c:\temp\..\bar" or "c:\temp\...\bar", don't. + // Also remove trailing spaces from both files & directory names. + // This was agreed on with the OS team to fix undeletable directory + // names ending in spaces. + + // If we saw a '\' as the previous last significant character and + // are simply going to write out dots, suppress them. + // If we only contain dots and slashes though, only allow + // a string like [dot]+ [space]*. Ignore everything else. + // Legal: "\.. \", "\...\", "\. \" + // Illegal: "\.. .\", "\. .\", "\ .\" + + if (numSigChars == 0) + { + // Dot and space handling + if (numDots > 0) + { + // Look for ".[space]*" or "..[space]*" + var start = lastSigChar + 1; + if (path[start] != CurrentDirectoryPrefixChar) + throw new ArgumentException(path); + + // Only allow "[dot]+[space]*", and normalize the + // legal ones to "." or ".." + if (numDots >= 2) + { + // Reject "C:..." + if (startedWithVolumeSeparator && numDots > 2) + throw new ArgumentException(path); + + + if (path[start + 1] == CurrentDirectoryPrefixChar) + { + // Search for a space in the middle of the dots and throw + for (var i = start + 2; i < start + numDots; i++) + { + if (path[i] != CurrentDirectoryPrefixChar) + throw new ArgumentException(path); + } + + numDots = 2; + } + + else + { + if (numDots > 1) + throw new ArgumentException(path); + + numDots = 1; + } + } + + + if (numDots == 2) + newBuffer.Append(CurrentDirectoryPrefixChar); + + + newBuffer.Append(CurrentDirectoryPrefixChar); + fixupDirectorySeparator = false; + + // Continue in this case, potentially writing out '\'. + } + + + if (numSpaces > 0 && firstSegment) + { + // Handle strings like " \\server\share". + if (index + 1 < path.Length && (path[index + 1] == DirectorySeparatorChar || path[index + 1] == AltDirectorySeparatorChar)) + newBuffer.Append(DirectorySeparatorChar); + } + } + + + numDots = 0; + numSpaces = 0; // Suppress trailing spaces + + if (!fixupDirectorySeparator) + { + fixupDirectorySeparator = true; + newBuffer.Append(DirectorySeparatorChar); + } + + numSigChars = 0; + lastSigChar = index; + startedWithVolumeSeparator = false; + firstSegment = false; + + + var thisPos = newBuffer.Length - 1; + if (thisPos - lastDirectorySeparatorPos > NativeMethods.MaxDirectoryLength) + throw new PathTooLongException(path); + + lastDirectorySeparatorPos = thisPos; + } // if (Found directory separator) + + else if (currentChar == CurrentDirectoryPrefixChar) + { + // Reduce only multiple .'s only after slash to 2 dots. For + // instance a...b is a valid file name. + numDots++; + // Don't flush out non-terminal spaces here, because they may in + // the end not be significant. Turn "c:\ . .\foo" -> "c:\foo" + // which is the conclusion of removing trailing dots & spaces, + // as well as folding multiple '\' characters. + } + + else if (currentChar == ' ') + numSpaces++; + + else + { // Normal character logic + fixupDirectorySeparator = false; + + // To reject strings like "C:...\foo" and "C :\foo" + if (firstSegment && currentChar == VolumeSeparatorChar) + { + // Only accept "C:", not "c :" or ":" + // Get a drive letter or ' ' if index is 0. + var driveLetter = (index > 0) ? path[index - 1] : ' '; + + var validPath = (numDots == 0) && (numSigChars >= 1) && (driveLetter != ' '); + if (!validPath) + throw new ArgumentException(path); + + startedWithVolumeSeparator = true; + // We need special logic to make " c:" work, we should not fix paths like " foo::$DATA" + if (numSigChars > 1) + { + // Common case, simply do nothing + var spaceCount = 0; // How many spaces did we write out, numSpaces has already been reset. + while ((spaceCount < newBuffer.Length) && newBuffer[spaceCount] == ' ') + spaceCount++; + + if (numSigChars - spaceCount == 1) + { + //Safe to update stack ptr directly + newBuffer.Length = 0; + newBuffer.Append(driveLetter); + // Overwrite spaces, we need a special case to not break " foo" as a relative path. + } + } + + numSigChars = 0; + } + + else + numSigChars += 1 + numDots + numSpaces; + + // Copy any spaces & dots since the last significant character + // to here. Note we only counted the number of dots & spaces, + // and don't know what order they're in. Hence the copy. + if (numDots > 0 || numSpaces > 0) + { + var numCharsToCopy = lastSigChar >= 0 ? index - lastSigChar - 1 : index; + + if (numCharsToCopy > 0) + for (var i = 0; i < numCharsToCopy; i++) + newBuffer.Append(path[lastSigChar + 1 + i]); + + numDots = 0; + numSpaces = 0; + } + + newBuffer.Append(currentChar); + lastSigChar = index; + } + + index++; + } + + + if (newBuffer.Length - 1 - lastDirectorySeparatorPos > NativeMethods.MaxDirectoryLength) + throw new PathTooLongException(path); + + + // Drop any trailing dots and spaces from file & directory names, EXCEPT + // we MUST make sure that "C:\foo\.." is correctly handled. + // Also handle "C:\foo\." -> "C:\foo", while "C:\." -> "C:\" + if (numSigChars == 0) + { + if (numDots > 0) + { + // Look for ".[space]*" or "..[space]*" + var start = lastSigChar + 1; + + if (path[start] != CurrentDirectoryPrefixChar) + throw new ArgumentException(path); + + + // Only allow "[dot]+[space]*", and normalize the legal ones to "." or ".." + if (numDots >= 2) + { + // Reject "C:..." + if (startedWithVolumeSeparator && numDots > 2) + throw new ArgumentException(path); + + + if (path[start + 1] == CurrentDirectoryPrefixChar) + { + // Search for a space in the middle of the dots and throw + for (var i = start + 2; i < start + numDots; i++) + if (path[i] != CurrentDirectoryPrefixChar) + throw new ArgumentException(path); + + numDots = 2; + } + + else + { + if (numDots > 1) + throw new ArgumentException(path); + + numDots = 1; + } + } + + if (numDots == 2) + newBuffer.Append(CurrentDirectoryPrefixChar); + + newBuffer.Append(CurrentDirectoryPrefixChar); + } + } + + + // If we ended up eating all the characters, bail out. + if (newBuffer.Length == 0) + throw new ArgumentException(path); + + + // Disallow URL's here. Some of our other Win32 API calls will reject + // them later, so we might be better off rejecting them here. + // Note we've probably turned them into "file:\D:\foo.tmp" by now. + // But for compatibility, ensure that callers that aren't doing a + // full check aren't rejected here. + if ((options & GetFullPathOptions.FullCheck) != 0) + { + var newBufferString = newBuffer.ToString(); + if (newBufferString.StartsWith("http:", StringComparison.OrdinalIgnoreCase) || newBufferString.StartsWith("file:", StringComparison.OrdinalIgnoreCase)) + throw new ArgumentException(path); + } + + // Call the Win32 API to do the final canonicalization step. + var result = 1; + + + if (result != 0) + { + /* Throw an ArgumentException for paths like \\, \\server, \\server\ + This check can only be properly done after normalizing, so + \\foo\.. will be properly rejected. Also, reject \\?\GLOBALROOT\ + (an internal kernel path) because it provides aliases for drives. */ + if (newBuffer.Length > 1 && newBuffer[0] == '\\' && newBuffer[1] == '\\') + { + var startIndex = 2; + while (startIndex < result) + { + if (newBuffer[startIndex] == '\\') + { + startIndex++; + break; + } + + startIndex++; + } + + if (startIndex == result) + throw new ArgumentException(path); + } + } + + + return newBuffer.ToString(); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/Path Class/Path.cs b/AlphaFS/Filesystem/Path Class/Path.cs new file mode 100644 index 0000000..2adfe74 --- /dev/null +++ b/AlphaFS/Filesystem/Path Class/Path.cs @@ -0,0 +1,29 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + /// Performs operations on String instances that contain file or directory path information. These operations are performed in a cross-platform manner. + public static partial class Path + { + // This file only exists for the documentation. + } +} \ No newline at end of file diff --git a/AlphaFS/Filesystem/Safe Handles/SafeCmConnectMachineHandle.cs b/AlphaFS/Filesystem/Safe Handles/SafeCmConnectMachineHandle.cs new file mode 100644 index 0000000..41b2b0f --- /dev/null +++ b/AlphaFS/Filesystem/Safe Handles/SafeCmConnectMachineHandle.cs @@ -0,0 +1,49 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Security; +using Microsoft.Win32.SafeHandles; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Represents a wrapper class for a handle used by the CM_Connect_Machine/CM_Disconnect_Machine Win32 API functions. + [SecurityCritical] + internal sealed class SafeCmConnectMachineHandle : SafeHandleZeroOrMinusOneIsInvalid + { + #region Constructor + + /// Initializes a new instance of the class. + public SafeCmConnectMachineHandle() : base(true) + { + } + + #endregion // Constructor + + #region ReleaseHandle + + protected override bool ReleaseHandle() + { + return NativeMethods.CM_Disconnect_Machine(handle) == Win32Errors.NO_ERROR; + } + + #endregion // ReleaseHandle + } +} diff --git a/AlphaFS/Filesystem/Safe Handles/SafeEncryptedFileRawHandle.cs b/AlphaFS/Filesystem/Safe Handles/SafeEncryptedFileRawHandle.cs new file mode 100644 index 0000000..21fc80a --- /dev/null +++ b/AlphaFS/Filesystem/Safe Handles/SafeEncryptedFileRawHandle.cs @@ -0,0 +1,35 @@ +using System; +using System.Security; +using Microsoft.Win32.SafeHandles; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Represents a wrapper class for a handle used by the FindFirstFile/FindNextFile Win32 API functions. + [SecurityCritical] + internal sealed class SafeEncryptedFileRawHandle : SafeHandleZeroOrMinusOneIsInvalid + { + /// Constructor that prevents a default instance of this class from being created. + private SafeEncryptedFileRawHandle() + : base(true) + { + } + + /// Constructor that prevents a default instance of this class from being created. + /// The handle. + /// true to reliably release the handle during the finalization phase; false to prevent + /// reliable release (not recommended). + public SafeEncryptedFileRawHandle(IntPtr handle, bool ownsHandle) + : base(ownsHandle) + { + SetHandle(handle); + } + + /// When overridden in a derived class, executes the code required to free the handle. + /// if the handle is released successfully; otherwise, in the event of a catastrophic failure, . In this case, it generates a ReleaseHandleFailed Managed Debugging Assistant. + protected override bool ReleaseHandle() + { + NativeMethods.CloseEncryptedFileRaw(handle); + return true; + } + } +} diff --git a/AlphaFS/Filesystem/Safe Handles/SafeFindFileHandle.cs b/AlphaFS/Filesystem/Safe Handles/SafeFindFileHandle.cs new file mode 100644 index 0000000..33c3dee --- /dev/null +++ b/AlphaFS/Filesystem/Safe Handles/SafeFindFileHandle.cs @@ -0,0 +1,52 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; +using Microsoft.Win32.SafeHandles; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Represents a wrapper class for a handle used by the FindFirstFile/FindNextFile Win32 API functions. + [SecurityCritical] + public sealed class SafeFindFileHandle : SafeHandleZeroOrMinusOneIsInvalid + { + /// Initializes a new instance of the class. + private SafeFindFileHandle() : base(true) + { + } + + /// Initializes a new instance of the class. + /// The handle. + /// [owns handle]. + public SafeFindFileHandle(IntPtr handle, bool callerHandle) : base(callerHandle) + { + SetHandle(handle); + } + + /// When overridden in a derived class, executes the code required to free the handle. + /// if the handle is released successfully; otherwise, in the event of a catastrophic failure, . In this case, it generates a ReleaseHandleFailed Managed Debugging Assistant. + protected override bool ReleaseHandle() + { + return NativeMethods.FindClose(handle); + } + } +} diff --git a/AlphaFS/Filesystem/Safe Handles/SafeFindVolumeHandle.cs b/AlphaFS/Filesystem/Safe Handles/SafeFindVolumeHandle.cs new file mode 100644 index 0000000..4020784 --- /dev/null +++ b/AlphaFS/Filesystem/Safe Handles/SafeFindVolumeHandle.cs @@ -0,0 +1,54 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; +using Microsoft.Win32.SafeHandles; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Represents a wrapper class for a handle used by the FindFirstVolume/FindNextVolume methods of the Win32 API. + [SecurityCritical] + public sealed class SafeFindVolumeHandle : SafeHandleZeroOrMinusOneIsInvalid + { + /// Initializes a new instance of the class. + private SafeFindVolumeHandle() + : base(true) + { + } + + /// Initializes a new instance of the class. + /// The handle. + /// [owns handle]. + public SafeFindVolumeHandle(IntPtr handle, bool callerHandle) : base(callerHandle) + { + SetHandle(handle); + } + + /// When overridden in a derived class, executes the code required to free the handle. + /// if the handle is released successfully; otherwise, in the event of a catastrophic failure, . In this case, it generates a ReleaseHandleFailed Managed Debugging Assistant. + /// + protected override bool ReleaseHandle() + { + return NativeMethods.FindVolumeClose(handle); + } + } +} diff --git a/AlphaFS/Filesystem/Safe Handles/SafeFindVolumeMountPointHandle.cs b/AlphaFS/Filesystem/Safe Handles/SafeFindVolumeMountPointHandle.cs new file mode 100644 index 0000000..2ecdf17 --- /dev/null +++ b/AlphaFS/Filesystem/Safe Handles/SafeFindVolumeMountPointHandle.cs @@ -0,0 +1,54 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Security; +using Microsoft.Win32.SafeHandles; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Represents a wrapper class for a handle used by the FindFirstVolumeMountPoint/FindVolumeMountPointClose methods of the Win32 API. + [SecurityCritical] + internal sealed class SafeFindVolumeMountPointHandle : SafeHandleZeroOrMinusOneIsInvalid + { + /// Initializes a new instance of the class. + private SafeFindVolumeMountPointHandle() + : base(true) + { + } + + /// Initializes a new instance of the class. + /// The handle. + /// [owns handle]. + public SafeFindVolumeMountPointHandle(IntPtr handle, bool callerHandle) : base(callerHandle) + { + SetHandle(handle); + } + + /// When overridden in a derived class, executes the code required to free the handle. + /// if the handle is released successfully; otherwise, in the event of a catastrophic failure, . + /// + protected override bool ReleaseHandle() + { + return NativeMethods.FindVolumeMountPointClose(handle); + } + } +} diff --git a/AlphaFS/Filesystem/Safe Handles/SafeKernelTransactionHandle.cs b/AlphaFS/Filesystem/Safe Handles/SafeKernelTransactionHandle.cs new file mode 100644 index 0000000..0a81af3 --- /dev/null +++ b/AlphaFS/Filesystem/Safe Handles/SafeKernelTransactionHandle.cs @@ -0,0 +1,44 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Microsoft.Win32.SafeHandles; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Provides a concrete implementation of SafeHandle supporting transactions. + internal class SafeKernelTransactionHandle : SafeHandleMinusOneIsInvalid + { + /// Initializes a new instance of the class. + public SafeKernelTransactionHandle() + : base(true) + { + } + + /// When overridden in a derived class, executes the code required to free the handle. + /// if the handle is released successfully; otherwise, in the event of a catastrophic failure, . In this case, it generates a ReleaseHandleFailed Managed Debugging Assistant. + [SecurityCritical] + protected override bool ReleaseHandle() + { + return NativeMethods.CloseHandle(handle); + } + } +} diff --git a/AlphaFS/Filesystem/Safe Handles/SafeLocalMemoryBufferHandle.cs b/AlphaFS/Filesystem/Safe Handles/SafeLocalMemoryBufferHandle.cs new file mode 100644 index 0000000..781050d --- /dev/null +++ b/AlphaFS/Filesystem/Safe Handles/SafeLocalMemoryBufferHandle.cs @@ -0,0 +1,104 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + +namespace Alphaleonis.Win32.Security +{ + /// An IntPtr wrapper which can be used as the result of a Marshal.AllocHGlobal operation. + /// Calls Marshal.FreeHGlobal when disposed or finalized. + /// + internal sealed class SafeLocalMemoryBufferHandle : SafeHandleZeroOrMinusOneIsInvalid + { + #region Constructors + + /// Creates new instance with zero IntPtr. + public SafeLocalMemoryBufferHandle() : base(true) + { + } + + #endregion // Constructors + + #region Methods + + #region CopyFrom + + /// Copies data from a one-dimensional, managed 8-bit unsigned integer array to the unmanaged memory pointer referenced by this instance. + /// The one-dimensional array to copy from. + /// The zero-based index into the array where Copy should start. + /// The number of array elements to copy. + public void CopyFrom(byte[] source, int startIndex, int length) + { + Marshal.Copy(source, startIndex, handle, length); + } + + #endregion // CopyFrom + + #region CopyTo + + public void CopyTo(byte[] destination, int destinationOffset, int length) + { + if (destination == null) + throw new ArgumentNullException("destination"); + + if (destinationOffset < 0) + throw new ArgumentOutOfRangeException("destinationOffset", Resources.Negative_Destination_Offset); + + if (length < 0) + throw new ArgumentOutOfRangeException("length", Resources.Negative_Length); + + if (destinationOffset + length > destination.Length) + throw new ArgumentException(Resources.Destination_Buffer_Not_Large_Enough); + + Marshal.Copy(handle, destination, destinationOffset, length); + } + + #endregion // CopyTo + + #region ToByteArray + + public byte[] ToByteArray(int startIndex, int length) + { + if (IsInvalid) + return null; + + byte[] arr = new byte[length]; + Marshal.Copy(handle, arr, startIndex, length); + return arr; + } + + #endregion // ToByteArray + + #region ReleaseHandle + + /// Called when object is disposed or finalized. + protected override bool ReleaseHandle() + { + return handle == IntPtr.Zero || NativeMethods.LocalFree(handle) == IntPtr.Zero; + } + + #endregion // ReleaseHandle + + #endregion // Methods + } +} diff --git a/AlphaFS/Filesystem/Safe Handles/SafeSetupDiClassDevsExHandle.cs b/AlphaFS/Filesystem/Safe Handles/SafeSetupDiClassDevsExHandle.cs new file mode 100644 index 0000000..2cab614 --- /dev/null +++ b/AlphaFS/Filesystem/Safe Handles/SafeSetupDiClassDevsExHandle.cs @@ -0,0 +1,45 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Microsoft.Win32.SafeHandles; +using System.Security; + +namespace Alphaleonis.Win32.Filesystem +{ + internal static partial class NativeMethods + { + /// Represents a wrapper class for a handle used by the SetupDiGetClassDevs/SetupDiDestroyDeviceInfoList Win32 API functions. + [SecurityCritical] + internal sealed class SafeSetupDiClassDevsExHandle : SafeHandleZeroOrMinusOneIsInvalid + { + /// Initializes a new instance of the class. + public SafeSetupDiClassDevsExHandle() + : base(true) + { + } + + protected override bool ReleaseHandle() + { + return SetupDiDestroyDeviceInfoList(handle); + } + } + } +} diff --git a/AlphaFS/Filesystem/Shell32.cs b/AlphaFS/Filesystem/Shell32.cs new file mode 100644 index 0000000..6824234 --- /dev/null +++ b/AlphaFS/Filesystem/Shell32.cs @@ -0,0 +1,845 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Provides access to a file system object, using Shell32. + public static class Shell32 + { + /// Provides information for the IQueryAssociations interface methods, used by Shell32. + [Flags] + public enum AssociationAttributes + { + /// None. + None = 0, + + /// Instructs not to map CLSID values to ProgID values. + InitNoRemapClsid = 1, + + /// Identifies the value of the supplied file parameter (3rd parameter of function GetFileAssociation()) as an executable file name. + /// If this flag is not set, the root key will be set to the ProgID associated with the .exe key instead of the executable file's ProgID. + InitByExeName = 2, + + /// Specifies that when an IQueryAssociation method does not find the requested value under the root key, it should attempt to retrieve the comparable value from the * subkey. + InitDefaultToStar = 4, + + /// Specifies that when an IQueryAssociation method does not find the requested value under the root key, it should attempt to retrieve the comparable value from the Folder subkey. + InitDefaultToFolder = 8, + + /// Specifies that only HKEY_CLASSES_ROOT should be searched, and that HKEY_CURRENT_USER should be ignored. + NoUserSettings = 16, + + /// Specifies that the return string should not be truncated. Instead, return an error value and the required size for the complete string. + NoTruncate = 32, + + /// + /// Instructs IQueryAssociations methods to verify that data is accurate. + /// This setting allows IQueryAssociations methods to read data from the user's hard disk for verification. + /// For example, they can check the friendly name in the registry against the one stored in the .exe file. + /// + /// Setting this flag typically reduces the efficiency of the method. + Verify = 64, + + /// + /// Instructs IQueryAssociations methods to ignore Rundll.exe and return information about its target. + /// Typically IQueryAssociations methods return information about the first .exe or .dll in a command string. + /// If a command uses Rundll.exe, setting this flag tells the method to ignore Rundll.exe and return information about its target. + /// + RemapRunDll = 128, + + /// Instructs IQueryAssociations methods not to fix errors in the registry, such as the friendly name of a function not matching the one found in the .exe file. + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "FixUps")] + NoFixUps = 256, + + /// Specifies that the BaseClass value should be ignored. + IgnoreBaseClass = 512, + + /// Specifies that the "Unknown" ProgID should be ignored; instead, fail. + /// Introduced in Windows 7. + InitIgnoreUnknown = 1024, + + /// Specifies that the supplied ProgID should be mapped using the system defaults, rather than the current user defaults. + /// Introduced in Windows 8. + InitFixedProgId = 2048, + + /// Specifies that the value is a protocol, and should be mapped using the current user defaults. + /// Introduced in Windows 8. + IsProtocol = 4096 + } + + + //internal enum AssociationData + //{ + // MsiDescriptor = 1, + // NoActivateHandler = 2 , + // QueryClassStore = 3, + // HasPerUserAssoc = 4, + // EditFlags = 5, + // Value = 6 + //} + + + //internal enum AssociationKey + //{ + // ShellExecClass = 1, + // App = 2, + // Class = 3, + // BaseClass = 4 + //} + + + /// ASSOCSTR enumeration - Used by the AssocQueryString() function to define the type of string that is to be returned. + public enum AssociationString + { + /// None. + None = 0, + + /// A command string associated with a Shell verb. + Command = 1, + + /// + /// An executable from a Shell verb command string. + /// For example, this string is found as the (Default) value for a subkey such as HKEY_CLASSES_ROOT\ApplicationName\shell\Open\command. + /// If the command uses Rundll.exe, set the flag in the attributes parameter of IQueryAssociations::GetString to retrieve the target executable. + /// + Executable = 2, + + /// The friendly name of a document type. + FriendlyDocName = 3, + + /// The friendly name of an executable file. + FriendlyAppName = 4, + + /// Ignore the information associated with the open subkey. + NoOpen = 5, + + /// Look under the ShellNew subkey. + ShellNewValue = 6, + + /// A template for DDE commands. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dde")] + DdeCommand = 7, + + /// The DDE command to use to create a process. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dde")] + DdeIfExec = 8, + + /// The application name in a DDE broadcast. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dde")] + DdeApplication = 9, + + /// The topic name in a DDE broadcast. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dde")] + DdeTopic = 10, + + /// + /// Corresponds to the InfoTip registry value. + /// Returns an info tip for an item, or list of properties in the form of an IPropertyDescriptionList from which to create an info tip, such as when hovering the cursor over a file name. + /// The list of properties can be parsed with PSGetPropertyDescriptionListFromString. + /// + InfoTip = 11, + + /// + /// Corresponds to the QuickTip registry value. This is the same as , except that it always returns a list of property names in the form of an IPropertyDescriptionList. + /// The difference between this value and is that this returns properties that are safe for any scenario that causes slow property retrieval, such as offline or slow networks. + /// Some of the properties returned from might not be appropriate for slow property retrieval scenarios. + /// The list of properties can be parsed with PSGetPropertyDescriptionListFromString. + /// + QuickTip = 12, + + /// + /// Corresponds to the TileInfo registry value. Contains a list of properties to be displayed for a particular file type in a Windows Explorer window that is in tile view. + /// This is the same as , but, like , it also returns a list of property names in the form of an IPropertyDescriptionList. + /// The list of properties can be parsed with PSGetPropertyDescriptionListFromString. + /// + TileInfo = 13, + + /// + /// Describes a general type of MIME file association, such as image and bmp, + /// so that applications can make general assumptions about a specific file type. + /// + ContentType = 14, + + /// + /// Returns the path to the icon resources to use by default for this association. + /// Positive numbers indicate an index into the dll's resource table, while negative numbers indicate a resource ID. + /// An example of the syntax for the resource is "c:\myfolder\myfile.dll,-1". + /// + DefaultIcon = 15, + + /// + /// For an object that has a Shell extension associated with it, + /// you can use this to retrieve the CLSID of that Shell extension object by passing a string representation + /// of the IID of the interface you want to retrieve as the pwszExtra parameter of IQueryAssociations::GetString. + /// For example, if you want to retrieve a handler that implements the IExtractImage interface, + /// you would specify "{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}", which is the IID of IExtractImage. + /// + ShellExtension = 16, + + /// + /// For a verb invoked through COM and the IDropTarget interface, you can use this flag to retrieve the IDropTarget object's CLSID. + /// This CLSID is registered in the DropTarget subkey. + /// The verb is specified in the supplied file parameter in the call to IQueryAssociations::GetString. + /// + DropTarget = 17, + + /// + /// For a verb invoked through COM and the IExecuteCommand interface, you can use this flag to retrieve the IExecuteCommand object's CLSID. + /// This CLSID is registered in the verb's command subkey as the DelegateExecute entry. + /// The verb is specified in the supplied file parameter in the call to IQueryAssociations::GetString. + /// + DelegateExecute = 18, + + /// (No description available on MSDN) + /// Introduced in Windows 8. + SupportedUriProtocols = 19, + + /// The maximum defined value, used for validation purposes. + Max = 20 + } + + + /// Shell32 FileAttributes structure, used to retrieve the different types of a file system object. + [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")] + [SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue")] + [Flags] + public enum FileAttributes + { + /// 0x000000000 - Get file system object large icon. + /// The flag must also be set. + LargeIcon = 0, + + /// 0x000000001 - Get file system object small icon. + /// The flag must also be set. + SmallIcon = 1, + + /// 0x000000002 - Get file system object open icon. + /// A container object displays an open icon to indicate that the container is open. + /// The and/or flag must also be set. + OpenIcon = 2, + + /// 0x000000004 - Get file system object Shell-sized icon. + /// If this attribute is not specified the function sizes the icon according to the system metric values. + ShellIconSize = 4, + + /// 0x000000008 - Get file system object by its PIDL. + /// Indicate that the given file contains the address of an ITEMIDLIST structure rather than a path name. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Pidl")] + Pidl = 8, + + /// 0x000000010 - Indicates that the given file should not be accessed. Rather, it should act as if the given file exists and use the supplied attributes. + /// This flag cannot be combined with the , or attributes. + UseFileAttributes = 16, + + /// 0x000000020 - Apply the appropriate overlays to the file's icon. + /// The flag must also be set. + AddOverlays = 32, + + /// 0x000000040 - Returns the index of the overlay icon. + /// The value of the overlay index is returned in the upper eight bits of the iIcon member of the structure specified by psfi. + OverlayIndex = 64, + + /// 0x000000100 - Retrieve the handle to the icon that represents the file and the index of the icon within the system image list. The handle is copied to the member of the structure, and the index is copied to the member. + Icon = 256, + + /// 0x000000200 - Retrieve the display name for the file. The name is copied to the member of the structure. + /// The returned display name uses the long file name, if there is one, rather than the 8.3 form of the file name. + DisplayName = 512, + + /// 0x000000400 - Retrieve the string that describes the file's type. + TypeName = 1024, + + /// 0x000000800 - Retrieve the item attributes. The attributes are copied to the member of the structure. + /// Will touch every file, degrading performance. + Attributes = 2048, + + /// 0x000001000 - Retrieve the name of the file that contains the icon representing the file specified by pszPath. The name of the file containing the icon is copied to the member of the structure. The icon's index is copied to that structure's member. + IconLocation = 4096, + + /// 0x000002000 - Retrieve the type of the executable file if pszPath identifies an executable file. + /// This flag cannot be specified with any other attributes. + ExeType = 8192, + + /// 0x000004000 - Retrieve the index of a system image list icon. + SysIconIndex = 16384, + + /// 0x000008000 - Add the link overlay to the file's icon. + /// The flag must also be set. + LinkOverlay = 32768, + + /// 0x000010000 - Blend the file's icon with the system highlight color. + Selected = 65536, + + /// 0x000020000 - Modify to indicate that contains specific attributes that are desired. + /// This flag cannot be specified with the attribute. Will touch every file, degrading performance. + AttributesSpecified = 131072 + } + + + /// SHFILEINFO structure, contains information about a file system object. + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Sh")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sh")] + [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")] + [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct FileInfo + { + /// A handle to the icon that represents the file. + /// Caller is responsible for destroying this handle with DestroyIcon() when no longer needed. + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")] + public readonly IntPtr IconHandle; + + /// The index of the icon image within the system image list. + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")] + public int IconIndex; + + /// An array of values that indicates the attributes of the file object. + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")] + [MarshalAs(UnmanagedType.U4)] + public readonly GetAttributesOf Attributes; + + /// The name of the file as it appears in the Windows Shell, or the path and file name of the file that contains the icon representing the file. + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NativeMethods.MaxPath)] + public string DisplayName; + + /// The type of file. + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] + public string TypeName; + } + + + /// SFGAO - Attributes that can be retrieved from a file system object. + [SuppressMessage("Microsoft.Usage", "CA2217:DoNotMarkEnumsWithFlags"), SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")] + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Sh")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sh")] + [SuppressMessage("Microsoft.Naming", "CA1714:FlagsEnumsShouldHavePluralNames")] + [Flags] + public enum GetAttributesOf + { + /// 0x00000000 - None. + None = 0, + + /// 0x00000001 - The specified items can be copied. + CanCopy = 1, + + /// 0x00000002 - The specified items can be moved. + CanMove = 2, + + /// 0x00000004 - Shortcuts can be created for the specified items. + CanLink = 4, + + /// 0x00000008 - The specified items can be bound to an IStorage object through IShellFolder::BindToObject. For more information about namespace manipulation capabilities, see IStorage. + Storage = 8, + + /// 0x00000010 - The specified items can be renamed. Note that this value is essentially a suggestion; not all namespace clients allow items to be renamed. However, those that do must have this attribute set. + CanRename = 16, + + /// 0x00000020 - The specified items can be deleted. + CanDelete = 32, + + /// 0x00000040 - The specified items have property sheets. + HasPropSheet = 64, + + /// 0x00000100 - The specified items are drop targets. + DropTarget = 256, + + /// 0x00001000 - The specified items are system items. + /// Windows 7 and later. + System = 4096, + + /// 0x00002000 - The specified items are encrypted and might require special presentation. + Encrypted = 8192, + + /// 0x00004000 - Accessing the item (through IStream or other storage interfaces) is expected to be a slow operation. + IsSlow = 16384, + + /// 0x00008000 - The specified items are shown as dimmed and unavailable to the user. + Ghosted = 32768, + + /// 0x00010000 - The specified items are shortcuts. + Link = 65536, + + /// 0x00020000 - The specified objects are shared. + Share = 131072, + + /// 0x00040000 - The specified items are read-only. In the case of folders, this means that new items cannot be created in those folders. + ReadOnly = 262144, + + /// 0x00080000 - The item is hidden and should not be displayed unless the Show hidden files and folders option is enabled in Folder Settings. + Hidden = 524288, + + /// 0x00100000 - The items are nonenumerated items and should be hidden. They are not returned through an enumerator such as that created by the IShellFolder::EnumObjects method. + NonEnumerated = 1048576, + + /// 0x00200000 - The items contain new content, as defined by the particular application. + NewContent = 2097152, + + /// 0x00400000 - Indicates that the item has a stream associated with it. + Stream = 4194304, + + /// 0x00800000 - Children of this item are accessible through IStream or IStorage. + StorageAncestor = 8388608, + + /// 0x01000000 - When specified as input, instructs the folder to validate that the items contained in a folder or Shell item array exist. + Validate = 16777216, + + /// 0x02000000 - The specified items are on removable media or are themselves removable devices. + Removable = 33554432, + + /// 0x04000000 - The specified items are compressed. + Compressed = 67108864, + + /// 0x08000000 - The specified items can be hosted inside a web browser or Windows Explorer frame. + Browsable = 134217728, + + /// 0x10000000 - The specified folders are either file system folders or contain at least one descendant (child, grandchild, or later) that is a file system folder. + FileSysAncestor = 268435456, + + /// 0x20000000 - The specified items are folders. + Folder = 536870912, + + /// 0x40000000 - The specified folders or files are part of the file system (that is, they are files, directories, or root directories). + FileSystem = 1073741824, + + /// 0x80000000 - The specified folders have subfolders. + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "SubFolder")] + HasSubFolder = unchecked ((int)0x80000000) + } + + + /// Used by method UrlIs() to define a URL type. + public enum UrlType + { + /// Is the URL valid? + IsUrl = 0, + + /// Is the URL opaque? + IsOpaque = 1, + + /// Is the URL a URL that is not typically tracked in navigation history? + IsNoHistory = 2, + + /// Is the URL a file URL? + IsFileUrl = 3, + + /// Attempt to determine a valid scheme for the URL. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Appliable")] + IsAppliable = 4, + + /// Does the URL string end with a directory? + IsDirectory = 5, + + /// Does the URL have an appended query string? + IsHasQuery = 6 + } + + + #region Methods + + /// Destroys an icon and frees any memory the icon occupied. + /// An handle to an icon. + public static void DestroyIcon(IntPtr iconHandle) + { + if (IntPtr.Zero != iconHandle) + NativeMethods.DestroyIcon(iconHandle); + } + + + /// Gets the file or protocol that is associated with from the registry. + /// A path to the file. + /// The associated file- or protocol-related string from the registry or string.Empty if no association can be found. + [SecurityCritical] + public static string GetFileAssociation(string path) + { + return GetFileAssociationCore(path, AssociationAttributes.Verify, AssociationString.Executable); + } + + + /// Gets the content-type that is associated with from the registry. + /// A path to the file. + /// The associated file- or protocol-related content-type from the registry or string.Empty if no association can be found. + [SecurityCritical] + public static string GetFileContentType(string path) + { + return GetFileAssociationCore(path, AssociationAttributes.Verify, AssociationString.ContentType); + } + + + /// Gets the default icon that is associated with from the registry. + /// A path to the file. + /// The associated file- or protocol-related default icon from the registry or string.Empty if no association can be found. + [SecurityCritical] + public static string GetFileDefaultIcon(string path) + { + return GetFileAssociationCore(path, AssociationAttributes.Verify, AssociationString.DefaultIcon); + } + + + /// Gets the friendly application name that is associated with from the registry. + /// A path to the file. + /// The associated file- or protocol-related friendly application name from the registry or string.Empty if no association can be found. + [SecurityCritical] + public static string GetFileFriendlyAppName(string path) + { + return GetFileAssociationCore(path, AssociationAttributes.InitByExeName, AssociationString.FriendlyAppName); + } + + + /// Gets the friendly document name that is associated with from the registry. + /// A path to the file. + /// The associated file- or protocol-related friendly document name from the registry or string.Empty if no association can be found. + [SecurityCritical] + public static string GetFileFriendlyDocName(string path) + { + return GetFileAssociationCore(path, AssociationAttributes.Verify, AssociationString.FriendlyDocName); + } + + + /// Gets an handle to the Shell icon that represents the file. + /// Caller is responsible for destroying this handle with DestroyIcon() when no longer needed. + /// + /// The path to the file system object which should not exceed maximum path length. Both absolute and + /// relative paths are valid. + /// + /// + /// Icon size or . Can also be combined + /// with and others. + /// + /// An handle to the Shell icon that represents the file, or IntPtr.Zero on failure. + [SecurityCritical] + public static IntPtr GetFileIcon(string filePath, FileAttributes iconAttributes) + { + if (Utils.IsNullOrWhiteSpace(filePath)) + return IntPtr.Zero; + + var fileInfo = GetFileInfoCore(filePath, System.IO.FileAttributes.Normal, FileAttributes.Icon | iconAttributes, true, true); + return fileInfo.IconHandle == IntPtr.Zero ? IntPtr.Zero : fileInfo.IconHandle; + } + + + /// Retrieves information about an object in the file system, such as a file, folder, directory, or drive root. + /// A struct instance. + /// + /// You should call this function from a background thread. + /// Failure to do so could cause the UI to stop responding. + /// Unicode path are supported. + /// + /// The path to the file system object which should not exceed the maximum path length. Both absolute and relative paths are valid. + /// A attribute. + /// One ore more attributes. + /// + /// suppress any Exception that might be thrown as a result from a failure, + /// such as ACLs protected directories or non-accessible reparse points. + /// + [SecurityCritical] + public static FileInfo GetFileInfo(string filePath, System.IO.FileAttributes attributes, FileAttributes fileAttributes, bool continueOnException) + { + return GetFileInfoCore(filePath, attributes, fileAttributes, true, continueOnException); + } + + + /// Retrieves an instance of containing information about the specified file. + /// A path to the file. + /// A class instance. + [SecurityCritical] + public static Shell32Info GetShell32Info(string path) + { + return new Shell32Info(path); + } + + /// Retrieves an instance of containing information about the specified file. + /// A path to the file. + /// Indicates the format of the path parameter(s). + /// A class instance. + [SecurityCritical] + public static Shell32Info GetShell32Info(string path, PathFormat pathFormat) + { + return new Shell32Info(path, pathFormat); + } + + + /// Gets the "Open With" command that is associated with from the registry. + /// A path to the file. + /// The associated file- or protocol-related "Open With" command from the registry or string.Empty if no association can be found. + [SecurityCritical] + public static string GetFileOpenWithAppName(string path) + { + return GetFileAssociationCore(path, AssociationAttributes.Verify, AssociationString.FriendlyAppName); + } + + + /// Gets the Shell command that is associated with from the registry. + /// A path to the file. + /// The associated file- or protocol-related Shell command from the registry or string.Empty if no association can be found. + [SecurityCritical] + public static string GetFileVerbCommand(string path) + { + return GetFileAssociationCore(path, AssociationAttributes.Verify, AssociationString.Command); + } + + + /// Converts a file URL to a Microsoft MS-DOS path. + /// The file URL. + /// + /// The Microsoft MS-DOS path. If no path can be created, string.Empty is returned. + /// If is , will also be returned. + /// + [SecurityCritical] + internal static string PathCreateFromUrl(string urlPath) + { + if (urlPath == null) + return null; + + var buffer = new StringBuilder(NativeMethods.MaxPathUnicode); + var bufferSize = (uint) buffer.Capacity; + + var lastError = NativeMethods.PathCreateFromUrl(urlPath, buffer, ref bufferSize, 0); + + // Don't throw exception, but return string.Empty; + return lastError == Win32Errors.S_OK ? buffer.ToString() : string.Empty; + } + + + /// Creates a path from a file URL. + /// The URL. + /// + /// The file path. If no path can be created, string.Empty is returned. + /// If is , will also be returned. + /// + [SecurityCritical] + internal static string PathCreateFromUrlAlloc(string urlPath) + { + if (!NativeMethods.IsAtLeastWindowsVista) + throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher); + + if (urlPath == null) + return null; + + StringBuilder buffer; + var lastError = NativeMethods.PathCreateFromUrlAlloc(urlPath, out buffer, 0); + + // Don't throw exception, but return string.Empty; + return lastError == Win32Errors.S_OK ? buffer.ToString() : string.Empty; + } + + + /// Determines whether a path to a file system object such as a file or folder is valid. + /// The full path of maximum length the maximum path length to the object to verify. + /// if the file exists; otherwise + [SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "lastError")] + [SecurityCritical] + public static bool PathFileExists(string path) + { + if (Utils.IsNullOrWhiteSpace(path)) + return false; + + // PathFileExists() + // 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 does not confirm LongPath usage but a Unicode version of this function exists. + + return NativeMethods.PathFileExists(Path.GetFullPathCore(null, path, GetFullPathOptions.AsLongPath | GetFullPathOptions.FullCheck | GetFullPathOptions.ContinueOnNonExist)); + } + + + /// Tests whether a URL is a specified type. + /// The URL. + /// + /// + /// For all but one of the URL types, UrlIs returns if the URL is the specified type, or otherwise. + /// If UrlIs is set to , UrlIs will attempt to determine the URL scheme. + /// If the function is able to determine a scheme, it returns , or otherwise. + /// + [SecurityCritical] + internal static bool UrlIs(string url, UrlType urlType) + { + return NativeMethods.UrlIs(url, urlType); + } + + + /// Converts a Microsoft MS-DOS path to a canonicalized URL. + /// The full MS-DOS path of maximum length . + /// + /// The URL. If no URL can be created string.Empty is returned. + /// If is , will also be returned. + /// + [SecurityCritical] + internal static string UrlCreateFromPath(string path) + { + if (path == null) + return null; + + // UrlCreateFromPath does not support extended paths. + var pathRp = Path.GetRegularPathCore(path, GetFullPathOptions.CheckInvalidPathChars, false); + + var buffer = new StringBuilder(NativeMethods.MaxPathUnicode); + var bufferSize = (uint) buffer.Capacity; + + var lastError = NativeMethods.UrlCreateFromPath(pathRp, buffer, ref bufferSize, 0); + + // Don't throw exception, but return null; + var url = buffer.ToString(); + if (Utils.IsNullOrWhiteSpace(url)) + url = string.Empty; + + return lastError == Win32Errors.S_OK ? url : string.Empty; + } + + + /// Tests a URL to determine if it is a file URL. + /// The URL. + /// if the URL is a file URL, or otherwise. + [SecurityCritical] + internal static bool UrlIsFileUrl(string url) + { + return NativeMethods.UrlIs(url, UrlType.IsFileUrl); + } + + + /// Returns whether a URL is a URL that browsers typically do not include in navigation history. + /// The URL. + /// if the URL is a URL that is not included in navigation history, or otherwise. + [SecurityCritical] + internal static bool UrlIsNoHistory(string url) + { + return NativeMethods.UrlIs(url, UrlType.IsNoHistory); + } + + + /// Returns whether a URL is opaque. + /// The URL. + /// if the URL is opaque, or otherwise. + [SecurityCritical] + internal static bool UrlIsOpaque(string url) + { + return NativeMethods.UrlIs(url, UrlType.IsOpaque); + } + + + #region Internal Methods + + /// Searches for and retrieves a file or protocol association-related string from the registry. + /// A path to a file. + /// One or more attributes. Only one "InitXXX" attribute can be used. + /// A attribute. + /// The associated file- or protocol-related string from the registry or string.Empty if no association can be found. + /// + [SecurityCritical] + private static string GetFileAssociationCore(string path, AssociationAttributes attributes, AssociationString associationType) + { + if (Utils.IsNullOrWhiteSpace(path)) + throw new ArgumentNullException("path"); + + attributes = attributes | AssociationAttributes.NoTruncate | AssociationAttributes.RemapRunDll; + + uint bufferSize = NativeMethods.MaxPath; + StringBuilder buffer; + uint retVal; + + do + { + buffer = new StringBuilder((int)bufferSize); + + // AssocQueryString() + // 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. + // 2014-02-05: MSDN does not confirm LongPath usage but a Unicode version of this function exists. + // However, the function fails when using Unicode format. + + retVal = NativeMethods.AssocQueryString(attributes, associationType, path, null, buffer, out bufferSize); + + // No Exception is thrown, just return empty string on error. + + //switch (retVal) + //{ + // // 0x80070483: No application is associated with the specified file for this operation. + // case 2147943555: + // case Win32Errors.E_POINTER: + // case Win32Errors.S_OK: + // break; + + // default: + // NativeError.ThrowException(retVal); + // break; + //} + + } while (retVal == Win32Errors.E_POINTER); + + return buffer.ToString(); + } + + + /// Retrieve information about an object in the file system, such as a file, folder, directory, or drive root. + /// A struct instance. + /// + /// You should call this function from a background thread. + /// Failure to do so could cause the UI to stop responding. + /// Unicode path are not supported. + /// + /// The path to the file system object which should not exceed the maximum path length in length. Both absolute and relative paths are valid. + /// A attribute. + /// A attribute. + /// Checks that the path contains only valid path-characters. + /// + /// suppress any Exception that might be thrown as a result from a failure, + /// such as ACLs protected directories or non-accessible reparse points. + /// + [SecurityCritical] + internal static FileInfo GetFileInfoCore(string path, System.IO.FileAttributes attributes, FileAttributes fileAttributes, bool checkInvalidPathChars, bool continueOnException) + { + // Prevent possible crash. + var fileInfo = new FileInfo + { + DisplayName = string.Empty, + TypeName = string.Empty, + IconIndex = 0 + }; + + if (!Utils.IsNullOrWhiteSpace(path)) + { + // ShGetFileInfo() + // 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 does not confirm LongPath usage but a Unicode version of this function exists. + // However, the function fails when using Unicode format. + + var shGetFileInfo = NativeMethods.ShGetFileInfo(Path.GetRegularPathCore(path, checkInvalidPathChars ? GetFullPathOptions.CheckInvalidPathChars : 0, false), attributes, out fileInfo, (uint) Marshal.SizeOf(fileInfo), fileAttributes); + + if (shGetFileInfo == IntPtr.Zero && !continueOnException) + NativeError.ThrowException(Marshal.GetLastWin32Error(), path); + } + + return fileInfo; + } + + #endregion // Internal Methods + + #endregion // Methods + } +} diff --git a/AlphaFS/Filesystem/Shell32Info.cs b/AlphaFS/Filesystem/Shell32Info.cs new file mode 100644 index 0000000..d958738 --- /dev/null +++ b/AlphaFS/Filesystem/Shell32Info.cs @@ -0,0 +1,337 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Contains Shell32 information about a file. + [SerializableAttribute] + [SecurityCritical] + public sealed class Shell32Info + { + #region Constructors + + /// Initializes a Shell32Info instance. + /// Shell32 is limited to MAX_PATH length. + /// This constructor does not check if a file exists. This constructor is a placeholder for a string that is used to access the file in subsequent operations. + /// + /// The fully qualified name of the new file, or the relative file name. Do not end the path with the directory separator character. + public Shell32Info(string fileName) : this(fileName, PathFormat.RelativePath) + { + } + + /// Initializes a Shell32Info instance. + /// Shell32 is limited to MAX_PATH length. + /// This constructor does not check if a file exists. This constructor is a placeholder for a string that is used to access the file in subsequent operations. + /// + /// The fully qualified name of the new file, or the relative file name. Do not end the path with the directory separator character. + /// Indicates the format of the path parameter(s). + public Shell32Info(string fileName, PathFormat pathFormat) + { + if (Utils.IsNullOrWhiteSpace(fileName)) + throw new ArgumentNullException("fileName"); + + // Shell32 is limited to MAX_PATH length. + // Get a full path of regular format. + + FullPath = Path.GetExtendedLengthPathCore(null, fileName, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + + Initialize(); + } + + #endregion // Constructors + + + #region Methods + + /// Gets an handle to the Shell icon that represents the file. + /// Icon size or . Can also be combined with and others. + /// An handle to the Shell icon that represents the file. + /// Caller is responsible for destroying this handle with DestroyIcon() when no longer needed. + [SecurityCritical] + public IntPtr GetIcon(Shell32.FileAttributes iconAttributes) + { + return Shell32.GetFileIcon(FullPath, iconAttributes); + } + + + /// Gets the Shell command association from the registry. + /// The shell verb. + /// + /// Returns the associated file- or protocol-related Shell command from the registry or string.Empty if no association can be + /// found. + /// + [SecurityCritical] + public string GetVerbCommand(string shellVerb) + { + return GetString(_iQaNone, Shell32.AssociationString.Command, shellVerb); + } + + + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + [SecurityCritical] + private static string GetString(NativeMethods.IQueryAssociations iQa, Shell32.AssociationString assocString, string shellVerb) + { + // GetString() throws Exceptions. + try + { + // Use a large buffer to prevent calling this function twice. + var size = NativeMethods.DefaultFileBufferSize; + var buffer = new StringBuilder(size); + + iQa.GetString(Shell32.AssociationAttributes.NoTruncate | Shell32.AssociationAttributes.RemapRunDll, assocString, shellVerb, buffer, out size); + + return buffer.ToString(); + } + catch + { + return string.Empty; + } + } + + + private NativeMethods.IQueryAssociations _iQaNone; // Retrieve info from Shell. + private NativeMethods.IQueryAssociations _iQaByExe; // Retrieve info from exe file. + + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + [SecurityCritical] + private void Initialize() + { + if (Initialized) + return; + + var iidIQueryAssociations = new Guid(NativeMethods.QueryAssociationsGuid); + + if (NativeMethods.AssocCreate(NativeMethods.ClsidQueryAssociations, ref iidIQueryAssociations, out _iQaNone) == Win32Errors.S_OK) + { + try + { + _iQaNone.Init(Shell32.AssociationAttributes.None, FullPath, IntPtr.Zero, IntPtr.Zero); + + if (NativeMethods.AssocCreate(NativeMethods.ClsidQueryAssociations, ref iidIQueryAssociations, out _iQaByExe) == Win32Errors.S_OK) + { + _iQaByExe.Init(Shell32.AssociationAttributes.InitByExeName, FullPath, IntPtr.Zero, IntPtr.Zero); + + Initialized = true; + } + } + catch + { + } + } + } + + + /// Refreshes the state of the object. + [SecurityCritical] + public void Refresh() + { + Association = Command = ContentType = DdeApplication = DefaultIcon = FriendlyAppName = FriendlyDocName = OpenWithAppName = null; + Attributes = Shell32.GetAttributesOf.None; + Initialized = false; + Initialize(); + } + + + /// Returns the path as a string. + /// The path. + public override string ToString() + { + return FullPath; + } + + #endregion // Methods + + + #region Properties + + private string _association; + + /// Gets the Shell file or protocol association from the registry. + public string Association + { + get + { + if (_association == null) + _association = GetString(_iQaNone, Shell32.AssociationString.Executable, null); + + return _association; + } + + private set { _association = value; } + } + + + private Shell32.GetAttributesOf _attributes; + + /// The attributes of the file object. + public Shell32.GetAttributesOf Attributes + { + get + { + if (_attributes == Shell32.GetAttributesOf.None) + { + var fileInfo = Shell32.GetFileInfoCore(FullPath, FileAttributes.Normal, Shell32.FileAttributes.Attributes, false, true); + _attributes = fileInfo.Attributes; + } + + return _attributes; + } + + private set { _attributes = value; } + } + + + private string _command; + + /// Gets the Shell command association from the registry. + public string Command + { + get + { + if (_command == null) + _command = GetString(_iQaNone, Shell32.AssociationString.Command, null); + + return _command; + } + + private set { _command = value; } + } + + + private string _contentType; + + /// Gets the Shell command association from the registry. + public string ContentType + { + get + { + if (_contentType == null) + _contentType = GetString(_iQaNone, Shell32.AssociationString.ContentType, null); + + return _contentType; + } + + private set { _contentType = value; } + } + + + private string _ddeApplication; + + /// Gets the Shell DDE association from the registry. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dde")] + public string DdeApplication + { + get + { + if (_ddeApplication == null) + _ddeApplication = GetString(_iQaNone, Shell32.AssociationString.DdeApplication, null); + + return _ddeApplication; + } + + private set { _ddeApplication = value; } + } + + + private string _defaultIcon; + + /// Gets the Shell default icon association from the registry. + public string DefaultIcon + { + get + { + if (_defaultIcon == null) + _defaultIcon = GetString(_iQaNone, Shell32.AssociationString.DefaultIcon, null); + + return _defaultIcon; + } + + private set { _defaultIcon = value; } + } + + + /// Represents the fully qualified path of the file. + public string FullPath { get; private set; } + + + private string _friendlyAppName; + + /// Gets the Shell friendly application name association from the registry. + public string FriendlyAppName + { + get + { + if (_friendlyAppName == null) + _friendlyAppName = GetString(_iQaByExe, Shell32.AssociationString.FriendlyAppName, null); + + return _friendlyAppName; + } + + private set { _friendlyAppName = value; } + } + + + private string _friendlyDocName; + + /// Gets the Shell friendly document name association from the registry. + public string FriendlyDocName + { + get + { + if (_friendlyDocName == null) + _friendlyDocName = GetString(_iQaNone, Shell32.AssociationString.FriendlyDocName, null); + + return _friendlyDocName; + } + + private set { _friendlyDocName = value; } + } + + + /// Reflects the initialization state of the instance. + internal bool Initialized { get; set; } + + + private string _openWithAppName; + + /// Gets the Shell "Open With" command association from the registry. + public string OpenWithAppName + { + get + { + if (_openWithAppName == null) + _openWithAppName = GetString(_iQaNone, Shell32.AssociationString.FriendlyAppName, null); + + return _openWithAppName; + } + + private set { _openWithAppName = value; } + } + + #endregion // Properties + } +} diff --git a/AlphaFS/Filesystem/SymbolicLinkTargetInfo.cs b/AlphaFS/Filesystem/SymbolicLinkTargetInfo.cs new file mode 100644 index 0000000..4e47790 --- /dev/null +++ b/AlphaFS/Filesystem/SymbolicLinkTargetInfo.cs @@ -0,0 +1,36 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Filesystem +{ + /// Represents information about a symbolic link. + public class SymbolicLinkTargetInfo : LinkTargetInfo + { + internal SymbolicLinkTargetInfo(string substituteName, string printName, SymbolicLinkType type) : base(substituteName, printName) + { + LinkType = type; + } + + /// Gets the type of the link. + /// The type of the link. + public SymbolicLinkType LinkType { get; private set; } + } +} diff --git a/AlphaFS/Filesystem/Volume.cs b/AlphaFS/Filesystem/Volume.cs new file mode 100644 index 0000000..5b23d51 --- /dev/null +++ b/AlphaFS/Filesystem/Volume.cs @@ -0,0 +1,1146 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Microsoft.Win32.SafeHandles; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Static class providing utility methods for working with Microsoft Windows devices and volumes. + public static class Volume + { + #region DosDevice + + #region DefineDosDevice + + /// Defines, redefines, or deletes MS-DOS device names. + /// An MS-DOS device name string specifying the device the function is defining, redefining, or deleting. + /// An MS-DOS path that will implement this device. + + [SecurityCritical] + public static void DefineDosDevice(string deviceName, string targetPath) + { + DefineDosDeviceCore(true, deviceName, targetPath, DosDeviceAttributes.None, false); + } + + /// Defines, redefines, or deletes MS-DOS device names. + /// + /// An MS-DOS device name string specifying the device the function is defining, redefining, or deleting. + /// + /// + /// >An MS-DOS path that will implement this device. If parameter has the + /// flag specified, is used as is. + /// + /// + /// The controllable aspects of the DefineDosDevice function, flags which will be combined with the + /// default. + /// + [SecurityCritical] + public static void DefineDosDevice(string deviceName, string targetPath, DosDeviceAttributes deviceAttributes) + { + DefineDosDeviceCore(true, deviceName, targetPath, deviceAttributes, false); + } + + #endregion // DefineDosDevice + + #region DeleteDosDevice + + /// Deletes an MS-DOS device name. + /// An MS-DOS device name specifying the device to delete. + [SecurityCritical] + public static void DeleteDosDevice(string deviceName) + { + DefineDosDeviceCore(false, deviceName, null, DosDeviceAttributes.RemoveDefinition, false); + } + + /// Deletes an MS-DOS device name. + /// An MS-DOS device name string specifying the device to delete. + /// + /// A pointer to a path string that will implement this device. The string is an MS-DOS path string unless the + /// flag is specified, in which case this string is a path string. + /// + [SecurityCritical] + public static void DeleteDosDevice(string deviceName, string targetPath) + { + DefineDosDeviceCore(false, deviceName, targetPath, DosDeviceAttributes.RemoveDefinition, false); + } + + /// Deletes an MS-DOS device name. + /// An MS-DOS device name string specifying the device to delete. + /// + /// A pointer to a path string that will implement this device. The string is an MS-DOS path string unless the + /// flag is specified, in which case this string is a path string. + /// + /// + /// Only delete MS-DOS device on an exact name match. If is , + /// must be the same path used to create the mapping. + /// + [SecurityCritical] + public static void DeleteDosDevice(string deviceName, string targetPath, bool exactMatch) + { + DefineDosDeviceCore(false, deviceName, targetPath, DosDeviceAttributes.RemoveDefinition, exactMatch); + } + + /// Deletes an MS-DOS device name. + /// An MS-DOS device name string specifying the device to delete. + /// + /// A pointer to a path string that will implement this device. The string is an MS-DOS path string unless the + /// flag is specified, in which case this string is a path string. + /// + /// + /// The controllable aspects of the DefineDosDevice function flags which will be combined with the + /// default. + /// + /// + /// Only delete MS-DOS device on an exact name match. If is , + /// must be the same path used to create the mapping. + /// + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + [SecurityCritical] + public static void DeleteDosDevice(string deviceName, string targetPath, DosDeviceAttributes deviceAttributes, bool exactMatch) + { + DefineDosDeviceCore(false, deviceName, targetPath, deviceAttributes, exactMatch); + } + + #endregion // DeleteDosDevice + + #region QueryAllDosDevices + + /// Retrieves a list of all existing MS-DOS device names. + /// An with one or more existing MS-DOS device names. + [SecurityCritical] + public static IEnumerable QueryAllDosDevices() + { + return QueryDosDevice(null, null); + } + + /// Retrieves a list of all existing MS-DOS device names. + /// + /// (Optional, default: ) An MS-DOS device name string specifying the target of the query. This parameter can be + /// "sort". In that case a sorted list of all existing MS-DOS device names is returned. This parameter can be . + /// In that case, the function will store a list of all existing MS-DOS device names into the buffer. + /// + /// An with or more existing MS-DOS device names. + [SecurityCritical] + public static IEnumerable QueryAllDosDevices(string deviceName) + { + return QueryDosDevice(null, deviceName); + } + + #endregion // QueryAllDosDevices + + #region QueryDosDevice + + /// + /// Retrieves information about MS-DOS device names. The function can obtain the current mapping for a particular MS-DOS device name. + /// The function can also obtain a list of all existing MS-DOS device names. + /// + /// + /// An MS-DOS device name string, or part of, specifying the target of the query. This parameter can be . In that + /// case, the QueryDosDevice function will store a list of all existing MS-DOS device names into the buffer. + /// + /// + /// (Optional, default: ) If options[0] = a sorted list will be returned. + /// + /// An with one or more existing MS-DOS device names. + [SecurityCritical] + public static IEnumerable QueryDosDevice(string deviceName, params string[] options) + { + // deviceName is allowed to be null. + // The deviceName cannot have a trailing backslash. + deviceName = Path.RemoveTrailingDirectorySeparator(deviceName, false); + + var searchFilter = (deviceName != null); + + // Only process options if a device is supplied. + if (searchFilter) + { + // Check that at least one "options[]" has something to say. If so, rebuild them. + options = options != null && options.Any() ? new[] { deviceName, options[0] } : new[] { deviceName, string.Empty }; + + deviceName = null; + } + + // Choose sorted output. + var doSort = options != null && + options.Any(s => s != null && s.Equals("sort", StringComparison.OrdinalIgnoreCase)); + + // Start with a larger buffer when using a searchFilter. + var bufferSize = (uint) (searchFilter || doSort || (options == null) ? 8*NativeMethods.DefaultFileBufferSize : 256); + uint bufferResult = 0; + + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + while (bufferResult == 0) + { + var cBuffer = new char[bufferSize]; + + // QueryDosDevice() + // 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. + // 2014-01-29: MSDN does not confirm LongPath usage but a Unicode version of this function exists. + + bufferResult = NativeMethods.QueryDosDevice(deviceName, cBuffer, bufferSize); + var lastError = Marshal.GetLastWin32Error(); + + if (bufferResult == 0) + switch ((uint) lastError) + { + case Win32Errors.ERROR_MORE_DATA: + case Win32Errors.ERROR_INSUFFICIENT_BUFFER: + bufferSize *= 2; + continue; + + default: + NativeError.ThrowException(lastError, deviceName); + break; + } + + var dosDev = new List(); + var buffer = new StringBuilder(); + + for (var i = 0; i < bufferResult; i++) + { + if (cBuffer[i] != Path.StringTerminatorChar) + buffer.Append(cBuffer[i]); + + else if (buffer.Length > 0) + { + dosDev.Add(buffer.ToString()); + buffer.Length = 0; + } + } + + // Choose the yield back query; filtered or list. + var selectQuery = searchFilter + ? dosDev.Where(dev => options != null && dev.StartsWith(options[0], StringComparison.OrdinalIgnoreCase)) + : dosDev; + + foreach (var dev in (doSort) ? selectQuery.OrderBy(n => n) : selectQuery) + yield return dev; + } + } + + #endregion // QueryDosDevice + + #endregion // DosDevice + + #region Drive + + #region GetDriveFormat + + /// Gets the name of the file system, such as NTFS or FAT32. + /// Use DriveFormat to determine what formatting a drive uses. + /// + /// A path to a drive. For example: "C:\", "\\server\share", or "\\?\Volume{c0580d5e-2ad6-11dc-9924-806e6f6e6963}\". + /// + /// The name of the file system on the specified drive or on failure or if not available. + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + [SecurityCritical] + public static string GetDriveFormat(string drivePath) + { + var fsName = new VolumeInfo(drivePath, true, true).FileSystemName; + return Utils.IsNullOrWhiteSpace(fsName) ? null : fsName; + } + + #endregion // GetDriveFormat + + #region GetDriveNameForNtDeviceName + + /// Gets the drive letter from an MS-DOS device name. For example: "\Device\HarddiskVolume2" returns "C:\". + /// An MS-DOS device name. + /// The drive letter from an MS-DOS device name. + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Nt")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Nt")] + public static string GetDriveNameForNtDeviceName(string deviceName) + { + return (from drive in Directory.EnumerateLogicalDrivesCore(false, false) + where drive.DosDeviceName.Equals(deviceName, StringComparison.OrdinalIgnoreCase) + select drive.Name).FirstOrDefault(); + } + + #endregion // GetDriveNameForNtDeviceName + + #region GetCurrentDriveType + + /// + /// Determines, based on the root of the current directory, whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or network + /// drive. + /// + /// A object. + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")] + [SecurityCritical] + public static DriveType GetCurrentDriveType() + { + return GetDriveType(null); + } + + #endregion // GetCurrentDriveType + + #region GetDriveType + + /// Determines whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or network drive. + /// A path to a drive. For example: "C:\", "\\server\share", or "\\?\Volume{c0580d5e-2ad6-11dc-9924-806e6f6e6963}\" + /// A object. + [SecurityCritical] + public static DriveType GetDriveType(string drivePath) + { + // drivePath is allowed to be == null. + + drivePath = Path.AddTrailingDirectorySeparator(drivePath, false); + + // ChangeErrorMode is for the Win32 SetThreadErrorMode() method, used to suppress possible pop-ups. + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + return NativeMethods.GetDriveType(drivePath); + } + + #endregion // GetDriveType + + #region GetDiskFreeSpace + + /// + /// Retrieves information about the amount of space that is available on a disk volume, which is the total amount of space, the total + /// amount of free space, and the total amount of free space available to the user that is associated with the calling thread. + /// + /// The calling application must have FILE_LIST_DIRECTORY access rights for this directory. + /// + /// A path to a drive. For example: "C:\", "\\server\share", or "\\?\Volume{c0580d5e-2ad6-11dc-9924-806e6f6e6963}\". + /// + /// A class instance. + [SecurityCritical] + public static DiskSpaceInfo GetDiskFreeSpace(string drivePath) + { + return new DiskSpaceInfo(drivePath, null, true, true); + } + + /// + /// Retrieves information about the amount of space that is available on a disk volume, which is the total amount of space, the total + /// amount of free space, and the total amount of free space available to the user that is associated with the calling thread. + /// + /// The calling application must have FILE_LIST_DIRECTORY access rights for this directory. + /// + /// A path to a drive. For example: "C:\", "\\server\share", or "\\?\Volume{c0580d5e-2ad6-11dc-9924-806e6f6e6963}\". + /// + /// + /// gets both size- and disk cluster information. Get only disk cluster information, + /// Get only size information. + /// + /// A class instance. + [SecurityCritical] + public static DiskSpaceInfo GetDiskFreeSpace(string drivePath, bool? spaceInfoType) + { + return new DiskSpaceInfo(drivePath, spaceInfoType, true, true); + } + + #endregion // GetDiskFreeSpace + + #region IsReady + + /// Gets a value indicating whether a drive is ready. + /// + /// A path to a drive. For example: "C:\", "\\server\share", or "\\?\Volume{c0580d5e-2ad6-11dc-9924-806e6f6e6963}\". + /// + /// if is ready; otherwise, . + [SecurityCritical] + public static bool IsReady(string drivePath) + { + return File.ExistsCore(true, null, drivePath, PathFormat.FullPath); + } + + #endregion // IsReady + + #endregion // Drive + + #region Volume + + #region DeleteCurrentVolumeLabel + + /// Deletes the label of the file system volume that is the root of the current directory. + /// + [SecurityCritical] + public static void DeleteCurrentVolumeLabel() + { + SetVolumeLabel(null, null); + } + #endregion // DeleteCurrentVolumeLabel + + #region DeleteVolumeLabel + + /// Deletes the label of a file system volume. + /// + /// The root directory of a file system volume. This is the volume the function will remove the label. + [SecurityCritical] + public static void DeleteVolumeLabel(string rootPathName) + { + if (Utils.IsNullOrWhiteSpace(rootPathName)) + throw new ArgumentNullException("rootPathName"); + + SetVolumeLabel(rootPathName, null); + } + + #endregion // DeleteVolumeLabel + + #region DeleteVolumeMountPoint + + /// Deletes a Drive letter or mounted folder. + /// Deleting a mounted folder does not cause the underlying directory to be deleted. + /// + /// If the parameter is a directory that is not a mounted folder, the function does nothing. The + /// directory is not deleted. + /// + /// + /// It's not an error to attempt to unmount a volume from a volume mount point when there is no volume actually mounted at that volume + /// mount point. + /// + /// The Drive letter or mounted folder to be deleted. For example, X:\ or Y:\MountX\. + [SecurityCritical] + public static void DeleteVolumeMountPoint(string volumeMountPoint) + { + DeleteVolumeMountPointCore(volumeMountPoint, false); + } + + #endregion // DeleteVolumeMountPoint + + #region EnumerateVolumeMountPoints + + /// + /// Returns an enumerable collection of of all mounted folders (volume mount points) on the specified volume. + /// + /// + /// + /// A containing the volume . + /// An enumerable collection of of all volume mount points on the specified volume. + [SecurityCritical] + public static IEnumerable EnumerateVolumeMountPoints(string volumeGuid) + { + if (Utils.IsNullOrWhiteSpace(volumeGuid)) + throw new ArgumentNullException("volumeGuid"); + + if (!volumeGuid.StartsWith(Path.VolumePrefix + "{", StringComparison.OrdinalIgnoreCase)) + throw new ArgumentException(Resources.Not_A_Valid_Guid, volumeGuid); + + // A trailing backslash is required. + volumeGuid = Path.AddTrailingDirectorySeparator(volumeGuid, false); + + var buffer = new StringBuilder(NativeMethods.MaxPathUnicode); + + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + using (var handle = NativeMethods.FindFirstVolumeMountPoint(volumeGuid, buffer, (uint)buffer.Capacity)) + { + var lastError = Marshal.GetLastWin32Error(); + + if (handle.IsInvalid) + { + handle.Close(); + + switch ((uint) lastError) + { + case Win32Errors.ERROR_NO_MORE_FILES: + case Win32Errors.ERROR_PATH_NOT_FOUND: // Observed with USB stick, FAT32 formatted. + yield break; + + default: + NativeError.ThrowException(lastError, volumeGuid); + break; + } + } + + yield return buffer.ToString(); + + + while (NativeMethods.FindNextVolumeMountPoint(handle, buffer, (uint)buffer.Capacity)) + { + lastError = Marshal.GetLastWin32Error(); + + if (handle.IsInvalid) + { + handle.Close(); + + switch ((uint) lastError) + { + case Win32Errors.ERROR_NO_MORE_FILES: + case Win32Errors.ERROR_PATH_NOT_FOUND: // Observed with USB stick, FAT32 formatted. + case Win32Errors.ERROR_MORE_DATA: + yield break; + + default: + NativeError.ThrowException(lastError, volumeGuid); + break; + } + } + + yield return buffer.ToString(); + } + } + } + + #endregion // EnumerateVolumeMountPoints + + #region EnumerateVolumePathNames + + /// + /// Returns an enumerable collection of drive letters and mounted folder paths for the specified volume. + /// + /// + /// + /// A volume path: \\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\. + /// An enumerable collection of containing the path names for the specified volume. + [SecurityCritical] + public static IEnumerable EnumerateVolumePathNames(string volumeGuid) + { + if (Utils.IsNullOrWhiteSpace(volumeGuid)) + throw new ArgumentNullException("volumeGuid"); + + if (!volumeGuid.StartsWith(Path.VolumePrefix + "{", StringComparison.OrdinalIgnoreCase)) + throw new ArgumentException(Resources.Not_A_Valid_Guid, volumeGuid); + + var volName = Path.AddTrailingDirectorySeparator(volumeGuid, false); + + uint requiredLength = 10; + var cBuffer = new char[requiredLength]; + + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + while (!NativeMethods.GetVolumePathNamesForVolumeName(volName, cBuffer, (uint)cBuffer.Length, out requiredLength)) + { + var lastError = Marshal.GetLastWin32Error(); + + switch ((uint)lastError) + { + case Win32Errors.ERROR_MORE_DATA: + case Win32Errors.ERROR_INSUFFICIENT_BUFFER: + cBuffer = new char[requiredLength]; + break; + + default: + NativeError.ThrowException(lastError, volumeGuid); + break; + } + } + + var buffer = new StringBuilder(cBuffer.Length); + foreach (var c in cBuffer) + { + if (c != Path.StringTerminatorChar) + buffer.Append(c); + else + { + if (buffer.Length > 0) + { + yield return buffer.ToString(); + buffer.Length = 0; + } + } + } + } + + #endregion // EnumerateVolumePathNames + + #region EnumerateVolumes + + /// Returns an enumerable collection of volumes on the computer. + /// An enumerable collection of volume names on the computer. + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")] + [SecurityCritical] + public static IEnumerable EnumerateVolumes() + { + var buffer = new StringBuilder(NativeMethods.MaxPathUnicode); + + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + using (var handle = NativeMethods.FindFirstVolume(buffer, (uint)buffer.Capacity)) + { + while (handle != null && !handle.IsInvalid) + { + if (NativeMethods.FindNextVolume(handle, buffer, (uint)buffer.Capacity)) + yield return buffer.ToString(); + + else + { + var lastError = Marshal.GetLastWin32Error(); + + handle.Close(); + + if (lastError == Win32Errors.ERROR_NO_MORE_FILES) + yield break; + + NativeError.ThrowException(lastError); + } + } + } + } + + #endregion // EnumerateVolumes + + #region GetUniqueVolumeNameForPath + + /// + /// Get the unique volume name for the given path. + /// + /// + /// + /// A path string. Both absolute and relative file and directory names, for example "..", is acceptable in this path. If you specify a + /// relative file or directory name without a volume qualifier, GetUniqueVolumeNameForPath returns the Drive letter of the current + /// volume. + /// + /// + /// Returns the unique volume name in the form: "\\?\Volume{GUID}\", + /// or on error or if unavailable. + /// + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + [SecurityCritical] + public static string GetUniqueVolumeNameForPath(string volumePathName) + { + if (Utils.IsNullOrWhiteSpace(volumePathName)) + throw new ArgumentNullException("volumePathName"); + + try + { + return GetVolumeGuid(GetVolumePathName(volumePathName)); + } + catch + { + return null; + } + } + + #endregion // GetUniqueVolumeNameForPath + + #region GetVolumeDeviceName + + /// Retrieves the Win32 Device name from the Volume name. + /// + /// Name of the Volume. + /// + /// The Win32 Device name from the Volume name (for example: "\Device\HarddiskVolume2"), or on error or if + /// unavailable. + /// + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + [SecurityCritical] + public static string GetVolumeDeviceName(string volumeName) + { + if (Utils.IsNullOrWhiteSpace(volumeName)) + throw new ArgumentNullException("volumeName"); + + volumeName = Path.RemoveTrailingDirectorySeparator(volumeName, false); + + #region GlobalRoot + + if (volumeName.StartsWith(Path.GlobalRootPrefix, StringComparison.OrdinalIgnoreCase)) + return volumeName.Substring(Path.GlobalRootPrefix.Length); + + #endregion // GlobalRoot + + bool doQueryDos; + + #region Volume + + if (volumeName.StartsWith(Path.VolumePrefix, StringComparison.OrdinalIgnoreCase)) + { + // Isolate the DOS Device from the Volume name, in the format: Volume{GUID} + volumeName = volumeName.Substring(Path.LongPathPrefix.Length); + doQueryDos = true; + } + + #endregion // Volume + + #region Logical Drive + + // Check for Logical Drives: C:, D:, ... + else + { + // Don't use char.IsLetter() here as that can be misleading. + // The only valid drive letters are: a-z and A-Z. + var c = volumeName[0]; + doQueryDos = (volumeName[1] == Path.VolumeSeparatorChar && ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))); + } + + #endregion // Logical Drive + + if (doQueryDos) + { + try + { + // Get the real Device underneath. + var dev = QueryDosDevice(volumeName).FirstOrDefault(); + return !Utils.IsNullOrWhiteSpace(dev) ? dev : null; + } + catch + { + } + } + + return null; + } + + #endregion // GetVolumeDeviceName + + #region GetVolumeDisplayName + + /// Gets the shortest display name for the specified . + /// This method basically returns the shortest string returned by + /// A volume path: \\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\. + /// + /// The shortest display name for the specified volume found, or if no display names were found. + /// + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + [SecurityCritical] + public static string GetVolumeDisplayName(string volumeName) + { + string[] smallestMountPoint = { new string(Path.WildcardStarMatchAllChar, NativeMethods.MaxPathUnicode) }; + + try + { + foreach (var m in EnumerateVolumePathNames(volumeName).Where(m => !Utils.IsNullOrWhiteSpace(m) && m.Length < smallestMountPoint[0].Length)) + smallestMountPoint[0] = m; + } + catch + { + } + + var result = smallestMountPoint[0][0] == Path.WildcardStarMatchAllChar ? null : smallestMountPoint[0]; + return Utils.IsNullOrWhiteSpace(result) ? null : result; + } + + #endregion // GetVolumeDisplayName + + #region GetVolumeGuid + + /// + /// Retrieves a volume path for the volume that is associated with the specified volume mount point (drive letter, + /// volume GUID path, or mounted folder). + /// + /// + /// + /// The path of a mounted folder (for example, "Y:\MountX\") or a drive letter (for example, "X:\"). + /// + /// The unique volume name of the form: "\\?\Volume{GUID}\". + [SuppressMessage("Microsoft.Interoperability", "CA1404:CallGetLastErrorImmediatelyAfterPInvoke", Justification = "Marshal.GetLastWin32Error() is manipulated.")] + [SecurityCritical] + public static string GetVolumeGuid(string volumeMountPoint) + { + if (Utils.IsNullOrWhiteSpace(volumeMountPoint)) + throw new ArgumentNullException("volumeMountPoint"); + + // The string must end with a trailing backslash ('\'). + volumeMountPoint = Path.GetFullPathCore(null, volumeMountPoint, GetFullPathOptions.AsLongPath | GetFullPathOptions.AddTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + + var volumeGuid = new StringBuilder(100); + var uniqueName = new StringBuilder(100); + + try + { + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + { + // GetVolumeNameForVolumeMountPoint() + // 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-07-18: MSDN does not confirm LongPath usage but a Unicode version of this function exists. + + return NativeMethods.GetVolumeNameForVolumeMountPoint(volumeMountPoint, volumeGuid, (uint) volumeGuid.Capacity) + ? NativeMethods.GetVolumeNameForVolumeMountPoint(Path.AddTrailingDirectorySeparator(volumeGuid.ToString(), false), uniqueName, (uint) uniqueName.Capacity) + ? uniqueName.ToString() + : null + : null; + } + } + finally + { + var lastError = (uint) Marshal.GetLastWin32Error(); + + switch (lastError) + { + case Win32Errors.ERROR_INVALID_NAME: + NativeError.ThrowException(lastError, volumeMountPoint); + break; + + case Win32Errors.ERROR_MORE_DATA: + // (1) When GetVolumeNameForVolumeMountPoint() succeeds, lastError is set to Win32Errors.ERROR_MORE_DATA. + break; + + default: + // (2) When volumeMountPoint is a network drive mapping or UNC path, lastError is set to Win32Errors.ERROR_INVALID_PARAMETER. + + // Throw IOException. + NativeError.ThrowException(lastError, volumeMountPoint); + break; + } + } + } + + #endregion // GetVolumeGuid + + #region GetVolumeGuidForNtDeviceName + + /// + /// Tranlates DosDevicePath to a Volume GUID. For example: "\Device\HarddiskVolumeX\path\filename.ext" can translate to: "\path\ + /// filename.ext" or: "\\?\Volume{GUID}\path\filename.ext". + /// + /// A DosDevicePath, for example: \Device\HarddiskVolumeX\path\filename.ext. + /// A translated dos path. + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Nt")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Nt")] + public static string GetVolumeGuidForNtDeviceName(string dosDevice) + { + return (from drive in Directory.EnumerateLogicalDrivesCore(false, false) + where drive.DosDeviceName.Equals(dosDevice, StringComparison.OrdinalIgnoreCase) + select drive.VolumeInfo.Guid).FirstOrDefault(); + } + + #endregion // GetVolumeGuidForNtDeviceName + + #region GetVolumeInfo + + /// Retrieves information about the file system and volume associated with the specified root file or directorystream. + /// A path that contains the root directory. + /// A instance describing the volume associatied with the specified root directory. + [SecurityCritical] + public static VolumeInfo GetVolumeInfo(string volumePath) + { + return new VolumeInfo(volumePath, true, false); + } + + /// Retrieves information about the file system and volume associated with the specified root file or directorystream. + /// An instance to a handle. + /// A instance describing the volume associatied with the specified root directory. + [SecurityCritical] + public static VolumeInfo GetVolumeInfo(SafeFileHandle volumeHandle) + { + return new VolumeInfo(volumeHandle, true, true); + } + + #endregion // GetVolumeInfo + + #region GetVolumeLabel + + /// Retrieve the label of a file system volume. + /// + /// A path to a volume. For example: "C:\", "\\server\share", or "\\?\Volume{c0580d5e-2ad6-11dc-9924-806e6f6e6963}\". + /// + /// + /// The the label of the file system volume. This function can return string.Empty since a volume label is generally not + /// mandatory. + /// + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + [SecurityCritical] + public static string GetVolumeLabel(string volumePath) + { + return new VolumeInfo(volumePath, true, true).Name; + } + + #endregion // GetVolumeLabel + + #region GetVolumePathName + + /// Retrieves the volume mount point where the specified path is mounted. + /// + /// The path to the volume, for example: "C:\Windows". + /// + /// Returns the nearest volume root path for a given directory. + /// The volume path name, for example: "C:\Windows" returns: "C:\". + /// + [SecurityCritical] + public static string GetVolumePathName(string path) + { + if (Utils.IsNullOrWhiteSpace(path)) + throw new ArgumentNullException("path"); + + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + { + var volumeRootPath = new StringBuilder(NativeMethods.MaxPathUnicode / 32); + var pathLp = Path.GetFullPathCore(null, path, GetFullPathOptions.AsLongPath | GetFullPathOptions.FullCheck); + + // GetVolumePathName() + // 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-07-18: MSDN does not confirm LongPath usage but a Unicode version of this function exists. + + var getOk = NativeMethods.GetVolumePathName(pathLp, volumeRootPath, (uint) volumeRootPath.Capacity); + var lastError = Marshal.GetLastWin32Error(); + + if (getOk) + return Path.GetRegularPathCore(volumeRootPath.ToString(), GetFullPathOptions.None, false); + + switch ((uint) lastError) + { + // Don't throw exception on these errors. + case Win32Errors.ERROR_NO_MORE_FILES: + case Win32Errors.ERROR_INVALID_PARAMETER: + case Win32Errors.ERROR_INVALID_NAME: + break; + + default: + NativeError.ThrowException(lastError, path); + break; + } + + // Return original path. + return path; + } + } + + #endregion // GetVolumePathName + + #region IsSameVolume + + /// Determines whether the volume of two file system objects is the same. + /// The first filesystem ojbect with full path information. + /// The second file system object with full path information. + /// if both filesytem objects reside on the same volume, otherwise. + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + [SecurityCritical] + public static bool IsSameVolume(string path1, string path2) + { + try + { + var volInfo1 = new VolumeInfo(GetVolumePathName(path1), true, true); + var volInfo2 = new VolumeInfo(GetVolumePathName(path2), true, true); + + return volInfo1.SerialNumber == volInfo2.SerialNumber; + } + catch { } + + return false; + } + + #endregion // IsSameVolume + + #region IsVolume + + /// Determines whether the specified volume name is a defined volume on the current computer. + /// + /// A path to a volume. For example: "C:\", "\\server\share", or "\\?\Volume{c0580d5e-2ad6-11dc-9924-806e6f6e6963}\". + /// + /// on success, otherwise. + [SecurityCritical] + public static bool IsVolume(string volumeMountPoint) + { + return !Utils.IsNullOrWhiteSpace(GetVolumeGuid(volumeMountPoint)); + } + + #endregion // IsVolume + + #region SetCurrentVolumeLabel + + /// Sets the label of the file system volume that is the root of the current directory. + /// + /// A name for the volume. + [SecurityCritical] + public static void SetCurrentVolumeLabel(string volumeName) + { + if (Utils.IsNullOrWhiteSpace(volumeName)) + throw new ArgumentNullException("volumeName"); + + if (!NativeMethods.SetVolumeLabel(null, volumeName)) + Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); + } + + #endregion // SetCurrentVolumeLabel + + #region SetVolumeLabel + + /// Sets the label of a file system volume. + /// + /// A path to a volume. For example: "C:\", "\\server\share", or "\\?\Volume{c0580d5e-2ad6-11dc-9924-806e6f6e6963}\" + /// If this parameter is , the function uses the current drive. + /// + /// + /// A name for the volume. + /// If this parameter is , the function deletes any existing label + /// from the specified volume and does not assign a new label. + /// + [SecurityCritical] + public static void SetVolumeLabel(string volumePath, string volumeName) + { + // rootPathName == null is allowed, means current drive. + + // Setting volume label only applies to Logical Drives pointing to local resources. + //if (!Path.IsLocalPath(rootPathName)) + //return false; + + volumePath = Path.AddTrailingDirectorySeparator(volumePath, false); + + // NTFS uses a limit of 32 characters for the volume label as of Windows Server 2003. + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + if (!NativeMethods.SetVolumeLabel(volumePath, volumeName)) + NativeError.ThrowException(volumePath, volumeName); + } + + #endregion // SetVolumeLabel + + #region SetVolumeMountPoint + + /// Associates a volume with a Drive letter or a directory on another volume. + /// + /// + /// + /// The user-mode path to be associated with the volume. This may be a Drive letter (for example, "X:\") + /// or a directory on another volume (for example, "Y:\MountX\"). + /// + /// A containing the volume . + [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "1", Justification = "Utils.IsNullOrWhiteSpace validates arguments.")] + [SecurityCritical] + public static void SetVolumeMountPoint(string volumeMountPoint, string volumeGuid) + { + if (Utils.IsNullOrWhiteSpace(volumeMountPoint)) + throw new ArgumentNullException("volumeMountPoint"); + + if (Utils.IsNullOrWhiteSpace(volumeGuid)) + throw new ArgumentNullException("volumeGuid"); + + if (!volumeGuid.StartsWith(Path.VolumePrefix + "{", StringComparison.OrdinalIgnoreCase)) + throw new ArgumentException(Resources.Not_A_Valid_Guid, volumeGuid); + + volumeMountPoint = Path.GetFullPathCore(null, volumeMountPoint, GetFullPathOptions.AsLongPath | GetFullPathOptions.AddTrailingDirectorySeparator | GetFullPathOptions.FullCheck); + + // This string must be of the form "\\?\Volume{GUID}\" + volumeGuid = Path.AddTrailingDirectorySeparator(volumeGuid, false); + + + // ChangeErrorMode is for the Win32 SetThreadErrorMode() method, used to suppress possible pop-ups. + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + + // SetVolumeMountPoint() + // 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. + // 2014-01-29: MSDN does not confirm LongPath usage but a Unicode version of this function exists. + + if (!NativeMethods.SetVolumeMountPoint(volumeMountPoint, volumeGuid)) + { + var lastError = Marshal.GetLastWin32Error(); + + // If the lpszVolumeMountPoint parameter contains a path to a mounted folder, + // GetLastError returns ERROR_DIR_NOT_EMPTY, even if the directory is empty. + + if (lastError != Win32Errors.ERROR_DIR_NOT_EMPTY) + NativeError.ThrowException(lastError, volumeGuid); + } + } + + #endregion // SetVolumeMountPoint + + #endregion // Volume + + + #region Internal Methods + + /// Defines, redefines, or deletes MS-DOS device names. + /// + /// + /// defines a new MS-DOS device. deletes a previously defined MS-DOS device. + /// + /// + /// An MS-DOS device name string specifying the device the function is defining, redefining, or deleting. + /// + /// + /// A pointer to a path string that will implement this device. The string is an MS-DOS path string unless the + /// flag is specified, in which case this string is a path string. + /// + /// + /// The controllable aspects of the DefineDosDevice function, flags which will be combined with the + /// default. + /// + /// + /// Only delete MS-DOS device on an exact name match. If is , + /// must be the same path used to create the mapping. + /// + /// + /// on success, otherwise. + [SecurityCritical] + internal static void DefineDosDeviceCore(bool isDefine, string deviceName, string targetPath, DosDeviceAttributes deviceAttributes, bool exactMatch) + { + if (Utils.IsNullOrWhiteSpace(deviceName)) + throw new ArgumentNullException("deviceName"); + + if (isDefine) + { + // targetPath is allowed to be null. + + // In no case is a trailing backslash ("\") allowed. + deviceName = Path.GetRegularPathCore(deviceName, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars, false); + + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + if (!NativeMethods.DefineDosDevice(deviceAttributes, deviceName, targetPath)) + NativeError.ThrowException(deviceName, targetPath); + } + else + { + // A pointer to a path string that will implement this device. + // The string is an MS-DOS path string unless the DDD_RAW_TARGET_PATH flag is specified, in which case this string is a path string. + + if (exactMatch && !Utils.IsNullOrWhiteSpace(targetPath)) + deviceAttributes = deviceAttributes | DosDeviceAttributes.ExactMatchOnRemove | DosDeviceAttributes.RawTargetPath; + + // Remove the MS-DOS device name. First, get the name of the Windows NT device + // from the symbolic link and then delete the symbolic link from the namespace. + + DefineDosDevice(deviceName, targetPath, deviceAttributes); + } + } + + /// Deletes a Drive letter or mounted folder. + /// + /// It's not an error to attempt to unmount a volume from a volume mount point when there is no volume actually mounted at that volume mount point. + /// Deleting a mounted folder does not cause the underlying directory to be deleted. + /// + /// + /// The Drive letter or mounted folder to be deleted. For example, X:\ or Y:\MountX\. + /// + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + /// + /// If completed successfully returns , otherwise the last error number. + [SecurityCritical] + internal static int DeleteVolumeMountPointCore(string volumeMountPoint, bool continueOnException) + { + if (Utils.IsNullOrWhiteSpace(volumeMountPoint)) + throw new ArgumentNullException("volumeMountPoint"); + + var lastError = (int) Win32Errors.ERROR_SUCCESS; + + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + { + // DeleteVolumeMountPoint() + // 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 does not confirm LongPath usage but a Unicode version of this function exists. + + if (!NativeMethods.DeleteVolumeMountPoint(Path.AddTrailingDirectorySeparator(volumeMountPoint, false))) + lastError = Marshal.GetLastWin32Error(); + + if (lastError != Win32Errors.ERROR_SUCCESS && !continueOnException) + { + if (lastError == Win32Errors.ERROR_FILE_NOT_FOUND) + lastError = (int) Win32Errors.ERROR_PATH_NOT_FOUND; + + NativeError.ThrowException(lastError, volumeMountPoint); + } + } + + return lastError; + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Filesystem/VolumeInfo.cs b/AlphaFS/Filesystem/VolumeInfo.cs new file mode 100644 index 0000000..164215f --- /dev/null +++ b/AlphaFS/Filesystem/VolumeInfo.cs @@ -0,0 +1,462 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Microsoft.Win32.SafeHandles; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Filesystem +{ + /// Contains information about a filesystem Volume. + [SerializableAttribute] + [SecurityCritical] + public sealed class VolumeInfo + { + #region Constructor + + /// Initializes a VolumeInfo instance. + /// + /// + /// A valid drive path or drive letter. This can be either uppercase or lowercase, 'a' to 'z' or a network share in the format: \\server\share. + [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Utils.IsNullOrWhiteSpace validates arguments.")] + public VolumeInfo(string volumeName) + { + if (Utils.IsNullOrWhiteSpace(volumeName)) + throw new ArgumentNullException("volumeName"); + + if (!volumeName.StartsWith(Path.LongPathPrefix, StringComparison.OrdinalIgnoreCase)) + volumeName = Path.IsUncPathCore(volumeName, false, false) + ? Path.GetLongPathCore(volumeName, GetFullPathOptions.None) + : Path.LongPathPrefix + volumeName; + else + { + if (volumeName.Length == 1) + volumeName += Path.VolumeSeparatorChar; + else if (!volumeName.StartsWith(Path.GlobalRootPrefix, StringComparison.OrdinalIgnoreCase)) + volumeName = Path.GetPathRoot(volumeName, false); + } + + if (Utils.IsNullOrWhiteSpace(volumeName)) + throw new ArgumentException("Argument must be a drive letter (\"C\"), RootDir (\"C:\\\") or UNC path (\"\\\\server\\share\")"); + + Name = Path.AddTrailingDirectorySeparator(volumeName, false); + + _volumeHandle = null; + } + + /// Initializes a VolumeInfo instance. + /// A valid drive path or drive letter. This can be either uppercase or lowercase, 'a' to 'z' or a network share in the format: "\\server\share". + /// Refreshes the state of the object. + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + public VolumeInfo(string driveName, bool refresh, bool continueOnException) : this(driveName) + { + _continueOnAccessError = continueOnException; + + if (refresh) + Refresh(); + } + + /// Initializes a VolumeInfo instance. + /// An instance to a handle. + [SecurityCritical] + public VolumeInfo(SafeFileHandle volumeHandle) + { + _volumeHandle = volumeHandle; + } + + /// Initializes a VolumeInfo instance. + /// An instance to a handle. + /// Refreshes the state of the object. + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + public VolumeInfo(SafeFileHandle volumeHandle, bool refresh, bool continueOnException) : this(volumeHandle) + { + _continueOnAccessError = continueOnException; + + if (refresh) + Refresh(); + } + + #endregion // Constructor + + #region Fields + + [NonSerialized] private readonly bool _continueOnAccessError; + [NonSerialized] private readonly SafeFileHandle _volumeHandle; + [NonSerialized] private NativeMethods.VolumeInfoAttributes _volumeInfoAttributes; + #endregion // Fields + + #region Methods + + #region Refresh + + /// Refreshes the state of the object. + public void Refresh() + { + var volumeNameBuffer = new StringBuilder(NativeMethods.MaxPath + 1); + var fileSystemNameBuffer = new StringBuilder(NativeMethods.MaxPath + 1); + int maximumComponentLength; + uint serialNumber; + + using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors)) + { + // GetVolumeInformationXxx() + // 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-07-18: MSDN does not confirm LongPath usage but a Unicode version of this function exists. + + uint lastError; + + do + { + if (!(_volumeHandle != null && NativeMethods.IsAtLeastWindowsVista + + // GetVolumeInformationByHandle() / GetVolumeInformation() + // 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-07-18: MSDN does not confirm LongPath usage but a Unicode version of this function exists. + + ? NativeMethods.GetVolumeInformationByHandle(_volumeHandle, volumeNameBuffer, (uint) volumeNameBuffer.Capacity, out serialNumber, out maximumComponentLength, out _volumeInfoAttributes, fileSystemNameBuffer, (uint) fileSystemNameBuffer.Capacity) + : NativeMethods.GetVolumeInformation(Path.AddTrailingDirectorySeparator(Name, false), volumeNameBuffer, (uint) volumeNameBuffer.Capacity, out serialNumber, out maximumComponentLength, out _volumeInfoAttributes, fileSystemNameBuffer, (uint) fileSystemNameBuffer.Capacity)) + // A trailing backslash is required. + ) + { + lastError = (uint) Marshal.GetLastWin32Error(); + switch (lastError) + { + case Win32Errors.ERROR_NOT_READY: + if (!_continueOnAccessError) + throw new DeviceNotReadyException(); + break; + + case Win32Errors.ERROR_MORE_DATA: + // With a large enough buffer this code never executes. + volumeNameBuffer.Capacity = volumeNameBuffer.Capacity*2; + fileSystemNameBuffer.Capacity = fileSystemNameBuffer.Capacity*2; + break; + + default: + if (!_continueOnAccessError) + NativeError.ThrowException(Name); + break; + } + } + else + break; + + } while (lastError == Win32Errors.ERROR_MORE_DATA); + } + + FullPath = Path.GetRegularPathCore(Name, GetFullPathOptions.None, false); + Name = volumeNameBuffer.ToString(); + + FileSystemName = fileSystemNameBuffer.ToString(); + FileSystemName = Utils.IsNullOrWhiteSpace(FileSystemName) ? null : FileSystemName; + + MaximumComponentLength = maximumComponentLength; + SerialNumber = serialNumber; + } + + #endregion // Refresh + + #region ToString + + /// Returns the full path of the volume. + /// A string that represents this instance. + public override string ToString() + { + return Guid; + } + + #endregion // ToString + + #endregion // Methods + + #region Properties + + #region CasePreservedNames + + /// The specified volume supports preserved case of file names when it places a name on disk. + public bool CasePreservedNames + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.CasePreservedNames) == NativeMethods.VolumeInfoAttributes.CasePreservedNames; } + } + + #endregion // CasePreservedNames + + #region CaseSensitiveSearch + + /// The specified volume supports case-sensitive file names. + public bool CaseSensitiveSearch + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.CaseSensitiveSearch) == NativeMethods.VolumeInfoAttributes.CaseSensitiveSearch; } + } + + #endregion // CaseSensitiveSearch + + #region Compression + + /// The specified volume supports file-based compression. + public bool Compression + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.Compression) == NativeMethods.VolumeInfoAttributes.Compression; } + } + + #endregion // Compression + + #region FileSystemName + + /// Gets the name of the file system, for example, the FAT file system or the NTFS file system. + /// The name of the file system. + public string FileSystemName { get; private set; } + + #endregion // FileSystemName + + #region FullPath + + /// The full path to the volume. + public string FullPath { get; private set; } + + #endregion // FullPath + + #region Guid + + private string _guid; + + /// The volume GUID. + + public string Guid + { + get + { + if (Utils.IsNullOrWhiteSpace(_guid)) + _guid = !Utils.IsNullOrWhiteSpace(FullPath) ? Volume.GetUniqueVolumeNameForPath(FullPath) : null; + + return _guid; + } + } + + #endregion // Guid + + #region MaximumComponentLength + + /// Gets the maximum length of a file name component that the file system supports. + /// The maximum length of a file name component that the file system supports. + public int MaximumComponentLength { get; set; } + + #endregion // MaximumComponentLength + + #region Name + + /// Gets the label of the volume. + /// The label of the volume. + /// This property is the label assigned to the volume, such "MyDrive" + public string Name { get; private set; } + + #endregion // Name + + #region NamedStreams + + /// The specified volume supports named streams. + public bool NamedStreams + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.NamedStreams) == NativeMethods.VolumeInfoAttributes.NamedStreams; } + } + + #endregion // NamedStreams + + #region PersistentAcls + + /// The specified volume preserves and enforces access control lists (ACL). + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Acls")] + public bool PersistentAcls + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.PersistentAcls) == NativeMethods.VolumeInfoAttributes.PersistentAcls; } + } + + #endregion // PersistentAcls + + #region ReadOnlyVolume + + /// The specified volume is read-only. + public bool ReadOnlyVolume + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.ReadOnlyVolume) == NativeMethods.VolumeInfoAttributes.ReadOnlyVolume; } + } + + #endregion // ReadOnlyVolume + + #region SequentialWriteOnce + + /// The specified volume supports a single sequential write. + public bool SequentialWriteOnce + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.SequentialWriteOnce) == NativeMethods.VolumeInfoAttributes.SequentialWriteOnce; } + } + + #endregion // SequentialWriteOnce + + #region SerialNumber + + /// Gets the volume serial number that the operating system assigns when a hard disk is formatted. + /// The volume serial number that the operating system assigns when a hard disk is formatted. + public long SerialNumber { get; private set; } + + #endregion // SerialNumber + + #region SupportsEncryption + + /// The specified volume supports the Encrypted File System (EFS). + public bool SupportsEncryption + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.SupportsEncryption) == NativeMethods.VolumeInfoAttributes.SupportsEncryption; } + } + + #endregion // SupportsEncryption + + #region SupportsExtendedAttributes + + /// The specified volume supports extended attributes. + public bool SupportsExtendedAttributes + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.SupportsExtendedAttributes) == NativeMethods.VolumeInfoAttributes.SupportsExtendedAttributes; } + } + + #endregion // SupportsExtendedAttributes + + #region SupportsHardLinks + + /// The specified volume supports hard links. + public bool SupportsHardLinks + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.SupportsHardLinks) == NativeMethods.VolumeInfoAttributes.SupportsHardLinks; } + } + + #endregion // SupportsHardLinks + + #region SupportsObjectIds + + /// The specified volume supports object identifiers. + public bool SupportsObjectIds + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.SupportsObjectIds) == NativeMethods.VolumeInfoAttributes.SupportsObjectIds; } + } + + #endregion // SupportsObjectIds + + #region SupportsOpenByFileId + + /// The file system supports open by FileID. + public bool SupportsOpenByFileId + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.SupportsOpenByFileId) == NativeMethods.VolumeInfoAttributes.SupportsOpenByFileId; } + } + + #endregion // SupportsOpenByFileId + + #region SupportsRemoteStorage + + /// The specified volume supports remote storage. (This property does not appear on MSDN) + public bool SupportsRemoteStorage + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.SupportsRemoteStorage) == NativeMethods.VolumeInfoAttributes.SupportsRemoteStorage; } + } + + #endregion // SupportsRemoteStorage + + #region SupportsReparsePoints + + /// The specified volume supports re-parse points. + public bool SupportsReparsePoints + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.SupportsReparsePoints) == NativeMethods.VolumeInfoAttributes.SupportsReparsePoints; } + } + + #endregion // SupportsReparsePoints + + #region SupportsSparseFiles + + /// The specified volume supports sparse files. + public bool SupportsSparseFiles + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.SupportsSparseFiles) == NativeMethods.VolumeInfoAttributes.SupportsSparseFiles; } + } + + #endregion // SupportsSparseFiles + + #region SupportsTransactions + + /// The specified volume supports transactions. + public bool SupportsTransactions + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.SupportsTransactions) == NativeMethods.VolumeInfoAttributes.SupportsTransactions; } + } + + #endregion // SupportsTransactions + + #region SupportsUsnJournal + + /// The specified volume supports update sequence number (USN) journals. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Usn")] + public bool SupportsUsnJournal + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.SupportsUsnJournal) == NativeMethods.VolumeInfoAttributes.SupportsUsnJournal; } + } + + #endregion // SupportsUsnJournal + + #region UnicodeOnDisk + + /// The specified volume supports Unicode in file names as they appear on disk. + public bool UnicodeOnDisk + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.UnicodeOnDisk) == NativeMethods.VolumeInfoAttributes.UnicodeOnDisk; } + } + + #endregion // UnicodeOnDisk + + #region VolumeIsCompressed + + /// The specified volume is a compressed volume, for example, a DoubleSpace volume. + public bool VolumeIsCompressed + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.VolumeIsCompressed) == NativeMethods.VolumeInfoAttributes.VolumeIsCompressed; } + } + + #endregion // VolumeIsCompressed + + #region VolumeQuotas + + /// The specified volume supports disk quotas. + public bool VolumeQuotas + { + get { return (_volumeInfoAttributes & NativeMethods.VolumeInfoAttributes.VolumeQuotas) == NativeMethods.VolumeInfoAttributes.VolumeQuotas; } + } + + #endregion // VolumeQuotas + + #endregion // Properties + } +} diff --git a/AlphaFS/GlobalSuppressions.cs b/AlphaFS/GlobalSuppressions.cs new file mode 100644 index 0000000..65a2170 --- /dev/null +++ b/AlphaFS/GlobalSuppressions.cs @@ -0,0 +1,34 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. +// +// To add a suppression to this file, right-click the message in the +// Error List, point to "Suppress Message(s)", and click +// "In Project Suppression File". +// You do not need to add suppressions to this file manually. +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Alphaleonis", Scope = "namespace", Target = "Alphaleonis.Win32.Network")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Alphaleonis", Scope = "namespace", Target = "Alphaleonis.Win32.Security")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Alphaleonis.Win32.Security")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Filesystem", Scope = "namespace", Target = "Alphaleonis.Win32.Filesystem")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Alphaleonis", Scope = "namespace", Target = "Alphaleonis.Win32.Filesystem")] diff --git a/AlphaFS/NativeError.cs b/AlphaFS/NativeError.cs new file mode 100644 index 0000000..54e78d1 --- /dev/null +++ b/AlphaFS/NativeError.cs @@ -0,0 +1,159 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Filesystem; +using System; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.IO; +using System.Runtime.InteropServices; +using System.Security.Policy; + +namespace Alphaleonis.Win32 +{ + internal static class NativeError + { + internal static void ThrowException() + { + ThrowException((uint)Marshal.GetLastWin32Error(), null, null); + } + + public static void ThrowException(int errorCode) + { + ThrowException((uint)errorCode, null, null); + } + + public static void ThrowException(int errorCode, string readPath) + { + ThrowException((uint)errorCode, readPath, null); + } + + public static void ThrowException(int errorCode, string readPath, string writePath) + { + ThrowException((uint)errorCode, readPath, writePath); + } + + public static void ThrowException(uint errorCode, string readPath) + { + ThrowException(errorCode, readPath, null); + } + + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + public static void ThrowException(uint errorCode, string readPath, string writePath) + { + string errorMessage = string.Format(CultureInfo.CurrentCulture, "({0}) {1}.", errorCode, new Win32Exception((int)errorCode).Message); + + if (!Utils.IsNullOrWhiteSpace(readPath)) + errorMessage = string.Format(CultureInfo.CurrentCulture, "{0}: [{1}]", errorMessage.TrimEnd('.'), readPath); + + if (!Utils.IsNullOrWhiteSpace(writePath)) + errorMessage = string.Format(CultureInfo.CurrentCulture, "{0}: [{1}]", errorMessage.TrimEnd('.'), writePath); + + switch (errorCode) + { + case Win32Errors.ERROR_INVALID_DRIVE: + throw new DriveNotFoundException(errorMessage); + + case Win32Errors.ERROR_OPERATION_ABORTED: + throw new OperationCanceledException(errorMessage); + + case Win32Errors.ERROR_FILE_NOT_FOUND: + throw new FileNotFoundException(errorMessage); + + case Win32Errors.ERROR_PATH_NOT_FOUND: + throw new DirectoryNotFoundException(errorMessage); + + case Win32Errors.ERROR_BAD_RECOVERY_POLICY: + throw new PolicyException(errorMessage); + + case Win32Errors.ERROR_FILE_READ_ONLY: + case Win32Errors.ERROR_ACCESS_DENIED: + case Win32Errors.ERROR_NETWORK_ACCESS_DENIED: + throw new UnauthorizedAccessException(errorMessage); + + case Win32Errors.ERROR_ALREADY_EXISTS: + case Win32Errors.ERROR_FILE_EXISTS: + throw new AlreadyExistsException(errorMessage); + + case Win32Errors.ERROR_DIR_NOT_EMPTY: + throw new DirectoryNotEmptyException(errorMessage); + + case Win32Errors.ERROR_NOT_READY: + throw new DeviceNotReadyException(errorMessage); + + + #region Transactional + + case Win32Errors.ERROR_INVALID_TRANSACTION: + throw new InvalidTransactionException(Resources.Transaction_Invalid, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode))); + + case Win32Errors.ERROR_TRANSACTION_ALREADY_COMMITTED: + throw new TransactionAlreadyCommittedException(Resources.Transaction_Already_Committed, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode))); + + case Win32Errors.ERROR_TRANSACTION_ALREADY_ABORTED: + throw new TransactionAlreadyAbortedException(Resources.Transaction_Already_Aborted, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode))); + + case Win32Errors.ERROR_TRANSACTIONAL_CONFLICT: + throw new TransactionalConflictException(Resources.Transactional_Conflict, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode))); + + case Win32Errors.ERROR_TRANSACTION_NOT_ACTIVE: + throw new TransactionException(Resources.Transaction_Not_Active, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode))); + + case Win32Errors.ERROR_TRANSACTION_NOT_REQUESTED: + throw new TransactionException(Resources.Transaction_Not_Requested, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode))); + + case Win32Errors.ERROR_TRANSACTION_REQUEST_NOT_VALID: + throw new TransactionException(Resources.Invalid_Transaction_Request, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode))); + + case Win32Errors.ERROR_TRANSACTIONS_UNSUPPORTED_REMOTE: + throw new UnsupportedRemoteTransactionException(Resources.Invalid_Transaction_Request, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode))); + + case Win32Errors.ERROR_NOT_A_REPARSE_POINT: + throw new NotAReparsePointException(Resources.Not_A_Reparse_Point, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode))); + + #endregion // Transacted + + case Win32Errors.ERROR_SUCCESS: + case Win32Errors.ERROR_SUCCESS_REBOOT_INITIATED: + case Win32Errors.ERROR_SUCCESS_REBOOT_REQUIRED: + case Win32Errors.ERROR_SUCCESS_RESTART_REQUIRED: + // We should really never get here, throwing an exception for a successful operation. + throw new NotImplementedException(string.Format(CultureInfo.CurrentCulture, "{0} {1}", Resources.Exception_From_Successful_Operation, errorMessage)); + + default: + // We don't have a specific exception to generate for this error. + throw new IOException(errorMessage, Win32Errors.GetHrFromWin32Error(errorCode)); + } + } + + + public static void ThrowException(string readPath) + { + ThrowException((uint)Marshal.GetLastWin32Error(), readPath, null); + } + + public static void ThrowException(string readPath, string writePath) + { + ThrowException((uint)Marshal.GetLastWin32Error(), readPath, writePath); + } + } +} diff --git a/AlphaFS/Network/DfsInfo.cs b/AlphaFS/Network/DfsInfo.cs new file mode 100644 index 0000000..1ab4318 --- /dev/null +++ b/AlphaFS/Network/DfsInfo.cs @@ -0,0 +1,148 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Filesystem; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Network +{ + /// Contains information about a Distributed File System (DFS) root or link. This class cannot be inherited. + /// This structure contains the name, status, GUID, time-out, number of targets, and information about each target of the root or link. + /// + [SerializableAttribute] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + public sealed class DfsInfo + { + #region Constructor + + /// Initializes a new instance of the class which acts as a wrapper for a DFS root or link target. + public DfsInfo() + { + } + + /// Initializes a new instance of the class, which acts as a wrapper for a DFS root or link target. + /// An initialized instance. + internal DfsInfo(NativeMethods.DFS_INFO_9 structure) + { + Comment = structure.Comment; + EntryPath = structure.EntryPath; + State = structure.State; + Timeout = structure.Timeout; + Guid = structure.Guid; + MetadataSize = structure.MetadataSize; + PropertyFlags = structure.PropertyFlags; + SecurityDescriptor = structure.pSecurityDescriptor; + + if (structure.NumberOfStorages > 0) + { + var typeOfStruct = typeof (NativeMethods.DFS_STORAGE_INFO_1); + var sizeOfStruct = Marshal.SizeOf(typeOfStruct); + + for (int i = 0; i < structure.NumberOfStorages; i++) + _storageInfoCollection.Add(new DfsStorageInfo((NativeMethods.DFS_STORAGE_INFO_1) Marshal.PtrToStructure(new IntPtr(structure.Storage.ToInt64() + i*sizeOfStruct), typeOfStruct))); + } + } + + #endregion // Constructor + + #region Methods + + /// Returns the Universal Naming Convention (UNC) path of the DFS root or link. + /// A string that represents this instance. + public override string ToString() + { + return EntryPath; + } + + #endregion // Methods + + #region Properties + + private DirectoryInfo _directoryInfo; + + /// The instance of the DFS root or link. + public DirectoryInfo DirectoryInfo + { + get + { + // Do not use ?? expression here. + if (_directoryInfo == null) + _directoryInfo = new DirectoryInfo(null, EntryPath, PathFormat.FullPath); + + return _directoryInfo; + } + } + + /// The comment of the DFS root or link. + public string Comment { get; internal set; } + + /// The Universal Naming Convention (UNC) path of the DFS root or link. + public string EntryPath { get; internal set; } + + /// Specifies the GUID of the DFS root or link. + public Guid Guid { get; internal set; } + + + private readonly List _storageInfoCollection = new List(); + + /// The collection of DFS targets of the DFS root or link. + public IEnumerable StorageInfoCollection + { + get { return _storageInfoCollection; } + } + + /// An enum that specifies a set of bit flags that describe the DFS root or link. + public DfsVolumeStates State { get; internal set; } + + //DfsVolumeStates flavorBits = (structure3.State & (DfsVolumeStates) DfsNamespaceFlavors.All); + //If (flavorBits == DFS_VOLUME_FLAVOR_STANDALONE) // Namespace is stand-alone DFS. + //else if (flavorBits == DFS_VOLUME_FLAVOR_AD_BLOB) // Namespace is AD Blob. + //else StateBits = (Flavor & DFS_VOLUME_STATES) // Unknown flavor. + // StateBits can be one of the following: + // (DFS_VOLUME_STATE_OK, DFS_VOLUME_STATE_INCONSISTENT, + // DFS_VOLUME_STATE_OFFLINE or DFS_VOLUME_STATE_ONLINE) + //State = flavorBits | structure3.State; + + /// Specifies the time-out, in seconds, of the DFS root or link. + public long Timeout { get; internal set; } + + /// Specifies a set of flags that describe specific properties of a DFS namespace, root, or link. + [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Flags")] + public DfsPropertyFlags PropertyFlags { get; internal set; } + + /// For domain-based DFS namespaces, this member specifies the size of the corresponding Active Directory data blob, in bytes. + /// For stand-alone DFS namespaces, this field specifies the size of the metadata stored in the registry, + /// including the key names and value names, in addition to the specific data items associated with them. This field is valid for DFS roots only. + /// + public long MetadataSize { get; internal set; } + + + /// Pointer to a SECURITY_DESCRIPTOR structure that specifies a self-relative security descriptor to be associated with the DFS link's reparse point. + /// This field is valid for DFS links only. + /// + public IntPtr SecurityDescriptor { get; internal set; } + + #endregion // Properties + } +} diff --git a/AlphaFS/Network/DfsStorageInfo.cs b/AlphaFS/Network/DfsStorageInfo.cs new file mode 100644 index 0000000..0e0e033 --- /dev/null +++ b/AlphaFS/Network/DfsStorageInfo.cs @@ -0,0 +1,84 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Network +{ + /// Contains information about a DFS root or link target in a DFS namespace or from the cache maintained by the DFS client. + /// This class cannot be inherited. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + public sealed class DfsStorageInfo + { + #region Constructor + + /// Initializes a new instance of the class, which acts as a wrapper for a DFS root or link target. + public DfsStorageInfo() + { + } + + /// Initializes a new instance of the class, which acts as a wrapper for a DFS root or link target. + /// An initialized instance. + internal DfsStorageInfo(NativeMethods.DFS_STORAGE_INFO_1 structure) + { + ServerName = structure.ServerName; + ShareName = structure.ShareName; + + State = structure.State; + + TargetPriorityClass = structure.TargetPriority.TargetPriorityClass; + TargetPriorityRank = structure.TargetPriority.TargetPriorityRank; + } + + #endregion // Constructor + + #region Methods + + /// The share name of the DFS root target or link target. + /// A string that represents this instance. + public override string ToString() + { + return ShareName; + } + + #endregion // Methods + + #region Properties + + /// The server name of the DFS root target or link target. + public string ServerName { get; private set; } + + /// The share name of the DFS root target or link target. + public string ShareName { get; private set; } + + /// An enum of the DFS root target or link target. + public DfsStorageStates State { get; private set; } + + /// Contains a DFS target's priority class and rank. + public DfsTargetPriorityClass TargetPriorityClass { get; private set; } + + /// Specifies the priority rank value of the target. The default value is 0, which indicates the highest priority rank within a priority class. + public int TargetPriorityRank { get; private set; } + + #endregion // Properties + } +} diff --git a/AlphaFS/Network/Enumerations/AccessPermissions.cs b/AlphaFS/Network/Enumerations/AccessPermissions.cs new file mode 100644 index 0000000..c87ecde --- /dev/null +++ b/AlphaFS/Network/Enumerations/AccessPermissions.cs @@ -0,0 +1,74 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace Alphaleonis.Win32.Network +{ + /// A set of bit flags that describe the permissions for the shared resource's on servers running with share-level security. + /// Note that Windows does not support share-level security. This member is ignored on a server running user-level security. + [Flags] + public enum AccessPermissions + { + /// No permissions. + None = 0, + + /// ACCESS_READ + /// Permission to read data from a resource and, by default, to execute the resource. + /// + Read = 1, + + /// ACCESS_WRITE + /// Permission to write data to the resource. + /// + Write = 2, + + /// ACCESS_CREATE + /// Permission to create an instance of the resource (such as a file); data can be written to the resource as the resource is created. + /// + Create = 4, + + /// ACCESS_EXEC + /// Permission to execute the resource. + /// + Execute = 8, + + /// ACCESS_DELETE + /// Permission to delete the resource. + /// + Delete = 16, + + /// ACCESS_ATRIB + /// Permission to modify the resource's attributes, such as the date and time when a file was last modified. + /// + Attributes = 32, + + /// ACCESS_PERM + /// Permission to modify the permissions (read, write, create, execute, and delete) assigned to a resource for a user or application. + /// + Permissions = 64, + + /// ACCESS_ALL + /// Permission to read, write, create, execute, and delete resources, and to modify their attributes and permissions. + /// + All = 32768 + } +} \ No newline at end of file diff --git a/AlphaFS/Network/Enumerations/Connect.cs b/AlphaFS/Network/Enumerations/Connect.cs new file mode 100644 index 0000000..d2c8d0f --- /dev/null +++ b/AlphaFS/Network/Enumerations/Connect.cs @@ -0,0 +1,57 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// Used by function WNetUseConnection(); Set of bit flags describing the connection. This parameter can be any combination of the following values. + [Flags] + internal enum Connect + { + /// No Connect options are used. + None = 0, + + /// This flag instructs the operating system to store the network resource connection. If this bit flag is set, the operating system automatically attempts to restore the connection when the user logs on. The system remembers only successful connections that redirect local devices. It does not remember connections that are unsuccessful or deviceless connections. + UpdateProfile = 1, + + /// If this flag is set, the operating system may interact with the user for authentication purposes. + Interactive = 8, + + /// This flag instructs the system not to use any default settings for user names or passwords without offering the user the opportunity to supply an alternative. This flag is ignored unless is also set. + Prompt = 16, + + /// This flag forces the redirection of a local device when making the connection. + Redirect = 128, + + ///// If this flag is set, the connection was made using a local device redirection. If the lpAccessName parameter points to a buffer, the local device name is copied to the buffer. + //LocalDrive = 256, + + // If this flag is set, the operating system prompts the user for authentication using the command line instead of a graphical user interface (GUI). This flag is ignored unless is also set. + //CommandLine = 2048, + + /// If this flag is set, and the operating system prompts for a credential, the credential should be saved by the credential manager. If the credential manager is disabled for the caller's logon session, or if the network provider does not support saving credentials, this flag is ignored. This flag is also ignored unless you set the "CommandLine" flag. + SaveCredentialManager = 4096 + } + } +} \ No newline at end of file diff --git a/AlphaFS/Network/Enumerations/DfsNamespaceFlavors.cs b/AlphaFS/Network/Enumerations/DfsNamespaceFlavors.cs new file mode 100644 index 0000000..50959cb --- /dev/null +++ b/AlphaFS/Network/Enumerations/DfsNamespaceFlavors.cs @@ -0,0 +1,55 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// Contains the name and type (domain-based or stand-alone) of a DFS namespace. + /// Minimum supported client: Windows XP with SP1 [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [Flags] + internal enum DfsNamespaceFlavors + { + /// + Unknown = 0, + + /// DFS_VOLUME_FLAVOR_STANDALONE + /// Specifies a stand-alone DFS namespace. + /// + Standalone = 256, + + /// DFS_VOLUME_FLAVOR_AD_BLOB + /// Specifies a domain-based DFS namespace. + /// + AdBlob = 512, + + /// DFS_VOLUME_FLAVORS bitmask (0x00000300) + /// Used to extract the DFS namespace flavor. + /// + All = 768 + } + } +} \ No newline at end of file diff --git a/AlphaFS/Network/Enumerations/DfsPropertyFlags.cs b/AlphaFS/Network/Enumerations/DfsPropertyFlags.cs new file mode 100644 index 0000000..5472f50 --- /dev/null +++ b/AlphaFS/Network/Enumerations/DfsPropertyFlags.cs @@ -0,0 +1,104 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Network +{ + /// A set of bit flags that describe specific properties of a DFS namespace, root, or link. + [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Flags")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [Flags] + public enum DfsPropertyFlags + { + /// No property flag. + None = 0, + + /// DFS_PROPERTY_FLAG_INSITE_REFERRALS + /// + /// Scope: Domain roots, stand-alone roots, and links. + /// If this flag is set at the DFS root, it applies to all links; otherwise, the value of this flag is considered for each individual link. + /// + /// + /// When this flag is set, a DFS referral response from a DFS server for a DFS root or link with the "INSITE" option enabled contains only + /// those targets which are in the same site as the DFS client requesting the referral. + /// Targets in the two global priority classes are always returned, regardless of their site location. + /// + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Insite")] + InsiteReferrals = 1, + + /// DFS_PROPERTY_FLAG_ROOT_SCALABILITY + /// + /// Scope: The entire DFS namespace for a domain-based DFS namespace only. + /// + /// + /// By default, a DFS root target server polls the PDS to detect changes to the DFS metadata. + /// To prevent heavy server load on the PDC, root scalability can be enabled for the DFS namespace. + /// Setting this flag will cause the DFS server to poll the nearest domain controller instead of the PDC for DFS metadata changes for the common namespace. + /// Note that any changes made to the metadata must still occur on the PDC, however. + /// + /// + RootScalability = 2, + + /// DFS_PROPERTY_FLAG_SITE_COSTING + /// + /// Scope: The entire DFS namespace for both domain-based and stand-alone DFS namespaces. + /// + /// + /// By default, targets returned in a referral response from a DFS server to a DFS client for a DFS root or link + /// consists of two groups: targets in the same site as the client, and targets outside the site. + /// + /// + /// If site-costing is enabled for the Active Directory, the response can have more than two groups, + /// with each group containing targets with the same site cost for the specific DFS client requesting the referral. + /// The groups are ordered by increasing site cost. For more information about how site-costing is used to prioritize targets. + /// + /// + SiteCosting = 4, + + /// DFS_PROPERTY_FLAG_TARGET_FAILBACK + /// + /// Scope: Domain-based DFS roots, stand-alone DFS roots, and DFS links. + /// If this flag is set at the DFS root, it applies to all links; otherwise, the value of this flag is considered for each individual link. + /// + /// + /// When this flag is set, optimal target failback is enabled for V4 DFS clients, + /// allowing them to fail back to an optimal target after failing over to a non-optimal one. + /// The target failback setting is provided to the DFS client in a V4 referral response by a DFS server. + /// + /// + TargetFailback = 8, + + /// DFS_PROPERTY_FLAG_CLUSTER_ENABLED + /// Scope: Stand-alone DFS roots and links only. + /// The DFS root is clustered to provide high availability for storage failover. + /// + ClusterEnabled = 16, + + /// DFS_PROPERTY_FLAG_ABDE + /// Scope: Domain-based DFS roots and stand-alone DFS roots. + /// When this flag is set, Access-Based Directory Enumeration (ABDE) mode support is enabled on the entire DFS root target share of the DFS namespace. + /// + AccessBasedDirectoryEnumeration = 32 + } +} diff --git a/AlphaFS/Network/Enumerations/DfsStorageStates.cs b/AlphaFS/Network/Enumerations/DfsStorageStates.cs new file mode 100644 index 0000000..3ddb140 --- /dev/null +++ b/AlphaFS/Network/Enumerations/DfsStorageStates.cs @@ -0,0 +1,51 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Network +{ + /// A set of bit flags that describe the storage state of the DFS root or link target. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [Flags] + public enum DfsStorageStates + { + /// No storage state. + None = 0, + + /// DFS_STORAGE_STATE_OFFLINE + /// The DFS root or link target is offline. + /// + /// Windows Server 2003: The state of a root target cannot be set to DFS_STORAGE_STATE_OFFLINE. + Offline = 1, + + /// DFS_STORAGE_STATE_ONLINE + /// The DFS root or link target is online. + /// + Online = 2, + + /// DFS_STORAGE_STATE_ACTIVE + /// The DFS root or link target is the active target. + /// + Active = 4 + } +} \ No newline at end of file diff --git a/AlphaFS/Network/Enumerations/DfsTargetPriorityClass.cs b/AlphaFS/Network/Enumerations/DfsTargetPriorityClass.cs new file mode 100644 index 0000000..5f456cc --- /dev/null +++ b/AlphaFS/Network/Enumerations/DfsTargetPriorityClass.cs @@ -0,0 +1,54 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Network +{ + /// Defines the set of possible DFS target priority class settings. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + public enum DfsTargetPriorityClass + { + /// The priority class is not valid. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + DfsInvalidPriorityClass = -1, + + /// The middle or "normal" site cost priority class for a DFS target. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + DfsSiteCostNormalPriorityClass = 0, + + /// The highest priority class for a DFS target. Targets assigned this class receive global preference. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + DfsGlobalHighPriorityClass = 1, + + /// The highest site cost priority class for a DFS target. Targets assigned this class receive the most preference among targets of the same site cost for a given DFS client. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + DfsSiteCostHighPriorityClass = 2, + + /// The lowest site cost priority class for a DFS target. Targets assigned this class receive the least preference among targets of the same site cost for a given DFS client. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + DfsSiteCostLowPriorityClass = 3, + + /// The lowest level of priority class for a DFS target. Targets assigned this class receive the least preference globally. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + DfsGlobalLowPriorityClass = 4 + } +} diff --git a/AlphaFS/Network/Enumerations/DfsVolumeStates.cs b/AlphaFS/Network/Enumerations/DfsVolumeStates.cs new file mode 100644 index 0000000..817ddf2 --- /dev/null +++ b/AlphaFS/Network/Enumerations/DfsVolumeStates.cs @@ -0,0 +1,72 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Network +{ + /// A set of bit flags that describe the state of the DFS root or link; + /// the state of the DFS namespace root cannot be changed. + /// One flag is set, and one DFS_VOLUME_FLAVOR flag is set. + /// + [SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [Flags] + public enum DfsVolumeStates + { + /// No volume state. + None = 0, + + /// DFS_VOLUME_STATE_OK + /// The specified DFS root or link is in the normal state. + /// + Ok = 1, + + /// DFS_VOLUME_STATE_INCONSISTENT + /// The internal DFS database is inconsistent with the specified DFS root or link. + /// Attempts to repair the inconsistency have failed. + /// + Inconsistent = 2, + + /// DFS_VOLUME_STATE_OFFLINE + /// The specified DFS root or link is offline or unavailable. + /// + Offline = 3, + + /// DFS_VOLUME_STATE_ONLINE + /// The specified DFS root or link is available. + /// + Online = 4, + + /// DFS_VOLUME_FLAVOR_STANDALONE + /// The system sets this flag if the root is associated with a stand-alone DFS namespace. + /// + /// Windows XP: This value is not supported. + FlavorStandalone = 256, + + /// DFS_VOLUME_FLAVOR_AD_BLOB + /// The system sets this flag if the root is associated with a domain-based DFS namespace. + /// + /// Windows XP: This value is not supported. + FlavorAdBlob = 512 + } +} \ No newline at end of file diff --git a/AlphaFS/Network/Enumerations/ResourceDisplayType.cs b/AlphaFS/Network/Enumerations/ResourceDisplayType.cs new file mode 100644 index 0000000..ef8f047 --- /dev/null +++ b/AlphaFS/Network/Enumerations/ResourceDisplayType.cs @@ -0,0 +1,90 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// The display options for the network object in a network browsing user interface. + internal enum ResourceDisplayType + { + /// RESOURCEDISPLAYTYPE_GENERIC + /// The method used to display the object does not matter. + /// + Generic = 0, + + /// RESOURCEDISPLAYTYPE_DOMAIN + /// The object should be displayed as a domain. + /// + Domain = 1, + + /// RESOURCEDISPLAYTYPE_SERVER + /// The object should be displayed as a server. + /// + Server = 2, + + /// RESOURCEDISPLAYTYPE_SHARE + /// The object should be displayed as a share + /// + Share = 3, + + /// RESOURCEDISPLAYTYPE_FILE + /// The object should be displayed as a file. + /// + File = 4, + + /// RESOURCEDISPLAYTYPE_GROUP + /// The object should be displayed as a group. + /// + Group = 5, + + /// RESOURCEDISPLAYTYPE_NETWORK + /// The object should be displayed as a network. + /// + Network = 6, + + /// RESOURCEDISPLAYTYPE_ROOT + /// The object should be displayed as a logical root for the entire network. + /// + Root = 7, + + /// RESOURCEDISPLAYTYPE_SHAREADMIN + /// The object should be displayed as a administrative share. + /// + ShareAdmin = 8, + + /// RESOURCEDISPLAYTYPE_DIRECTORY + /// The object should be displayed as a directory. + /// + Directory = 9, + + /// RESOURCEDISPLAYTYPE_TREE + /// The object should be displayed as a tree. + /// + Tree = 10, + + /// RESOURCEDISPLAYTYPE_NDSCONTAINER + /// The object should be displayed as a Netware Directory Service container. + /// + NdsContainer = 11 + } + } +} \ No newline at end of file diff --git a/AlphaFS/Network/Enumerations/ResourceScope.cs b/AlphaFS/Network/Enumerations/ResourceScope.cs new file mode 100644 index 0000000..eade41b --- /dev/null +++ b/AlphaFS/Network/Enumerations/ResourceScope.cs @@ -0,0 +1,58 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// NETRESOURCE structure. + /// ResourceScope: The scope of the enumeration. + /// + internal enum ResourceScope + { + /// RESOURCE_CONNECTED + /// Enumerate all currently connected resources. + /// The function ignores the parameter. + /// + Connected = 1, + + /// RESOURCE_GLOBALNET + /// Enumerate all resources on the network. + /// + GlobalNet = 2, + + /// RESOURCE_REMEMBERED + /// Enumerate all remembered (persistent) connections. + /// The function ignores the parameter. + /// + Remembered = 3, + + /// RESOURCE_RECENT + Recent = 4, + + /// RESOURCE_CONTEXT + /// Enumerate only resources in the network context of the caller. Specify this value for a Network Neighborhood view. + /// The function ignores the parameter. + /// + Context = 5 + } + } +} \ No newline at end of file diff --git a/AlphaFS/Network/Enumerations/ResourceType.cs b/AlphaFS/Network/Enumerations/ResourceType.cs new file mode 100644 index 0000000..6e847e6 --- /dev/null +++ b/AlphaFS/Network/Enumerations/ResourceType.cs @@ -0,0 +1,55 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// NETRESOURCE structure. + /// ResourceType: The type of resource. + /// + /// If a network provider cannot distinguish between + /// print and disk resources, it can enumerate all resources. + /// + /// + internal enum ResourceType + { + /// RESOURCETYPE_ANY + /// ResourceType: All resources. + /// + /// If a network provider cannot distinguish between print and disk resources, it can enumerate all resources. + /// This value cannot be combined with or . + /// + /// + Any = 0, + + /// RESOURCETYPE_DISK + /// All disk resources. + /// + Disk = 1, + + /// RESOURCETYPE_PRINT + /// All print resources. + /// + Print = 2, + } + } +} \ No newline at end of file diff --git a/AlphaFS/Network/Enumerations/ResourceUsage.cs b/AlphaFS/Network/Enumerations/ResourceUsage.cs new file mode 100644 index 0000000..a59fd14 --- /dev/null +++ b/AlphaFS/Network/Enumerations/ResourceUsage.cs @@ -0,0 +1,72 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// NETRESOURCE structure. + /// ResourceUsage: A set of bit flags describing how the resource can be used. + /// + /// Note that this member can be specified only if the member is equal to . + [Flags] + internal enum ResourceUsage + { + /// RESOURCEUSAGE_CONNECTABLE + /// The resource is a connectable resource. + /// The name pointed to by the lpRemoteName member can be passed to the WNetAddConnection function to make a network connection. + /// + Connectable = 1, + + /// RESOURCEUSAGE_CONTAINER + /// The resource is a container resource. + /// The name pointed to by the lpRemoteName member can be passed to the WNetAddConnection function to make a network connection. + /// + Container = 2, + + /// RESOURCEUSAGE_NOLOCALDEVICE + /// The resource is not a local device. + /// + NoLocalDevice = 4, + + /// RESOURCEUSAGE_SIBLING + /// The resource is a sibling. + /// This value is not used by Windows. + /// + Sibling = 8, + + /// RESOURCEUSAGE_ATTACHED + /// The resource must be attached. + /// This value specifies that a function to enumerate this resource should fail + /// if the caller is not authenticated, even if the network permits enumeration without authentication. + /// + Attached = 16, + + + /// RESOURCEUSAGE_ALL + /// Setting this value is equivalent to setting: , , and . + /// + All = (Connectable | Container | Attached) + } + } +} \ No newline at end of file diff --git a/AlphaFS/Network/Enumerations/ShareInfoLevel.cs b/AlphaFS/Network/Enumerations/ShareInfoLevel.cs new file mode 100644 index 0000000..d54262c --- /dev/null +++ b/AlphaFS/Network/Enumerations/ShareInfoLevel.cs @@ -0,0 +1,46 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Network +{ + /// The information level. + public enum ShareInfoLevel + { + /// No specific information level used. + None = 0, + + /// Contains information about the shared resource, including the name and type of the resource, and a comment associated with the resource. + Info1 = 1, + + /// Contains information about the shared resource, including the name, type, and permissions of the resource, comments associated with the resource, + /// the maximum number of concurrent connections, the number of current connections, the local path for the resource, and a password for the current connection. + /// + Info2 = 2, + + /// Contains information about the shared resource, including the server name, name of the resource, type, and permissions, + /// the number of connections, and other pertinent information. + /// + Info503 = 503, + + /// Contains information about the shared resource. + Info1005 = 1005, + } +} \ No newline at end of file diff --git a/AlphaFS/Network/Enumerations/ShareResourceTypes.cs b/AlphaFS/Network/Enumerations/ShareResourceTypes.cs new file mode 100644 index 0000000..85ed77f --- /dev/null +++ b/AlphaFS/Network/Enumerations/ShareResourceTypes.cs @@ -0,0 +1,91 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Network +{ + /// Contains information about the shared resource. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + [Flags] + public enum ShareResourceTypes + { + /// No specific resource type used. + None = 0, + + /// SHI1005_FLAGS_DFS + /// The specified share is present in a DFS tree structure. This flag cannot be set with NetShareSetInfo. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + Dfs = 1, + + /// SHI1005_FLAGS_DFS_ROOT + /// The specified share is the root volume in a DFS tree structure. This flag cannot be set with NetShareSetInfo. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + DfsRoot = 2, + + /// SHI1005_FLAGS_RESTRICT_EXCLUSIVE_OPENS + /// The specified share disallows exclusive file opens, where reads to an open file are disallowed. + /// + RestrictExclusiveOpens = 256, + + /// SHI1005_FLAGS_FORCE_SHARED_DELETE + /// Shared files in the specified share can be forcibly deleted. + /// + ForceSharedDelete = 512, + + /// SHI1005_FLAGS_ALLOW_NAMESPACE_CACHING + /// Clients are allowed to cache the namespace of the specified share. + /// + AllowNamespaceCaching = 1024, + + /// SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM + /// The server will filter directory entries based on the access permissions that the user on the client computer has for the server on which the files reside. + /// Only files for which the user has read access and directories for which the user has FILE_LIST_DIRECTORY access will be returned. If the user has SeBackupPrivilege, all available information will be returned. + /// + /// This flag is supported only on servers running Windows Server 2003 with SP1 or later. + AccessBasedDirectoryEnum = 2048, + + /// SHI1005_FLAGS_FORCE_LEVELII_OPLOCK + /// Prevents exclusive caching modes that can cause delays for highly shared read-only data. + /// + /// This flag is supported only on servers running Windows Server 2008 R2 or later. + ForceLevel2OpLock = 4096, + + /// SHI1005_FLAGS_ENABLE_HASH + /// Enables server-side functionality needed for peer caching support. + /// Clients on high-latency or low-bandwidth connections can use alternate methods to retrieve data from peers if available, instead of sending requests to the server. + /// This is only supported on shares configured for manual caching (CSC_CACHE_MANUAL_REINT). + /// This flag is supported only on servers running Windows Server 2008 R2 or later. + EnableHash = 8192, + + /// SHI1005_FLAGS_ENABLE_CA (0X4000) - Enables server-side functionality needed for peer caching support. Clients on high-latency or low-bandwidth connections can use alternate methods to retrieve data from peers if available, instead of sending requests to the server. This is only supported on shares configured for manual caching (CSC_CACHE_MANUAL_REINT). + /// Windows 7, Windows Server 2008 R2, Windows Vista, Windows Server 2008, and Windows Server 2003: This flag is not supported. + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Ca")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ca")] + EnableCa = 16384, + } +} \ No newline at end of file diff --git a/AlphaFS/Network/Enumerations/ShareType.cs b/AlphaFS/Network/Enumerations/ShareType.cs new file mode 100644 index 0000000..a35966f --- /dev/null +++ b/AlphaFS/Network/Enumerations/ShareType.cs @@ -0,0 +1,79 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Network +{ + /// The type of the shared resource. + /// MSDN: 2.2.2.4 Share Types + /// http://msdn.microsoft.com/en-us/library/cc247110.aspx + /// + [SuppressMessage("Microsoft.Naming", "CA1714:FlagsEnumsShouldHavePluralNames")] + [SuppressMessage("Microsoft.Usage", "CA2217:DoNotMarkEnumsWithFlags")] + [SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue")] + [Flags] // Needs Flags attribute to combine attributes. + public enum ShareType + { + /// Disk drive. + DiskTree = 0, + + /// Print queue. + PrintQueue = 1, + + /// Communication device. + Device = 2, + + /// Interprocess communication (IPC). + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ipc")] + Ipc = 3, + + /// A cluster share. + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Fs")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Fs")] + ClusterFs = 33554432, + + /// A Scale-Out cluster share. + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Fs")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Fs")] + ClusterSoFs = 67108864, + + /// A DFS share in a cluster. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + ClusterDfs = 134217728, + + + // The following table of values can be OR'd with the values in the preceding table to further specify the characteristics of a shared resource. + // It is possible to use both values in this OR operation. + + /// Special share reserved for interprocess communication (IPC$) or remote administration of the server (ADMIN$). + /// Can also refer to administrative shares such as C$, D$, E$, and so forth. + /// + Special = -2147483648, + + /// A temporary share that is not persisted for creation each time the file server initializes. + Temporary = 1073741824, + + /// Retriev all known + All = DiskTree | PrintQueue | Device | Ipc | ClusterFs | ClusterSoFs | ClusterDfs | Special | Temporary + } +} diff --git a/AlphaFS/Network/Host Class/Connect.cs b/AlphaFS/Network/Host Class/Connect.cs new file mode 100644 index 0000000..b8805c6 --- /dev/null +++ b/AlphaFS/Network/Host Class/Connect.cs @@ -0,0 +1,507 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Filesystem; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Net; +using System.Net.NetworkInformation; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Network +{ + partial class Host + { + #region ConnectDrive + + /// Creates a connection to a network resource. The function can redirect a local device to a network resource. + /// If is or string.Empty, returns the last available drive letter, otherwise. + /// + /// The name of a local device to be redirected, such as "F:". When is or + /// string.Empty, the last available drive letter will be used. Letters are assigned beginning with Z:, then Y: and so on. + /// + /// The network resource to connect to. The string can be up to MAX_PATH characters in length. + [SecurityCritical] + public static string ConnectDrive(string localName, string remoteName) + { + return ConnectDisconnectCore(new ConnectDisconnectArguments + { + LocalName = localName, + RemoteName = remoteName, + IsDeviceMap = true + }); + } + + /// Creates a connection to a network resource. The function can redirect a local device to a network resource. + /// If is or string.Empty, returns the last available drive letter, null otherwise. + /// + /// The name of a local device to be redirected, such as "F:". When is or + /// string.Empty, the last available drive letter will be used. Letters are assigned beginning with Z:, then Y: and so on. + /// + /// The network resource to connect to. The string can be up to MAX_PATH characters in length. + /// + /// The user name for making the connection. If is , the function uses the default + /// user name. (The user context for the process provides the default user name) + /// + /// + /// The password to be used for making the network connection. If is , the function + /// uses the current default password associated with the user specified by . + /// + /// always pops-up an authentication dialog box. + /// successful network resource connections will be saved. + /// + /// When the operating system prompts for a credential, the credential should be saved by the credential manager when true. + /// + [SecurityCritical] + public static string ConnectDrive(string localName, string remoteName, string userName, string password, bool prompt, bool updateProfile, bool saveCredentials) + { + return ConnectDisconnectCore(new ConnectDisconnectArguments + { + LocalName = localName, + RemoteName = remoteName, + UserName = userName, + Password = password, + Prompt = prompt, + UpdateProfile = updateProfile, + SaveCredentials = saveCredentials, + IsDeviceMap = true + }); + } + + /// Creates a connection to a network resource. The function can redirect a local device to a network resource. + /// If is or string.Empty, returns the last available drive letter, null otherwise. + /// + /// The name of a local device to be redirected, such as "F:". When is or + /// string.Empty, the last available drive letter will be used. Letters are assigned beginning with Z:, then Y: and so on. + /// + /// The network resource to connect to. The string can be up to MAX_PATH characters in length. + /// + /// An instance of which provides credentials for password-based authentication schemes such as basic, + /// digest, NTLM, and Kerberos authentication. + /// + /// always pops-up an authentication dialog box. + /// successful network resource connections will be saved. + /// + /// When the operating system prompts for a credential, the credential should be saved by the credential manager when true. + /// + [SecurityCritical] + public static string ConnectDrive(string localName, string remoteName, NetworkCredential credentials, bool prompt, bool updateProfile, bool saveCredentials) + { + return ConnectDisconnectCore(new ConnectDisconnectArguments + { + LocalName = localName, + RemoteName = remoteName, + Credential = credentials, + Prompt = prompt, + UpdateProfile = updateProfile, + SaveCredentials = saveCredentials, + IsDeviceMap = true + }); + } + + /// Creates a connection to a network resource. The function can redirect a local device to a network resource. + /// If is or string.Empty, returns the last available drive letter, null otherwise. + /// Handle to a window that the provider of network resources can use as an owner window for dialog boxes. + /// + /// The name of a local device to be redirected, such as "F:". When is or + /// string.Empty, the last available drive letter will be used. Letters are assigned beginning with Z:, then Y: and so on. + /// + /// The network resource to connect to. The string can be up to MAX_PATH characters in length. + /// + /// The user name for making the connection. If is , the function uses the default + /// user name. (The user context for the process provides the default user name) + /// + /// + /// The password to be used for making the network connection. If is , the function + /// uses the current default password associated with the user specified by . + /// + /// always pops-up an authentication dialog box. + /// successful network resource connections will be saved. + /// + /// When the operating system prompts for a credential, the credential should be saved by the credential manager when true. + /// + [SecurityCritical] + public static string ConnectDrive(IntPtr winOwner, string localName, string remoteName, string userName, string password, bool prompt, bool updateProfile, bool saveCredentials) + { + return ConnectDisconnectCore(new ConnectDisconnectArguments + { + WinOwner = winOwner, + LocalName = localName, + RemoteName = remoteName, + UserName = userName, + Password = password, + Prompt = prompt, + UpdateProfile = updateProfile, + SaveCredentials = saveCredentials, + IsDeviceMap = true + }); + } + + /// Creates a connection to a network resource. The function can redirect a local device to a network resource. + /// If is or string.Empty, returns the last available drive letter, null otherwise. + /// Handle to a window that the provider of network resources can use as an owner window for dialog boxes. + /// + /// The name of a local device to be redirected, such as "F:". When is or + /// string.Empty, the last available drive letter will be used. Letters are assigned beginning with Z:, then Y: and so on. + /// + /// The network resource to connect to. The string can be up to MAX_PATH characters in length. + /// + /// An instance of which provides credentials for password-based authentication schemes such as basic, + /// digest, NTLM, and Kerberos authentication. + /// + /// always pops-up an authentication dialog box. + /// successful network resource connections will be saved. + /// + /// When the operating system prompts for a credential, the credential should be saved by the credential manager when true. + /// + [SecurityCritical] + public static string ConnectDrive(IntPtr winOwner, string localName, string remoteName, NetworkCredential credentials, bool prompt, bool updateProfile, bool saveCredentials) + { + return ConnectDisconnectCore(new ConnectDisconnectArguments + { + WinOwner = winOwner, + LocalName = localName, + RemoteName = remoteName, + Credential = credentials, + Prompt = prompt, + UpdateProfile = updateProfile, + SaveCredentials = saveCredentials, + IsDeviceMap = true + }); + } + + #endregion // ConnectDrive + + #region ConnectTo + + /// Creates a connection to a network resource. + /// + /// A network resource to connect to, for example: \\server or \\server\share. + [SecurityCritical] + public static void ConnectTo(string remoteName) + { + ConnectDisconnectCore(new ConnectDisconnectArguments { RemoteName = remoteName }); + } + + /// Creates a connection to a network resource. + /// + /// A network resource to connect to, for example: \\server or \\server\share. + /// + /// The user name for making the connection. If is , the function uses the default + /// user name. (The user context for the process provides the default user name) + /// + /// + /// The password to be used for making the network connection. If is , the function + /// uses the current default password associated with the user specified by . + /// + /// always pops-up an authentication dialog box. + /// successful network resource connections will be saved. + /// + /// When the operating system prompts for a credential, the credential should be saved by the credential manager when true. + /// + [SecurityCritical] + public static void ConnectTo(string remoteName, string userName, string password, bool prompt, bool updateProfile, bool saveCredentials) + { + ConnectDisconnectCore(new ConnectDisconnectArguments + { + RemoteName = remoteName, + UserName = userName, + Password = password, + Prompt = prompt, + UpdateProfile = updateProfile, + SaveCredentials = saveCredentials + }); + } + + /// Creates a connection to a network resource. + /// A network resource to connect to, for example: \\server or \\server\share. + /// An instance of which provides credentials for password-based authentication schemes such as basic, digest, NTLM, and Kerberos authentication. + /// always pops-up an authentication dialog box. + /// successful network resource connections will be saved. + /// When the operating system prompts for a credential, the credential should be saved by the credential manager when true. + /// + /// + [SecurityCritical] + public static void ConnectTo(string remoteName, NetworkCredential credentials, bool prompt, bool updateProfile, bool saveCredentials) + { + ConnectDisconnectCore(new ConnectDisconnectArguments + { + RemoteName = remoteName, + Credential = credentials, + Prompt = prompt, + UpdateProfile = updateProfile, + SaveCredentials = saveCredentials + }); + } + + /// Creates a connection to a network resource. + /// + /// Handle to a window that the provider of network resources can use as an owner window for dialog boxes. + /// A network resource to connect to, for example: \\server or \\server\share. + /// + /// The user name for making the connection. If is , the function uses the default + /// user name. (The user context for the process provides the default user name) + /// + /// + /// The password to be used for making the network connection. If is , the function + /// uses the current default password associated with the user specified by . + /// + /// always pops-up an authentication dialog box. + /// successful network resource connections will be saved. + /// When the operating system prompts for a credential, the credential should be saved by the credential manager when true. + [SecurityCritical] + public static void ConnectTo(IntPtr winOwner, string remoteName, string userName, string password, bool prompt, bool updateProfile, bool saveCredentials) + { + ConnectDisconnectCore(new ConnectDisconnectArguments + { + WinOwner = winOwner, + RemoteName = remoteName, + UserName = userName, + Password = password, + Prompt = prompt, + UpdateProfile = updateProfile, + SaveCredentials = saveCredentials + }); + } + + /// Creates a connection to a network resource. + /// + /// Handle to a window that the provider of network resources can use as an owner window for dialog boxes. + /// A network resource to connect to, for example: \\server or \\server\share. + /// An instance of which provides credentials for password-based authentication schemes such as basic, digest, NTLM, and Kerberos authentication. + /// always pops-up an authentication dialog box. + /// successful network resource connections will be saved. + /// When the operating system prompts for a credential, the credential should be saved by the credential manager when true. + [SecurityCritical] + public static void ConnectTo(IntPtr winOwner, string remoteName, NetworkCredential credentials, bool prompt, bool updateProfile, bool saveCredentials) + { + ConnectDisconnectCore(new ConnectDisconnectArguments + { + WinOwner = winOwner, + RemoteName = remoteName, + Credential = credentials, + Prompt = prompt, + UpdateProfile = updateProfile, + SaveCredentials = saveCredentials + }); + } + + #endregion // ConnectTo + + + #region DisconnectDrive + + /// Cancels an existing network connection. You can also call the function to remove remembered network connections that are not currently connected. + /// The name of a local device to be disconnected, such as "F:". + [SecurityCritical] + public static void DisconnectDrive(string localName) + { + ConnectDisconnectCore(new ConnectDisconnectArguments + { + LocalName = localName, + IsDeviceMap = true, + IsDisconnect = true + }); + } + + /// Cancels an existing network connection. You can also call the function to remove remembered network connections that are not currently connected. + /// The name of a local device to be disconnected, such as "F:". + /// + /// Specifies whether the disconnection should occur if there are open files or jobs on the connection. + /// If this parameter is , the function fails if there are open files or jobs. + /// + /// successful removal of network resource connections will be saved. + [SecurityCritical] + public static void DisconnectDrive(string localName, bool force, bool updateProfile) + { + ConnectDisconnectCore(new ConnectDisconnectArguments + { + LocalName = localName, + Prompt = force, + UpdateProfile = updateProfile, + IsDeviceMap = true, + IsDisconnect = true + }); + } + + #endregion // DisconnectDrive + + #region DisconnectFrom + + /// Cancels an existing network connection. You can also call the function to remove remembered network connections that are not currently connected. + /// A network resource to disconnect from, for example: \\server or \\server\share. + [SecurityCritical] + public static void DisconnectFrom(string remoteName) + { + ConnectDisconnectCore(new ConnectDisconnectArguments + { + RemoteName = remoteName, + IsDisconnect = true + }); + } + + /// Cancels an existing network connection. You can also call the function to remove remembered network connections that are not currently connected. + /// A network resource to disconnect from, for example: \\server or \\server\share. + /// + /// Specifies whether the disconnection should occur if there are open files or jobs on the connection. + /// If this parameter is , the function fails if there are open files or jobs. + /// + /// successful removal of network resource connections will be saved. + [SecurityCritical] + public static void DisconnectFrom(string remoteName, bool force, bool updateProfile) + { + ConnectDisconnectCore(new ConnectDisconnectArguments + { + RemoteName = remoteName, + Prompt = force, + UpdateProfile = updateProfile, + IsDisconnect = true + }); + } + + #endregion // DisconnectFrom + + + #region Internal Methods + + /// Connects to/disconnects from a network resource. The function can redirect a local device to a network resource. + /// If is or string.Empty, returns the last available drive letter, null otherwise. + /// + /// + /// The . + [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] + [SecurityCritical] + internal static string ConnectDisconnectCore(ConnectDisconnectArguments arguments) + { + uint lastError; + + // Always remove backslash for local device. + if (!Utils.IsNullOrWhiteSpace(arguments.LocalName)) + arguments.LocalName = Path.RemoveTrailingDirectorySeparator(arguments.LocalName, false).ToUpperInvariant(); + + + #region Disconnect + + if (arguments.IsDisconnect) + { + bool force = arguments.Prompt; // Use value of prompt variable for force value. + string target = arguments.IsDeviceMap ? arguments.LocalName : arguments.RemoteName; + + if (Utils.IsNullOrWhiteSpace(target)) + throw new ArgumentNullException(arguments.IsDeviceMap ? "localName" : "remoteName"); + + lastError = NativeMethods.WNetCancelConnection(target, arguments.UpdateProfile ? NativeMethods.Connect.UpdateProfile : NativeMethods.Connect.None, force); + + if (lastError != Win32Errors.NO_ERROR) + throw new NetworkInformationException((int)lastError); + + return null; + } + + #endregion // Disconnect + + #region Connect + + // arguments.LocalName is allowed to be null or empty. + //if (Utils.IsNullOrWhiteSpace(arguments.LocalName) && !arguments.IsDeviceMap) + // throw new ArgumentNullException("localName"); + + if (Utils.IsNullOrWhiteSpace(arguments.RemoteName) && !arguments.IsDeviceMap) + throw new ArgumentNullException("remoteName"); + + + // When supplied, use data from NetworkCredential instance. + if (arguments.Credential != null) + { + arguments.UserName = Utils.IsNullOrWhiteSpace(arguments.Credential.Domain) + ? arguments.Credential.UserName + : string.Format(CultureInfo.InvariantCulture, @"{0}\{1}", arguments.Credential.Domain, arguments.Credential.UserName); + + arguments.Password = arguments.Credential.Password; + } + + + // Assemble Connect arguments. + var connect = NativeMethods.Connect.None; + + if (arguments.IsDeviceMap) + connect = connect | NativeMethods.Connect.Redirect; + + if (arguments.Prompt) + connect = connect | NativeMethods.Connect.Prompt | NativeMethods.Connect.Interactive; + + if (arguments.UpdateProfile) + connect = connect | NativeMethods.Connect.UpdateProfile; + + if (arguments.SaveCredentials) + connect = connect | NativeMethods.Connect.SaveCredentialManager; + + + // Initialize structure. + var resource = new NativeMethods.NETRESOURCE + { + lpLocalName = arguments.LocalName, + lpRemoteName = arguments.RemoteName, + dwType = NativeMethods.ResourceType.Disk + }; + + // Three characters for: "X:\0" (Drive X: with null terminator) + uint bufferSize = 3; + StringBuilder buffer; + + do + { + buffer = new StringBuilder((int)bufferSize); + + uint result; + lastError = NativeMethods.WNetUseConnection(arguments.WinOwner, ref resource, arguments.Password, arguments.UserName, connect, buffer, out bufferSize, out result); + + switch (lastError) + { + case Win32Errors.NO_ERROR: + break; + + case Win32Errors.ERROR_MORE_DATA: + // MSDN, lpBufferSize: If the call fails because the buffer is not large enough, + // the function returns the required buffer size in this location. + // + // Windows 8 x64: bufferSize remains unchanged. + + bufferSize = bufferSize * 2; + break; + } + + } while (lastError == Win32Errors.ERROR_MORE_DATA); + + + if (lastError != Win32Errors.NO_ERROR) + throw new NetworkInformationException((int)lastError); + + return arguments.IsDeviceMap ? buffer.ToString() : null; + + #endregion // Connect + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Network/Host Class/DistributedFileSystem.cs b/AlphaFS/Network/Host Class/DistributedFileSystem.cs new file mode 100644 index 0000000..c921811 --- /dev/null +++ b/AlphaFS/Network/Host Class/DistributedFileSystem.cs @@ -0,0 +1,294 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Filesystem; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Linq; +using System.Net.NetworkInformation; +using System.Security; + +namespace Alphaleonis.Win32.Network +{ + partial class Host + { + #region EnumerateDfsLinks + + /// Enumerates the DFS Links from a DFS namespace. + /// of DFS namespaces. + /// + /// + /// + /// The Universal Naming Convention (UNC) path of a DFS root or link. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "dfs")] + [SecurityCritical] + public static IEnumerable EnumerateDfsLinks(string dfsName) + { + if (!Filesystem.NativeMethods.IsAtLeastWindowsVista) + throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher); + + if (Utils.IsNullOrWhiteSpace(dfsName)) + throw new ArgumentNullException("dfsName"); + + var fd = new FunctionData(); + + return EnumerateNetworkObjectCore(fd, (NativeMethods.DFS_INFO_9 structure, SafeGlobalMemoryBufferHandle buffer) => + + new DfsInfo(structure), + + (FunctionData functionData, out SafeGlobalMemoryBufferHandle buffer, int prefMaxLen, out uint entriesRead, out uint totalEntries, out uint resumeHandle1) => + { + totalEntries = 0; + return NativeMethods.NetDfsEnum(dfsName, 9, prefMaxLen, out buffer, out entriesRead, out resumeHandle1); + + }, false); + } + + #endregion // EnumerateDfsLinks + + #region EnumerateDfsRoot + + /// Enumerates the DFS namespaces from the local host. + /// of DFS Root namespaces from the local host. + /// + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [SecurityCritical] + public static IEnumerable EnumerateDfsRoot() + { + return EnumerateDfsRootCore(null, false); + } + + /// Enumerates the DFS namespaces from a host. + /// of DFS Root namespaces from a host. + /// + /// + /// The DNS or NetBIOS name of a host. + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [SecurityCritical] + public static IEnumerable EnumerateDfsRoot(string host, bool continueOnException) + { + return EnumerateDfsRootCore(host, continueOnException); + } + + #endregion // EnumerateDfsRoot + + #region EnumerateDomainDfsRoot + + /// Enumerates the DFS namespaces from the domain. + /// of DFS Root namespaces from the domain. + /// + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [SecurityCritical] + public static IEnumerable EnumerateDomainDfsRoot() + { + return EnumerateDomainDfsRootCore(null, false); + } + + /// Enumerates the DFS namespaces from a domain. + /// of DFS Root namespaces from a domain. + /// + /// + /// A domain name. + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [SecurityCritical] + public static IEnumerable EnumerateDomainDfsRoot(string domain, bool continueOnException) + { + return EnumerateDomainDfsRootCore(domain, continueOnException); + } + + #endregion // EnumerateDomainDfsRoot + + + #region GetDfsClientInfo + + /// Gets information about a DFS root or link from the cache maintained by the DFS client. + /// A instance. + /// + /// + /// The Universal Naming Convention (UNC) path of a DFS root or link. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "dfs")] + [SecurityCritical] + public static DfsInfo GetDfsClientInfo(string dfsName) + { + return GetDfsInfoCore(true, dfsName, null, null); + } + + /// Gets information about a DFS root or link from the cache maintained by the DFS client. + /// A instance. + /// + /// + /// The Universal Naming Convention (UNC) path of a DFS root or link. + /// The name of the DFS root target or link target server. + /// The name of the share corresponding to the DFS root target or link target. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "dfs")] + [SecurityCritical] + public static DfsInfo GetDfsClientInfo(string dfsName, string serverName, string shareName) + { + return GetDfsInfoCore(true, dfsName, serverName, shareName); + } + + #endregion // GetDfsClientInfo + + #region GetDfsInfo + + /// Gets information about a specified DFS root or link in a DFS namespace. + /// A instance. + /// + /// + /// The Universal Naming Convention (UNC) path of a DFS root or link. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "dfs")] + [SecurityCritical] + public static DfsInfo GetDfsInfo(string dfsName) + { + return GetDfsInfoCore(false, dfsName, null, null); + } + + #endregion // GetDfsInfo + + + #region Internal Methods + + /// Enumerates the DFS namespaces from a host. + /// of DFS Root namespaces from a host. + /// + /// + /// + /// The DNS or NetBIOS name of a host. + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [SecurityCritical] + private static IEnumerable EnumerateDfsRootCore(string host, bool continueOnException) + { + if (!Filesystem.NativeMethods.IsAtLeastWindowsVista) + throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher); + + return EnumerateNetworkObjectCore(new FunctionData(), (NativeMethods.DFS_INFO_300 structure, SafeGlobalMemoryBufferHandle buffer) => + + new DfsInfo { EntryPath = structure.DfsName }, + + (FunctionData functionData, out SafeGlobalMemoryBufferHandle buffer, int prefMaxLen, out uint entriesRead, out uint totalEntries, out uint resumeHandle) => + { + totalEntries = 0; + + // When host == null, the local computer is used. + // However, the resulting OpenResourceInfo.Host property will be empty. + // So, explicitly state Environment.MachineName to prevent this. + // Furthermore, the UNC prefix: \\ is not required and always removed. + string stripUnc = Utils.IsNullOrWhiteSpace(host) ? Environment.MachineName : Path.GetRegularPathCore(host, GetFullPathOptions.CheckInvalidPathChars, false).Replace(Path.UncPrefix, string.Empty); + + return NativeMethods.NetDfsEnum(stripUnc, 300, prefMaxLen, out buffer, out entriesRead, out resumeHandle); + + }, continueOnException).Select(dfs => dfs.EntryPath); + } + + + /// Enumerates the DFS namespaces from a domain. + /// of DFS Root namespaces from a domain. + /// + /// + /// + /// A domain name. + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [SecurityCritical] + private static IEnumerable EnumerateDomainDfsRootCore(string domain, bool continueOnException) + { + if (!Filesystem.NativeMethods.IsAtLeastWindowsVista) + throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher); + + return EnumerateNetworkObjectCore(new FunctionData(), (NativeMethods.DFS_INFO_200 structure, SafeGlobalMemoryBufferHandle buffer) => + + new DfsInfo { EntryPath = string.Format(CultureInfo.CurrentCulture, "{0}{1}{2}{3}", Path.UncPrefix, NativeMethods.ComputerDomain, Path.DirectorySeparatorChar, structure.FtDfsName) }, + + (FunctionData functionData, out SafeGlobalMemoryBufferHandle buffer, int prefMaxLen, out uint entriesRead, out uint totalEntries, out uint resumeHandle) => + { + totalEntries = 0; + + // When host == null, the local computer is used. + // However, the resulting OpenResourceInfo.Host property will be empty. + // So, explicitly state Environment.MachineName to prevent this. + // Furthermore, the UNC prefix: \\ is not required and always removed. + string stripUnc = Utils.IsNullOrWhiteSpace(domain) ? NativeMethods.ComputerDomain : Path.GetRegularPathCore(domain, GetFullPathOptions.CheckInvalidPathChars, false).Replace(Path.UncPrefix, string.Empty); + + return NativeMethods.NetDfsEnum(stripUnc, 200, prefMaxLen, out buffer, out entriesRead, out resumeHandle); + + }, continueOnException).Select(dfs => dfs.EntryPath); + } + + + /// Retrieves information about a specified DFS root or link in a DFS namespace. + /// A instance. + /// + /// + /// + /// + /// retrieves information about a Distributed File System (DFS) root or link from the cache maintained by the + /// DFS client. When retrieves information about a specified Distributed File System (DFS) root or link in a + /// DFS namespace. + /// + /// The Universal Naming Convention (UNC) path of a DFS root or link. + /// + /// The name of the DFS root target or link target server. If is , this + /// parameter is always . + /// + /// + /// The name of the share corresponding to the DFS root target or link target. If is + /// , this parameter is always . + /// + [SecurityCritical] + private static DfsInfo GetDfsInfoCore(bool getFromClient, string dfsName, string serverName, string shareName) + { + if (!Filesystem.NativeMethods.IsAtLeastWindowsVista) + throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher); + + if (Utils.IsNullOrWhiteSpace(dfsName)) + throw new ArgumentNullException("dfsName"); + + serverName = Utils.IsNullOrWhiteSpace(serverName) ? null : serverName; + shareName = Utils.IsNullOrWhiteSpace(shareName) ? null : shareName; + + SafeGlobalMemoryBufferHandle safeBuffer; + + // Level 9 = DFS_INFO_9 + + uint lastError = getFromClient + ? NativeMethods.NetDfsGetClientInfo(dfsName, serverName, shareName, 9, out safeBuffer) + : NativeMethods.NetDfsGetInfo(dfsName, null, null, 9, out safeBuffer); + + if (lastError == Win32Errors.NERR_Success) + return new DfsInfo(safeBuffer.PtrToStructure(0)); + + throw new NetworkInformationException((int) lastError); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Network/Host Class/DriveConnection.cs b/AlphaFS/Network/Host Class/DriveConnection.cs new file mode 100644 index 0000000..9852203 --- /dev/null +++ b/AlphaFS/Network/Host Class/DriveConnection.cs @@ -0,0 +1,151 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Net; + +namespace Alphaleonis.Win32.Network +{ + /// Used to create a temporary connection to a network resource that will be disconnected once this instance is disposed. + public sealed class DriveConnection : IDisposable + { + #region Constructors + + /// Creates a temporary connection to a network resource. The function can redirect a local device to a network resource, using the current user credentials. + /// The network resource to connect to. The string can be up to MAX_PATH characters in length. + public DriveConnection(string remoteName) + { + Share = remoteName; + + LocalName = Host.ConnectDisconnectCore(new Host.ConnectDisconnectArguments + { + RemoteName = Share, + IsDeviceMap = true + }); + } + + /// Creates a temporary connection to a network resource. The function can redirect a local device to a network resource, using a user name and password. + /// The network resource to connect to. The string can be up to MAX_PATH characters in length. + /// + /// The user name for making the connection. If is , the function uses the default + /// user name. (The user context for the process provides the default user name) + /// + /// + /// The password to be used for making the network connection. If is , the function + /// uses the current default password associated with the user specified by . + /// + /// always pops-up an authentication dialog box. + public DriveConnection(string remoteName, string userName, string password, bool prompt) + { + Share = remoteName; + + LocalName = Host.ConnectDisconnectCore(new Host.ConnectDisconnectArguments + { + RemoteName = Share, + UserName = userName, + Password = password, + Prompt = prompt, + IsDeviceMap = true + }); + } + + /// Creates a temporary connection to a network resource. The function can redirect a local device to a network resource, can be supplied. + /// The network resource to connect to. The string can be up to MAX_PATH characters in length. + /// An instance of which provides credentials for password-based authentication schemes such as basic, digest, NTLM, and Kerberos authentication. + /// always pops-up an authentication dialog box. + public DriveConnection(string remoteName, NetworkCredential credentials, bool prompt) + { + Share = remoteName; + + LocalName = Host.ConnectDisconnectCore(new Host.ConnectDisconnectArguments + { + RemoteName = Share, + Credential = credentials, + Prompt = prompt, + IsDeviceMap = true + }); + } + + /// class destructor. + ~DriveConnection() + { + Dispose(false); + } + + #endregion // Constructors + + #region Methods + + #region Dispose + + /// Releases all resources used by the class. + public void Dispose() + { + GC.SuppressFinalize(this); + Dispose(true); + } + + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "isDisposing")] + private void Dispose(bool isDisposing) + { + if (!Utils.IsNullOrWhiteSpace(LocalName)) + { + Host.ConnectDisconnectCore(new Host.ConnectDisconnectArguments + { + LocalName = LocalName, + Prompt = true, // Use value of prompt variable for force value. + IsDeviceMap = true, + IsDisconnect = true + }); + + LocalName = null; + } + } + + #endregion // Dispose + + #region ToString + + /// Returns the last available drive letter used for this connection. + /// A string that represents this instance. + public override string ToString() + { + return LocalName; + } + + #endregion // ToString + + #endregion // Methods + + #region Properties + + /// The last available drive letter used for this connection. + /// The last available drive letter used for this connection. + public string LocalName { get; private set; } + + /// The path originally specified by the user. + /// The path originally specified by the user. + public string Share { get; private set; } + + #endregion // Properties + } +} diff --git a/AlphaFS/Network/Host Class/EnumerateDrives.cs b/AlphaFS/Network/Host Class/EnumerateDrives.cs new file mode 100644 index 0000000..bb29525 --- /dev/null +++ b/AlphaFS/Network/Host Class/EnumerateDrives.cs @@ -0,0 +1,87 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Filesystem; +using System; +using System.Collections.Generic; +using System.Net.NetworkInformation; +using System.Security; + +namespace Alphaleonis.Win32.Network +{ + partial class Host + { + /// Enumerates drives from the local host. + /// drives from the local host. + /// + [SecurityCritical] + public static IEnumerable EnumerateDrives() + { + return EnumerateDrivesCore(null, false); + } + + /// Enumerates local drives from the specified host. + /// drives from the specified host. + /// + /// The DNS or NetBIOS name of the remote server. refers to the local host. + /// + /// suppress any Exception that might be thrown as a result from a failure, + /// such as unavailable resources. + /// + [SecurityCritical] + public static IEnumerable EnumerateDrives(string host, bool continueOnException) + { + return EnumerateDrivesCore(host, continueOnException); + } + + + + /// Enumerates local drives from the specified host. + /// drives from the specified host. + /// + /// + /// The DNS or NetBIOS name of the remote server. refers to the local host. + /// + /// suppress any Exception that might be thrown as a result from a failure, + /// such as unavailable resources. + /// + [SecurityCritical] + private static IEnumerable EnumerateDrivesCore(string host, bool continueOnException) + { + return EnumerateNetworkObjectCore(new FunctionData { EnumType = 1 }, (string structure, SafeGlobalMemoryBufferHandle buffer) => + + structure, + + (FunctionData functionData, out SafeGlobalMemoryBufferHandle buffer, int prefMaxLen, out uint entriesRead, out uint totalEntries, out uint resume) => + { + // When host == null, the local computer is used. + // However, the resulting OpenResourceInfo.Host property will be empty. + // So, explicitly state Environment.MachineName to prevent this. + // Furthermore, the UNC prefix: \\ is not required and always removed. + + string stripUnc = Utils.IsNullOrWhiteSpace(host) ? Environment.MachineName : Path.GetRegularPathCore(host, GetFullPathOptions.CheckInvalidPathChars, false).Replace(Path.UncPrefix, string.Empty); + + return NativeMethods.NetServerDiskEnum(stripUnc, 0, out buffer, NativeMethods.MaxPreferredLength, out entriesRead, out totalEntries, out resume); + + }, continueOnException); + } + } +} diff --git a/AlphaFS/Network/Host Class/EnumerateOpenResources.cs b/AlphaFS/Network/Host Class/EnumerateOpenResources.cs new file mode 100644 index 0000000..5d911f6 --- /dev/null +++ b/AlphaFS/Network/Host Class/EnumerateOpenResources.cs @@ -0,0 +1,114 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Filesystem; +using System; +using System.Collections.Generic; +using System.Net.NetworkInformation; +using System.Security; + +namespace Alphaleonis.Win32.Network +{ + partial class Host + { + #region EnumerateOpenResources + + /// Enumerates open resources from the local host. + /// open resources from the local host. + /// + /// + [SecurityCritical] + public static IEnumerable EnumerateOpenResources() + { + return EnumerateOpenResourcesCore(null, null, null, false); + } + + /// Enumerates open resources from the specified host. + /// open resources from the specified . + /// + /// + /// The DNS or NetBIOS name of the remote server. refers to the local host. + /// + /// This parameter may be . Enumerates only resources that have the value of the basepath parameter as a prefix. + /// (A prefix is the portion of a path that comes before a backslash.) + /// + /// + /// This parameter may be . The name of the user or the name of the connection; If + /// does not begin with two backslashes ("\\") it indicates the name of the user. If begins with two + /// backslashes ("\\") it indicates the name of the connection. + /// + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + public static IEnumerable EnumerateOpenResources(string host, string basePath, string typeName, bool continueOnException) + { + return EnumerateOpenResourcesCore(host, basePath, typeName, continueOnException); + } + + #endregion // EnumerateOpenResources + + + #region Internal Methods + + /// >Enumerates open resources from the specified host. + /// open resources from the specified . + /// + /// + /// The DNS or NetBIOS name of the remote server. refers to the local host. + /// + /// This parameter may be . Enumerates only resources that have the value of the basepath parameter as a prefix. + /// (A prefix is the portion of a path that comes before a backslash.) + /// + /// + /// This parameter may be . The name of the user or the name of the connection; If + /// does not begin with two backslashes ("\\") it indicates the name of the user. If begins with two + /// backslashes ("\\") it indicates the name of the connection. + /// + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + private static IEnumerable EnumerateOpenResourcesCore(string host, string basePath, string typeName, bool continueOnException) + { + basePath = Utils.IsNullOrWhiteSpace(basePath) ? null : Path.GetRegularPathCore(basePath, GetFullPathOptions.CheckInvalidPathChars, false); + typeName = Utils.IsNullOrWhiteSpace(typeName) ? null : typeName; + + + var fd = new FunctionData { ExtraData1 = basePath, ExtraData2 = typeName }; + + return EnumerateNetworkObjectCore(fd, (NativeMethods.FILE_INFO_3 structure, SafeGlobalMemoryBufferHandle buffer) => + + new OpenResourceInfo(host, structure), + + (FunctionData functionData, out SafeGlobalMemoryBufferHandle buffer, int prefMaxLen, out uint entriesRead, out uint totalEntries, out uint resumeHandle) => + { + // When host == null, the local computer is used. + // However, the resulting OpenResourceInfo.Host property will be empty. + // So, explicitly state Environment.MachineName to prevent this. + // Furthermore, the UNC prefix: \\ is not required and always removed. + string stripUnc = Utils.IsNullOrWhiteSpace(host) ? Environment.MachineName : Path.GetRegularPathCore(host, GetFullPathOptions.CheckInvalidPathChars, false).Replace(Path.UncPrefix, string.Empty); + + return NativeMethods.NetFileEnum(stripUnc, fd.ExtraData1, fd.ExtraData2, 3, out buffer, NativeMethods.MaxPreferredLength, out entriesRead, out totalEntries, out resumeHandle); + + }, + continueOnException); + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Network/Host Class/Host.cs b/AlphaFS/Network/Host Class/Host.cs new file mode 100644 index 0000000..4133b3a --- /dev/null +++ b/AlphaFS/Network/Host Class/Host.cs @@ -0,0 +1,244 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Filesystem; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.IO; +using System.Net; +using System.Net.NetworkInformation; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; +using Path = Alphaleonis.Win32.Filesystem.Path; + +namespace Alphaleonis.Win32.Network +{ + /// Provides static methods to retrieve network resource information from a local- or remote host. + public static partial class Host + { + #region GetUncName + + /// Return the host name in UNC format, for example: \\hostname. + /// The unc name. + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")] + [SecurityCritical] + public static string GetUncName() + { + return string.Format(CultureInfo.InvariantCulture, "{0}{1}", Path.UncPrefix, Environment.MachineName); + } + + /// Return the host name in UNC format, for example: \\hostname. + /// Name of the computer. + /// The unc name. + [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Utils.IsNullOrWhiteSpace validates arguments.")] + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")] + [SecurityCritical] + public static string GetUncName(string computerName) + { + return Utils.IsNullOrWhiteSpace(computerName) + ? GetUncName() + : (computerName.StartsWith(Path.UncPrefix, StringComparison.OrdinalIgnoreCase) + ? computerName.Trim() + : Path.UncPrefix + computerName.Trim()); + } + + #endregion // GetUncName + + #region Internal Methods + + private delegate uint EnumerateNetworkObjectDelegate( + FunctionData functionData, out SafeGlobalMemoryBufferHandle netApiBuffer, [MarshalAs(UnmanagedType.I4)] int prefMaxLen, + [MarshalAs(UnmanagedType.U4)] out uint entriesRead, [MarshalAs(UnmanagedType.U4)] out uint totalEntries, + [MarshalAs(UnmanagedType.U4)] out uint resumeHandle); + + /// Structure is used to pass additional data to the Win32 function. + private struct FunctionData + { + public int EnumType; + public string ExtraData1; + public string ExtraData2; + } + + [SecurityCritical] + private static IEnumerable EnumerateNetworkObjectCore(FunctionData functionData, Func createTStruct, EnumerateNetworkObjectDelegate enumerateNetworkObject, bool continueOnException) + { + Type objectType; + int objectSize; + bool isString; + + switch (functionData.EnumType) + { + // Logical Drives + case 1: + objectType = typeof(IntPtr); + isString = true; + objectSize = Marshal.SizeOf(objectType) + UnicodeEncoding.CharSize; + break; + + default: + objectType = typeof(TNative); + isString = objectType == typeof(string); + objectSize = isString ? 0 : Marshal.SizeOf(objectType); + break; + } + + + uint lastError; + do + { + uint entriesRead; + uint totalEntries; + uint resumeHandle; + SafeGlobalMemoryBufferHandle buffer; + + lastError = enumerateNetworkObject(functionData, out buffer, NativeMethods.MaxPreferredLength, out entriesRead, out totalEntries, out resumeHandle); + + using (buffer) + switch (lastError) + { + case Win32Errors.NERR_Success: + case Win32Errors.ERROR_MORE_DATA: + if (entriesRead > 0) + { + for (int i = 0, itemOffset = 0; i < entriesRead; i++, itemOffset += objectSize) + yield return (TStruct) (isString + ? buffer.PtrToStringUni(itemOffset, 2) + : (object) createTStruct(buffer.PtrToStructure(itemOffset), buffer)); + } + break; + + case Win32Errors.ERROR_BAD_NETPATH: + break; + + // Observed when SHARE_INFO_503 is requested but not supported/possible. + case Win32Errors.RPC_X_BAD_STUB_DATA: + yield break; + } + + } while (lastError == Win32Errors.ERROR_MORE_DATA); + + if (lastError != Win32Errors.NO_ERROR && !continueOnException) + throw new NetworkInformationException((int) lastError); + } + + /// This method uses level to retieve full REMOTE_NAME_INFO structure. + /// A structure. + /// AlphaFS regards network drives created using SUBST.EXE as invalid. + /// + /// + /// + /// + /// The local path with drive name. + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + internal static NativeMethods.REMOTE_NAME_INFO GetRemoteNameInfoCore(string path, bool continueOnException) + { + if (Utils.IsNullOrWhiteSpace(path)) + throw new ArgumentNullException("path"); + + path = Path.GetRegularPathCore(path, GetFullPathOptions.CheckInvalidPathChars, false); + + // If path already is a network share path, we fill the REMOTE_NAME_INFO structure ourselves. + if (Path.IsUncPathCore(path, true, false)) + return new NativeMethods.REMOTE_NAME_INFO + { + lpUniversalName = Path.AddTrailingDirectorySeparator(path, false), + lpConnectionName = Path.RemoveTrailingDirectorySeparator(path, false), + lpRemainingPath = Path.DirectorySeparator + }; + + + uint lastError; + + // Use large enough buffer to prevent a 2nd call. + uint bufferSize = 1024; + + do + { + using (var buffer = new SafeGlobalMemoryBufferHandle((int) bufferSize)) + { + // Structure: UNIVERSAL_NAME_INFO_LEVEL = 1 (not used in AlphaFS). + // Structure: REMOTE_NAME_INFO_LEVEL = 2 + + lastError = NativeMethods.WNetGetUniversalName(path, 2, buffer, out bufferSize); + + switch (lastError) + { + case Win32Errors.NO_ERROR: + return buffer.PtrToStructure(0); + + case Win32Errors.ERROR_MORE_DATA: + //bufferSize = Received the required buffer size, retry. + break; + } + } + + } while (lastError == Win32Errors.ERROR_MORE_DATA); + + if (!continueOnException && lastError != Win32Errors.NO_ERROR) + throw new NetworkInformationException((int) lastError); + + // Return an empty structure (all fields set to null). + return new NativeMethods.REMOTE_NAME_INFO(); + } + + internal struct ConnectDisconnectArguments + { + /// Handle to a window that the provider of network resources can use as an owner window for dialog boxes. + public IntPtr WinOwner; + + /// The name of a local device to be redirected, such as "F:". When is or string.Empty, the last available drive letter will be used. Letters are assigned beginning with Z:, then Y: and so on. + public string LocalName; + + /// A network resource to connect to/disconnect from, for example: \\server or \\server\share + public string RemoteName; + + /// A instance. Use either this or the combination of and . + public NetworkCredential Credential; + + /// The user name for making the connection. If is , the function uses the default user name. (The user context for the process provides the default user name) + public string UserName; + + /// The password to be used for making the network connection. If is , the function uses the current default password associated with the user specified by . + public string Password; + + /// always pops-up an authentication dialog box. + public bool Prompt; + + /// successful network resource connections will be saved. + public bool UpdateProfile; + + /// When the operating system prompts for a credential, the credential should be saved by the credential manager when true. + public bool SaveCredentials; + + /// indicates that the operation concerns a drive mapping. + public bool IsDeviceMap; + + /// indicates that the operation needs to disconnect from the network resource, otherwise connect. + public bool IsDisconnect; + } + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Network/Host Class/ServerMessageBlock.cs b/AlphaFS/Network/Host Class/ServerMessageBlock.cs new file mode 100644 index 0000000..5ece5ed --- /dev/null +++ b/AlphaFS/Network/Host Class/ServerMessageBlock.cs @@ -0,0 +1,395 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Filesystem; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Linq; +using System.Net.NetworkInformation; +using System.Security; + +namespace Alphaleonis.Win32.Network +{ + partial class Host + { + #region EnumerateOpenConnections + + /// Enumerates open connections from the local host. + /// connection information from the local host. + /// + /// + [SecurityCritical] + public static IEnumerable EnumerateOpenConnections() + { + return EnumerateOpenConnectionsCore(null, null, false); + } + + /// Enumerates open connections from the specified host. + /// connection information from the specified . + /// + /// + /// The DNS or NetBIOS name of the remote server. refers to the local host. + /// The name of the Server Message Block (SMB) share. + /// + /// suppress any Exception that might be thrown as a result from a failure, + /// such as unavailable resources. + /// + [SecurityCritical] + public static IEnumerable EnumerateOpenConnections(string host, string share, bool continueOnException) + { + return EnumerateOpenConnectionsCore(host, share, continueOnException); + } + + #endregion // EnumerateOpenConnections + + #region EnumerateShares + + /// Enumerates Server Message Block (SMB) shares from the local host. + /// shares from the specified host. + /// This method also enumerates hidden shares. + [SecurityCritical] + public static IEnumerable EnumerateShares() + { + return EnumerateSharesCore(null, ShareType.All, false); + } + + /// Enumerates Server Message Block (SMB) shares from the local host. + /// shares from the specified host. + /// This method also enumerates hidden shares. + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + public static IEnumerable EnumerateShares(bool continueOnException) + { + return EnumerateSharesCore(null, ShareType.All, continueOnException); + } + + /// Enumerates Server Message Block (SMB) shares from the local host. + /// shares from the specified host. + /// This method also enumerates hidden shares. + /// The type of the shared resource to retrieve. + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + public static IEnumerable EnumerateShares(ShareType shareType, bool continueOnException) + { + return EnumerateSharesCore(null, shareType, continueOnException); + } + + /// Enumerates Server Message Block (SMB) shares from the specified . + /// shares from the specified host. + /// This method also enumerates hidden shares. + /// The DNS or NetBIOS name of the specified host. + [SecurityCritical] + public static IEnumerable EnumerateShares(string host) + { + return EnumerateSharesCore(host, ShareType.All, false); + } + + /// Enumerates Server Message Block (SMB) shares from the specified . + /// shares from the specified host. + /// This method also enumerates hidden shares. + /// The DNS or NetBIOS name of the specified host. + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + public static IEnumerable EnumerateShares(string host, bool continueOnException) + { + return EnumerateSharesCore(host, ShareType.All, continueOnException); + } + + /// Enumerates Server Message Block (SMB) shares from the specified . + /// shares from the specified host. + /// This method also enumerates hidden shares. + /// The DNS or NetBIOS name of the specified host. + /// The type of the shared resource to retrieve. + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + public static IEnumerable EnumerateShares(string host, ShareType shareType, bool continueOnException) + { + return EnumerateSharesCore(host, shareType, continueOnException); + } + + #endregion // EnumerateShares + + #region GetHostShareFromPath + + /// Gets the host and share path name for the given . + /// The share in the format: \\host\share. + /// The host and share path. For example, if is: "\\SERVER001\C$\WINDOWS\System32", + /// its is returned as string[0] = "SERVER001" and string[1] = "\C$\WINDOWS\System32". + /// If the conversion from local path to UNC path fails, is returned. + /// + [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Utils.IsNullOrWhiteSpace validates arguments.")] + [SecurityCritical] + public static string[] GetHostShareFromPath(string uncPath) + { + if (Utils.IsNullOrWhiteSpace(uncPath)) + return null; + + Uri uri; + if (Uri.TryCreate(Path.GetRegularPathCore(uncPath, GetFullPathOptions.None, false), UriKind.Absolute, out uri) && uri.IsUnc) + { + return new[] + { + uri.Host, + uri.AbsolutePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar) + }; + } + + return null; + } + + #endregion // GetHostShareFromPath + + #region GetShareInfo + + /// Retrieves information about the Server Message Block (SMB) share as defined on the specified host. + /// A class, or on failure or when not available, and is . + /// The share in the format: \\host\share. + /// to suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + public static ShareInfo GetShareInfo(string uncPath, bool continueOnException) + { + string[] unc = GetHostShareFromPath(uncPath); + return GetShareInfoCore(ShareInfoLevel.Info503, unc[0], unc[1], continueOnException); + } + + /// Retrieves information about the Server Message Block (SMB) share as defined on the specified host. + /// A class, or on failure or when not available, and is . + /// One of the options. + /// The share in the format: \\host\share. + /// to suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + public static ShareInfo GetShareInfo(ShareInfoLevel shareLevel, string uncPath, bool continueOnException) + { + string[] unc = GetHostShareFromPath(uncPath); + return GetShareInfoCore(shareLevel, unc[0], unc[1], continueOnException); + } + + /// Retrieves information about the Server Message Block (SMB) share as defined on the specified host. + /// A class, or on failure or when not available, and is . + /// The DNS or NetBIOS name of the specified host. + /// The name of the Server Message Block (SMB) share. + /// to suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + public static ShareInfo GetShareInfo(string host, string share, bool continueOnException) + { + return GetShareInfoCore(ShareInfoLevel.Info503, host, share, continueOnException); + } + + /// Retrieves information about the Server Message Block (SMB) share as defined on the specified host. + /// A class, or on failure or when not available, and is . + /// One of the options. + /// A string that specifies the DNS or NetBIOS name of the specified . + /// A string that specifies the name of the Server Message Block (SMB) share. + /// to suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + public static ShareInfo GetShareInfo(ShareInfoLevel shareLevel, string host, string share, bool continueOnException) + { + return GetShareInfoCore(shareLevel, host, share, continueOnException); + } + + #endregion // GetShareInfo + + #region Internal Methods + + #region EnumerateOpenConnectionsCore + + /// Enumerates open connections from the specified host. + /// connection information from the specified . + /// + /// + /// The DNS or NetBIOS name of the remote server. refers to the local host. + /// The name of the Server Message Block (SMB) share. + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + private static IEnumerable EnumerateOpenConnectionsCore(string host, string share, bool continueOnException) + { + if (Utils.IsNullOrWhiteSpace(share)) + throw new ArgumentNullException("share"); + + return EnumerateNetworkObjectCore(new FunctionData { ExtraData1 = share }, (NativeMethods.CONNECTION_INFO_1 structure, SafeGlobalMemoryBufferHandle buffer) => + + new OpenConnectionInfo(host, structure), + + (FunctionData functionData, out SafeGlobalMemoryBufferHandle buffer, int prefMaxLen, out uint entriesRead, out uint totalEntries, out uint resumeHandle) => + { + // When host == null, the local computer is used. + // However, the resulting OpenResourceInfo.Host property will be empty. + // So, explicitly state Environment.MachineName to prevent this. + // Furthermore, the UNC prefix: \\ is not required and always removed. + string stripUnc = Utils.IsNullOrWhiteSpace(host) ? Environment.MachineName : Path.GetRegularPathCore(host, GetFullPathOptions.CheckInvalidPathChars, false).Replace(Path.UncPrefix, string.Empty); + + return NativeMethods.NetConnectionEnum(stripUnc, functionData.ExtraData1, 1, out buffer, NativeMethods.MaxPreferredLength, out entriesRead, out totalEntries, out resumeHandle); + + }, + continueOnException); + } + + #endregion // EnumerateOpenConnectionsCore + + #region EnumerateSharesCore + + /// Enumerates Server Message Block (SMB) shares from a local or remote host. + /// shares from the specified host. + /// This method also enumerates hidden shares. + /// + /// + /// The DNS or NetBIOS name of the specified host. + /// The type of the shared resource to retrieve. + /// suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + internal static IEnumerable EnumerateSharesCore(string host, ShareType shareType, bool continueOnException) + { + // When host == null, the local computer is used. + // However, the resulting OpenResourceInfo.Host property will be empty. + // So, explicitly state Environment.MachineName to prevent this. + // Furthermore, the UNC prefix: \\ is not required and always removed. + string stripUnc = Utils.IsNullOrWhiteSpace(host) + ? Environment.MachineName + : Path.GetRegularPathCore(host, GetFullPathOptions.CheckInvalidPathChars, false).Replace(Path.UncPrefix, string.Empty); + + var fd = new FunctionData(); + bool hasItems = false; + bool yieldAll = shareType == ShareType.All; + + // Try SHARE_INFO_503 structure. + foreach (var si in EnumerateNetworkObjectCore(fd, (NativeMethods.SHARE_INFO_503 structure, SafeGlobalMemoryBufferHandle buffer) => + new ShareInfo(stripUnc, ShareInfoLevel.Info503, structure), + (FunctionData functionData, out SafeGlobalMemoryBufferHandle buffer, int prefMaxLen, out uint entriesRead, out uint totalEntries, out uint resumeHandle) => + NativeMethods.NetShareEnum(stripUnc, 503, out buffer, NativeMethods.MaxPreferredLength, out entriesRead, out totalEntries, out resumeHandle), continueOnException).Where(si => yieldAll || si.ShareType == shareType)) + { + yield return si; + hasItems = true; + } + + // SHARE_INFO_503 is requested, but not supported/possible. + // Try again with SHARE_INFO_2 structure. + if (!hasItems) + foreach (var si in EnumerateNetworkObjectCore(fd, (NativeMethods.SHARE_INFO_2 structure, SafeGlobalMemoryBufferHandle buffer) => + new ShareInfo(stripUnc, ShareInfoLevel.Info2, structure), + (FunctionData functionData, out SafeGlobalMemoryBufferHandle buffer, int prefMaxLen, out uint entriesRead, out uint totalEntries, out uint resumeHandle) => + NativeMethods.NetShareEnum(stripUnc, 2, out buffer, NativeMethods.MaxPreferredLength, out entriesRead, out totalEntries, out resumeHandle), continueOnException).Where(si => yieldAll || si.ShareType == shareType)) + { + yield return si; + hasItems = true; + } + + // SHARE_INFO_2 is requested, but not supported/possible. + // Try again with SHARE_INFO_1 structure. + if (!hasItems) + foreach (var si in EnumerateNetworkObjectCore(fd, (NativeMethods.SHARE_INFO_1 structure, SafeGlobalMemoryBufferHandle buffer) => + new ShareInfo(stripUnc, ShareInfoLevel.Info1, structure), + (FunctionData functionData, out SafeGlobalMemoryBufferHandle buffer, int prefMaxLen, out uint entriesRead, out uint totalEntries, out uint resumeHandle) => + NativeMethods.NetShareEnum(stripUnc, 1, out buffer, NativeMethods.MaxPreferredLength, out entriesRead, out totalEntries, out resumeHandle), continueOnException).Where(si => yieldAll || si.ShareType == shareType)) + { + yield return si; + } + } + + #endregion // EnumerateSharesCore + + #region GetShareInfoCore + + /// Gets the structure of a Server Message Block (SMB) share. + /// A class, or on failure or when not available, and is . + /// + /// One of the options. + /// A string that specifies the DNS or NetBIOS name of the specified . + /// A string that specifies the name of the Server Message Block (SMB) share. + /// to suppress any Exception that might be thrown as a result from a failure, such as unavailable resources. + [SecurityCritical] + internal static ShareInfo GetShareInfoCore(ShareInfoLevel shareLevel, string host, string share, bool continueOnException) + { + if (Utils.IsNullOrWhiteSpace(share)) + return null; + + // When host == null, the local computer is used. + // However, the resulting OpenResourceInfo.Host property will be empty. + // So, explicitly state Environment.MachineName to prevent this. + // Furthermore, the UNC prefix: \\ is not required and always removed. + string stripUnc = Utils.IsNullOrWhiteSpace(host) + ? Environment.MachineName + : Path.GetRegularPathCore(host, GetFullPathOptions.CheckInvalidPathChars, false).Replace(Path.UncPrefix, string.Empty); + + bool fallback = false; + + + startNetShareGetInfo: + + SafeGlobalMemoryBufferHandle safeBuffer; + + uint structureLevel = Convert.ToUInt16(shareLevel, CultureInfo.InvariantCulture); + uint lastError = NativeMethods.NetShareGetInfo(stripUnc, share, structureLevel, out safeBuffer); + + using (safeBuffer) + { + switch (lastError) + { + case Win32Errors.NERR_Success: + switch (shareLevel) + { + case ShareInfoLevel.Info1005: + return new ShareInfo(stripUnc, shareLevel, safeBuffer.PtrToStructure(0)) + { + NetFullPath = Path.CombineCore(false, Path.UncPrefix + stripUnc, share) + }; + + case ShareInfoLevel.Info503: + return new ShareInfo(stripUnc, shareLevel, safeBuffer.PtrToStructure(0)); + + case ShareInfoLevel.Info2: + return new ShareInfo(stripUnc, shareLevel, safeBuffer.PtrToStructure(0)); + + case ShareInfoLevel.Info1: + return new ShareInfo(stripUnc, shareLevel, safeBuffer.PtrToStructure(0)); + } + break; + + + // Observed when SHARE_INFO_503 is requested, but not supported/possible. + // Fall back on SHARE_INFO_2 structure and try again. + case Win32Errors.RPC_X_BAD_STUB_DATA: + + case Win32Errors.ERROR_ACCESS_DENIED: + if (!fallback && shareLevel != ShareInfoLevel.Info2) + { + shareLevel = ShareInfoLevel.Info2; + fallback = true; + goto startNetShareGetInfo; + } + break; + + default: + if (!continueOnException) + throw new NetworkInformationException((int) lastError); + break; + } + + return null; + } + } + + #endregion // GetShareInfoCore + + #endregion // Internal Methods + } +} diff --git a/AlphaFS/Network/Native Methods/NativeMethods.DistributedFileSystem.cs b/AlphaFS/Network/Native Methods/NativeMethods.DistributedFileSystem.cs new file mode 100644 index 0000000..9ea02a1 --- /dev/null +++ b/AlphaFS/Network/Native Methods/NativeMethods.DistributedFileSystem.cs @@ -0,0 +1,78 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// Enumerates the Distributed File System (DFS) namespaces hosted on a server or DFS links of a namespace hosted by a server. + /// + /// If the function succeeds, the return value is NERR_Success. + /// If the function fails, the return value is a system error code. + /// + /// + /// No special group membership is required for using the NetDfsEnum function. + /// Minimum supported client: Windows Vista + /// Minimum supported server: Windows Server 2003 + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint NetDfsEnum([MarshalAs(UnmanagedType.LPWStr)] string dfsName, [MarshalAs(UnmanagedType.U4)] uint level, [MarshalAs(UnmanagedType.U4)] int prefMaxLen, out SafeGlobalMemoryBufferHandle buffer, [MarshalAs(UnmanagedType.U4)] out uint entriesRead, [MarshalAs(UnmanagedType.U4)] out uint resumeHandle); + + + /// Retrieves information about a Distributed File System (DFS) root or link from the cache maintained by the DFS client. + /// + /// If the function succeeds, the return value is NERR_Success. + /// If the function fails, the return value is a system error code. + /// + /// + /// No special group membership is required for using the NetDfsGetClientInfo function. + /// Minimum supported client: Windows Vista + /// Minimum supported server: Windows Server 2003 + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint NetDfsGetClientInfo([MarshalAs(UnmanagedType.LPWStr)] string dfsEntryPath, [MarshalAs(UnmanagedType.LPWStr)] string serverName, [MarshalAs(UnmanagedType.LPWStr)] string shareName, [MarshalAs(UnmanagedType.U4)] uint level, out SafeGlobalMemoryBufferHandle buffer); + + + /// Retrieves information about a specified Distributed File System (DFS) root or link in a DFS namespace. + /// + /// If the function succeeds, the return value is NERR_Success. + /// If the function fails, the return value is a system error code. + /// + /// + /// No special group membership is required for using the NetDfsGetInfo function. + /// Minimum supported client: Windows Vista + /// Minimum supported server: Windows Server 2003 + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint NetDfsGetInfo([MarshalAs(UnmanagedType.LPWStr)] string dfsEntryPath, [MarshalAs(UnmanagedType.LPWStr)] string serverName, [MarshalAs(UnmanagedType.LPWStr)] string shareName, [MarshalAs(UnmanagedType.U4)] uint level, out SafeGlobalMemoryBufferHandle buffer); + } +} diff --git a/AlphaFS/Network/Native Methods/NativeMethods.NetworkManagement.cs b/AlphaFS/Network/Native Methods/NativeMethods.NetworkManagement.cs new file mode 100644 index 0000000..9c4408a --- /dev/null +++ b/AlphaFS/Network/Native Methods/NativeMethods.NetworkManagement.cs @@ -0,0 +1,46 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Network +{ + partial class NativeMethods + { + /// The NetServerDiskEnum function retrieves a list of disk drives on a server. + /// + /// If the function succeeds, the return value is NERR_Success. + /// If the function fails, the return value is a system error code. + /// + /// + /// The function returns an array of three-character strings (a drive letter, a colon, and a terminating null character). + /// Only members of the Administrators or Server Operators local group can successfully execute the NetServerDiskEnum function on a remote computer. + /// Minimum supported client: Windows 2000 Professional [desktop apps only] + /// Minimum supported server: Windows 2000 Server [desktop apps only] + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint NetServerDiskEnum([MarshalAs(UnmanagedType.LPWStr)] string serverName, [MarshalAs(UnmanagedType.U4)] uint level, out SafeGlobalMemoryBufferHandle bufPtr, [MarshalAs(UnmanagedType.I4)] int prefMaxLen, [MarshalAs(UnmanagedType.U4)] out uint entriesRead, [MarshalAs(UnmanagedType.U4)] out uint totalEntries, [MarshalAs(UnmanagedType.U4)] out uint resumeHandle); + } +} diff --git a/AlphaFS/Network/Native Methods/NativeMethods.NetworkShareManagement.cs b/AlphaFS/Network/Native Methods/NativeMethods.NetworkShareManagement.cs new file mode 100644 index 0000000..f236f0a --- /dev/null +++ b/AlphaFS/Network/Native Methods/NativeMethods.NetworkShareManagement.cs @@ -0,0 +1,117 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32.Network +{ + partial class NativeMethods + { + /// Lists all connections made to a shared resource on the server or all connections established from a particular computer. + /// + /// If the function succeeds, the return value is NERR_Success. + /// If the function fails, the return value is a system error code. + /// + /// + /// If there is more than one user using this connection, then it is possible to get more than one structure for the same connection, but with a different user name. + /// Administrator, Server or Print Operator, or Power User group membership is required to successfully execute the NetConnectionEnum function. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint NetConnectionEnum([MarshalAs(UnmanagedType.LPWStr)] string serverName, [MarshalAs(UnmanagedType.LPWStr)] string qualifier, [MarshalAs(UnmanagedType.U4)] uint level, out SafeGlobalMemoryBufferHandle bufPtr, [MarshalAs(UnmanagedType.I4)] int prefMaxLen, [MarshalAs(UnmanagedType.U4)] out uint entriesRead, [MarshalAs(UnmanagedType.U4)] out uint totalEntries, [MarshalAs(UnmanagedType.U4)] out uint resumeHandle); + + + /// Forces a resource to close. This function can be used when an error prevents closure by any other means. + /// + /// If the function succeeds, the return value is NERR_Success. + /// If the function fails, the return value is a system error code. + /// + /// + /// You should use NetFileClose with caution because it does not write data cached on the client system to the file before closing the file. + /// Only members of the Administrators or Server Operators local group can successfully execute the NetFileEnum function. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint NetFileClose([MarshalAs(UnmanagedType.LPWStr)] string serverName, [MarshalAs(UnmanagedType.U4)] uint fileid); + + + /// Returns information about some or all open files on a server, depending on the parameters specified. + /// + /// If the function succeeds, the return value is NERR_Success. + /// If the function fails, the return value is a system error code. + /// + /// + /// Only members of the Administrators or Server Operators local group can successfully execute the NetFileEnum function. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint NetFileEnum([MarshalAs(UnmanagedType.LPWStr)] string serverName, [MarshalAs(UnmanagedType.LPWStr)] string basepath, [MarshalAs(UnmanagedType.LPWStr)] string username, [MarshalAs(UnmanagedType.U4)] uint level, out SafeGlobalMemoryBufferHandle buffer, [MarshalAs(UnmanagedType.I4)] int prefmaxlen, [MarshalAs(UnmanagedType.U4)] out uint entriesRead, [MarshalAs(UnmanagedType.U4)] out uint totalentries, [MarshalAs(UnmanagedType.U4)] out uint resumeHandle); + + + /// Retrieves information about each (hidden) Server Message Block (SMB) resource/share on a server. + /// + /// If the function succeeds, the return value is NERR_Success. + /// If the function fails, the return value is a system error code. + /// + /// + /// For interactive users (users who are logged on locally to the machine), no special group membership is required to execute the NetShareEnum function. + /// For non-interactive users, Administrator, Power User, Print Operator, or Server Operator group membership is required to successfully execute the NetShareEnum function at levels 2, 502, and 503. No special group membership is required for level 0 or level 1 calls. + /// This function applies only to Server Message Block (SMB) shares. + /// Windows Server 2003 and Windows XP: For all users, Administrator, Power User, Print Operator, or Server Operator group membership is required to successfully execute the NetShareEnum function at levels 2 and 502. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint NetShareEnum([MarshalAs(UnmanagedType.LPWStr)] string serverName, [MarshalAs(UnmanagedType.U4)] uint level, out SafeGlobalMemoryBufferHandle bufPtr, [MarshalAs(UnmanagedType.I4)] int prefMaxLen, [MarshalAs(UnmanagedType.U4)] out uint entriesRead, [MarshalAs(UnmanagedType.U4)] out uint totalEntries, [MarshalAs(UnmanagedType.U4)] out uint resumeHandle); + + + /// Retrieves information about a particular Server Message Block (SMB) shared resource on a server. + /// + /// If the function succeeds, the return value is NERR_Success. + /// If the function fails, the return value is a system error code. + /// + /// + /// For interactive users (users who are logged on locally to the machine), no special group membership is required to execute the NetShareGetInfo function. + /// For non-interactive users, Administrator, Power User, Print Operator, or Server Operator group membership is required to successfully execute the NetShareGetInfo function at levels 2, 502, and 503. + /// This function applies only to Server Message Block (SMB) shares. + /// Windows Server 2003 and Windows XP: For all users, Administrator, Power User, Print Operator, or Server Operator group membership is required to successfully execute the NetShareGetInfo function at levels 2 and 502. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint NetShareGetInfo([MarshalAs(UnmanagedType.LPWStr)] string serverName, [MarshalAs(UnmanagedType.LPWStr)] string netName, [MarshalAs(UnmanagedType.U4)] uint level, out SafeGlobalMemoryBufferHandle lpBuffer); + } +} diff --git a/AlphaFS/Network/Native Methods/NativeMethods.WindowsNetworking.cs b/AlphaFS/Network/Native Methods/NativeMethods.WindowsNetworking.cs new file mode 100644 index 0000000..2658f27 --- /dev/null +++ b/AlphaFS/Network/Native Methods/NativeMethods.WindowsNetworking.cs @@ -0,0 +1,78 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Network +{ + partial class NativeMethods + { + /// The WNetCancelConnection function cancels an existing network connection. You can also call the function to remove remembered network connections that are not currently connected. + /// + /// If the function succeeds, the return value is + /// If the function fails, the return value is a system error code. + /// + /// + /// Minimum supported client: Windows 2000 Professional [desktop apps only] + /// Minimum supported server: Windows 2000 Server [desktop apps only] + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("mpr.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "WNetCancelConnection2W"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint WNetCancelConnection([MarshalAs(UnmanagedType.LPWStr)] string lpName, Connect dwFlags, [MarshalAs(UnmanagedType.Bool)] bool fForce); + + + /// The WNetGetUniversalName function takes a drive-based path for a network resource and returns an information structure that contains a more universal form of the name. + /// + /// If the function succeeds, the return value is + /// If the function fails, the return value is a system error code. + /// + /// + /// Minimum supported client: Windows 2000 Professional [desktop apps only] + /// Minimum supported server: Windows 2000 Server [desktop apps only] + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("mpr.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "WNetGetUniversalNameW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint WNetGetUniversalName([MarshalAs(UnmanagedType.LPWStr)] string lpLocalPath, [MarshalAs(UnmanagedType.U4)] uint dwInfoLevel, SafeGlobalMemoryBufferHandle lpBuffer, [MarshalAs(UnmanagedType.U4)] out uint lpBufferSize); + + + /// The WNetUseConnection function creates a connection to a network resource. The function can redirect a local device to a network resource. + /// + /// If the function succeeds, the return value is + /// If the function fails, the return value is a system error code. + /// + /// + /// Minimum supported client: Windows 2000 Professional [desktop apps only] + /// Minimum supported server: Windows 2000 Server [desktop apps only] + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("mpr.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "WNetUseConnectionW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint WNetUseConnection(IntPtr hwndOwner, [MarshalAs(UnmanagedType.Struct)] ref NETRESOURCE lpNetResource, [MarshalAs(UnmanagedType.LPWStr)] string lpPassword, [MarshalAs(UnmanagedType.LPWStr)] string lpUserId, [MarshalAs(UnmanagedType.U4)] Connect dwFlags, StringBuilder lpAccessName, [MarshalAs(UnmanagedType.U4)] out uint lpBufferSize, [MarshalAs(UnmanagedType.U4)] out uint lpResult); + + // Note: When NETRESOURCE is struct: use ref, when NETRESOURCE is class: ommit ref. + } +} diff --git a/AlphaFS/Network/Native Methods/NativeMethods.cs b/AlphaFS/Network/Native Methods/NativeMethods.cs new file mode 100644 index 0000000..4cb9315 --- /dev/null +++ b/AlphaFS/Network/Native Methods/NativeMethods.cs @@ -0,0 +1,66 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Net; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + #region Constants + + /// A constant of type DWORD that is set to –1. This value is valid as an input parameter to any method in section 3.1.4 that takes a PreferedMaximumLength parameter. When specified as an input parameter, this value indicates that the method MUST allocate as much space as the data requires. + /// MSDN "2.2.2.2 MAX_PREFERRED_LENGTH": http://msdn.microsoft.com/en-us/library/cc247107.aspx + internal const int MaxPreferredLength = -1; + + #endregion // Constants + + #region GetComputerDomain + + internal static readonly string ComputerDomain = GetComputerDomain(); + + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + private static string GetComputerDomain(bool fdqn = false) + { + string domain = Environment.UserDomainName; + string machine = Environment.MachineName.ToUpper(CultureInfo.InvariantCulture); + + try + { + if (fdqn) + { + domain = Dns.GetHostEntry("LocalHost").HostName.ToUpper(CultureInfo.InvariantCulture).Replace(machine + ".", string.Empty); + domain = domain.Replace(machine, string.Empty); + } + } + catch + { + } + + return domain; + } + + #endregion // GetComputerDomain + } +} \ No newline at end of file diff --git a/AlphaFS/Network/Native Structures/CONNECTION_INFO_1.cs b/AlphaFS/Network/Native Structures/CONNECTION_INFO_1.cs new file mode 100644 index 0000000..35343b5 --- /dev/null +++ b/AlphaFS/Network/Native Structures/CONNECTION_INFO_1.cs @@ -0,0 +1,57 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// Contains the identification number of a connection, number of open files, connection time, number of users on the connection, and the type of connection. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct CONNECTION_INFO_1 + { + /// Specifies a connection identification number. + [MarshalAs(UnmanagedType.U4)] public readonly uint coni1_id; + + /// A combination of values that specify the type of connection made from the local device name to the shared resource. + [MarshalAs(UnmanagedType.U4)] public readonly ShareType coni1_type; + + /// Specifies the number of files currently open as a result of the connection. + [MarshalAs(UnmanagedType.U4)] public readonly uint coni1_num_opens; + + /// Specifies the number of users on the connection. + [MarshalAs(UnmanagedType.U4)] public readonly uint coni1_num_users; + + /// Specifies the number of seconds that the connection has been established. + [MarshalAs(UnmanagedType.U4)] public readonly uint coni1_time; + + /// If the server sharing the resource is running with user-level security, the UserName member describes which user made the connection. If the server is running with share-level security, coni1_username describes which computer (computername) made the connection. + /// Note that Windows does not support share-level security. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string coni1_username; + + /// String that specifies either the share name of the server's shared resource or the computername of the client. The value of this member depends on which name was specified as the qualifier parameter to the NetConnectionEnum function. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string oni1_netname; + } + } +} diff --git a/AlphaFS/Network/Native Structures/DFS_INFO_200.cs b/AlphaFS/Network/Native Structures/DFS_INFO_200.cs new file mode 100644 index 0000000..585cc2b --- /dev/null +++ b/AlphaFS/Network/Native Structures/DFS_INFO_200.cs @@ -0,0 +1,39 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// Contains the name of a domain-based Distributed File System (DFS) namespace. + /// This structure is only for use with the NetDfsEnum, NetDfsGetClientInfo, and NetDfsGetInfo functions. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct DFS_INFO_200 + { + /// The name of a domain-based DFS namespace. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string FtDfsName; + } + } +} diff --git a/AlphaFS/Network/Native Structures/DFS_INFO_300.cs b/AlphaFS/Network/Native Structures/DFS_INFO_300.cs new file mode 100644 index 0000000..345b888 --- /dev/null +++ b/AlphaFS/Network/Native Structures/DFS_INFO_300.cs @@ -0,0 +1,53 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// Contains the name and type (domain-based or stand-alone) of a DFS namespace. + /// The DFS functions use the structure to enumerate DFS namespaces hosted on a machine. + /// Minimum supported client: Windows XP with SP1 [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct DFS_INFO_300 + { + /// Value that specifies the type of the DFS namespace. This member can be one of the values. + [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Flags")] + [MarshalAs(UnmanagedType.U4)] public readonly DfsNamespaceFlavors Flags; + + /// The name of a DFS namespace. + /// This member can have one of the following two formats: + /// The first format is: \ServerName\DfsName + /// where ServerName is the name of the root target server that hosts the stand-alone DFS namespace and DfsName is the name of the DFS namespace. + /// The second format is: + /// \DomainName\DomDfsName + /// where DomainName is the name of the domain that hosts the domain-based DFS namespace and DomDfsname is the name of the DFS namespace. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [MarshalAs(UnmanagedType.LPWStr)] public readonly string DfsName; + } + } +} diff --git a/AlphaFS/Network/Native Structures/DFS_INFO_9.cs b/AlphaFS/Network/Native Structures/DFS_INFO_9.cs new file mode 100644 index 0000000..5cdde49 --- /dev/null +++ b/AlphaFS/Network/Native Structures/DFS_INFO_9.cs @@ -0,0 +1,77 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// Contains the name, status, GUID, time-out, property flags, metadata size, DFS target information, link reparse point security descriptor, and a list of DFS targets for a root or link. + /// Minimum supported client: Windows Vista with SP1 + /// Minimum supported server: Windows Server 2008 + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dfs")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct DFS_INFO_9 + { + /// The Universal Naming Convention (UNC) path of a DFS root or link. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string EntryPath; + + /// The comment associated with the DFS root or link. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string Comment; + + /// A that specifies a set of bit flags that describe the DFS root or link. + [MarshalAs(UnmanagedType.U4)] public readonly DfsVolumeStates State; + + /// Specifies the time-out, in seconds, of the DFS root or link. + [MarshalAs(UnmanagedType.U4)] public readonly uint Timeout; + + /// Specifies the GUID of the DFS root or link. + public readonly Guid Guid; + + /// Specifies a set of flags that describe specific properties of a DFS namespace, root, or link. + [MarshalAs(UnmanagedType.U4)] public readonly DfsPropertyFlags PropertyFlags; + + /// For domain-based DFS namespaces, this member specifies the size of the corresponding Active Directory data blob, in bytes. + /// For stand-alone DFS namespaces, this field specifies the size of the metadata stored in the registry, + /// including the key names and value names, in addition to the specific data items associated with them. + /// This field is valid for DFS roots only. + /// + [MarshalAs(UnmanagedType.U4)] public readonly uint MetadataSize; + + /// This member is reserved for system use. + [MarshalAs(UnmanagedType.U4)] public readonly uint SdLengthReserved; + + /// Pointer to a SECURITY_DESCRIPTOR structure that specifies a self-relative security descriptor to be associated with the DFS link's reparse point. + /// This field is valid for DFS links only. + /// + public IntPtr pSecurityDescriptor; + + /// Specifies the number of DFS targets. + [MarshalAs(UnmanagedType.U4)] public readonly uint NumberOfStorages; + + /// An array of structures. + public readonly IntPtr Storage; + } + } +} diff --git a/AlphaFS/Network/Native Structures/DFS_STORAGE_INFO_1.cs b/AlphaFS/Network/Native Structures/DFS_STORAGE_INFO_1.cs new file mode 100644 index 0000000..6078678 --- /dev/null +++ b/AlphaFS/Network/Native Structures/DFS_STORAGE_INFO_1.cs @@ -0,0 +1,47 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// Contains information about a DFS target, including the DFS target server name and share name as well as the target's state and priority. + /// Minimum supported client: Windows Vista + /// Minimum supported server: Windows Server 2008, Windows Server 2003 with SP1 + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct DFS_STORAGE_INFO_1 + { + /// State of the target. + [MarshalAs(UnmanagedType.U4)] public readonly DfsStorageStates State; + + /// The DFS root target or link target server name. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string ServerName; + + /// The DFS root target or link target share name. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string ShareName; + + /// DFS_TARGET_PRIORITY structure that contains a DFS target's priority class and rank. + [MarshalAs(UnmanagedType.Struct)] public readonly DFS_TARGET_PRIORITY TargetPriority; + } + } +} diff --git a/AlphaFS/Network/Native Structures/DFS_TARGET_PRIORITY.cs b/AlphaFS/Network/Native Structures/DFS_TARGET_PRIORITY.cs new file mode 100644 index 0000000..14bdb97 --- /dev/null +++ b/AlphaFS/Network/Native Structures/DFS_TARGET_PRIORITY.cs @@ -0,0 +1,44 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// Contains the priority class and rank of a specific DFS target. + /// Minimum supported client: Windows Vista + /// Minimum supported server: Windows Server 2008, Windows Server 2003 with SP1 + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct DFS_TARGET_PRIORITY + { + /// DFS_TARGET_PRIORITY_CLASS enumeration value that specifies the priority class of the target. + [MarshalAs(UnmanagedType.I4)] public readonly DfsTargetPriorityClass TargetPriorityClass; + + /// Specifies the priority rank value of the target. The default value is 0, which indicates the highest priority rank within a priority class. + public readonly ushort TargetPriorityRank; + + /// This member is reserved and must be zero. + public readonly ushort Reserved; + } + } +} diff --git a/AlphaFS/Network/Native Structures/FILE_INFO_3.cs b/AlphaFS/Network/Native Structures/FILE_INFO_3.cs new file mode 100644 index 0000000..9b9220b --- /dev/null +++ b/AlphaFS/Network/Native Structures/FILE_INFO_3.cs @@ -0,0 +1,51 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// Contains the identifier and other pertinent information about files, devices, and pipes. + /// This structure is only for use with the NetFileEnum function. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct FILE_INFO_3 + { + /// The identification number assigned to the resource when it is opened. + [MarshalAs(UnmanagedType.U4)] public readonly uint fi3_id; + + /// The access permissions associated with the opening application. This member can be one or more of the following values. + [MarshalAs(UnmanagedType.U4)] public readonly AccessPermissions fi3_permissions; + + /// The number of file locks on the file, device, or pipe. + [MarshalAs(UnmanagedType.U4)] public readonly uint fi3_num_locks; + + /// The path of the opened resource. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string fi3_pathname; + + /// Specifies which user (on servers that have user-level security) or which computer (on servers that have share-level security) opened the resource. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string fi3_username; + } + } +} diff --git a/AlphaFS/Network/Native Structures/NETRESOURCE.cs b/AlphaFS/Network/Native Structures/NETRESOURCE.cs new file mode 100644 index 0000000..3325a4a --- /dev/null +++ b/AlphaFS/Network/Native Structures/NETRESOURCE.cs @@ -0,0 +1,71 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// Contains information about a network resource. + /// The NETRESOURCE structure is returned during an enumeration of network resources. + /// The NETRESOURCE structure is also specified when making or querying + /// a network connection with calls to various Windows Networking functions. + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct NETRESOURCE + { + /// The scope of the enumeration. + [MarshalAs(UnmanagedType.U4)] public readonly ResourceScope dwScope; + + /// The type of resource + [MarshalAs(UnmanagedType.U4)] public ResourceType dwType; + + /// The display options for the network object in a network browsing user interface. + [MarshalAs(UnmanagedType.U4)] public readonly ResourceDisplayType dwDisplayType; + + /// A set of bit flags describing how the resource can be used. + [MarshalAs(UnmanagedType.U4)] public readonly ResourceUsage dwUsage; + + /// If the member is equal to or , + /// this member is a pointer to a -terminated character string that specifies the name of a local device. + /// This member is if the connection does not use a device. + /// + [MarshalAs(UnmanagedType.LPWStr)] public string lpLocalName; + + /// If the entry is a network resource, this member is a that specifies the remote network name. + /// If the entry is a current or persistent connection, member points to + /// the network name associated with the name pointed to by the member. + /// The can be characters in length, + /// and it must follow the network provider's naming conventions. + /// + [MarshalAs(UnmanagedType.LPWStr)] public string lpRemoteName; + + /// A that contains a comment supplied by the network provider. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string lpComment; + + /// A that contains the name of the provider that owns the resource. + /// This member can be if the provider name is unknown. + /// + [MarshalAs(UnmanagedType.LPWStr)] public readonly string lpProvider; + } + } +} diff --git a/AlphaFS/Network/Native Structures/REMOTE_NAME_INFO.cs b/AlphaFS/Network/Native Structures/REMOTE_NAME_INFO.cs new file mode 100644 index 0000000..62e890e --- /dev/null +++ b/AlphaFS/Network/Native Structures/REMOTE_NAME_INFO.cs @@ -0,0 +1,43 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + ///Contains path and name information for a network resource. + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct REMOTE_NAME_INFO + { + /// Identifies a network resource. + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")] [MarshalAs(UnmanagedType.LPWStr)] public string lpUniversalName; + + /// The name of a network connection. + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")] [MarshalAs(UnmanagedType.LPWStr)] public string lpConnectionName; + + /// The remaing path. + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")] [MarshalAs(UnmanagedType.LPWStr)] public string lpRemainingPath; + } + } +} diff --git a/AlphaFS/Network/Native Structures/SHARE_INFO_1.cs b/AlphaFS/Network/Native Structures/SHARE_INFO_1.cs new file mode 100644 index 0000000..b1f8d2a --- /dev/null +++ b/AlphaFS/Network/Native Structures/SHARE_INFO_1.cs @@ -0,0 +1,44 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// Contains information about the shared resource, including the name and type of the resource, and a comment associated with the resource. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct SHARE_INFO_1 + { + /// The name of a shared resource. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string shi1_netname; + + /// The type of share. + [MarshalAs(UnmanagedType.U4)] public readonly ShareType shi1_type; + + /// An optional comment about the shared resource. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string shi1_remark; + } + } +} diff --git a/AlphaFS/Network/Native Structures/SHARE_INFO_1005.cs b/AlphaFS/Network/Native Structures/SHARE_INFO_1005.cs new file mode 100644 index 0000000..8ab9eb2 --- /dev/null +++ b/AlphaFS/Network/Native Structures/SHARE_INFO_1005.cs @@ -0,0 +1,39 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// Contains information about the shared resource. + /// This structure can be retrieved by calling the NetShareGetInfo function. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct SHARE_INFO_1005 + { + /// A bitmask of flags that specify information about the shared resource. + [MarshalAs(UnmanagedType.U4)] public readonly ShareResourceTypes shi1005_flags; + } + } +} diff --git a/AlphaFS/Network/Native Structures/SHARE_INFO_2.cs b/AlphaFS/Network/Native Structures/SHARE_INFO_2.cs new file mode 100644 index 0000000..9223623 --- /dev/null +++ b/AlphaFS/Network/Native Structures/SHARE_INFO_2.cs @@ -0,0 +1,65 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// Contains information about the shared resource, including the name, type, and permissions of the resource, comments associated with the resource, + /// the maximum number of concurrent connections, the number of current connections, the local path for the resource, and a password for the current connection. + /// + /// Share information, NT, level 2, requires admin rights to work. + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct SHARE_INFO_2 + { + /// The name of a shared resource. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string shi2_netname; + + /// The type of share. + [MarshalAs(UnmanagedType.U4)] public readonly ShareType shi2_type; + + /// An optional comment about the shared resource. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string shi2_remark; + + /// The shared resource's permissions for servers running with share-level security. + /// Note that Windows does not support share-level security. This member is ignored on a server running user-level security. + [MarshalAs(UnmanagedType.U4)] public readonly AccessPermissions shi2_permissions; + + /// The maximum number of concurrent connections that the shared resource can accommodate. + /// The number of connections is unlimited if the value specified in this member is –1. + [MarshalAs(UnmanagedType.U4)] public readonly uint shi2_max_uses; + + /// The number of current connections to the resource. + [MarshalAs(UnmanagedType.U4)] public readonly uint shi2_current_uses; + + /// The local path for the shared resource. + /// For disks, this member is the path being shared. For print queues, this member is the name of the print queue being shared. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string shi2_path; + + /// The share's password (when the server is running with share-level security). + [MarshalAs(UnmanagedType.LPWStr)] public readonly string shi2_passwd; + } + } +} diff --git a/AlphaFS/Network/Native Structures/SHARE_INFO_503.cs b/AlphaFS/Network/Native Structures/SHARE_INFO_503.cs new file mode 100644 index 0000000..4ac57d3 --- /dev/null +++ b/AlphaFS/Network/Native Structures/SHARE_INFO_503.cs @@ -0,0 +1,75 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Network +{ + internal static partial class NativeMethods + { + /// Contains information about the shared resource, including the server name, name of the resource, type, and permissions, + /// the number of connections, and other pertinent information. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct SHARE_INFO_503 + { + /// The name of a shared resource. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string shi503_netname; + + /// The type of share. + [MarshalAs(UnmanagedType.U4)] public readonly ShareType shi503_type; + + /// An optional comment about the shared resource. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string shi503_remark; + + /// The shared resource's permissions for servers running with share-level security. + /// Note that Windows does not support share-level security. This member is ignored on a server running user-level security. + [MarshalAs(UnmanagedType.U4)] public readonly AccessPermissions shi503_permissions; + + /// The maximum number of concurrent connections that the shared resource can accommodate. + /// The number of connections is unlimited if the value specified in this member is –1. + [MarshalAs(UnmanagedType.U4)] public readonly uint shi503_max_uses; + + /// The number of current connections to the resource. + [MarshalAs(UnmanagedType.U4)] public readonly uint shi503_current_uses; + + /// The local path for the shared resource. + /// For disks, this member is the path being shared. For print queues, this member is the name of the print queue being shared. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string shi503_path; + + /// The share's password (when the server is running with share-level security). + [MarshalAs(UnmanagedType.LPWStr)] public readonly string shi503_passwd; + + /// The DNS or NetBIOS name of the remote server on which the shared resource resides. + /// A value of "*" indicates no configured server name. + [MarshalAs(UnmanagedType.LPWStr)] public readonly string shi503_servername; + + /// Reserved; must be zero. + [MarshalAs(UnmanagedType.U4)] public readonly uint shi503_reserved; + + /// Specifies the SECURITY_DESCRIPTOR associated with this share. + public IntPtr shi503_security_descriptor; + } + } +} diff --git a/AlphaFS/Network/OpenConnectionInfo.cs b/AlphaFS/Network/OpenConnectionInfo.cs new file mode 100644 index 0000000..803b832 --- /dev/null +++ b/AlphaFS/Network/OpenConnectionInfo.cs @@ -0,0 +1,88 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Globalization; +using Alphaleonis.Win32.Filesystem; + +namespace Alphaleonis.Win32.Network +{ + /// Contains the identification number of a connection, number of open files, connection time, number of users on the connection, and the type of connection. + [SerializableAttribute] + public sealed class OpenConnectionInfo + { + #region Constructor + + /// Create a OpenConnectionInfo instance. + internal OpenConnectionInfo(string host, NativeMethods.CONNECTION_INFO_1 connectionInfo) + { + Host = host; + Id = connectionInfo.coni1_id; + ShareType = connectionInfo.coni1_type; + TotalOpenFiles = connectionInfo.coni1_num_opens; + TotalUsers = connectionInfo.coni1_num_users; + ConnectedSeconds = connectionInfo.coni1_time; + UserName = connectionInfo.coni1_username; + NetName = connectionInfo.oni1_netname.Replace(Path.LongPathUncPrefix, string.Empty).Replace(Path.UncPrefix, string.Empty); + } + + #endregion // Constructor + + #region Methods + + /// Returns the full path to the share. + /// A string that represents this instance. + public override string ToString() + { + return Id.ToString(CultureInfo.InvariantCulture); + } + + #endregion // Methods + + #region Properties + + /// The local or remote Host. + public string Host { get; private set; } + + /// Specifies a connection identification number. + public long Id { get; private set; } + + /// The type of share. + public ShareType ShareType { get; private set; } + + /// Specifies the number of files currently open as a result of the connection. + public long TotalOpenFiles { get; private set; } + + /// Specifies the number of users on the connection. + public long TotalUsers { get; private set; } + + /// Specifies the number of seconds that the connection has been established. + public long ConnectedSeconds { get; private set; } + + /// If the server sharing the resource is running with user-level security, the UserName member describes which user made the connection. If the server is running with share-level security, coni1_username describes which computer (computername) made the connection. + public string UserName { get; private set; } + + /// String that specifies either the share name of the server's shared resource or the computername of the client. The value of this member depends on which name was specified as the qualifier parameter to the NetConnectionEnum function. + public string NetName { get; private set; } + + #endregion // Properties + } +} diff --git a/AlphaFS/Network/OpenResourceInfo.cs b/AlphaFS/Network/OpenResourceInfo.cs new file mode 100644 index 0000000..61628fe --- /dev/null +++ b/AlphaFS/Network/OpenResourceInfo.cs @@ -0,0 +1,88 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Globalization; + +namespace Alphaleonis.Win32.Network +{ + /// Contains the identification number and other pertinent information about files, devices, and pipes. This class cannot be inherited. + [SerializableAttribute] + public sealed class OpenResourceInfo + { + #region Constructor + + /// Create a OpenResourceInfo instance. + internal OpenResourceInfo(string host, NativeMethods.FILE_INFO_3 fileInfo) + { + Host = host; + Id = fileInfo.fi3_id; + Permissions = fileInfo.fi3_permissions; + TotalLocks = fileInfo.fi3_num_locks; + PathName = fileInfo.fi3_pathname.Replace(@"\\", @"\"); + UserName = fileInfo.fi3_username; + } + + #endregion // Constructor + + #region Methods + + /// Forces the open resource to close. + /// You should this method with caution because it does not write data cached on the client system to the file before closing the file. + public void Close() + { + uint lastError = NativeMethods.NetFileClose(Host, (uint) Id); + if (lastError != Win32Errors.NERR_Success && lastError != Win32Errors.NERR_FileIdNotFound) + NativeError.ThrowException(lastError, Host, PathName); + } + + /// Returns the full path to the share. + /// A string that represents this instance. + public override string ToString() + { + return Id.ToString(CultureInfo.InvariantCulture); + } + + #endregion // Methods + + #region Properties + + /// The local or remote Host. + public string Host { get; private set; } + + /// The identification number assigned to the resource when it is opened. + public long Id { get; private set; } + + /// The path of the opened resource. + public string PathName { get; private set; } + + /// The access permissions associated with the opening application. This member can be one or more of the following values. + public AccessPermissions Permissions { get; private set; } + + /// The number of file locks on the file, device, or pipe. + public long TotalLocks { get; private set; } + + /// Specifies which user (on servers that have user-level security) or which computer (on servers that have share-level security) opened the resource. + public string UserName { get; private set; } + + #endregion // Properties + } +} diff --git a/AlphaFS/Network/ShareInfo.cs b/AlphaFS/Network/ShareInfo.cs new file mode 100644 index 0000000..b371393 --- /dev/null +++ b/AlphaFS/Network/ShareInfo.cs @@ -0,0 +1,247 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Alphaleonis.Win32.Filesystem; +using System; +using System.Globalization; + +namespace Alphaleonis.Win32.Network +{ + /// Contains information about Server Message Block (SMB) shares. This class cannot be inherited. + [SerializableAttribute] + public sealed class ShareInfo + { + #region Constructor + + #region ShareInfo + + /// Creates a instance. + /// A host to retrieve shares from. + /// One of the options. + /// A or instance. + internal ShareInfo(string host, ShareInfoLevel shareLevel, object shareInfo) + { + switch (shareLevel) + { + case ShareInfoLevel.Info1005: + NativeMethods.SHARE_INFO_1005 s1005 = (NativeMethods.SHARE_INFO_1005) shareInfo; + ServerName = host ?? Environment.MachineName; + ResourceType = s1005.shi1005_flags; + break; + + case ShareInfoLevel.Info503: + NativeMethods.SHARE_INFO_503 s503 = (NativeMethods.SHARE_INFO_503) shareInfo; + CurrentUses = s503.shi503_current_uses; + MaxUses = s503.shi503_max_uses; + NetName = s503.shi503_netname; + Password = s503.shi503_passwd; + Path = Utils.IsNullOrWhiteSpace(s503.shi503_path) ? null : s503.shi503_path; + Permissions = s503.shi503_permissions; + Remark = s503.shi503_remark; + ServerName = s503.shi503_servername == "*" ? host ?? Environment.MachineName : s503.shi503_servername; + ShareType = s503.shi503_type; + SecurityDescriptor = s503.shi503_security_descriptor; + break; + + case ShareInfoLevel.Info2: + NativeMethods.SHARE_INFO_2 s2 = (NativeMethods.SHARE_INFO_2)shareInfo; + CurrentUses = s2.shi2_current_uses; + MaxUses = s2.shi2_max_uses; + NetName = s2.shi2_netname; + Password = s2.shi2_passwd; + Path = Utils.IsNullOrWhiteSpace(s2.shi2_path) ? null : s2.shi2_path; + Permissions = s2.shi2_permissions; + Remark = s2.shi2_remark; + ServerName = host ?? Environment.MachineName; + ShareType = s2.shi2_type; + break; + + case ShareInfoLevel.Info1: + NativeMethods.SHARE_INFO_1 s1 = (NativeMethods.SHARE_INFO_1)shareInfo; + CurrentUses = 0; + MaxUses = 0; + NetName = s1.shi1_netname; + Password = null; + Path = null; + Permissions = AccessPermissions.None; + Remark = s1.shi1_remark; + ServerName = host ?? Environment.MachineName; + ShareType = s1.shi1_type; + break; + } + + + NetFullPath = string.Format(CultureInfo.CurrentCulture, "{0}{1}{2}{3}", Filesystem.Path.UncPrefix, ServerName, Filesystem.Path.DirectorySeparatorChar, NetName); + + ShareLevel = shareLevel; + } + + #endregion // ShareInfo + + #endregion // Constructor + + #region Methods + + #region ToString + + /// Returns the full path to the share. + /// A string that represents this instance. + public override string ToString() + { + return NetFullPath; + } + + #endregion // ToString + + #endregion // Methods + + #region Properties + + #region CurrentUses + + /// The number of current connections to the resource. + public long CurrentUses { get; private set; } + + #endregion // CurrentUses + + #region DirectoryInfo + + private DirectoryInfo _directoryInfo; + + /// The instance associated with this share. + public DirectoryInfo DirectoryInfo + { + get + { + // Do not use ?? expression here. + if (_directoryInfo == null) + _directoryInfo = new DirectoryInfo(null, NetFullPath, PathFormat.FullPath); + + return _directoryInfo; + } + } + + #endregion // DirectoryInfo + + #region NetFullPath + + /// Returns the full UNC path to the share. + public string NetFullPath { get; internal set; } + + #endregion // NetFullPath + + #region MaxUses + + /// The maximum number of concurrent connections that the shared resource can accommodate. + /// The number of connections is unlimited if the value specified in this member is –1. + public long MaxUses { get; private set; } + + #endregion // MaxUses + + #region NetName + + /// The name of a shared resource. + public string NetName { get; private set; } + + #endregion // NetName + + #region Password + + /// The share's password (when the server is running with share-level security). + public string Password { get; private set; } + + #endregion // Password + + #region Path + + /// The local path for the shared resource. + /// For disks, this member is the path being shared. For print queues, this member is the name of the print queue being shared. + public string Path { get; private set; } + + #endregion // Path + + #region Permissions + + /// The shared resource's permissions for servers running with share-level security. + /// Note that Windows does not support share-level security. This member is ignored on a server running user-level security. + public AccessPermissions Permissions { get; private set; } + + #endregion // Permissions + + #region Remark + + /// An optional comment about the shared resource. + public string Remark { get; private set; } + + #endregion // Remark + + #region SecurityDescriptor + + /// Specifies the SECURITY_DESCRIPTOR associated with this share. + public IntPtr SecurityDescriptor { get; private set; } + + #endregion // SecurityDescriptor + + #region ServerName + + /// A pointer to a string that specifies the DNS or NetBIOS name of the remote server on which the shared resource resides. + /// A value of "*" indicates no configured server name. + public string ServerName { get; private set; } + + #endregion // ServerName + + #region ShareType + + /// The type of share. + public ShareType ShareType { get; private set; } + + #endregion // ShareType + + #region ResourceType + + private ShareResourceTypes _shareResourceType; + + /// The type of share resource. + public ShareResourceTypes ResourceType + { + get + { + if (_shareResourceType == ShareResourceTypes.None && !Utils.IsNullOrWhiteSpace(NetName)) + _shareResourceType = (Host.GetShareInfoCore(ShareInfoLevel.Info1005, ServerName, NetName, true)).ResourceType; + + return _shareResourceType; + } + + private set { _shareResourceType = value; } + } + + #endregion // ResourceType + + #region ShareLevel + + /// The structure level for the ShareInfo instance. + public ShareInfoLevel ShareLevel { get; private set; } + + #endregion // ShareLevel + + #endregion // Properties + } +} diff --git a/AlphaFS/OperatingSystem.cs b/AlphaFS/OperatingSystem.cs new file mode 100644 index 0000000..145a92e --- /dev/null +++ b/AlphaFS/OperatingSystem.cs @@ -0,0 +1,507 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; + +namespace Alphaleonis.Win32 +{ + /// Static class providing access to information about the operating system under which the assembly is executing. + public static class OperatingSystem + { + #region OperatingSystem Name Enum + + /// A set of flags that describe the named Windows versions. + /// The values of the enumeration are ordered. A later released operating system version has a higher number, so comparisons between named versions are meaningful. + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Os")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Os")] + public enum EnumOsName + { + /// A Windows version earlier than Windows 2000. + Earlier = -1, + + /// Windows 2000 (Server or Professional). + Windows2000 = 0, + + /// Windows XP. + WindowsXP = 1, + + /// Windows Server 2003. + WindowsServer2003 = 2, + + /// Windows Vista. + WindowsVista = 3, + + /// Windows Server 2008. + WindowsServer2008 = 4, + + /// Windows 7. + Windows7 = 5, + + /// Windows Server 2008 R2. + WindowsServer2008R2 = 6, + + /// Windows 8. + Windows8 = 7, + + /// Windows Server 2012. + WindowsServer2012 = 8, + + /// Windows 8.1. + Windows81 = 9, + + /// Windows Server 2012 R2 + WindowsServer2012R2 = 10, + + /// Windows 10 + Windows10 = 11, + + /// Windows Server + WindowsServer = 12, + + /// A later version of Windows than currently installed. + Later = 65535 + } + + #endregion // OperatingSystem Name Enum + + #region ProcessorArchitecture Name enum + + /// A set of flags to indicate the current processor architecture for which the operating system is targeted and running. + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Pa")] + [SuppressMessage("Microsoft.Design", "CA1028:EnumStorageShouldBeInt32")] + public enum EnumProcessorArchitecture + { + /// PROCESSOR_ARCHITECTURE_INTEL + /// The system is running a 32-bit version of Windows. + /// + X86 = 0, + + /// PROCESSOR_ARCHITECTURE_IA64 + /// The system is running on a Itanium processor. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ia")] + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Ia")] + IA64 = 6, + + /// PROCESSOR_ARCHITECTURE_AMD64 + /// The system is running a 64-bit version of Windows. + /// + X64 = 9, + + /// PROCESSOR_ARCHITECTURE_UNKNOWN + /// Unknown architecture. + /// + Unknown = 65535 + } + + #endregion // ProcessorArchitecture Name enum + + + #region Properties + + #region IsServer + + private static bool _isServer; + + /// Gets a value indicating whether the operating system is a server operating system. + /// if the current operating system is a server operating system; otherwise, . + public static bool IsServer + { + get + { + if (_servicePackVersion == null) + UpdateData(); + return _isServer; + } + } + + #endregion // IsServer + + #region IsWow64Process + + private static bool? _isWow64Process; + + /// Gets a value indicating whether the current process is running under WOW64. + /// if the current process is running under WOW64; otherwise, . + public static bool IsWow64Process + { + get + { + if (_isWow64Process == null) + { + bool value; + IntPtr processHandle = Process.GetCurrentProcess().Handle; + + if (!NativeMethods.IsWow64Process(processHandle, out value)) + Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error()); + + // A pointer to a value that is set to TRUE if the process is running under WOW64. + // If the process is running under 32-bit Windows, the value is set to FALSE. + // If the process is a 64-bit application running under 64-bit Windows, the value is also set to FALSE. + + _isWow64Process = value; + } + + return (bool) _isWow64Process; + } + } + + #endregion // IsWow64Process + + #region OSVersion + + private static Version _osVersion; + + /// Gets the numeric version of the operating system. + /// The numeric version of the operating system. + public static Version OSVersion + { + get + { + if (_osVersion == null) + UpdateData(); + + return _osVersion; + } + } + + #endregion // OSVersion + + #region VersionName + + private static EnumOsName _enumOsName = EnumOsName.Later; + + /// Gets the named version of the operating system. + /// The named version of the operating system. + public static EnumOsName VersionName + { + get + { + if (_servicePackVersion == null) + UpdateData(); + + return _enumOsName; + } + } + + #endregion // VersionName + + #region ProcessorArchitecture + + private static EnumProcessorArchitecture _processorArchitecture; + + /// Gets the processor architecture for which the operating system is targeted. + /// The processor architecture for which the operating system is targeted. + /// If running under WOW64 this will return a 32-bit processor. Use to determine if this is the case. + public static EnumProcessorArchitecture ProcessorArchitecture + { + get + { + if (_servicePackVersion == null) + UpdateData(); + + return _processorArchitecture; + } + } + + #endregion // ProcessorArchitecture + + #region ServicePackVersion + + private static Version _servicePackVersion; + + /// Gets the version of the service pack currently installed on the operating system. + /// The version of the service pack currently installed on the operating system. + /// Only the and fields are used. + public static Version ServicePackVersion + { + get + { + if (_servicePackVersion == null) + UpdateData(); + + return _servicePackVersion; + } + } + + #endregion // ServicePackVersion + + #endregion // Properties + + #region Methods + + #region IsAtLeast + + /// Determines whether the operating system is of the specified version or later. + /// if the operating system is of the specified or later; otherwise, . + /// The lowest version for which to return true. + public static bool IsAtLeast(EnumOsName version) + { + return VersionName >= version; + } + + /// Determines whether the operating system is of the specified version or later, allowing specification of a minimum service pack that must be installed on the lowest version. + /// if the operating system matches the specified with the specified service pack, or if the operating system is of a later version; otherwise, . + /// The minimum required version. + /// The major version of the service pack that must be installed on the minimum required version to return true. This can be 0 to indicate that no service pack is required. + public static bool IsAtLeast(EnumOsName version, int servicePackVersion) + { + return IsAtLeast(version) && ServicePackVersion.Major >= servicePackVersion; + } + + #endregion // IsAtLeast + + #endregion // Methods + + + #region Private + + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "RtlGetVersion")] + private static void UpdateData() + { + var verInfo = new NativeMethods.RTL_OSVERSIONINFOEXW(); + + // Needed to prevent: System.Runtime.InteropServices.COMException: + // The data area passed to a system call is too small. (Exception from HRESULT: 0x8007007A) + verInfo.dwOSVersionInfoSize = Marshal.SizeOf(verInfo); + + var sysInfo = new NativeMethods.SYSTEM_INFO(); + NativeMethods.GetNativeSystemInfo(ref sysInfo); + + + // RtlGetVersion returns STATUS_SUCCESS (0). + if (NativeMethods.RtlGetVersion(ref verInfo)) + throw new Win32Exception(Marshal.GetLastWin32Error(), "Function RtlGetVersion() failed to retrieve the operating system information."); + + + _osVersion = new Version(verInfo.dwMajorVersion, verInfo.dwMinorVersion, verInfo.dwBuildNumber); + + _processorArchitecture = (EnumProcessorArchitecture) sysInfo.wProcessorArchitecture; + _servicePackVersion = new Version(verInfo.wServicePackMajor, verInfo.wServicePackMinor); + _isServer = verInfo.wProductType == NativeMethods.VER_NT_DOMAIN_CONTROLLER || verInfo.wProductType == NativeMethods.VER_NT_SERVER; + + + // RtlGetVersion: https://msdn.microsoft.com/en-us/library/windows/hardware/ff561910%28v=vs.85%29.aspx + + // The following table summarizes the most recent operating system version numbers. + // Operating system Version number Other + // ================================================================================ + // Windows 10 10.0 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION + // Windows Server 10.0 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION + // Windows 8.1 6.3 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION + // Windows Server 2012 R2 6.3 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION + // Windows 8 6.2 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION + // Windows Server 2012 6.2 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION + // Windows 7 6.1 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION + // Windows Server 2008 R2 6.1 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION + // Windows Server 2008 6.0 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION + // Windows Vista 6.0 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION + // Windows Server 2003 R2 5.2 GetSystemMetrics(SM_SERVERR2) != 0 + // Windows Server 2003 5.2 GetSystemMetrics(SM_SERVERR2) == 0 + // Windows XP 64-Bit Edition 5.2 (OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION) && (sysInfo.PaName == PaName.X64) + // Windows XP 5.1 Not applicable + // Windows 2000 5.0 Not applicable + + + // 10 == The lastest MajorVersion of Windows. + if (verInfo.dwMajorVersion > 10) + _enumOsName = EnumOsName.Later; + + else + switch (verInfo.dwMajorVersion) + { + #region Version 10 + + case 10: + switch (verInfo.dwMinorVersion) + { + // Windows 10 or Windows Server + case 0: + _enumOsName = (verInfo.wProductType == NativeMethods.VER_NT_WORKSTATION) + ? EnumOsName.Windows10 + : EnumOsName.WindowsServer; + break; + } + break; + + #endregion // Version 10 + + #region Version 6 + + case 6: + switch (verInfo.dwMinorVersion) + { + // Windows Vista or Windows Server 2008 + case 0: + _enumOsName = (verInfo.wProductType == NativeMethods.VER_NT_WORKSTATION) + ? EnumOsName.WindowsVista + : EnumOsName.WindowsServer2008; + break; + + // Windows 7 or Windows Server 2008 R2 + case 1: + _enumOsName = (verInfo.wProductType == NativeMethods.VER_NT_WORKSTATION) + ? EnumOsName.Windows7 + : EnumOsName.WindowsServer2008R2; + break; + + // Windows 8 or Windows Server 2012 + case 2: + _enumOsName = (verInfo.wProductType == NativeMethods.VER_NT_WORKSTATION) + ? EnumOsName.Windows8 + : EnumOsName.WindowsServer2012; + break; + + // Windows 8.1 or Windows Server 2012 R2 + case 3: + _enumOsName = (verInfo.wProductType == NativeMethods.VER_NT_WORKSTATION) + ? EnumOsName.Windows81 + : EnumOsName.WindowsServer2012R2; + break; + + default: + _enumOsName = EnumOsName.Later; + break; + } + break; + + #endregion // Version 6 + + #region Version 5 + + case 5: + switch (verInfo.dwMinorVersion) + { + case 0: + _enumOsName = EnumOsName.Windows2000; + break; + + case 1: + _enumOsName = EnumOsName.WindowsXP; + break; + + case 2: + _enumOsName = (verInfo.wProductType == NativeMethods.VER_NT_WORKSTATION && _processorArchitecture == EnumProcessorArchitecture.X64) + ? EnumOsName.WindowsXP + : (verInfo.wProductType != NativeMethods.VER_NT_WORKSTATION) ? EnumOsName.WindowsServer2003 : EnumOsName.Later; + break; + + default: + _enumOsName = EnumOsName.Later; + break; + } + break; + + #endregion // Version 5 + + default: + _enumOsName = EnumOsName.Earlier; + break; + } + } + + #region P/Invoke members / NativeMethods + + private static class NativeMethods + { + internal const short VER_NT_WORKSTATION = 1; + internal const short VER_NT_DOMAIN_CONTROLLER = 2; + internal const short VER_NT_SERVER = 3; + + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct RTL_OSVERSIONINFOEXW + { + public int dwOSVersionInfoSize; + public readonly int dwMajorVersion; + public readonly int dwMinorVersion; + public readonly int dwBuildNumber; + public readonly int dwPlatformId; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] + public readonly string szCSDVersion; + public readonly ushort wServicePackMajor; + public readonly ushort wServicePackMinor; + public readonly ushort wSuiteMask; + public readonly byte wProductType; + public readonly byte wReserved; + } + + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct SYSTEM_INFO + { + public readonly ushort wProcessorArchitecture; + private readonly ushort wReserved; + public readonly uint dwPageSize; + public readonly IntPtr lpMinimumApplicationAddress; + public readonly IntPtr lpMaximumApplicationAddress; + public readonly IntPtr dwActiveProcessorMask; + public readonly uint dwNumberOfProcessors; + public readonly uint dwProcessorType; + public readonly uint dwAllocationGranularity; + public readonly ushort wProcessorLevel; + public readonly ushort wProcessorRevision; + } + + + /// The RtlGetVersion routine returns version information about the currently running operating system. + /// RtlGetVersion returns STATUS_SUCCESS. + /// Available starting with Windows 2000. + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule"), DllImport("ntdll.dll", SetLastError = true, CharSet = CharSet.Unicode)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool RtlGetVersion([MarshalAs(UnmanagedType.Struct)] ref RTL_OSVERSIONINFOEXW lpVersionInformation); + + + /// Retrieves information about the current system to an application running under WOW64. + /// If the function is called from a 64-bit application, it is equivalent to the GetSystemInfo function. + /// + /// This function does not return a value. + /// To determine whether a Win32-based application is running under WOW64, call the function. + /// Minimum supported client: Windows XP [desktop apps | Windows Store apps] + /// Minimum supported server: Windows Server 2003 [desktop apps | Windows Store apps] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + internal static extern void GetNativeSystemInfo([MarshalAs(UnmanagedType.Struct)] ref SYSTEM_INFO lpSystemInfo); + + + /// Determines whether the specified process is running under WOW64. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows Vista, Windows XP with SP2 [desktop apps only] + /// Minimum supported server: Windows Server 2008, Windows Server 2003 with SP1 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool IsWow64Process([In] IntPtr hProcess, [Out, MarshalAs(UnmanagedType.Bool)] out bool lpSystemInfo); + } + + #endregion // P/Invoke members / NativeMethods + + #endregion // Private + } +} diff --git a/AlphaFS/Properties/AssemblyInfo.cs b/AlphaFS/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..abdd031 --- /dev/null +++ b/AlphaFS/Properties/AssemblyInfo.cs @@ -0,0 +1,40 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AlphaFS")] +[assembly: AssemblyDescription("Alphaleonis Extended Win32 File System Support Library for .NET")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +[assembly: Guid("6dc8e700-bb73-43fe-9f01-3300a9d61cd7")] + +[assembly: System.CLSCompliant(true)] + +// This will enable internal class members to be visible from the UnitTest namespace. +[assembly: InternalsVisibleToAttribute("AlphaFS.UnitTest, PublicKey=002400000480000094000000060200000024000052534131000400000100010033b590a45dff32ded24ceeb7e9ecbad4541e77de3e741c09c26ab0d569a9bccd9ac3997761139f0ede66c514377bb4d3aaa72548f535a6171d6a78884da038a711ad11cfab3369d86ee2de84ecc443c80fb606d8a6e8c337b77b87797239fb3e7e5806982380de7eb75bc6bdb08b4f3a405f146597e173c0357a95ecf8c771bd")] diff --git a/AlphaFS/Resources.Designer.cs b/AlphaFS/Resources.Designer.cs new file mode 100644 index 0000000..a30e182 --- /dev/null +++ b/AlphaFS/Resources.Designer.cs @@ -0,0 +1,442 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Alphaleonis.Win32 { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Alphaleonis.Win32.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Buffer is not large enough for the requested operation.. + /// + internal static string Buffer_Not_Large_Enough { + get { + return ResourceManager.GetString("Buffer_Not_Large_Enough", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cannot create directory.. + /// + internal static string Cannot_Create_Directory { + get { + return ResourceManager.GetString("Cannot_Create_Directory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cannot determine Copy or Move action.. + /// + internal static string Cannot_Determine_Copy_Or_Move { + get { + return ResourceManager.GetString("Cannot_Determine_Copy_Or_Move", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Destination buffer not large enough for the requested operation.. + /// + internal static string Destination_Buffer_Not_Large_Enough { + get { + return ResourceManager.GetString("Destination_Buffer_Not_Large_Enough", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The device is not ready.. + /// + internal static string Device_Not_Ready { + get { + return ResourceManager.GetString("Device_Not_Ready", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Incorrectly implemented function attempting to generate exception from successful operation. + ///. + /// + internal static string Exception_From_Successful_Operation { + get { + return ResourceManager.GetString("Exception_From_Successful_Operation", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The specified file is hidden: [{0}]. + /// + internal static string File_Is_Hidden { + get { + return ResourceManager.GetString("File_Is_Hidden", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The file or directory already exists.. + /// + internal static string File_Or_Directory_Already_Exists { + get { + return ResourceManager.GetString("File_Or_Directory_Already_Exists", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The handle is closed.. + /// + internal static string Handle_Is_Closed { + get { + return ResourceManager.GetString("Handle_Is_Closed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The handle is invalid.. + /// + internal static string Handle_Is_Invalid { + get { + return ResourceManager.GetString("Handle_Is_Invalid", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The handle is invalid. Win32Error: [{0}]. + /// + internal static string Handle_Is_Invalid_Win32Error { + get { + return ResourceManager.GetString("Handle_Is_Invalid_Win32Error", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Creating hard-links on non-NTFS partitions is not supported.. + /// + internal static string HardLinks_Not_Supported { + get { + return ResourceManager.GetString("HardLinks_Not_Supported", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Illegal characters: [{0}] in path.. + /// + internal static string Illegal_Characters_In_Path { + get { + return ResourceManager.GetString("Illegal_Characters_In_Path", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An attempt to set an invalid file attribute failed.. + /// + internal static string Invalid_File_Attribute { + get { + return ResourceManager.GetString("Invalid_File_Attribute", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid stream name.. + /// + internal static string Invalid_Stream_Name { + get { + return ResourceManager.GetString("Invalid_Stream_Name", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid Subpath. + /// + internal static string Invalid_Subpath { + get { + return ResourceManager.GetString("Invalid_Subpath", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid transaction request.. + /// + internal static string Invalid_Transaction_Request { + get { + return ResourceManager.GetString("Invalid_Transaction_Request", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Count cannot be negative.. + /// + internal static string Negative_Count { + get { + return ResourceManager.GetString("Negative_Count", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Destination offset cannot be negative.. + /// + internal static string Negative_Destination_Offset { + get { + return ResourceManager.GetString("Negative_Destination_Offset", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Length cannot be negative.. + /// + internal static string Negative_Length { + get { + return ResourceManager.GetString("Negative_Length", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lock length cannot be negative.. + /// + internal static string Negative_Lock_Length { + get { + return ResourceManager.GetString("Negative_Lock_Length", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Offset cannot be negative.. + /// + internal static string Negative_Offset { + get { + return ResourceManager.GetString("Negative_Offset", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This stream does not support seeking.. + /// + internal static string No_Stream_Seeking_Support { + get { + return ResourceManager.GetString("No_Stream_Seeking_Support", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The file or directory is not a reparse point.. + /// + internal static string Not_A_Reparse_Point { + get { + return ResourceManager.GetString("Not_A_Reparse_Point", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Argument is not a valid Volume GUID.. + /// + internal static string Not_A_Valid_Guid { + get { + return ResourceManager.GetString("Not_A_Valid_Guid", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Path is a zero-length string or contains only white space.. + /// + internal static string Path_Is_Zero_Length_Or_Only_White_Space { + get { + return ResourceManager.GetString("Path_Is_Zero_Length_Or_Only_White_Space", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Privilege name cannot be empty.. + /// + internal static string Privilege_Name_Cannot_Be_Empty { + get { + return ResourceManager.GetString("Privilege_Name_Cannot_Be_Empty", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Incomplete header read.. + /// + internal static string Read_Incomplete_Header { + get { + return ResourceManager.GetString("Read_Incomplete_Header", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This method requires Windows Vista or higher.. + /// + internal static string Requires_Windows_Vista_Or_Higher { + get { + return ResourceManager.GetString("Requires_Windows_Vista_Or_Higher", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid security descriptor returned from system.. + /// + internal static string Returned_Invalid_Security_Descriptor { + get { + return ResourceManager.GetString("Returned_Invalid_Security_Descriptor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Source offset and length outside the bounds of the array. + /// + internal static string Source_Offset_And_Length_Outside_Bounds { + get { + return ResourceManager.GetString("Source_Offset_And_Length_Outside_Bounds", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The target directory is a file, not a directory: [{0}]. + /// + internal static string Target_Directory_Is_A_File { + get { + return ResourceManager.GetString("Target_Directory_Is_A_File", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The target file is a directory, not a file: [{0}]. + /// + internal static string Target_File_Is_A_Directory { + get { + return ResourceManager.GetString("Target_File_Is_A_Directory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transaction already aborted.. + /// + internal static string Transaction_Already_Aborted { + get { + return ResourceManager.GetString("Transaction_Already_Aborted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transaction already committed.. + /// + internal static string Transaction_Already_Committed { + get { + return ResourceManager.GetString("Transaction_Already_Committed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid transaction object.. + /// + internal static string Transaction_Invalid { + get { + return ResourceManager.GetString("Transaction_Invalid", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transaction not active.. + /// + internal static string Transaction_Not_Active { + get { + return ResourceManager.GetString("Transaction_Not_Active", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transaction not requested.. + /// + internal static string Transaction_Not_Requested { + get { + return ResourceManager.GetString("Transaction_Not_Requested", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transactional conflict.. + /// + internal static string Transactional_Conflict { + get { + return ResourceManager.GetString("Transactional_Conflict", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Network share path should match the format: \\server\share. + /// + internal static string UNC_Path_Should_Match_Format { + get { + return ResourceManager.GetString("UNC_Path_Should_Match_Format", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Backup FileStream Unlock Position must not be negative.. + /// + internal static string Unlock_Position_Negative { + get { + return ResourceManager.GetString("Unlock_Position_Negative", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The given path's format is not supported: [{0}]. + /// + internal static string Unsupported_Path_Format { + get { + return ResourceManager.GetString("Unsupported_Path_Format", resourceCulture); + } + } + } +} diff --git a/AlphaFS/Resources.resx b/AlphaFS/Resources.resx new file mode 100644 index 0000000..4674042 --- /dev/null +++ b/AlphaFS/Resources.resx @@ -0,0 +1,247 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Invalid transaction object. + + + Transaction already committed. + + + Transaction already aborted. + + + Transactional conflict. + + + Transaction not active. + + + Transaction not requested. + + + Invalid transaction request. + + + Creating hard-links on non-NTFS partitions is not supported. + + + This stream does not support seeking. + + + Count cannot be negative. + + + Offset cannot be negative. + + + Buffer is not large enough for the requested operation. + + + Invalid security descriptor returned from system. + + + The handle is invalid. + + + The handle is invalid. Win32Error: [{0}] + + + Network share path should match the format: \\server\share + + + Backup FileStream Unlock Position must not be negative. + + + Lock length cannot be negative. + + + Destination offset cannot be negative. + + + Length cannot be negative. + + + Source offset and length outside the bounds of the array + + + Privilege name cannot be empty. + + + Cannot create directory. + + + This method requires Windows Vista or higher. + + + The target directory is a file, not a directory: [{0}] + + + Illegal characters: [{0}] in path. + + + Path is a zero-length string or contains only white space. + + + The given path's format is not supported: [{0}] + + + The target file is a directory, not a file: [{0}] + + + The specified file is hidden: [{0}] + + + Cannot determine Copy or Move action. + + + An attempt to set an invalid file attribute failed. + + + Incomplete header read. + + + Invalid stream name. + + + The file or directory is not a reparse point. + + + The file or directory already exists. + + + Destination buffer not large enough for the requested operation. + + + Incorrectly implemented function attempting to generate exception from successful operation. + + + + Argument is not a valid Volume GUID. + + + The device is not ready. + + + Invalid Subpath + + + The handle is closed. + + \ No newline at end of file diff --git a/AlphaFS/SafeGlobalMemoryBufferHandle.cs b/AlphaFS/SafeGlobalMemoryBufferHandle.cs new file mode 100644 index 0000000..59eea9f --- /dev/null +++ b/AlphaFS/SafeGlobalMemoryBufferHandle.cs @@ -0,0 +1,78 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace Alphaleonis.Win32 +{ + /// Represents a block of native memory of a specified size allocated using the LocalAlloc function from Kernel32.dll. + internal sealed class SafeGlobalMemoryBufferHandle : SafeNativeMemoryBufferHandle + { + /// Creates new instance with zero IntPtr. + public SafeGlobalMemoryBufferHandle() + : base(true) + { + } + + /// Initializes a new instance of the class allocating the specified number of bytes of unmanaged memory. + /// The capacity. + public SafeGlobalMemoryBufferHandle(int capacity) : + base(capacity) + { + SetHandle(Marshal.AllocHGlobal(capacity)); + } + + private SafeGlobalMemoryBufferHandle(IntPtr buffer, int capacity) + : base(buffer, capacity) + { + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + public static SafeGlobalMemoryBufferHandle FromLong(long? value) + { + if (value.HasValue) + { + var safeBuffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(typeof (long))); + Marshal.WriteInt64(safeBuffer.handle, value.Value); + return safeBuffer; + } + + return new SafeGlobalMemoryBufferHandle(); + } + + public static SafeGlobalMemoryBufferHandle FromStringUni(string str) + { + if (str == null) + throw new ArgumentNullException("str"); + + return new SafeGlobalMemoryBufferHandle(Marshal.StringToHGlobalUni(str), str.Length*UnicodeEncoding.CharSize + UnicodeEncoding.CharSize); + } + + /// Called when object is disposed or finalized. + protected override bool ReleaseHandle() + { + Marshal.FreeHGlobal(handle); + return true; + } + } +} diff --git a/AlphaFS/SafeNativeMemoryBufferHandle.cs b/AlphaFS/SafeNativeMemoryBufferHandle.cs new file mode 100644 index 0000000..487b1a2 --- /dev/null +++ b/AlphaFS/SafeNativeMemoryBufferHandle.cs @@ -0,0 +1,301 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using Microsoft.Win32.SafeHandles; +using System; +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32 +{ + /// Base class for classes representing a block of unmanaged memory. + internal abstract class SafeNativeMemoryBufferHandle : SafeHandleZeroOrMinusOneIsInvalid + { + #region Private Fields + + private int m_capacity; + + #endregion + + #region Constructors + + protected SafeNativeMemoryBufferHandle(bool ownsHandle) + : base(ownsHandle) + { + } + + /// Initializes a new instance of the specifying the allocated capacity of the memory block. + /// The capacity. + protected SafeNativeMemoryBufferHandle(int capacity) + : this(true) + { + m_capacity = capacity; + } + + protected SafeNativeMemoryBufferHandle(IntPtr memory, int capacity) + : this(capacity) + { + SetHandle(memory); + } + + #endregion + + #region Properties + + /// Gets the capacity. Only valid if this instance was created using a constructor that specifies the size, + /// it is not correct if this handle was returned by a native method using p/invoke. + /// + public int Capacity + { + get { return m_capacity; } + } + + #endregion + + #region Public Methods + + /// Copies data from a one-dimensional, managed 8-bit unsigned integer array to the unmanaged memory pointer referenced by this instance. + /// The one-dimensional array to copy from. + /// The zero-based index into the array where Copy should start. + /// The number of array elements to copy. + public void CopyFrom(byte[] source, int startIndex, int length) + { + Marshal.Copy(source, startIndex, handle, length); + } + + public void CopyFrom(char[] source, int startIndex, int length) + { + Marshal.Copy(source, startIndex, handle, length); + } + + public void CopyFrom(char[] source, int startIndex, int length, int offset) + { + Marshal.Copy(source, startIndex, new IntPtr(handle.ToInt64() + offset), length); + } + + /// Copies data from an unmanaged memory pointer to a managed 8-bit unsigned integer array. + /// The array to copy to. + /// The zero-based index in the destination array where copying should start. + /// The number of array elements to copy. + public void CopyTo(byte[] destination, int destinationOffset, int length) + { + if (destination == null) + throw new ArgumentNullException("destination"); + + if (destinationOffset < 0) + throw new ArgumentOutOfRangeException("destinationOffset", Resources.Negative_Destination_Offset); + + if (length < 0) + throw new ArgumentOutOfRangeException("length", Resources.Negative_Length); + + if (destinationOffset + length > destination.Length) + throw new ArgumentException(Resources.Destination_Buffer_Not_Large_Enough); + + if (length > Capacity) + throw new ArgumentOutOfRangeException("length", Resources.Source_Offset_And_Length_Outside_Bounds); + + Marshal.Copy(handle, destination, destinationOffset, length); + } + + /// Copies data from this unmanaged memory pointer to a managed 8-bit unsigned integer array. + /// The offset in the buffer to start copying from. + /// The array to copy to. + /// The zero-based index in the destination array where copying should start. + /// The number of array elements to copy. + public void CopyTo(int sourceOffset, byte[] destination, int destinationOffset, int length) + { + if (destination == null) + throw new ArgumentNullException("destination"); + + if (destinationOffset < 0) + throw new ArgumentOutOfRangeException("destinationOffset", Resources.Negative_Destination_Offset); + + if (length < 0) + throw new ArgumentOutOfRangeException("length", Resources.Negative_Length); + + if (destinationOffset + length > destination.Length) + throw new ArgumentException(Resources.Destination_Buffer_Not_Large_Enough); + + if (length > Capacity) + throw new ArgumentOutOfRangeException("length", Resources.Source_Offset_And_Length_Outside_Bounds); + + Marshal.Copy(new IntPtr(handle.ToInt64() + sourceOffset), destination, destinationOffset, length); + } + + public byte[] ToByteArray(int startIndex, int length) + { + if (IsInvalid) + return null; + + byte[] arr = new byte[length]; + Marshal.Copy(handle, arr, startIndex, length); + return arr; + } + + #region Write + + public void WriteInt16(int offset, short value) + { + Marshal.WriteInt16(handle, offset, value); + } + + public void WriteInt16(int offset, char value) + { + Marshal.WriteInt16(handle, offset, value); + } + + public void WriteInt16(char value) + { + Marshal.WriteInt16(handle, value); + } + + public void WriteInt16(short value) + { + Marshal.WriteInt16(handle, value); + } + + public void WriteInt32(int offset, short value) + { + Marshal.WriteInt32(handle, offset, value); + } + + public void WriteInt32(int value) + { + Marshal.WriteInt32(handle, value); + } + + public void WriteInt64(int offset, long value) + { + Marshal.WriteInt64(handle, offset, value); + } + + public void WriteInt64(long value) + { + Marshal.WriteInt64(handle, value); + } + + public void WriteByte(int offset, byte value) + { + Marshal.WriteByte(handle, offset, value); + } + + public void WriteByte(byte value) + { + Marshal.WriteByte(handle, value); + } + + public void WriteIntPtr(int offset, IntPtr value) + { + Marshal.WriteIntPtr(handle, offset, value); + } + + public void WriteIntPtr(IntPtr value) + { + Marshal.WriteIntPtr(handle, value); + } + + #endregion // Write + + #region Read + + public byte ReadByte() + { + return Marshal.ReadByte(handle); + } + + public byte ReadByte(int offset) + { + return Marshal.ReadByte(handle, offset); + } + + public short ReadInt16() + { + return Marshal.ReadInt16(handle); + } + + public short ReadInt16(int offset) + { + return Marshal.ReadInt16(handle, offset); + } + + public int ReadInt32() + { + return Marshal.ReadInt32(handle); + } + + public int ReadInt32(int offset) + { + return Marshal.ReadInt32(handle, offset); + } + + public long ReadInt64() + { + return Marshal.ReadInt64(handle); + } + + public long ReadInt64(int offset) + { + return Marshal.ReadInt64(handle, offset); + } + + public IntPtr ReadIntPtr() + { + return Marshal.ReadIntPtr(handle); + } + + public IntPtr ReadIntPtr(int offset) + { + return Marshal.ReadIntPtr(handle, offset); + } + + #endregion // Read + + + + /// Marshals data from a managed object to an unmanaged block of memory. + public void StructureToPtr(object structure, bool deleteOld) + { + Marshal.StructureToPtr(structure, handle, deleteOld); + } + + /// Marshals data from an unmanaged block of memory to a newly allocated managed object of the specified type. + /// A managed object containing the data pointed to by the ptr parameter. + public T PtrToStructure(int offset) + { + return (T) Marshal.PtrToStructure(new IntPtr(handle.ToInt64() + offset), typeof (T)); + } + + /// Allocates a managed System.String and copies a specified number of characters from an unmanaged Unicode string into it. + /// A managed string that holds a copy of the unmanaged string if the value of the ptr parameter is not null; otherwise, this method returns null. + public string PtrToStringUni(int offset, int length) + { + return Marshal.PtrToStringUni(new IntPtr(handle.ToInt64() + offset), length); + } + + /// Allocates a managed System.String and copies all characters up to the first null character from an unmanaged Unicode string into it. + /// A managed string that holds a copy of the unmanaged string if the value of the ptr parameter is not null; otherwise, this method returns null. + public string PtrToStringUni() + { + return Marshal.PtrToStringUni(handle); + } + + #endregion // Public Methods + } +} diff --git a/AlphaFS/Security/Crc32.cs b/AlphaFS/Security/Crc32.cs new file mode 100644 index 0000000..64b8af5 --- /dev/null +++ b/AlphaFS/Security/Crc32.cs @@ -0,0 +1,165 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * + * Copyright (c) Damien Guard. All rights reserved. + * AlphaFS has written permission from the author to include the CRC code. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Security.Cryptography; + +namespace Alphaleonis.Win32.Security +{ + /// Implements a 32-bit CRC hash algorithm compatible with Zip etc. + /// + /// Crc32 should only be used for backward compatibility with older file formats + /// and algorithms. It is not secure enough for new applications. + /// If you need to call multiple times for the same data either use the HashAlgorithm + /// interface or remember that the result of one Compute call needs to be ~ (XOR) before + /// being passed in as the seed for the next Compute call. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Crc")] + internal sealed class Crc32 : HashAlgorithm + { + private const uint DefaultPolynomial = 0xedb88320u; + private const uint DefaultSeed = 0xffffffffu; + + private uint m_hash; + private static uint[] s_defaultTable; + private readonly uint m_seed; + private readonly uint[] m_table; + + /// + /// Initializes a new instance of Crc32. + /// + public Crc32() + : this(DefaultPolynomial, DefaultSeed) + { + } + + /// Initializes a new instance of Crc32. + /// The polynomial. + /// The seed. + private Crc32(uint polynomial, uint seed) + { + m_table = InitializeTable(polynomial); + m_seed = m_hash = seed; + } + + /// + /// Initializes an implementation of the + /// class. + /// + public override void Initialize() + { + m_hash = m_seed; + } + + /// When overridden in a derived class, routes data written to the object into the hash algorithm for computing the hash. + /// The input to compute the hash code for.. + /// The offset into the byte array from which to begin using data. + /// The number of bytes in the byte array to use as data. + protected override void HashCore(byte[] array, int ibStart, int cbSize) + { + m_hash = CalculateHash(m_table, m_hash, array, ibStart, cbSize); + } + + /// + /// Finalizes the hash computation after the last data is processed by the cryptographic stream + /// object. + /// + /// + /// This method finalizes any partial computation and returns the correct hash value for the data + /// stream. + /// + protected override byte[] HashFinal() + { + var hashBuffer = UInt32ToBigEndianBytes(~m_hash); + HashValue = hashBuffer; + return hashBuffer; + } + + /// Gets the size, in bits, of the computed hash code. + /// The size, in bits, of the computed hash code. + public override int HashSize + { + get { return 32; } + } + + /// Initializes the table. + /// The polynomial. + /// The table. + private static uint[] InitializeTable(uint polynomial) + { + if (polynomial == DefaultPolynomial && s_defaultTable != null) + return s_defaultTable; + + var createTable = new uint[256]; + for (var i = 0; i < 256; i++) + { + var entry = (uint) i; + for (var j = 0; j < 8; j++) + if ((entry & 1) == 1) + entry = (entry >> 1) ^ polynomial; + else + entry = entry >> 1; + createTable[i] = entry; + } + + if (polynomial == DefaultPolynomial) + s_defaultTable = createTable; + + return createTable; + } + + /// Calculates the hash. + /// The table. + /// The seed. + /// The buffer. + /// The start. + /// The size. + /// The calculated hash. + private static uint CalculateHash(uint[] table, uint seed, IList buffer, int start, int size) + { + var hash = seed; + + for (var i = start; i < start + size; i++) + hash = (hash >> 8) ^ table[buffer[i] ^ hash & 0xff]; + + return hash; + } + + /// Int 32 to big endian bytes. + /// The second uint 3. + /// A byte[]. + private static byte[] UInt32ToBigEndianBytes(uint uint32) + { + var result = BitConverter.GetBytes(uint32); + + if (BitConverter.IsLittleEndian) + Array.Reverse(result); + + return result; + } + } +} diff --git a/AlphaFS/Security/Crc64.cs b/AlphaFS/Security/Crc64.cs new file mode 100644 index 0000000..800d33a --- /dev/null +++ b/AlphaFS/Security/Crc64.cs @@ -0,0 +1,166 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * + * Copyright (c) Damien Guard. All rights reserved. + * AlphaFS has written permission from the author to include the CRC code. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Security.Cryptography; + +namespace Alphaleonis.Win32.Security +{ + /// Implements an ISO-3309 compliant 64-bit CRC hash algorithm. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Crc")] + internal class Crc64 : HashAlgorithm + { + private static ulong[] Table; + private const ulong Iso3309Polynomial = 0xD800000000000000; + private const ulong DefaultSeed = 0x0; + private readonly ulong[] m_table; + private readonly ulong m_seed; + private ulong m_hash; + + /// Initializes a new instance of + public Crc64() + : this(Iso3309Polynomial, DefaultSeed) + { + } + + /// Initializes a new instance of + /// The polynomial. + /// The seed. + private Crc64(ulong polynomial, ulong seed) + { + m_table = InitializeTable(polynomial); + this.m_seed = m_hash = seed; + } + + /// + /// Initializes an implementation of the + /// class. + /// + public override void Initialize() + { + m_hash = m_seed; + } + + /// When overridden in a derived class, routes data written to the object into the hash algorithm for computing the hash. + /// The input to compute the hash code for.. + /// The offset into the byte array from which to begin using data. + /// The number of bytes in the byte array to use as data. + protected override void HashCore(byte[] array, int ibStart, int cbSize) + { + m_hash = CalculateHash(m_hash, m_table, array, ibStart, cbSize); + } + + /// + /// Finalizes the hash computation after the last data is processed by the cryptographic stream + /// object. + /// + /// + /// This method finalizes any partial computation and returns the correct hash value for the data + /// stream. + /// + protected override byte[] HashFinal() + { + var hashBuffer = UInt64ToBigEndianBytes(m_hash); + HashValue = hashBuffer; + return hashBuffer; + } + + /// Gets the size, in bits, of the computed hash code. + /// The size, in bits, of the computed hash code. + public override int HashSize + { + get { return 64; } + } + + /// Calculates the hash. + /// The seed. + /// The table. + /// The buffer. + /// The start. + /// The size. + /// The calculated hash. + private static ulong CalculateHash(ulong seed, ulong[] table, IList buffer, int start, int size) + { + var hash = seed; + for (var i = start; i < start + size; i++) + unchecked + { + hash = (hash >> 8) ^ table[(buffer[i] ^ hash) & 0xff]; + } + return hash; + } + + /// Int 64 to big endian bytes. + /// The value. + /// A byte[]. + private static byte[] UInt64ToBigEndianBytes(ulong value) + { + var result = BitConverter.GetBytes(value); + + if (BitConverter.IsLittleEndian) + Array.Reverse(result); + + return result; + } + + /// Initializes the table. + /// The polynomial. + /// An ulong[]. + private static ulong[] InitializeTable(ulong polynomial) + { + if (polynomial == Iso3309Polynomial && Table != null) + return Table; + + var createTable = CreateTable(polynomial); + + if (polynomial == Iso3309Polynomial) + Table = createTable; + + return createTable; + } + + /// Creates a table. + /// The polynomial. + /// A new array of ulong. + private static ulong[] CreateTable(ulong polynomial) + { + var createTable = new ulong[256]; + for (var i = 0; i < 256; ++i) + { + var entry = (ulong)i; + for (var j = 0; j < 8; ++j) + if ((entry & 1) == 1) + entry = (entry >> 1) ^ polynomial; + else + entry = entry >> 1; + createTable[i] = entry; + } + + return createTable; + } + } +} diff --git a/AlphaFS/Security/Enumerations/HashType.cs b/AlphaFS/Security/Enumerations/HashType.cs new file mode 100644 index 0000000..bd234c6 --- /dev/null +++ b/AlphaFS/Security/Enumerations/HashType.cs @@ -0,0 +1,61 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Diagnostics.CodeAnalysis; + +namespace Alphaleonis.Win32.Security +{ + /// Enum containing the supported hash types. + public enum HashType + { + /// CRC-32 (Cyclic Redundancy Check) + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "CRC")] + CRC32, + + /// CRC-64 ISO-3309 compliant. + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "CRC")] + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ISO")] + CRC64ISO3309, + + /// MD5 (Message digest) + MD5, + + /// RIPEMD-160 is a 160-bit cryptographic hash function. It is intended for use as a replacement for the 128-bit hash functions MD4, MD5, and RIPEMD. + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "RIPEMD")] + RIPEMD160, + + /// SHA-1 (Secure Hash Algorithm) + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SHA")] + SHA1, + + /// SHA-256 (Secure Hash Algorithm) + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SHA")] + SHA256, + + /// SHA-384 (Secure Hash Algorithm) + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SHA")] + SHA384, + + /// SHA-512 (Secure Hash Algorithm) + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SHA")] + SHA512 + } +} diff --git a/AlphaFS/Security/Enumerations/ObjectType.cs b/AlphaFS/Security/Enumerations/ObjectType.cs new file mode 100644 index 0000000..1d13f2f --- /dev/null +++ b/AlphaFS/Security/Enumerations/ObjectType.cs @@ -0,0 +1,76 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32.Security +{ + /// The ObjectType (SE_OBJECT_TYPE) enumeration contains values that correspond to the types of Windows objects that support security. + /// The functions, such as GetSecurityInfo and SetSecurityInfo, that set and retrieve the security information of an object, use these values to indicate the type of object. + /// + internal enum ObjectType + { + /// Unknown object type. + UnknownObjectType = 0, + + /// Indicates a file or directory. The name string that identifies a file or directory object can be in one of the following formats: + /// A relative path, such as FileName.dat or ..\FileName + /// An absolute path, such as FileName.dat, C:\DirectoryName\FileName.dat, or G:\RemoteDirectoryName\FileName.dat. + /// A UNC name, such as \\ComputerName\ShareName\FileName.dat. + /// + FileObject, + + /// Indicates a Windows service. A service object can be a local service, such as ServiceName, or a remote service, such as \\ComputerName\ServiceName. + Service, + + /// Indicates a printer. A printer object can be a local printer, such as PrinterName, or a remote printer, such as \\ComputerName\PrinterName. + Printer, + + /// Indicates a registry key. A registry key object can be in the local registry, such as CLASSES_ROOT\SomePath or in a remote registry, such as \\ComputerName\CLASSES_ROOT\SomePath. + /// The names of registry keys must use the following literal strings to identify the predefined registry keys: "CLASSES_ROOT", "CURRENT_USER", "MACHINE", and "USERS". + /// + RegistryKey, + + /// Indicates a network share. A share object can be local, such as ShareName, or remote, such as \\ComputerName\ShareName. + LmShare, + + /// Indicates a local kernel object. The GetSecurityInfo and SetSecurityInfo functions support all types of kernel objects. + /// The GetNamedSecurityInfo and SetNamedSecurityInfo functions work only with the following kernel objects: semaphore, event, mutex, waitable timer, and file mapping. + KernelObject, + + /// Indicates a window station or desktop object on the local computer. You cannot use GetNamedSecurityInfo and SetNamedSecurityInfo with these objects because the names of window stations or desktops are not unique. + WindowObject, + + /// Indicates a directory service object or a property set or property of a directory service object. + /// The name string for a directory service object must be in X.500 form, for example: CN=SomeObject,OU=ou2,OU=ou1,DC=DomainName,DC=CompanyName,DC=com,O=internet + DsObject, + + /// Indicates a directory service object and all of its property sets and properties. + DsObjectAll, + + /// Indicates a provider-defined object. + ProviderDefinedObject, + + /// Indicates a WMI object. + WmiGuidObject, + + /// Indicates an object for a registry entry under WOW64. + RegistryWow6432Key + } +} diff --git a/AlphaFS/Security/Enumerations/SecurityDescriptorControl.cs b/AlphaFS/Security/Enumerations/SecurityDescriptorControl.cs new file mode 100644 index 0000000..b18ed13 --- /dev/null +++ b/AlphaFS/Security/Enumerations/SecurityDescriptorControl.cs @@ -0,0 +1,76 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace Alphaleonis.Win32.Security +{ + /// The SECURITY_DESCRIPTOR_CONTROL data type is a set of bit flags that qualify the meaning of a security descriptor or its components. + /// Each security descriptor has a Control member that stores the SECURITY_DESCRIPTOR_CONTROL bits. + [Flags] + internal enum SecurityDescriptorControl + { + /// + None = 0, + + /// SE_OWNER_DEFAULTED (0x0001) - Indicates an SD with a default owner security identifier (SID). You can use this bit to find all of the objects that have default owner permissions set. + OwnerDefaulted = 1, + + /// SE_GROUP_DEFAULTED (0x0002) - Indicates an SD with a default group SID. You can use this bit to find all of the objects that have default group permissions set. + GroupDefaulted = 2, + + /// SE_DACL_PRESENT (0x0004) - Indicates an SD that has a discretionary access control list (DACL). If this flag is not set, or if this flag is set and the DACL is NULL, the SD allows full access to everyone. + DaclPresent = 4, + + /// SE_DACL_DEFAULTED (0x0008) - Indicates an SD with a default DACL. For example, if an object creator does not specify a DACL, the object receives the default DACL from the access token of the creator. This flag can affect how the system treats the DACL, with respect to access control entry (ACE) inheritance. The system ignores this flag if the SE_DACL_PRESENT flag is not set. + DaclDefaulted = 8, + + /// SE_SACL_PRESENT (0x0010) - Indicates an SD that has a system access control list (SACL). + SaclPresent = 16, + + /// SE_SACL_DEFAULTED (0x0020) - Indicates an SD with a default SACL. For example, if an object creator does not specify an SACL, the object receives the default SACL from the access token of the creator. This flag can affect how the system treats the SACL, with respect to ACE inheritance. The system ignores this flag if the SE_SACL_PRESENT flag is not set. + SaclDefaulted = 32, + + /// SE_DACL_AUTO_INHERIT_REQ (0x0100) - Requests that the provider for the object protected by the SD automatically propagate the DACL to existing child objects. If the provider supports automatic inheritance, it propagates the DACL to any existing child objects, and sets the SE_DACL_AUTO_INHERITED bit in the security descriptors of the object and its child objects. + DaclAutoInheritReq = 256, + + /// SE_SACL_AUTO_INHERIT_REQ (0x0200) - Requests that the provider for the object protected by the SD automatically propagate the SACL to existing child objects. If the provider supports automatic inheritance, it propagates the SACL to any existing child objects, and sets the SE_SACL_AUTO_INHERITED bit in the SDs of the object and its child objects. + SaclAutoInheritReq = 512, + + /// SE_DACL_AUTO_INHERITED (0x0400) - Windows 2000 only. Indicates an SD in which the DACL is set up to support automatic propagation of inheritable ACEs to existing child objects. The system sets this bit when it performs the automatic inheritance algorithm for the object and its existing child objects. This bit is not set in SDs for Windows NT versions 4.0 and earlier, which do not support automatic propagation of inheritable ACEs. + DaclAutoInherited = 1024, + + /// SE_SACL_AUTO_INHERITED (0x0800) - Windows 2000: Indicates an SD in which the SACL is set up to support automatic propagation of inheritable ACEs to existing child objects. The system sets this bit when it performs the automatic inheritance algorithm for the object and its existing child objects. This bit is not set in SDs for Windows NT versions 4.0 and earlier, which do not support automatic propagation of inheritable ACEs. + SaclAutoInherited = 2048, + + /// SE_DACL_PROTECTED (0x1000) - Windows 2000: Prevents the DACL of the SD from being modified by inheritable ACEs. + DaclProtected = 4096, + + /// SE_SACL_PROTECTED (0x2000) - Windows 2000: Prevents the SACL of the SD from being modified by inheritable ACEs. + SaclProtected = 8192, + + /// SE_RM_CONTROL_VALID (0x4000) - Indicates that the resource manager control is valid. + RmControlValid = 16384, + + /// SE_SELF_RELATIVE (0x8000) - Indicates an SD in self-relative format with all of the security information in a contiguous block of memory. If this flag is not set, the SD is in absolute format. For more information, see Absolute and Self-Relative Security Descriptors. + SelfRelative = 32768 + } +} \ No newline at end of file diff --git a/AlphaFS/Security/Enumerations/SecurityInformation.cs b/AlphaFS/Security/Enumerations/SecurityInformation.cs new file mode 100644 index 0000000..c4540d2 --- /dev/null +++ b/AlphaFS/Security/Enumerations/SecurityInformation.cs @@ -0,0 +1,87 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace Alphaleonis.Win32.Security +{ + /// The SECURITY_INFORMATION data type identifies the object-related security information being set or queried. + /// This security information includes: + /// The owner of an object; + /// The primary group of an object; + /// The discretionary access control list (DACL) of an object; + /// The system access control list (SACL) of an object; + /// + /// + /// An unsigned 32-bit integer specifies portions of a SECURITY_DESCRIPTOR by means of bit flags. + /// Individual bit values (combinable with the bitwise OR operation) are as shown in the following table. + /// + [Flags] + internal enum SecurityInformation : uint + { + /// + None = 0, + + /// OWNER_SECURITY_INFORMATION (0x00000001) - The owner identifier of the object is being referenced. + Owner = 1, + + /// GROUP_SECURITY_INFORMATION (0x00000002) - The primary group identifier of the object is being referenced. + Group = 2, + + /// DACL_SECURITY_INFORMATION (0x00000004) - The DACL of the object is being referenced. + Dacl = 4, + + /// SACL_SECURITY_INFORMATION (0x00000008) - The SACL of the object is being referenced. + Sacl = 8, + + /// LABEL_SECURITY_INFORMATION (0x00000010) - The mandatory integrity label is being referenced. The mandatory integrity label is an ACE in the SACL of the object. + /// Windows Server 2003 and Windows XP: This bit flag is not available. + Label = 16, + + /// ATTRIBUTE_SECURITY_INFORMATION (0x00000020) - The resource properties of the object being referenced. + /// The resource properties are stored in SYSTEM_RESOURCE_ATTRIBUTE_ACE types in the SACL of the security descriptor. + /// + /// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: This bit flag is not available. + Attribute = 32, + + /// SCOPE_SECURITY_INFORMATION (0x00000040) - The Central Access Policy (CAP) identifier applicable on the object that is being referenced. + /// Each CAP identifier is stored in a SYSTEM_SCOPED_POLICY_ID_ACE type in the SACL of the SD. + /// + /// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: This bit flag is not available. + Scope = 64, + + /// BACKUP_SECURITY_INFORMATION (0x00010000) - All parts of the security descriptor. This is useful for backup and restore software that needs to preserve the entire security descriptor. + /// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: This bit flag is not available. + Backup = 65536, + + /// UNPROTECTED_SACL_SECURITY_INFORMATION (0x10000000) - The SACL inherits ACEs from the parent object. + UnprotectedSacl = 268435456, + + /// UNPROTECTED_DACL_SECURITY_INFORMATION (0x20000000) - The DACL inherits ACEs from the parent object. + UnprotectedDacl = 536870912, + + /// PROTECTED_SACL_SECURITY_INFORMATION (0x40000000) - The SACL cannot inherit ACEs. + ProtectedSacl = 1073741824, + + /// PROTECTED_DACL_SECURITY_INFORMATION (0x80000000) - The DACL cannot inherit access control entries (ACEs). + ProtectedDacl = 2147483648 + } +} \ No newline at end of file diff --git a/AlphaFS/Security/InternalPrivilegeEnabler.cs b/AlphaFS/Security/InternalPrivilegeEnabler.cs new file mode 100644 index 0000000..14156a0 --- /dev/null +++ b/AlphaFS/Security/InternalPrivilegeEnabler.cs @@ -0,0 +1,101 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.Principal; + +namespace Alphaleonis.Win32.Security +{ + /// + /// This object is used to enable a specific privilege for the currently running process during its lifetime. + /// It should be disposed as soon as the elevated privilege is no longer needed. + /// For more information see the documentation on AdjustTokenPrivileges on MSDN. + /// + internal sealed class InternalPrivilegeEnabler : IDisposable + { + /// Initializes a new instance of the class and enabling the specified privilege for the currently running process. + /// The name of the privilege. + [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] + [SecurityCritical] + public InternalPrivilegeEnabler(Privilege privilegeName) + { + if (privilegeName == null) + throw new ArgumentNullException("privilegeName"); + + _mPrivilege = privilegeName; + AdjustPrivilege(true); + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// In this case the privilege previously enabled will be disabled. + /// + public void Dispose() + { + try + { + if (_mPrivilege != null) + AdjustPrivilege(false); + } + finally + { + _mPrivilege = null; + } + } + + /// Adjusts the privilege. + /// the privilege will be enabled, otherwise disabled. + [SecurityCritical] + private void AdjustPrivilege(bool enable) + { + using (WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent(TokenAccessLevels.Query | TokenAccessLevels.AdjustPrivileges)) + { + if (currentIdentity != null) + { + IntPtr hToken = currentIdentity.Token; + TokenPrivileges newPrivilege = new TokenPrivileges(); + TokenPrivileges mOldPrivilege = new TokenPrivileges(); + newPrivilege.PrivilegeCount = 1; + newPrivilege.Luid = Filesystem.NativeMethods.LongToLuid(_mPrivilege.LookupLuid()); + newPrivilege.Attributes = (uint)(enable ? 2 : 0); // 2 = SePrivilegeEnabled; + + uint length; + if (!NativeMethods.AdjustTokenPrivileges(hToken, false, ref newPrivilege, (uint) Marshal.SizeOf(mOldPrivilege), out mOldPrivilege, out length)) + NativeError.ThrowException(Marshal.GetLastWin32Error()); + + // If no privilege was changed, we don't want to reset it. + if (mOldPrivilege.PrivilegeCount == 0) + _mPrivilege = null; + } + } + } + + public Privilege EnabledPrivilege + { + get { return _mPrivilege; } + } + + private Privilege _mPrivilege; + } +} diff --git a/AlphaFS/Security/NativeMethods.cs b/AlphaFS/Security/NativeMethods.cs new file mode 100644 index 0000000..246ba9c --- /dev/null +++ b/AlphaFS/Security/NativeMethods.cs @@ -0,0 +1,275 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Security +{ + internal static partial class NativeMethods + { + #region AdjustTokenPrivileges + + /// The AdjustTokenPrivileges function enables or disables privileges in the specified access token. Enabling or disabling privileges in an access token requires TOKEN_ADJUST_PRIVILEGES access. + /// + /// If the function succeeds, the return value is nonzero. + /// To determine whether the function adjusted all of the specified privileges, call GetLastError. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool AdjustTokenPrivileges(IntPtr tokenHandle, [MarshalAs(UnmanagedType.Bool)] bool disableAllPrivileges, ref TokenPrivileges newState, uint bufferLength, out TokenPrivileges previousState, out uint returnLength); + + #endregion // AdjustTokenPrivileges + + #region LookupPrivilegeDisplayName + + /// The LookupPrivilegeDisplayName function retrieves the display name that represents a specified privilege. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, it returns zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "LookupPrivilegeDisplayNameW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool LookupPrivilegeDisplayName([MarshalAs(UnmanagedType.LPWStr)] string lpSystemName, [MarshalAs(UnmanagedType.LPWStr)] string lpName, ref StringBuilder lpDisplayName, ref uint cchDisplayName, out uint lpLanguageId); + + #endregion // LookupPrivilegeDisplayName + + #region LookupPrivilegeValue + + /// The LookupPrivilegeValue function retrieves the locally unique identifier (LUID) used on a specified system to locally represent the specified privilege name. + /// + /// If the function succeeds, the function returns nonzero. + /// If the function fails, it returns zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "LookupPrivilegeValueW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool LookupPrivilegeValue([MarshalAs(UnmanagedType.LPWStr)] string lpSystemName, [MarshalAs(UnmanagedType.LPWStr)] string lpName, out Luid lpLuid); + + #endregion // LookupPrivilegeValue + + + #region GetNamedSecurityInfo + + /// The GetNamedSecurityInfo function retrieves a copy of the security descriptor for an object specified by name. + ///   + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is a nonzero error code defined in WinError.h. + /// + ///   + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetNamedSecurityInfoW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint GetNamedSecurityInfo([MarshalAs(UnmanagedType.LPWStr)] string pObjectName, ObjectType objectType, SecurityInformation securityInfo, out IntPtr pSidOwner, out IntPtr pSidGroup, out IntPtr pDacl, out IntPtr pSacl, out SafeGlobalMemoryBufferHandle pSecurityDescriptor); + + #endregion // GetNamedSecurityInfo + + #region GetSecurityInfo + + /// The GetSecurityInfo function retrieves a copy of the security descriptor for an object specified by a handle. + /// + /// If the function succeeds, the function returns nonzero. + /// If the function fails, it returns zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint GetSecurityInfo(SafeHandle handle, ObjectType objectType, SecurityInformation securityInfo, out IntPtr pSidOwner, out IntPtr pSidGroup, out IntPtr pDacl, out IntPtr pSacl, out SafeGlobalMemoryBufferHandle pSecurityDescriptor); + + #endregion // GetSecurityInfo + + #region SetSecurityInfo + + /// The SetSecurityInfo function sets specified security information in the security descriptor of a specified object. + /// The caller identifies the object by a handle. + /// + /// If the function succeeds, the function returns ERROR_SUCCESS. + /// If the function fails, it returns a nonzero error code defined in WinError.h. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint SetSecurityInfo(SafeHandle handle, ObjectType objectType, SecurityInformation securityInfo, IntPtr psidOwner, IntPtr psidGroup, IntPtr pDacl, IntPtr pSacl); + + #endregion // SetSecurityInfo + + #region SetNamedSecurityInfo + + /// The SetNamedSecurityInfo function sets specified security information in the security descriptor of a specified object. The caller identifies the object by name. + ///   + /// + /// If the function succeeds, the function returns ERROR_SUCCESS. + /// If the function fails, it returns a nonzero error code defined in WinError.h. + /// + ///   + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + /// + /// + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "SetNamedSecurityInfoW"), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint SetNamedSecurityInfo([MarshalAs(UnmanagedType.LPWStr)] string pObjectName, ObjectType objectType, SecurityInformation securityInfo, IntPtr pSidOwner, IntPtr pSidGroup, IntPtr pDacl, IntPtr pSacl); + + #endregion // SetNamedSecurityInfo + + + #region GetSecurityDescriptorDacl + + /// The GetSecurityDescriptorDacl function retrieves a pointer to the discretionary access control list (DACL) in a specified security descriptor. + /// + /// If the function succeeds, the function returns nonzero. + /// If the function fails, it returns zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetSecurityDescriptorDacl(SafeGlobalMemoryBufferHandle pSecurityDescriptor, [MarshalAs(UnmanagedType.Bool)] out bool lpbDaclPresent, out IntPtr pDacl, [MarshalAs(UnmanagedType.Bool)] out bool lpbDaclDefaulted); + + #endregion // GetSecurityDescriptorDacl + + #region GetSecurityDescriptorSacl + + /// The GetSecurityDescriptorSacl function retrieves a pointer to the system access control list (SACL) in a specified security descriptor. + /// + /// If the function succeeds, the function returns nonzero. + /// If the function fails, it returns zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetSecurityDescriptorSacl(SafeGlobalMemoryBufferHandle pSecurityDescriptor, [MarshalAs(UnmanagedType.Bool)] out bool lpbSaclPresent, out IntPtr pSacl, [MarshalAs(UnmanagedType.Bool)] out bool lpbSaclDefaulted); + + #endregion // GetSecurityDescriptorSacl + + #region GetSecurityDescriptorGroup + + /// The GetSecurityDescriptorGroup function retrieves the primary group information from a security descriptor. + /// + /// If the function succeeds, the function returns nonzero. + /// If the function fails, it returns zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetSecurityDescriptorGroup(SafeGlobalMemoryBufferHandle pSecurityDescriptor, out IntPtr pGroup, [MarshalAs(UnmanagedType.Bool)] out bool lpbGroupDefaulted); + + #endregion // GetSecurityDescriptorGroup + + #region GetSecurityDescriptorControl + + /// The GetSecurityDescriptorControl function retrieves a security descriptor control and revision information. + /// + /// If the function succeeds, the function returns nonzero. + /// If the function fails, it returns zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetSecurityDescriptorControl(SafeGlobalMemoryBufferHandle pSecurityDescriptor, out SecurityDescriptorControl pControl, out uint lpdwRevision); + + #endregion // GetSecurityDescriptorControl + + #region GetSecurityDescriptorOwner + + /// The GetSecurityDescriptorOwner function retrieves the owner information from a security descriptor. + /// + /// If the function succeeds, the function returns nonzero. + /// If the function fails, it returns zero. To get extended error information, call GetLastError. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetSecurityDescriptorOwner(SafeGlobalMemoryBufferHandle pSecurityDescriptor, out IntPtr pOwner, [MarshalAs(UnmanagedType.Bool)] out bool lpbOwnerDefaulted); + + #endregion // GetSecurityDescriptorOwner + + #region GetSecurityDescriptorLength + + /// The GetSecurityDescriptorLength function returns the length, in bytes, of a structurally valid security descriptor. The length includes the length of all associated structures. + /// + /// If the function succeeds, the function returns the length, in bytes, of the SECURITY_DESCRIPTOR structure. + /// If the SECURITY_DESCRIPTOR structure is not valid, the return value is undefined. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.U4)] + internal static extern uint GetSecurityDescriptorLength(SafeGlobalMemoryBufferHandle pSecurityDescriptor); + + #endregion // GetSecurityDescriptorLength + + + #region LocalFree + + /// Frees the specified local memory object and invalidates its handle. + /// + /// If the function succeeds, the return value is . + /// If the function fails, the return value is equal to a handle to the local memory object. To get extended error information, call GetLastError. + /// + /// SetLastError is set to . + /// + /// Note The local functions have greater overhead and provide fewer features than other memory management functions. + /// New applications should use the heap functions unless documentation states that a local function should be used. + /// For more information, see Global and Local Functions. + /// + /// Minimum supported client: Windows XP [desktop apps only] + /// Minimum supported server: Windows Server 2003 [desktop apps only] + [SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")] + [DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + internal static extern IntPtr LocalFree(IntPtr hMem); + + #endregion // LocalFree + } +} \ No newline at end of file diff --git a/AlphaFS/Security/Privilege.cs b/AlphaFS/Security/Privilege.cs new file mode 100644 index 0000000..f80273d --- /dev/null +++ b/AlphaFS/Security/Privilege.cs @@ -0,0 +1,494 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace Alphaleonis.Win32.Security +{ + /// Represents a privilege for an access token. The privileges available on the local machine are available as + /// static instances from this class. To create a representing a privilege on another system, + /// use the constructor specifying a system name together with one of these static instances. + /// + /// + [ImmutableObject(true)] + public class Privilege : IEquatable + { + #region System Privileges + + #region AssignPrimaryToken + + /// Required to assign the primary token of a process. User Right: Replace a process-level token. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege AssignPrimaryToken = new Privilege("SeAssignPrimaryTokenPrivilege"); + + #endregion // AssignPrimaryToken + + #region Audit + + /// Required to generate audit-log entries. Give this privilege to secure servers. User Right: Generate security audits. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege Audit = new Privilege("SeAuditPrivilege"); + + #endregion // Audit + + #region Backup + + /// Required to perform backup operations. This privilege causes the system to grant all read access control to any file, regardless of the access control list (ACL) specified for the file. Any access request other than read is still evaluated with the ACL. User Right: Back up files and directories. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege Backup = new Privilege("SeBackupPrivilege"); + + #endregion // Backup + + #region ChangeNotify + + /// Required to receive notifications of changes to files or directories. This privilege also causes the system to skip all traversal access checks. It is enabled by default for all users. User Right: Bypass traverse checking. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege ChangeNotify = new Privilege("SeChangeNotifyPrivilege"); + + #endregion // ChangeNotify + + #region CreateGlobal + + /// Required to create named file mapping objects in the global namespace during Terminal Services sessions. This privilege is enabled by default for administrators, services, and the local system account. User Right: Create global objects. + /// Windows XP/2000: This privilege is not supported. Note that this value is supported starting with Windows Server 2003, Windows XP SP2, and Windows 2000 SP4. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege CreateGlobal = new Privilege("SeCreateGlobalPrivilege"); + + #endregion // CreateGlobal + + #region CreatePagefile + + /// Required to create a paging file. User Right: Create a pagefile. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Pagefile")] + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege CreatePagefile = new Privilege("SeCreatePagefilePrivilege"); + + #endregion // CreatePagefile + + #region CreatePermanent + + /// Required to create a permanent object. User Right: Create permanent shared objects. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege CreatePermanent = new Privilege("SeCreatePermanentPrivilege"); + + #endregion // CreatePermanent + + #region CreateSymbolicLink + + /// Required to create a symbolic link. User Right: Create symbolic links. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege CreateSymbolicLink = new Privilege("SeCreateSymbolicLinkPrivilege"); + + #endregion // CreateSymbolicLink + + #region CreateToken + + /// Required to create a primary token. User Right: Create a token object. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege CreateToken = new Privilege("SeCreateTokenPrivilege"); + + #endregion // CreateToken + + #region Debug + + /// Required to debug and adjust the memory of a process owned by another account. User Right: Debug programs. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege Debug = new Privilege("SeDebugPrivilege"); + + #endregion // Debug + + #region EnableDelegation + + /// Required to mark user and computer accounts as trusted for delegation. User Right: Enable computer and user accounts to be trusted for delegation. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege EnableDelegation = new Privilege("SeEnableDelegationPrivilege"); + + #endregion // EnableDelegation + + #region Impersonate + + /// Required to impersonate. User Right: Impersonate a client after authentication. + /// Windows XP/2000: This privilege is not supported. Note that this value is supported starting with Windows Server 2003, Windows XP SP2, and Windows 2000 SP4. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege Impersonate = new Privilege("SeImpersonatePrivilege"); + + #endregion // Impersonate + + #region IncreaseBasePriority + + /// Required to increase the base priority of a process. User Right: Increase scheduling priority. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege IncreaseBasePriority = new Privilege("SeIncreaseBasePriorityPrivilege"); + + #endregion // IncreaseBasePriority + + #region IncreaseQuota + + /// Required to increase the quota assigned to a process. User Right: Adjust memory quotas for a process. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege IncreaseQuota = new Privilege("SeIncreaseQuotaPrivilege"); + + #endregion // IncreaseQuota + + #region IncreaseWorkingSet + + /// Required to allocate more memory for applications that run in the context of users. User Right: Increase a process working set. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege IncreaseWorkingSet = new Privilege("SeIncreaseWorkingSetPrivilege"); + + #endregion // IncreaseWorkingSet + + #region LoadDriver + + /// Required to load or unload a device driver. User Right: Load and unload device drivers. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege LoadDriver = new Privilege("SeLoadDriverPrivilege"); + + #endregion // LoadDriver + + #region LockMemory + + /// Required to lock physical pages in memory. User Right: Lock pages in memory. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege LockMemory = new Privilege("SeLockMemoryPrivilege"); + + #endregion // LockMemory + + #region MachineAccount + + /// Required to create a computer account. User Right: Add workstations to domain. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege MachineAccount = new Privilege("SeMachineAccountPrivilege"); + + #endregion // MachineAccount + + #region ManageVolume + + /// Required to enable volume management privileges. User Right: Manage the files on a volume. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege ManageVolume = new Privilege("SeManageVolumePrivilege"); + + #endregion // ManageVolume + + #region ProfileSingleProcess + + /// Required to gather profiling information for a single process. User Right: Profile single process. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege ProfileSingleProcess = new Privilege("SeProfileSingleProcessPrivilege"); + + #endregion // ProfileSingleProcess + + #region Relabel + + /// Required to modify the mandatory integrity level of an object. User Right: Modify an object label. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Relabel")] + public static readonly Privilege Relabel = new Privilege("SeRelabelPrivilege"); + + #endregion // Relabel + + #region RemoteShutdown + + /// Required to shut down a system using a network request. User Right: Force shutdown from a remote system. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege RemoteShutdown = new Privilege("SeRemoteShutdownPrivilege"); + + #endregion // RemoteShutdown + + #region Restore + + /// Required to perform restore operations. This privilege causes the system to grant all write access control to any file, regardless of the ACL specified for the file. Any access request other than write is still evaluated with the ACL. Additionally, this privilege enables you to set any valid user or group SID as the owner of a file. User Right: Restore files and directories. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege Restore = new Privilege("SeRestorePrivilege"); + + #endregion // Restore + + #region Security + + /// Required to perform a number of security-related functions, such as controlling and viewing audit messages. This privilege identifies its holder as a security operator. User Right: Manage auditing and security log. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege Security = new Privilege("SeSecurityPrivilege"); + + #endregion // Security + + #region Shutdown + + /// Required to shut down a local system. User Right: Shut down the system. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege Shutdown = new Privilege("SeShutdownPrivilege"); + + #endregion // Shutdown + + #region SyncAgent + + /// Required for a domain controller to use the LDAP directory synchronization services. This privilege enables the holder to read all objects and properties in the directory, regardless of the protection on the objects and properties. By default, it is assigned to the Administrator and LocalSystem accounts on domain controllers. User Right: Synchronize directory service data. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege SyncAgent = new Privilege("SeSyncAgentPrivilege"); + + #endregion // SyncAgent + + #region SystemEnvironment + + /// Required to modify the nonvolatile RAM of systems that use this type of memory to store configuration information. User Right: Modify firmware environment values. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege SystemEnvironment = new Privilege("SeSystemEnvironmentPrivilege"); + + #endregion // SystemEnvironment + + #region SystemProfile + + /// Required to gather profiling information for the entire system. User Right: Profile system performance. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege SystemProfile = new Privilege("SeSystemProfilePrivilege"); + + #endregion // SystemProfile + + #region SystemTime + + /// Required to modify the system time. User Right: Change the system time. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege SystemTime = new Privilege("SeSystemtimePrivilege"); + + #endregion // SystemTime + + #region TakeOwnership + + /// Required to take ownership of an object without being granted discretionary access. This privilege allows the owner value to be set only to those values that the holder may legitimately assign as the owner of an object. User Right: Take ownership of files or other objects. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege TakeOwnership = new Privilege("SeTakeOwnershipPrivilege"); + + #endregion // TakeOwnership + + #region Tcb + + /// This privilege identifies its holder as part of the trusted computer base. Some trusted protected subsystems are granted this privilege. User Right: Act as part of the operating system. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tcb")] + public static readonly Privilege Tcb = new Privilege("SeTcbPrivilege"); + + #endregion // Tcb + + #region TimeZone + + /// Required to adjust the time zone associated with the computer's internal clock. User Right: Change the time zone. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege TimeZone = new Privilege("SeTimeZonePrivilege"); + + #endregion // TimeZone + + #region TrustedCredManAccess + + /// Required to access Credential Manager as a trusted caller. User Right: Access Credential Manager as a trusted caller. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cred")] + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege TrustedCredManAccess = new Privilege("SeTrustedCredManAccessPrivilege"); + + #endregion // TrustedCredManAccess + + #region Undock + + /// Required to undock a laptop. User Right: Remove computer from docking station. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege Undock = new Privilege("SeUndockPrivilege"); + + #endregion // Undock + + #region UnsolicitedInput + + /// Required to read unsolicited input from a terminal device. User Right: Not applicable. + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly Privilege UnsolicitedInput = new Privilege("SeUnsolicitedInputPrivilege"); + + #endregion // UnsolicitedInput + + #endregion // System Privileges + + #region Privilege + + private readonly string _systemName; + + /// Create a new representing the specified privilege on the specified system. + /// Name of the system. + /// The privilege to copy the privilege name from. + public Privilege(string systemName, Privilege privilege) + { + if (Utils.IsNullOrWhiteSpace(systemName)) + throw new ArgumentException(Resources.Privilege_Name_Cannot_Be_Empty, "systemName"); + + _systemName = systemName; + + if (privilege != null) + _name = privilege._name; + } + + #endregion // Privilege + + #region Name + + private readonly string _name; + + /// Gets the system name identifying this privilege. + /// The system name identifying this privilege. + public string Name + { + get { return _name; } + } + + #endregion // Name + + #region LookupDisplayName + + /// Retrieves the display name that represents this privilege. + /// The display name that represents this privilege. + [SecurityCritical] + public string LookupDisplayName() + { + const uint initialCapacity = 10; + uint displayNameCapacity = initialCapacity; + StringBuilder displayName = new StringBuilder((int) displayNameCapacity); + uint languageId; + + if (!NativeMethods.LookupPrivilegeDisplayName(_systemName, _name, ref displayName, ref displayNameCapacity, out languageId)) + { + int lastError = Marshal.GetLastWin32Error(); + if (lastError == Win32Errors.ERROR_INSUFFICIENT_BUFFER) + { + displayName = new StringBuilder((int) displayNameCapacity + 1); + if (!NativeMethods.LookupPrivilegeDisplayName(_systemName, _name, ref displayName, ref displayNameCapacity, out languageId)) + NativeError.ThrowException(Marshal.GetLastWin32Error()); + } + else + NativeError.ThrowException(lastError); + } + return displayName.ToString(); + } + + #endregion // LookupDisplayName + + #region LookupLuid + + /// Retrieves the locally unique identifier (LUID) used on to represent this privilege (on the system from which it originates). + /// the locally unique identifier (LUID) used on to represent this privilege (on the system from which it originates). + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Luid")] + [SecurityCritical] + public long LookupLuid() + { + Luid luid; + + if (!NativeMethods.LookupPrivilegeValue(_systemName, _name, out luid)) + NativeError.ThrowException(Marshal.GetLastWin32Error()); + + return Filesystem.NativeMethods.LuidToLong(luid); + } + + #endregion // LookupLuid + + #region Equals + + /// Indicates whether the current object is equal to another object of the same type. + /// An object to compare with this object. + /// if the current object is equal to the parameter; otherwise, . + public bool Equals(Privilege other) + { + if (other == null) + return false; + + return _name.Equals(other._name, StringComparison.OrdinalIgnoreCase) && + ((_systemName == null && other._systemName == null) || + (_systemName != null && _systemName.Equals(other._systemName, StringComparison.OrdinalIgnoreCase))); + } + + /// Determines whether the specified is equal to the current . + /// The to compare with the current . + /// if the specified is equal to the current ; otherwise, . + /// + public override bool Equals(object obj) + { + Privilege other = obj as Privilege; + + if (other == null) + return false; + + return _name.Equals(other._name, StringComparison.OrdinalIgnoreCase) && + ((_systemName == null && other._systemName == null) || + (_systemName != null && _systemName.Equals(other._systemName, StringComparison.OrdinalIgnoreCase))); + } + + #endregion // Equals + + #region GetHashCode + + // A random prime number will be picked and added to the HashCode, each time an instance is created. + [NonSerialized] private readonly int _random = new Random().Next(0, 19); + [NonSerialized] private static readonly int[] Primes = { 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919 }; + + /// Serves as a hash function for a particular type. + /// A hash code for the current Object. + public override int GetHashCode() + { + unchecked + { + int hash = Primes[_random]; + + if (!Utils.IsNullOrWhiteSpace(_name)) + hash = hash * Primes[1] + _name.GetHashCode(); + + if (!Utils.IsNullOrWhiteSpace(_systemName)) + hash = hash * Primes[1] + _systemName.GetHashCode(); + + return hash; + } + } + + #endregion // GetHashCode + + #region ToString + + /// Returns the system name for this privilege. + /// This is equivalent to . + /// A that represents the current . + public override string ToString() + { + return _name; + } + + #endregion // ToString + + #region Privilege + + /// Initializes a new instance of the class, representing a privilege with the specified name on the local system. + /// The name. + private Privilege(string name) + { + if (Utils.IsNullOrWhiteSpace(name)) + throw new ArgumentException(Resources.Privilege_Name_Cannot_Be_Empty, "name"); + + _name = name; + } + + #endregion // Privilege + }; +} diff --git a/AlphaFS/Security/PrivilegeEnabler.cs b/AlphaFS/Security/PrivilegeEnabler.cs new file mode 100644 index 0000000..8416e8b --- /dev/null +++ b/AlphaFS/Security/PrivilegeEnabler.cs @@ -0,0 +1,85 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; + +namespace Alphaleonis.Win32.Security +{ + /// Used to enable one or more privileges. The privileges specified will be enabled during the lifetime of the instance. Users create an instance of this object in a using statement to ensure that it is properly disposed when the elevated privileges are no longer needed. + public sealed class PrivilegeEnabler : IDisposable + { + #region PrivilegeEnabler + + private readonly List _enabledPrivileges = new List(); + + /// Initializes a new instance of the class. + /// This will enable the privileges specified (unless already enabled), and ensure that they are disabled again when + /// the object is disposed. (Any privileges already enabled will not be disabled). + /// + /// The privilege to enable. + /// Additional privileges to enable. + public PrivilegeEnabler(Privilege privilege, params Privilege[] privileges) + { + _enabledPrivileges.Add(new InternalPrivilegeEnabler(privilege)); + + if (privileges != null) + foreach (Privilege priv in privileges) + _enabledPrivileges.Add(new InternalPrivilegeEnabler(priv)); + } + + #endregion // PrivilegeEnabler + + #region Dispose + + /// Makes sure any privileges enabled by this instance are disabled. + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + public void Dispose() + { + foreach (InternalPrivilegeEnabler t in _enabledPrivileges) + { + try + { + t.Dispose(); + } + catch + { + // We ignore any exceptions here + } + } + } + + #endregion // Dispose + + #region EnabledPrivileges + + /// Gets the enabled privileges. Note that this might not contain all privileges specified to the constructor. Only the privileges actually enabled by this instance is returned. + /// The enabled privileges. + public IEnumerable EnabledPrivileges + { + get { return from priv in _enabledPrivileges where priv.EnabledPrivilege != null select priv.EnabledPrivilege; } + } + + #endregion // EnabledPrivileges + } +} \ No newline at end of file diff --git a/AlphaFS/Security/SecurityAttributes.cs b/AlphaFS/Security/SecurityAttributes.cs new file mode 100644 index 0000000..42cbd4e --- /dev/null +++ b/AlphaFS/Security/SecurityAttributes.cs @@ -0,0 +1,80 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security.AccessControl; + +namespace Alphaleonis.Win32.Security +{ + internal static partial class NativeMethods + { + /// Class used to represent the SECURITY_ATTRIBUES native Win32 structure. It provides initialization function from an object. + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal sealed class SecurityAttributes : IDisposable + { + // Removing this member results in: "Invalid access to memory location: ..." + [MarshalAs(UnmanagedType.U4)] + private int _length; + + private readonly SafeGlobalMemoryBufferHandle _securityDescriptor; + + public SecurityAttributes(ObjectSecurity securityDescriptor) + { + SafeGlobalMemoryBufferHandle safeBuffer = ToUnmanagedSecurityAttributes(securityDescriptor); + _length = safeBuffer.Capacity; + _securityDescriptor = safeBuffer; + } + + /// Marshals an ObjectSecurity instance to unmanaged memory. + /// A safe handle containing the marshalled security descriptor. + /// The security descriptor. + [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] + private static SafeGlobalMemoryBufferHandle ToUnmanagedSecurityAttributes(ObjectSecurity securityDescriptor) + { + if (securityDescriptor == null) + return new SafeGlobalMemoryBufferHandle(); + + + byte[] src = securityDescriptor.GetSecurityDescriptorBinaryForm(); + var safeBuffer = new SafeGlobalMemoryBufferHandle(src.Length); + + try + { + safeBuffer.CopyFrom(src, 0, src.Length); + return safeBuffer; + } + catch + { + safeBuffer.Close(); + throw; + } + } + + public void Dispose() + { + if (_securityDescriptor != null) + _securityDescriptor.Close(); + } + } + } +} diff --git a/AlphaFS/Security/Structures/Luid.cs b/AlphaFS/Security/Structures/Luid.cs new file mode 100644 index 0000000..7ed91f9 --- /dev/null +++ b/AlphaFS/Security/Structures/Luid.cs @@ -0,0 +1,32 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Security +{ + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct Luid + { + internal uint LowPart; + internal uint HighPart; + } +} diff --git a/AlphaFS/Security/Structures/TokenPrivileges.cs b/AlphaFS/Security/Structures/TokenPrivileges.cs new file mode 100644 index 0000000..a8e690a --- /dev/null +++ b/AlphaFS/Security/Structures/TokenPrivileges.cs @@ -0,0 +1,33 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Alphaleonis.Win32.Security +{ + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct TokenPrivileges + { + internal uint PrivilegeCount; + internal Luid Luid; + internal uint Attributes; + } +} diff --git a/AlphaFS/Utils.cs b/AlphaFS/Utils.cs new file mode 100644 index 0000000..7406576 --- /dev/null +++ b/AlphaFS/Utils.cs @@ -0,0 +1,131 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Linq; +using System.Reflection; + +namespace Alphaleonis +{ + internal static class Utils + { + #region EnumMemberToList + + public static IEnumerable EnumMemberToList() + { + Type enumType = typeof(T); + + // Can't use generic type constraints on value types, so have to do check like this. + if (enumType.BaseType != typeof(Enum)) + throw new ArgumentException("T must be of type System.Enum"); + + //Array enumValArray = Enum.GetValues(enumType); + //List enumValList = new List(enumValArray.Length); + IOrderedEnumerable enumValArray = Enum.GetValues(enumType).Cast().OrderBy(e => e.ToString()); + var enumValList = new List(enumValArray.Count()); + + enumValList.AddRange(enumValArray.Select(val => (T)Enum.Parse(enumType, val.ToString()))); + return enumValList; + } + + #endregion // EnumMemberToList + + #region GetEnumDescription + + /// Gets an attribute on an enum field value. + /// The description belonging to the enum option, as a string + /// One of the enum types. + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + public static string GetEnumDescription(Enum enumValue) + { + FieldInfo fi = enumValue.GetType().GetField(enumValue.ToString()); + var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); + return attributes.Length > 0 ? attributes[0].Description : enumValue.ToString(); + } + + #endregion // GetEnumDescription + + #region IsNullOrWhiteSpace + + /// Indicates whether a specified string is null, empty, or consists only of white-space characters. + /// if the parameter is null or , or if consists exclusively of white-space characters. + /// The string to test. + public static bool IsNullOrWhiteSpace(string value) + { +#if NET35 + if (value != null) + { + for (int index = 0; index < value.Length; ++index) + { + if (!char.IsWhiteSpace(value[index])) + return false; + } + } + + return true; +#else + return string.IsNullOrWhiteSpace(value); +#endif + } + + #endregion // IsNullOrWhiteSpace + + #region UnitSizeToText + + /// Converts a number of type T to string, suffixed with a unit size. + public static string UnitSizeToText(T numberOfBytes) + { + string[] sizeFormats = + { + "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" + }; + + + var i = 0; + var bytes = Convert.ToDouble(numberOfBytes, CultureInfo.InvariantCulture); + + while (i < sizeFormats.Length && bytes > 1024) + { + i++; + bytes /= 1024; + } + + + // Will return "512 B" instead of "512,00 B". + return string.Format(CultureInfo.CurrentCulture, i == 0 ? "{0:0} {1}" : "{0:0.##} {1}", bytes, sizeFormats[i]); + } + + /// Calculates a percentage value. + /// + /// + /// + public static double PercentCalculate(double currentValue, double minimumValue, double maximumValue) + { + return (currentValue < 0 || maximumValue <= 0) ? 0 : currentValue * 100 / (maximumValue - minimumValue); + } + + #endregion // UnitSizeToText + } +} diff --git a/AlphaFS/Win32Errors.cs b/AlphaFS/Win32Errors.cs new file mode 100644 index 0000000..ef0d89e --- /dev/null +++ b/AlphaFS/Win32Errors.cs @@ -0,0 +1,4262 @@ +/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Alphaleonis.Win32 +{ + internal static class Win32Errors + { + /// Use this to translate error codes into HRESULTs like 0x80070006 for ERROR_INVALID_HANDLE. + public static int GetHrFromWin32Error(uint errorCode) + { + return (int) unchecked(((int) 0x80070000) | errorCode); + } + + // System Error Codes + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms681381%28v=vs.85%29.aspx + + public const uint ERROR_INVALID_FILE_SIZE = 0xFFFFFFFF; + + /// (0) The operation completed successfully. + public const uint ERROR_SUCCESS = 0; + + /// (0) The operation completed successfully. + public const uint NO_ERROR = 0; + + /// (1) Incorrect function. + public const uint ERROR_INVALID_FUNCTION = 1; + + /// (2) The system cannot find the file specified. + public const uint ERROR_FILE_NOT_FOUND = 2; + + /// (3) The system cannot find the path specified. + public const uint ERROR_PATH_NOT_FOUND = 3; + //public const uint ERROR_TOO_MANY_OPEN_FILES = 4; + + /// (5) Access is denied. + public const uint ERROR_ACCESS_DENIED = 5; + + //public const uint ERROR_INVALID_HANDLE = 6; + //public const uint ERROR_ARENA_TRASHED = 7; + //public const uint ERROR_NOT_ENOUGH_MEMORY = 8; + //public const uint ERROR_INVALID_BLOCK = 9; + //public const uint ERROR_BAD_ENVIRONMENT = 10; + //public const uint ERROR_BAD_FORMAT = 11; + //public const uint ERROR_INVALID_ACCESS = 12; + //public const uint ERROR_INVALID_DATA = 13; + //public const uint ERROR_OUTOFMEMORY = 14; + + /// (15) The system cannot find the drive specified. + public const uint ERROR_INVALID_DRIVE = 15; + + //public const uint ERROR_CURRENT_DIRECTORY = 16; + + /// (17) The system cannot move the file to a different disk drive. + public const uint ERROR_NOT_SAME_DEVICE = 17; + + /// (18) There are no more files. + public const uint ERROR_NO_MORE_FILES = 18; + //public const uint ERROR_WRITE_PROTECT = 19; + //public const uint ERROR_BAD_UNIT = 20; + + /// (21) The device is not ready. + public const uint ERROR_NOT_READY = 21; + + //public const uint ERROR_BAD_COMMAND = 22; + //public const uint ERROR_CRC = 23; + //public const uint ERROR_BAD_LENGTH = 24; + + /// (25) The drive cannot locate a specific area or track on the disk. + public const uint ERROR_SEEK = 25; + + //public const uint ERROR_NOT_DOS_DISK = 26; + //public const uint ERROR_SECTOR_NOT_FOUND = 27; + //public const uint ERROR_OUT_OF_PAPER = 28; + //public const uint ERROR_WRITE_FAULT = 29; + //public const uint ERROR_READ_FAULT = 30; + //public const uint ERROR_GEN_FAILURE = 31; + + /// (32) The process cannot access the file because it is being used by another process. + public const uint ERROR_SHARING_VIOLATION = 32; + + /// (33) The process cannot access the file because another process has locked a portion of the file. + public const uint ERROR_LOCK_VIOLATION = 33; + + //public const uint ERROR_WRONG_DISK = 34; + //public const uint ERROR_SHARING_BUFFER_EXCEEDED = 36; + + /// (38) Reached the end of the file. + public const uint ERROR_HANDLE_EOF = 38; + + //public const uint ERROR_HANDLE_DISK_FULL = 39; + //public const uint ERROR_NOT_SUPPORTED = 50; + //public const uint ERROR_REM_NOT_LIST = 51; + //public const uint ERROR_DUP_NAME = 52; + + /// (53) The network path was not found. + public const uint ERROR_BAD_NETPATH = 53; + + //public const uint ERROR_NETWORK_BUSY = 54; + //public const uint ERROR_DEV_NOT_EXIST = 55; + //public const uint ERROR_TOO_MANY_CMDS = 56; + //public const uint ERROR_ADAP_HDW_ERR = 57; + //public const uint ERROR_BAD_NET_RESP = 58; + //public const uint ERROR_UNEXP_NET_ERR = 59; + //public const uint ERROR_BAD_REM_ADAP = 60; + //public const uint ERROR_PRINTQ_FULL = 61; + //public const uint ERROR_NO_SPOOL_SPACE = 62; + //public const uint ERROR_PRINT_CANCELLED = 63; + //public const uint ERROR_NETNAME_DELETED = 64; + + /// (65) Network access is denied. + public const uint ERROR_NETWORK_ACCESS_DENIED = 65; + + //public const uint ERROR_BAD_DEV_TYPE = 66; + + /// (67) The network name cannot be found. + public const uint ERROR_BAD_NET_NAME = 67; + + //public const uint ERROR_TOO_MANY_NAMES = 68; + //public const uint ERROR_TOO_MANY_SESS = 69; + //public const uint ERROR_SHARING_PAUSED = 70; + //public const uint ERROR_REQ_NOT_ACCEP = 71; + //public const uint ERROR_REDIR_PAUSED = 72; + + /// (80) The file exists. + public const uint ERROR_FILE_EXISTS = 80; + + //public const uint ERROR_CANNOT_MAKE = 82; + //public const uint ERROR_FAIL_I24 = 83; + //public const uint ERROR_OUT_OF_STRUCTURES = 84; + //public const uint ERROR_ALREADY_ASSIGNED = 85; + //public const uint ERROR_INVALID_PASSWORD = 86; + + /// (87) The parameter is incorrect. + public const uint ERROR_INVALID_PARAMETER = 87; + + //public const uint ERROR_NET_WRITE_FAULT = 88; + //public const uint ERROR_NO_PROC_SLOTS = 89; + //public const uint ERROR_TOO_MANY_SEMAPHORES = 100; + //public const uint ERROR_EXCL_SEM_ALREADY_OWNED = 101; + //public const uint ERROR_SEM_IS_SET = 102; + //public const uint ERROR_TOO_MANY_SEM_REQUESTS = 103; + //public const uint ERROR_INVALID_AT_INTERRUPT_TIME = 104; + //public const uint ERROR_SEM_OWNER_DIED = 105; + //public const uint ERROR_SEM_USER_LIMIT = 106; + //public const uint ERROR_DISK_CHANGE = 107; + //public const uint ERROR_DRIVE_LOCKED = 108; + //public const uint ERROR_BROKEN_PIPE = 109; + //public const uint ERROR_OPEN_FAILED = 110; + //public const uint ERROR_BUFFER_OVERFLOW = 111; + //public const uint ERROR_DISK_FULL = 112; + //public const uint ERROR_NO_MORE_SEARCH_HANDLES = 113; + //public const uint ERROR_INVALID_TARGET_HANDLE = 114; + //public const uint ERROR_INVALID_CATEGORY = 117; + //public const uint ERROR_INVALID_VERIFY_SWITCH = 118; + //public const uint ERROR_BAD_DRIVER_LEVEL = 119; + //public const uint ERROR_CALL_NOT_IMPLEMENTED = 120; + //public const uint ERROR_SEM_TIMEOUT = 121; + + /// (122) The data area passed to a system call is too small. + public const uint ERROR_INSUFFICIENT_BUFFER = 122; + + /// (123) The filename, directory name, or volume label syntax is incorrect. + public const uint ERROR_INVALID_NAME = 123; + + //public const uint ERROR_INVALID_LEVEL = 124; + //public const uint ERROR_NO_VOLUME_LABEL = 125; + //public const uint ERROR_INVALID_FILE_ATTRIBUTES = 0xFFFFFFFF; + //public const uint ERROR_MOD_NOT_FOUND = 126; + //public const uint ERROR_PROC_NOT_FOUND = 127; + //public const uint ERROR_WAIT_NO_CHILDREN = 128; + //public const uint ERROR_CHILD_NOT_COMPLETE = 129; + //public const uint ERROR_DIRECT_ACCESS_HANDLE = 130; + //public const uint ERROR_NEGATIVE_SEEK = 131; + //public const uint ERROR_SEEK_ON_DEVICE = 132; + //public const uint ERROR_IS_JOIN_TARGET = 133; + //public const uint ERROR_IS_JOINED = 134; + //public const uint ERROR_IS_SUBSTED = 135; + //public const uint ERROR_NOT_JOINED = 136; + //public const uint ERROR_NOT_SUBSTED = 137; + //public const uint ERROR_JOIN_TO_JOIN = 138; + //public const uint ERROR_SUBST_TO_SUBST = 139; + //public const uint ERROR_JOIN_TO_SUBST = 140; + //public const uint ERROR_SUBST_TO_JOIN = 141; + //public const uint ERROR_BUSY_DRIVE = 142; + + /// (143) The system cannot join or substitute a drive to or for a directory on the same drive. + public const uint ERROR_SAME_DRIVE = 143; + + //public const uint ERROR_DIR_NOT_ROOT = 144; + + /// (145) The directory is not empty. + public const uint ERROR_DIR_NOT_EMPTY = 145; + + //public const uint ERROR_IS_SUBST_PATH = 146; + //public const uint ERROR_IS_JOIN_PATH = 147; + //public const uint ERROR_PATH_BUSY = 148; + //public const uint ERROR_IS_SUBST_TARGET = 149; + //public const uint ERROR_SYSTEM_TRACE = 150; + //public const uint ERROR_INVALID_EVENT_COUNT = 151; + //public const uint ERROR_TOO_MANY_MUXWAITERS = 152; + //public const uint ERROR_INVALID_LIST_FORMAT = 153; + //public const uint ERROR_LABEL_TOO_LONG = 154; + //public const uint ERROR_TOO_MANY_TCBS = 155; + //public const uint ERROR_SIGNAL_REFUSED = 156; + //public const uint ERROR_DISCARDED = 157; + + /// (158) The segment is already unlocked. + public const uint ERROR_NOT_LOCKED = 158; + + //public const uint ERROR_BAD_THREADID_ADDR = 159; + //public const uint ERROR_BAD_ARGUMENTS = 160; + //public const uint ERROR_BAD_PATHNAME = 161; + //public const uint ERROR_SIGNAL_PENDING = 162; + //public const uint ERROR_MAX_THRDS_REACHED = 164; + //public const uint ERROR_LOCK_FAILED = 167; + //public const uint ERROR_BUSY = 170; + //public const uint ERROR_CANCEL_VIOLATION = 173; + //public const uint ERROR_ATOMIC_LOCKS_NOT_SUPPORTED = 174; + //public const uint ERROR_INVALID_SEGMENT_NUMBER = 180; + //public const uint ERROR_INVALID_ORDINAL = 182; + + /// (183) Cannot create a file when that file already exists. + public const uint ERROR_ALREADY_EXISTS = 183; + + //public const uint ERROR_INVALID_FLAG_NUMBER = 186; + //public const uint ERROR_SEM_NOT_FOUND = 187; + //public const uint ERROR_INVALID_STARTING_CODESEG = 188; + //public const uint ERROR_INVALID_STACKSEG = 189; + //public const uint ERROR_INVALID_MODULETYPE = 190; + //public const uint ERROR_INVALID_EXE_SIGNATURE = 191; + //public const uint ERROR_EXE_MARKED_INVALID = 192; + //public const uint ERROR_BAD_EXE_FORMAT = 193; + //public const uint ERROR_ITERATED_DATA_EXCEEDS_64k = 194; + //public const uint ERROR_INVALID_MINALLOCSIZE = 195; + //public const uint ERROR_DYNLINK_FROM_INVALID_RING = 196; + //public const uint ERROR_IOPL_NOT_ENABLED = 197; + //public const uint ERROR_INVALID_SEGDPL = 198; + //public const uint ERROR_AUTODATASEG_EXCEEDS_64k = 199; + //public const uint ERROR_RING2SEG_MUST_BE_MOVABLE = 200; + //public const uint ERROR_RELOC_CHAIN_XEEDS_SEGLIM = 201; + //public const uint ERROR_INFLOOP_IN_RELOC_CHAIN = 202; + + /// (203) The system could not find the environment option that was entered. + public const uint ERROR_ENVVAR_NOT_FOUND = 203; + + //public const uint ERROR_NO_SIGNAL_SENT = 205; + //public const uint ERROR_FILENAME_EXCED_RANGE = 206; + //public const uint ERROR_RING2_STACK_IN_USE = 207; + //public const uint ERROR_META_EXPANSION_TOO_LONG = 208; + //public const uint ERROR_INVALID_SIGNAL_NUMBER = 209; + //public const uint ERROR_THREAD_1_INACTIVE = 210; + //public const uint ERROR_LOCKED = 212; + //public const uint ERROR_TOO_MANY_MODULES = 214; + //public const uint ERROR_NESTING_NOT_ALLOWED = 215; + //public const uint ERROR_EXE_MACHINE_TYPE_MISMATCH = 216; + //public const uint ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY = 217; + //public const uint ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY = 218; + //public const uint ERROR_BAD_PIPE = 230; + //public const uint ERROR_PIPE_BUSY = 231; + //public const uint ERROR_NO_DATA = 232; + //public const uint ERROR_PIPE_NOT_CONNECTED = 233; + + /// (234) More data is available. + public const uint ERROR_MORE_DATA = 234; + + //public const uint ERROR_VC_DISCONNECTED = 240; + //public const uint ERROR_INVALID_EA_NAME = 254; + //public const uint ERROR_EA_LIST_INCONSISTENT = 255; + //public const uint WAIT_TIMEOUT = 258; + + ///// (259) No more data is available. + //public const uint ERROR_NO_MORE_ITEMS = 259; + + //public const uint ERROR_CANNOT_COPY = 266; + + /// (267) The directory name is invalid. + public const uint ERROR_DIRECTORY = 267; + + //public const uint ERROR_EAS_DIDNT_FIT = 275; + //public const uint ERROR_EA_FILE_CORRUPT = 276; + //public const uint ERROR_EA_TABLE_FULL = 277; + //public const uint ERROR_INVALID_EA_HANDLE = 278; + //public const uint ERROR_EAS_NOT_SUPPORTED = 282; + //public const uint ERROR_NOT_OWNER = 288; + //public const uint ERROR_TOO_MANY_POSTS = 298; + //public const uint ERROR_PARTIAL_COPY = 299; + //public const uint ERROR_OPLOCK_NOT_GRANTED = 300; + //public const uint ERROR_INVALID_OPLOCK_PROTOCOL = 301; + //public const uint ERROR_DISK_TOO_FRAGMENTED = 302; + //public const uint ERROR_DELETE_PENDING = 303; + //public const uint ERROR_MR_MID_NOT_FOUND = 317; + //public const uint ERROR_SCOPE_NOT_FOUND = 318; + //public const uint ERROR_INVALID_ADDRESS = 487; + //public const uint ERROR_ARITHMETIC_OVERFLOW = 534; + //public const uint ERROR_PIPE_CONNECTED = 535; + //public const uint ERROR_PIPE_LISTENING = 536; + //public const uint ERROR_EA_ACCESS_DENIED = 994; + + /// (995) The I/O operation has been aborted because of either a thread exit or an application request. + public const uint ERROR_OPERATION_ABORTED = 995; + + //public const uint ERROR_IO_INCOMPLETE = 996; + + /// (997) Overlapped I/O operation is in progress. + public const uint ERROR_IO_PENDING = 997; + + //public const uint ERROR_NOACCESS = 998; + //public const uint ERROR_SWAPERROR = 999; + //public const uint ERROR_STACK_OVERFLOW = 1001; + //public const uint ERROR_INVALID_MESSAGE = 1002; + //public const uint ERROR_CAN_NOT_COMPLETE = 1003; + //public const uint ERROR_INVALID_FLAGS = 1004; + //public const uint ERROR_UNRECOGNIZED_VOLUME = 1005; + //public const uint ERROR_FILE_INVALID = 1006; + //public const uint ERROR_FULLSCREEN_MODE = 1007; + //public const uint ERROR_NO_TOKEN = 1008; + //public const uint ERROR_BADDB = 1009; + //public const uint ERROR_BADKEY = 1010; + //public const uint ERROR_CANTOPEN = 1011; + //public const uint ERROR_CANTREAD = 1012; + //public const uint ERROR_CANTWRITE = 1013; + //public const uint ERROR_REGISTRY_RECOVERED = 1014; + //public const uint ERROR_REGISTRY_CORRUPT = 1015; + //public const uint ERROR_REGISTRY_IO_FAILED = 1016; + //public const uint ERROR_NOT_REGISTRY_FILE = 1017; + //public const uint ERROR_KEY_DELETED = 1018; + //public const uint ERROR_NO_LOG_SPACE = 1019; + //public const uint ERROR_KEY_HAS_CHILDREN = 1020; + //public const uint ERROR_CHILD_MUST_BE_VOLATILE = 1021; + //public const uint ERROR_NOTIFY_ENUM_DIR = 1022; + //public const uint ERROR_DEPENDENT_SERVICES_RUNNING = 1051; + //public const uint ERROR_INVALID_SERVICE_CONTROL = 1052; + //public const uint ERROR_SERVICE_REQUEST_TIMEOUT = 1053; + //public const uint ERROR_SERVICE_NO_THREAD = 1054; + //public const uint ERROR_SERVICE_DATABASE_LOCKED = 1055; + //public const uint ERROR_SERVICE_ALREADY_RUNNING = 1056; + //public const uint ERROR_INVALID_SERVICE_ACCOUNT = 1057; + //public const uint ERROR_SERVICE_DISABLED = 1058; + //public const uint ERROR_CIRCULAR_DEPENDENCY = 1059; + //public const uint ERROR_SERVICE_DOES_NOT_EXIST = 1060; + //public const uint ERROR_SERVICE_CANNOT_ACCEPT_CTRL = 1061; + //public const uint ERROR_SERVICE_NOT_ACTIVE = 1062; + //public const uint ERROR_FAILED_SERVICE_CONTROLLER_CONNECT = 1063; + //public const uint ERROR_EXCEPTION_IN_SERVICE = 1064; + //public const uint ERROR_DATABASE_DOES_NOT_EXIST = 1065; + //public const uint ERROR_SERVICE_SPECIFIC_ERROR = 1066; + //public const uint ERROR_PROCESS_ABORTED = 1067; + //public const uint ERROR_SERVICE_DEPENDENCY_FAIL = 1068; + //public const uint ERROR_SERVICE_LOGON_FAILED = 1069; + //public const uint ERROR_SERVICE_START_HANG = 1070; + //public const uint ERROR_INVALID_SERVICE_LOCK = 1071; + //public const uint ERROR_SERVICE_MARKED_FOR_DELETE = 1072; + //public const uint ERROR_SERVICE_EXISTS = 1073; + //public const uint ERROR_ALREADY_RUNNING_LKG = 1074; + //public const uint ERROR_SERVICE_DEPENDENCY_DELETED = 1075; + //public const uint ERROR_BOOT_ALREADY_ACCEPTED = 1076; + //public const uint ERROR_SERVICE_NEVER_STARTED = 1077; + //public const uint ERROR_DUPLICATE_SERVICE_NAME = 1078; + //public const uint ERROR_DIFFERENT_SERVICE_ACCOUNT = 1079; + //public const uint ERROR_CANNOT_DETECT_DRIVER_FAILURE = 1080; + //public const uint ERROR_CANNOT_DETECT_PROCESS_ABORT = 1081; + //public const uint ERROR_NO_RECOVERY_PROGRAM = 1082; + //public const uint ERROR_SERVICE_NOT_IN_EXE = 1083; + //public const uint ERROR_NOT_SAFEBOOT_SERVICE = 1084; + //public const uint ERROR_END_OF_MEDIA = 1100; + //public const uint ERROR_FILEMARK_DETECTED = 1101; + //public const uint ERROR_BEGINNING_OF_MEDIA = 1102; + //public const uint ERROR_SETMARK_DETECTED = 1103; + //public const uint ERROR_NO_DATA_DETECTED = 1104; + //public const uint ERROR_PARTITION_FAILURE = 1105; + //public const uint ERROR_INVALID_BLOCK_LENGTH = 1106; + //public const uint ERROR_DEVICE_NOT_PARTITIONED = 1107; + //public const uint ERROR_UNABLE_TO_LOCK_MEDIA = 1108; + //public const uint ERROR_UNABLE_TO_UNLOAD_MEDIA = 1109; + //public const uint ERROR_MEDIA_CHANGED = 1110; + //public const uint ERROR_BUS_RESET = 1111; + //public const uint ERROR_NO_MEDIA_IN_DRIVE = 1112; + //public const uint ERROR_NO_UNICODE_TRANSLATION = 1113; + //public const uint ERROR_DLL_INIT_FAILED = 1114; + //public const uint ERROR_SHUTDOWN_IN_PROGRESS = 1115; + //public const uint ERROR_NO_SHUTDOWN_IN_PROGRESS = 1116; + //public const uint ERROR_IO_DEVICE = 1117; + //public const uint ERROR_SERIAL_NO_DEVICE = 1118; + //public const uint ERROR_IRQ_BUSY = 1119; + //public const uint ERROR_MORE_WRITES = 1120; + //public const uint ERROR_COUNTER_TIMEOUT = 1121; + //public const uint ERROR_FLOPPY_ID_MARK_NOT_FOUND = 1122; + //public const uint ERROR_FLOPPY_WRONG_CYLINDER = 1123; + //public const uint ERROR_FLOPPY_UNKNOWN_ERROR = 1124; + //public const uint ERROR_FLOPPY_BAD_REGISTERS = 1125; + //public const uint ERROR_DISK_RECALIBRATE_FAILED = 1126; + //public const uint ERROR_DISK_OPERATION_FAILED = 1127; + //public const uint ERROR_DISK_RESET_FAILED = 1128; + //public const uint ERROR_EOM_OVERFLOW = 1129; + //public const uint ERROR_NOT_ENOUGH_SERVER_MEMORY = 1130; + //public const uint ERROR_POSSIBLE_DEADLOCK = 1131; + //public const uint ERROR_MAPPED_ALIGNMENT = 1132; + //public const uint ERROR_SET_POWER_STATE_VETOED = 1140; + //public const uint ERROR_SET_POWER_STATE_FAILED = 1141; + //public const uint ERROR_TOO_MANY_LINKS = 1142; + //public const uint ERROR_OLD_WIN_VERSION = 1150; + //public const uint ERROR_APP_WRONG_OS = 1151; + //public const uint ERROR_SINGLE_INSTANCE_APP = 1152; + //public const uint ERROR_RMODE_APP = 1153; + //public const uint ERROR_INVALID_DLL = 1154; + //public const uint ERROR_NO_ASSOCIATION = 1155; + //public const uint ERROR_DDE_FAIL = 1156; + //public const uint ERROR_DLL_NOT_FOUND = 1157; + //public const uint ERROR_NO_MORE_USER_HANDLES = 1158; + //public const uint ERROR_MESSAGE_SYNC_ONLY = 1159; + //public const uint ERROR_SOURCE_ELEMENT_EMPTY = 1160; + //public const uint ERROR_DESTINATION_ELEMENT_FULL = 1161; + //public const uint ERROR_ILLEGAL_ELEMENT_ADDRESS = 1162; + //public const uint ERROR_MAGAZINE_NOT_PRESENT = 1163; + //public const uint ERROR_DEVICE_REINITIALIZATION_NEEDED = 1164; + //public const uint ERROR_DEVICE_REQUIRES_CLEANING = 1165; + //public const uint ERROR_DEVICE_DOOR_OPEN = 1166; + //public const uint ERROR_DEVICE_NOT_CONNECTED = 1167; + //public const uint ERROR_NOT_FOUND = 1168; + //public const uint ERROR_NO_MATCH = 1169; + //public const uint ERROR_SET_NOT_FOUND = 1170; + //public const uint ERROR_POINT_NOT_FOUND = 1171; + //public const uint ERROR_NO_TRACKING_SERVICE = 1172; + //public const uint ERROR_NO_VOLUME_ID = 1173; + //public const uint ERROR_UNABLE_TO_REMOVE_REPLACED = 1175; + //public const uint ERROR_UNABLE_TO_MOVE_REPLACEMENT = 1176; + //public const uint ERROR_UNABLE_TO_MOVE_REPLACEMENT_2 = 1177; + //public const uint ERROR_JOURNAL_DELETE_IN_PROGRESS = 1178; + //public const uint ERROR_JOURNAL_NOT_ACTIVE = 1179; + //public const uint ERROR_POTENTIAL_FILE_FOUND = 1180; + //public const uint ERROR_JOURNAL_ENTRY_DELETED = 1181; + + /// (1200) The specified device name is invalid. + public const uint ERROR_BAD_DEVICE = 1200; + + //public const uint ERROR_CONNECTION_UNAVAIL = 1201; + //public const uint ERROR_DEVICE_ALREADY_REMEMBERED = 1202; + //public const uint ERROR_NO_NET_OR_BAD_PATH = 1203; + //public const uint ERROR_BAD_PROVIDER = 1204; + //public const uint ERROR_CANNOT_OPEN_PROFILE = 1205; + //public const uint ERROR_BAD_PROFILE = 1206; + //public const uint ERROR_NOT_CONTAINER = 1207; + + /// (1208) An extended error has occurred. + public const uint ERROR_EXTENDED_ERROR = 1208; + + //public const uint ERROR_INVALID_GROUPNAME = 1209; + //public const uint ERROR_INVALID_COMPUTERNAME = 1210; + //public const uint ERROR_INVALID_EVENTNAME = 1211; + //public const uint ERROR_INVALID_DOMAINNAME = 1212; + //public const uint ERROR_INVALID_SERVICENAME = 1213; + //public const uint ERROR_INVALID_NETNAME = 1214; + //public const uint ERROR_INVALID_SHARENAME = 1215; + //public const uint ERROR_INVALID_PASSWORDNAME = 1216; + //public const uint ERROR_INVALID_MESSAGENAME = 1217; + //public const uint ERROR_INVALID_MESSAGEDEST = 1218; + //public const uint ERROR_SESSION_CREDENTIAL_CONFLICT = 1219; + //public const uint ERROR_REMOTE_SESSION_LIMIT_EXCEEDED = 1220; + //public const uint ERROR_DUP_DOMAINNAME = 1221; + + /// (1222) The network is not present or not started. + public const uint ERROR_NO_NETWORK = 1222; + + //public const uint ERROR_CANCELLED = 1223; + //public const uint ERROR_USER_MAPPED_FILE = 1224; + //public const uint ERROR_CONNECTION_REFUSED = 1225; + //public const uint ERROR_GRACEFUL_DISCONNECT = 1226; + //public const uint ERROR_ADDRESS_ALREADY_ASSOCIATED = 1227; + //public const uint ERROR_ADDRESS_NOT_ASSOCIATED = 1228; + //public const uint ERROR_CONNECTION_INVALID = 1229; + //public const uint ERROR_CONNECTION_ACTIVE = 1230; + //public const uint ERROR_NETWORK_UNREACHABLE = 1231; + //public const uint ERROR_HOST_UNREACHABLE = 1232; + //public const uint ERROR_PROTOCOL_UNREACHABLE = 1233; + //public const uint ERROR_PORT_UNREACHABLE = 1234; + + /// (1235) The request was aborted. + public const uint ERROR_REQUEST_ABORTED = 1235; + + //public const uint ERROR_CONNECTION_ABORTED = 1236; + //public const uint ERROR_RETRY = 1237; + //public const uint ERROR_CONNECTION_COUNT_LIMIT = 1238; + //public const uint ERROR_LOGIN_TIME_RESTRICTION = 1239; + //public const uint ERROR_LOGIN_WKSTA_RESTRICTION = 1240; + //public const uint ERROR_INCORRECT_ADDRESS = 1241; + //public const uint ERROR_ALREADY_REGISTERED = 1242; + //public const uint ERROR_SERVICE_NOT_FOUND = 1243; + //public const uint ERROR_NOT_AUTHENTICATED = 1244; + //public const uint ERROR_NOT_LOGGED_ON = 1245; + //public const uint ERROR_CONTINUE = 1246; + //public const uint ERROR_ALREADY_INITIALIZED = 1247; + //public const uint ERROR_NO_MORE_DEVICES = 1248; + //public const uint ERROR_NO_SUCH_SITE = 1249; + //public const uint ERROR_DOMAIN_CONTROLLER_EXISTS = 1250; + //public const uint ERROR_ONLY_IF_CONNECTED = 1251; + //public const uint ERROR_OVERRIDE_NOCHANGES = 1252; + //public const uint ERROR_BAD_USER_PROFILE = 1253; + //public const uint ERROR_NOT_SUPPORTED_ON_SBS = 1254; + //public const uint ERROR_SERVER_SHUTDOWN_IN_PROGRESS = 1255; + //public const uint ERROR_HOST_DOWN = 1256; + //public const uint ERROR_NON_ACCOUNT_SID = 1257; + //public const uint ERROR_NON_DOMAIN_SID = 1258; + //public const uint ERROR_APPHELP_BLOCK = 1259; + //public const uint ERROR_ACCESS_DISABLED_BY_POLICY = 1260; + //public const uint ERROR_REG_NAT_CONSUMPTION = 1261; + //public const uint ERROR_CSCSHARE_OFFLINE = 1262; + //public const uint ERROR_PKINIT_FAILURE = 1263; + //public const uint ERROR_SMARTCARD_SUBSYSTEM_FAILURE = 1264; + //public const uint ERROR_DOWNGRADE_DETECTED = 1265; + //public const uint ERROR_MACHINE_LOCKED = 1271; + //public const uint ERROR_CALLBACK_SUPPLIED_INVALID_DATA = 1273; + //public const uint ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED = 1274; + //public const uint ERROR_DRIVER_BLOCKED = 1275; + //public const uint ERROR_INVALID_IMPORT_OF_NON_DLL = 1276; + //public const uint ERROR_ACCESS_DISABLED_WEBBLADE = 1277; + //public const uint ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER = 1278; + //public const uint ERROR_RECOVERY_FAILURE = 1279; + //public const uint ERROR_ALREADY_FIBER = 1280; + //public const uint ERROR_ALREADY_THREAD = 1281; + //public const uint ERROR_STACK_BUFFER_OVERRUN = 1282; + //public const uint ERROR_PARAMETER_QUOTA_EXCEEDED = 1283; + //public const uint ERROR_DEBUGGER_INACTIVE = 1284; + //public const uint ERROR_DELAY_LOAD_FAILED = 1285; + //public const uint ERROR_VDM_DISALLOWED = 1286; + //public const uint ERROR_UNIDENTIFIED_ERROR = 1287; + //public const uint ERROR_NOT_ALL_ASSIGNED = 1300; + //public const uint ERROR_SOME_NOT_MAPPED = 1301; + //public const uint ERROR_NO_QUOTAS_FOR_ACCOUNT = 1302; + //public const uint ERROR_LOCAL_USER_SESSION_KEY = 1303; + //public const uint ERROR_NULL_LM_PASSWORD = 1304; + //public const uint ERROR_UNKNOWN_REVISION = 1305; + //public const uint ERROR_REVISION_MISMATCH = 1306; + //public const uint ERROR_INVALID_OWNER = 1307; + //public const uint ERROR_INVALID_PRIMARY_GROUP = 1308; + //public const uint ERROR_NO_IMPERSONATION_TOKEN = 1309; + //public const uint ERROR_CANT_DISABLE_MANDATORY = 1310; + //public const uint ERROR_NO_LOGON_SERVERS = 1311; + //public const uint ERROR_NO_SUCH_LOGON_SESSION = 1312; + //public const uint ERROR_NO_SUCH_PRIVILEGE = 1313; + //public const uint ERROR_PRIVILEGE_NOT_HELD = 1314; + //public const uint ERROR_INVALID_ACCOUNT_NAME = 1315; + //public const uint ERROR_USER_EXISTS = 1316; + //public const uint ERROR_NO_SUCH_USER = 1317; + //public const uint ERROR_GROUP_EXISTS = 1318; + //public const uint ERROR_NO_SUCH_GROUP = 1319; + //public const uint ERROR_MEMBER_IN_GROUP = 1320; + //public const uint ERROR_MEMBER_NOT_IN_GROUP = 1321; + //public const uint ERROR_LAST_ADMIN = 1322; + //public const uint ERROR_WRONG_PASSWORD = 1323; + //public const uint ERROR_ILL_FORMED_PASSWORD = 1324; + //public const uint ERROR_PASSWORD_RESTRICTION = 1325; + //public const uint ERROR_LOGON_FAILURE = 1326; + //public const uint ERROR_ACCOUNT_RESTRICTION = 1327; + //public const uint ERROR_INVALID_LOGON_HOURS = 1328; + //public const uint ERROR_INVALID_WORKSTATION = 1329; + //public const uint ERROR_PASSWORD_EXPIRED = 1330; + //public const uint ERROR_ACCOUNT_DISABLED = 1331; + //public const uint ERROR_NONE_MAPPED = 1332; + //public const uint ERROR_TOO_MANY_LUIDS_REQUESTED = 1333; + //public const uint ERROR_LUIDS_EXHAUSTED = 1334; + //public const uint ERROR_INVALID_SUB_AUTHORITY = 1335; + //public const uint ERROR_INVALID_ACL = 1336; + //public const uint ERROR_INVALID_SID = 1337; + //public const uint ERROR_INVALID_SECURITY_DESCR = 1338; + //public const uint ERROR_BAD_INHERITANCE_ACL = 1340; + //public const uint ERROR_SERVER_DISABLED = 1341; + //public const uint ERROR_SERVER_NOT_DISABLED = 1342; + //public const uint ERROR_INVALID_ID_AUTHORITY = 1343; + //public const uint ERROR_ALLOTTED_SPACE_EXCEEDED = 1344; + //public const uint ERROR_INVALID_GROUP_ATTRIBUTES = 1345; + //public const uint ERROR_BAD_IMPERSONATION_LEVEL = 1346; + //public const uint ERROR_CANT_OPEN_ANONYMOUS = 1347; + //public const uint ERROR_BAD_VALIDATION_CLASS = 1348; + //public const uint ERROR_BAD_TOKEN_TYPE = 1349; + //public const uint ERROR_NO_SECURITY_ON_OBJECT = 1350; + //public const uint ERROR_CANT_ACCESS_DOMAIN_INFO = 1351; + //public const uint ERROR_INVALID_SERVER_STATE = 1352; + //public const uint ERROR_INVALID_DOMAIN_STATE = 1353; + //public const uint ERROR_INVALID_DOMAIN_ROLE = 1354; + //public const uint ERROR_NO_SUCH_DOMAIN = 1355; + //public const uint ERROR_DOMAIN_EXISTS = 1356; + //public const uint ERROR_DOMAIN_LIMIT_EXCEEDED = 1357; + //public const uint ERROR_INTERNAL_DB_CORRUPTION = 1358; + //public const uint ERROR_INTERNAL_ERROR = 1359; + //public const uint ERROR_GENERIC_NOT_MAPPED = 1360; + //public const uint ERROR_BAD_DESCRIPTOR_FORMAT = 1361; + //public const uint ERROR_NOT_LOGON_PROCESS = 1362; + //public const uint ERROR_LOGON_SESSION_EXISTS = 1363; + //public const uint ERROR_NO_SUCH_PACKAGE = 1364; + //public const uint ERROR_BAD_LOGON_SESSION_STATE = 1365; + //public const uint ERROR_LOGON_SESSION_COLLISION = 1366; + //public const uint ERROR_INVALID_LOGON_TYPE = 1367; + //public const uint ERROR_CANNOT_IMPERSONATE = 1368; + //public const uint ERROR_RXACT_INVALID_STATE = 1369; + //public const uint ERROR_RXACT_COMMIT_FAILURE = 1370; + //public const uint ERROR_SPECIAL_ACCOUNT = 1371; + //public const uint ERROR_SPECIAL_GROUP = 1372; + //public const uint ERROR_SPECIAL_USER = 1373; + //public const uint ERROR_MEMBERS_PRIMARY_GROUP = 1374; + //public const uint ERROR_TOKEN_ALREADY_IN_USE = 1375; + //public const uint ERROR_NO_SUCH_ALIAS = 1376; + //public const uint ERROR_MEMBER_NOT_IN_ALIAS = 1377; + //public const uint ERROR_MEMBER_IN_ALIAS = 1378; + //public const uint ERROR_ALIAS_EXISTS = 1379; + //public const uint ERROR_LOGON_NOT_GRANTED = 1380; + //public const uint ERROR_TOO_MANY_SECRETS = 1381; + //public const uint ERROR_SECRET_TOO_LONG = 1382; + //public const uint ERROR_INTERNAL_DB_ERROR = 1383; + //public const uint ERROR_TOO_MANY_CONTEXT_IDS = 1384; + //public const uint ERROR_LOGON_TYPE_NOT_GRANTED = 1385; + //public const uint ERROR_NT_CROSS_ENCRYPTION_REQUIRED = 1386; + //public const uint ERROR_NO_SUCH_MEMBER = 1387; + //public const uint ERROR_INVALID_MEMBER = 1388; + //public const uint ERROR_TOO_MANY_SIDS = 1389; + //public const uint ERROR_LM_CROSS_ENCRYPTION_REQUIRED = 1390; + //public const uint ERROR_NO_INHERITANCE = 1391; + //public const uint ERROR_FILE_CORRUPT = 1392; + //public const uint ERROR_DISK_CORRUPT = 1393; + //public const uint ERROR_NO_USER_SESSION_KEY = 1394; + //public const uint ERROR_LICENSE_QUOTA_EXCEEDED = 1395; + //public const uint ERROR_WRONG_TARGET_NAME = 1396; + //public const uint ERROR_MUTUAL_AUTH_FAILED = 1397; + //public const uint ERROR_TIME_SKEW = 1398; + //public const uint ERROR_CURRENT_DOMAIN_NOT_ALLOWED = 1399; + //public const uint ERROR_INVALID_WINDOW_HANDLE = 1400; + //public const uint ERROR_INVALID_MENU_HANDLE = 1401; + //public const uint ERROR_INVALID_CURSOR_HANDLE = 1402; + //public const uint ERROR_INVALID_ACCEL_HANDLE = 1403; + //public const uint ERROR_INVALID_HOOK_HANDLE = 1404; + //public const uint ERROR_INVALID_DWP_HANDLE = 1405; + //public const uint ERROR_TLW_WITH_WSCHILD = 1406; + //public const uint ERROR_CANNOT_FIND_WND_CLASS = 1407; + //public const uint ERROR_WINDOW_OF_OTHER_THREAD = 1408; + //public const uint ERROR_HOTKEY_ALREADY_REGISTERED = 1409; + //public const uint ERROR_CLASS_ALREADY_EXISTS = 1410; + //public const uint ERROR_CLASS_DOES_NOT_EXIST = 1411; + //public const uint ERROR_CLASS_HAS_WINDOWS = 1412; + //public const uint ERROR_INVALID_INDEX = 1413; + //public const uint ERROR_INVALID_ICON_HANDLE = 1414; + //public const uint ERROR_PRIVATE_DIALOG_INDEX = 1415; + //public const uint ERROR_LISTBOX_ID_NOT_FOUND = 1416; + //public const uint ERROR_NO_WILDCARD_CHARACTERS = 1417; + //public const uint ERROR_CLIPBOARD_NOT_OPEN = 1418; + //public const uint ERROR_HOTKEY_NOT_REGISTERED = 1419; + //public const uint ERROR_WINDOW_NOT_DIALOG = 1420; + //public const uint ERROR_CONTROL_ID_NOT_FOUND = 1421; + //public const uint ERROR_INVALID_COMBOBOX_MESSAGE = 1422; + //public const uint ERROR_WINDOW_NOT_COMBOBOX = 1423; + //public const uint ERROR_INVALID_EDIT_HEIGHT = 1424; + //public const uint ERROR_DC_NOT_FOUND = 1425; + //public const uint ERROR_INVALID_HOOK_FILTER = 1426; + //public const uint ERROR_INVALID_FILTER_PROC = 1427; + //public const uint ERROR_HOOK_NEEDS_HMOD = 1428; + //public const uint ERROR_GLOBAL_ONLY_HOOK = 1429; + //public const uint ERROR_JOURNAL_HOOK_SET = 1430; + //public const uint ERROR_HOOK_NOT_INSTALLED = 1431; + //public const uint ERROR_INVALID_LB_MESSAGE = 1432; + //public const uint ERROR_SETCOUNT_ON_BAD_LB = 1433; + //public const uint ERROR_LB_WITHOUT_TABSTOPS = 1434; + //public const uint ERROR_DESTROY_OBJECT_OF_OTHER_THREAD = 1435; + //public const uint ERROR_CHILD_WINDOW_MENU = 1436; + //public const uint ERROR_NO_SYSTEM_MENU = 1437; + //public const uint ERROR_INVALID_MSGBOX_STYLE = 1438; + //public const uint ERROR_INVALID_SPI_VALUE = 1439; + //public const uint ERROR_SCREEN_ALREADY_LOCKED = 1440; + //public const uint ERROR_HWNDS_HAVE_DIFF_PARENT = 1441; + //public const uint ERROR_NOT_CHILD_WINDOW = 1442; + //public const uint ERROR_INVALID_GW_COMMAND = 1443; + //public const uint ERROR_INVALID_THREAD_ID = 1444; + //public const uint ERROR_NON_MDICHILD_WINDOW = 1445; + //public const uint ERROR_POPUP_ALREADY_ACTIVE = 1446; + //public const uint ERROR_NO_SCROLLBARS = 1447; + //public const uint ERROR_INVALID_SCROLLBAR_RANGE = 1448; + //public const uint ERROR_INVALID_SHOWWIN_COMMAND = 1449; + //public const uint ERROR_NO_SYSTEM_RESOURCES = 1450; + //public const uint ERROR_NONPAGED_SYSTEM_RESOURCES = 1451; + //public const uint ERROR_PAGED_SYSTEM_RESOURCES = 1452; + //public const uint ERROR_WORKING_SET_QUOTA = 1453; + //public const uint ERROR_PAGEFILE_QUOTA = 1454; + //public const uint ERROR_COMMITMENT_LIMIT = 1455; + //public const uint ERROR_MENU_ITEM_NOT_FOUND = 1456; + //public const uint ERROR_INVALID_KEYBOARD_HANDLE = 1457; + //public const uint ERROR_HOOK_TYPE_NOT_ALLOWED = 1458; + //public const uint ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION = 1459; + //public const uint ERROR_TIMEOUT = 1460; + //public const uint ERROR_INVALID_MONITOR_HANDLE = 1461; + //public const uint ERROR_INCORRECT_SIZE = 1462; + //public const uint ERROR_EVENTLOG_FILE_CORRUPT = 1500; + //public const uint ERROR_EVENTLOG_CANT_START = 1501; + //public const uint ERROR_LOG_FILE_FULL = 1502; + //public const uint ERROR_EVENTLOG_FILE_CHANGED = 1503; + //public const uint ERROR_INSTALL_SERVICE_FAILURE = 1601; + //public const uint ERROR_INSTALL_USEREXIT = 1602; + //public const uint ERROR_INSTALL_FAILURE = 1603; + //public const uint ERROR_INSTALL_SUSPEND = 1604; + //public const uint ERROR_UNKNOWN_PRODUCT = 1605; + //public const uint ERROR_UNKNOWN_FEATURE = 1606; + //public const uint ERROR_UNKNOWN_COMPONENT = 1607; + //public const uint ERROR_UNKNOWN_PROPERTY = 1608; + //public const uint ERROR_INVALID_HANDLE_STATE = 1609; + //public const uint ERROR_BAD_CONFIGURATION = 1610; + //public const uint ERROR_INDEX_ABSENT = 1611; + //public const uint ERROR_INSTALL_SOURCE_ABSENT = 1612; + //public const uint ERROR_INSTALL_PACKAGE_VERSION = 1613; + //public const uint ERROR_PRODUCT_UNINSTALLED = 1614; + //public const uint ERROR_BAD_QUERY_SYNTAX = 1615; + //public const uint ERROR_INVALID_FIELD = 1616; + //public const uint ERROR_DEVICE_REMOVED = 1617; + //public const uint ERROR_INSTALL_ALREADY_RUNNING = 1618; + //public const uint ERROR_INSTALL_PACKAGE_OPEN_FAILED = 1619; + //public const uint ERROR_INSTALL_PACKAGE_INVALID = 1620; + //public const uint ERROR_INSTALL_UI_FAILURE = 1621; + //public const uint ERROR_INSTALL_LOG_FAILURE = 1622; + //public const uint ERROR_INSTALL_LANGUAGE_UNSUPPORTED = 1623; + //public const uint ERROR_INSTALL_TRANSFORM_FAILURE = 1624; + //public const uint ERROR_INSTALL_PACKAGE_REJECTED = 1625; + //public const uint ERROR_FUNCTION_NOT_CALLED = 1626; + //public const uint ERROR_FUNCTION_FAILED = 1627; + //public const uint ERROR_INVALID_TABLE = 1628; + //public const uint ERROR_DATATYPE_MISMATCH = 1629; + //public const uint ERROR_UNSUPPORTED_TYPE = 1630; + //public const uint ERROR_CREATE_FAILED = 1631; + //public const uint ERROR_INSTALL_TEMP_UNWRITABLE = 1632; + //public const uint ERROR_INSTALL_PLATFORM_UNSUPPORTED = 1633; + //public const uint ERROR_INSTALL_NOTUSED = 1634; + //public const uint ERROR_PATCH_PACKAGE_OPEN_FAILED = 1635; + //public const uint ERROR_PATCH_PACKAGE_INVALID = 1636; + //public const uint ERROR_PATCH_PACKAGE_UNSUPPORTED = 1637; + //public const uint ERROR_PRODUCT_VERSION = 1638; + //public const uint ERROR_INVALID_COMMAND_LINE = 1639; + //public const uint ERROR_INSTALL_REMOTE_DISALLOWED = 1640; + + /// (1641) The requested operation completed successfully. + /// The system will be restarted so the changes can take effect. + /// + public const uint ERROR_SUCCESS_REBOOT_INITIATED = 1641; + + //public const uint ERROR_PATCH_TARGET_NOT_FOUND = 1642; + //public const uint ERROR_PATCH_PACKAGE_REJECTED = 1643; + //public const uint ERROR_INSTALL_TRANSFORM_REJECTED = 1644; + //public const uint ERROR_INSTALL_REMOTE_PROHIBITED = 1645; + //public const uint RPC_S_INVALID_STRING_BINDING = 1700; + //public const uint RPC_S_WRONG_KIND_OF_BINDING = 1701; + //public const uint RPC_S_INVALID_BINDING = 1702; + //public const uint RPC_S_PROTSEQ_NOT_SUPPORTED = 1703; + //public const uint RPC_S_INVALID_RPC_PROTSEQ = 1704; + //public const uint RPC_S_INVALID_STRING_UUID = 1705; + //public const uint RPC_S_INVALID_ENDPOINT_FORMAT = 1706; + //public const uint RPC_S_INVALID_NET_ADDR = 1707; + //public const uint RPC_S_NO_ENDPOINT_FOUND = 1708; + //public const uint RPC_S_INVALID_TIMEOUT = 1709; + //public const uint RPC_S_OBJECT_NOT_FOUND = 1710; + //public const uint RPC_S_ALREADY_REGISTERED = 1711; + //public const uint RPC_S_TYPE_ALREADY_REGISTERED = 1712; + //public const uint RPC_S_ALREADY_LISTENING = 1713; + //public const uint RPC_S_NO_PROTSEQS_REGISTERED = 1714; + //public const uint RPC_S_NOT_LISTENING = 1715; + //public const uint RPC_S_UNKNOWN_MGR_TYPE = 1716; + //public const uint RPC_S_UNKNOWN_IF = 1717; + //public const uint RPC_S_NO_BINDINGS = 1718; + //public const uint RPC_S_NO_PROTSEQS = 1719; + //public const uint RPC_S_CANT_CREATE_ENDPOINT = 1720; + //public const uint RPC_S_OUT_OF_RESOURCES = 1721; + //public const uint RPC_S_SERVER_UNAVAILABLE = 1722; + //public const uint RPC_S_SERVER_TOO_BUSY = 1723; + //public const uint RPC_S_INVALID_NETWORK_OPTIONS = 1724; + //public const uint RPC_S_NO_CALL_ACTIVE = 1725; + //public const uint RPC_S_CALL_FAILED = 1726; + //public const uint RPC_S_CALL_FAILED_DNE = 1727; + //public const uint RPC_S_PROTOCOL_ERROR = 1728; + //public const uint RPC_S_UNSUPPORTED_TRANS_SYN = 1730; + //public const uint RPC_S_UNSUPPORTED_TYPE = 1732; + //public const uint RPC_S_INVALID_TAG = 1733; + //public const uint RPC_S_INVALID_BOUND = 1734; + //public const uint RPC_S_NO_ENTRY_NAME = 1735; + //public const uint RPC_S_INVALID_NAME_SYNTAX = 1736; + //public const uint RPC_S_UNSUPPORTED_NAME_SYNTAX = 1737; + //public const uint RPC_S_UUID_NO_ADDRESS = 1739; + //public const uint RPC_S_DUPLICATE_ENDPOINT = 1740; + //public const uint RPC_S_UNKNOWN_AUTHN_TYPE = 1741; + //public const uint RPC_S_MAX_CALLS_TOO_SMALL = 1742; + //public const uint RPC_S_STRING_TOO_LONG = 1743; + //public const uint RPC_S_PROTSEQ_NOT_FOUND = 1744; + //public const uint RPC_S_PROCNUM_OUT_OF_RANGE = 1745; + //public const uint RPC_S_BINDING_HAS_NO_AUTH = 1746; + //public const uint RPC_S_UNKNOWN_AUTHN_SERVICE = 1747; + //public const uint RPC_S_UNKNOWN_AUTHN_LEVEL = 1748; + //public const uint RPC_S_INVALID_AUTH_IDENTITY = 1749; + //public const uint RPC_S_UNKNOWN_AUTHZ_SERVICE = 1750; + //public const uint EPT_S_INVALID_ENTRY = 1751; + //public const uint EPT_S_CANT_PERFORM_OP = 1752; + //public const uint EPT_S_NOT_REGISTERED = 1753; + //public const uint RPC_S_NOTHING_TO_EXPORT = 1754; + //public const uint RPC_S_INCOMPLETE_NAME = 1755; + //public const uint RPC_S_INVALID_VERS_OPTION = 1756; + //public const uint RPC_S_NO_MORE_MEMBERS = 1757; + //public const uint RPC_S_NOT_ALL_OBJS_UNEXPORTED = 1758; + //public const uint RPC_S_INTERFACE_NOT_FOUND = 1759; + //public const uint RPC_S_ENTRY_ALREADY_EXISTS = 1760; + //public const uint RPC_S_ENTRY_NOT_FOUND = 1761; + //public const uint RPC_S_NAME_SERVICE_UNAVAILABLE = 1762; + //public const uint RPC_S_INVALID_NAF_ID = 1763; + //public const uint RPC_S_CANNOT_SUPPORT = 1764; + //public const uint RPC_S_NO_CONTEXT_AVAILABLE = 1765; + //public const uint RPC_S_INTERNAL_ERROR = 1766; + //public const uint RPC_S_ZERO_DIVIDE = 1767; + //public const uint RPC_S_ADDRESS_ERROR = 1768; + //public const uint RPC_S_FP_DIV_ZERO = 1769; + //public const uint RPC_S_FP_UNDERFLOW = 1770; + //public const uint RPC_S_FP_OVERFLOW = 1771; + //public const uint RPC_X_NO_MORE_ENTRIES = 1772; + //public const uint RPC_X_SS_CHAR_TRANS_OPEN_FAIL = 1773; + //public const uint RPC_X_SS_CHAR_TRANS_SHORT_FILE = 1774; + //public const uint RPC_X_SS_IN_NULL_CONTEXT = 1775; + //public const uint RPC_X_SS_CONTEXT_DAMAGED = 1777; + //public const uint RPC_X_SS_HANDLES_MISMATCH = 1778; + //public const uint RPC_X_SS_CANNOT_GET_CALL_HANDLE = 1779; + //public const uint RPC_X_NULL_REF_POINTER = 1780; + //public const uint RPC_X_ENUM_VALUE_OUT_OF_RANGE = 1781; + //public const uint RPC_X_BYTE_COUNT_TOO_SMALL = 1782; + + /// (1783) The stub received bad data. + public const uint RPC_X_BAD_STUB_DATA = 1783; + + //public const uint ERROR_INVALID_USER_BUFFER = 1784; + //public const uint ERROR_UNRECOGNIZED_MEDIA = 1785; + //public const uint ERROR_NO_TRUST_LSA_SECRET = 1786; + //public const uint ERROR_NO_TRUST_SAM_ACCOUNT = 1787; + //public const uint ERROR_TRUSTED_DOMAIN_FAILURE = 1788; + //public const uint ERROR_TRUSTED_RELATIONSHIP_FAILURE = 1789; + //public const uint ERROR_TRUST_FAILURE = 1790; + //public const uint RPC_S_CALL_IN_PROGRESS = 1791; + //public const uint ERROR_NETLOGON_NOT_STARTED = 1792; + //public const uint ERROR_ACCOUNT_EXPIRED = 1793; + //public const uint ERROR_REDIRECTOR_HAS_OPEN_HANDLES = 1794; + //public const uint ERROR_PRINTER_DRIVER_ALREADY_INSTALLED = 1795; + //public const uint ERROR_UNKNOWN_PORT = 1796; + //public const uint ERROR_UNKNOWN_PRINTER_DRIVER = 1797; + //public const uint ERROR_UNKNOWN_PRINTPROCESSOR = 1798; + //public const uint ERROR_INVALID_SEPARATOR_FILE = 1799; + //public const uint ERROR_INVALID_PRIORITY = 1800; + //public const uint ERROR_INVALID_PRINTER_NAME = 1801; + //public const uint ERROR_PRINTER_ALREADY_EXISTS = 1802; + //public const uint ERROR_INVALID_PRINTER_COMMAND = 1803; + //public const uint ERROR_INVALID_DATATYPE = 1804; + //public const uint ERROR_INVALID_ENVIRONMENT = 1805; + //public const uint RPC_S_NO_MORE_BINDINGS = 1806; + //public const uint ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT = 1807; + //public const uint ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT = 1808; + //public const uint ERROR_NOLOGON_SERVER_TRUST_ACCOUNT = 1809; + //public const uint ERROR_DOMAIN_TRUST_INCONSISTENT = 1810; + //public const uint ERROR_SERVER_HAS_OPEN_HANDLES = 1811; + //public const uint ERROR_RESOURCE_DATA_NOT_FOUND = 1812; + //public const uint ERROR_RESOURCE_TYPE_NOT_FOUND = 1813; + //public const uint ERROR_RESOURCE_NAME_NOT_FOUND = 1814; + //public const uint ERROR_RESOURCE_LANG_NOT_FOUND = 1815; + //public const uint ERROR_NOT_ENOUGH_QUOTA = 1816; + //public const uint RPC_S_NO_INTERFACES = 1817; + //public const uint RPC_S_CALL_CANCELLED = 1818; + //public const uint RPC_S_BINDING_INCOMPLETE = 1819; + //public const uint RPC_S_COMM_FAILURE = 1820; + //public const uint RPC_S_UNSUPPORTED_AUTHN_LEVEL = 1821; + //public const uint RPC_S_NO_PRINC_NAME = 1822; + //public const uint RPC_S_NOT_RPC_ERROR = 1823; + //public const uint RPC_S_UUID_LOCAL_ONLY = 1824; + //public const uint RPC_S_SEC_PKG_ERROR = 1825; + //public const uint RPC_S_NOT_CANCELLED = 1826; + //public const uint RPC_X_INVALID_ES_ACTION = 1827; + //public const uint RPC_X_WRONG_ES_VERSION = 1828; + //public const uint RPC_X_WRONG_STUB_VERSION = 1829; + //public const uint RPC_X_INVALID_PIPE_OBJECT = 1830; + //public const uint RPC_X_WRONG_PIPE_ORDER = 1831; + //public const uint RPC_X_WRONG_PIPE_VERSION = 1832; + //public const uint RPC_S_GROUP_MEMBER_NOT_FOUND = 1898; + //public const uint EPT_S_CANT_CREATE = 1899; + //public const uint RPC_S_INVALID_OBJECT = 1900; + //public const uint ERROR_INVALID_TIME = 1901; + //public const uint ERROR_INVALID_FORM_NAME = 1902; + //public const uint ERROR_INVALID_FORM_SIZE = 1903; + //public const uint ERROR_ALREADY_WAITING = 1904; + //public const uint ERROR_PRINTER_DELETED = 1905; + //public const uint ERROR_INVALID_PRINTER_STATE = 1906; + //public const uint ERROR_PASSWORD_MUST_CHANGE = 1907; + //public const uint ERROR_DOMAIN_CONTROLLER_NOT_FOUND = 1908; + //public const uint ERROR_ACCOUNT_LOCKED_OUT = 1909; + //public const uint OR_INVALID_OXID = 1910; + //public const uint OR_INVALID_OID = 1911; + //public const uint OR_INVALID_SET = 1912; + //public const uint RPC_S_SEND_INCOMPLETE = 1913; + //public const uint RPC_S_INVALID_ASYNC_HANDLE = 1914; + //public const uint RPC_S_INVALID_ASYNC_CALL = 1915; + //public const uint RPC_X_PIPE_CLOSED = 1916; + //public const uint RPC_X_PIPE_DISCIPLINE_ERROR = 1917; + //public const uint RPC_X_PIPE_EMPTY = 1918; + //public const uint ERROR_NO_SITENAME = 1919; + //public const uint ERROR_CANT_ACCESS_FILE = 1920; + //public const uint ERROR_CANT_RESOLVE_FILENAME = 1921; + //public const uint RPC_S_ENTRY_TYPE_MISMATCH = 1922; + //public const uint RPC_S_NOT_ALL_OBJS_EXPORTED = 1923; + //public const uint RPC_S_INTERFACE_NOT_EXPORTED = 1924; + //public const uint RPC_S_PROFILE_NOT_ADDED = 1925; + //public const uint RPC_S_PRF_ELT_NOT_ADDED = 1926; + //public const uint RPC_S_PRF_ELT_NOT_REMOVED = 1927; + //public const uint RPC_S_GRP_ELT_NOT_ADDED = 1928; + //public const uint RPC_S_GRP_ELT_NOT_REMOVED = 1929; + //public const uint ERROR_KM_DRIVER_BLOCKED = 1930; + //public const uint ERROR_CONTEXT_EXPIRED = 1931; + //public const uint ERROR_PER_USER_TRUST_QUOTA_EXCEEDED = 1932; + //public const uint ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED = 1933; + //public const uint ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED = 1934; + //public const uint ERROR_AUTHENTICATION_FIREWALL_FAILED = 1935; + //public const uint ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED = 1936; + //public const uint ERROR_INVALID_PIXEL_FORMAT = 2000; + //public const uint ERROR_BAD_DRIVER = 2001; + //public const uint ERROR_INVALID_WINDOW_STYLE = 2002; + //public const uint ERROR_METAFILE_NOT_SUPPORTED = 2003; + //public const uint ERROR_TRANSFORM_NOT_SUPPORTED = 2004; + //public const uint ERROR_CLIPPING_NOT_SUPPORTED = 2005; + //public const uint ERROR_INVALID_CMM = 2010; + //public const uint ERROR_INVALID_PROFILE = 2011; + //public const uint ERROR_TAG_NOT_FOUND = 2012; + //public const uint ERROR_TAG_NOT_PRESENT = 2013; + //public const uint ERROR_DUPLICATE_TAG = 2014; + //public const uint ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE = 2015; + //public const uint ERROR_PROFILE_NOT_FOUND = 2016; + //public const uint ERROR_INVALID_COLORSPACE = 2017; + //public const uint ERROR_ICM_NOT_ENABLED = 2018; + //public const uint ERROR_DELETING_ICM_XFORM = 2019; + //public const uint ERROR_INVALID_TRANSFORM = 2020; + //public const uint ERROR_COLORSPACE_MISMATCH = 2021; + //public const uint ERROR_INVALID_COLORINDEX = 2022; + //public const uint ERROR_CONNECTED_OTHER_PASSWORD = 2108; + //public const uint ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT = 2109; + //public const uint ERROR_UNKNOWN_PRINT_MONITOR = 3000; + //public const uint ERROR_PRINTER_DRIVER_IN_USE = 3001; + //public const uint ERROR_SPOOL_FILE_NOT_FOUND = 3002; + //public const uint ERROR_SPL_NO_STARTDOC = 3003; + //public const uint ERROR_SPL_NO_ADDJOB = 3004; + //public const uint ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED = 3005; + //public const uint ERROR_PRINT_MONITOR_ALREADY_INSTALLED = 3006; + //public const uint ERROR_INVALID_PRINT_MONITOR = 3007; + //public const uint ERROR_PRINT_MONITOR_IN_USE = 3008; + //public const uint ERROR_PRINTER_HAS_JOBS_QUEUED = 3009; + + /// (3010) The requested operation is successful. + /// Changes will not be effective until the system is rebooted. + /// + public const uint ERROR_SUCCESS_REBOOT_REQUIRED = 3010; + + /// (3011) The requested operation is successful. + /// Changes will not be effective until the service is restarted. + /// + public const uint ERROR_SUCCESS_RESTART_REQUIRED = 3011; + + //public const uint ERROR_PRINTER_NOT_FOUND = 3012; + //public const uint ERROR_PRINTER_DRIVER_WARNED = 3013; + //public const uint ERROR_PRINTER_DRIVER_BLOCKED = 3014; + //public const uint ERROR_WINS_INTERNAL = 4000; + //public const uint ERROR_CAN_NOT_DEL_LOCAL_WINS = 4001; + //public const uint ERROR_STATIC_INIT = 4002; + //public const uint ERROR_INC_BACKUP = 4003; + //public const uint ERROR_FULL_BACKUP = 4004; + //public const uint ERROR_REC_NON_EXISTENT = 4005; + //public const uint ERROR_RPL_NOT_ALLOWED = 4006; + //public const uint ERROR_DHCP_ADDRESS_CONFLICT = 4100; + //public const uint ERROR_WMI_GUID_NOT_FOUND = 4200; + //public const uint ERROR_WMI_INSTANCE_NOT_FOUND = 4201; + //public const uint ERROR_WMI_ITEMID_NOT_FOUND = 4202; + //public const uint ERROR_WMI_TRY_AGAIN = 4203; + //public const uint ERROR_WMI_DP_NOT_FOUND = 4204; + //public const uint ERROR_WMI_UNRESOLVED_INSTANCE_REF = 4205; + //public const uint ERROR_WMI_ALREADY_ENABLED = 4206; + //public const uint ERROR_WMI_GUID_DISCONNECTED = 4207; + //public const uint ERROR_WMI_SERVER_UNAVAILABLE = 4208; + //public const uint ERROR_WMI_DP_FAILED = 4209; + //public const uint ERROR_WMI_INVALID_MOF = 4210; + //public const uint ERROR_WMI_INVALID_REGINFO = 4211; + //public const uint ERROR_WMI_ALREADY_DISABLED = 4212; + //public const uint ERROR_WMI_READ_ONLY = 4213; + //public const uint ERROR_WMI_SET_FAILURE = 4214; + //public const uint ERROR_INVALID_MEDIA = 4300; + //public const uint ERROR_INVALID_LIBRARY = 4301; + //public const uint ERROR_INVALID_MEDIA_POOL = 4302; + //public const uint ERROR_DRIVE_MEDIA_MISMATCH = 4303; + //public const uint ERROR_MEDIA_OFFLINE = 4304; + //public const uint ERROR_LIBRARY_OFFLINE = 4305; + //public const uint ERROR_EMPTY = 4306; + //public const uint ERROR_NOT_EMPTY = 4307; + //public const uint ERROR_MEDIA_UNAVAILABLE = 4308; + //public const uint ERROR_RESOURCE_DISABLED = 4309; + //public const uint ERROR_INVALID_CLEANER = 4310; + //public const uint ERROR_UNABLE_TO_CLEAN = 4311; + //public const uint ERROR_OBJECT_NOT_FOUND = 4312; + //public const uint ERROR_DATABASE_FAILURE = 4313; + //public const uint ERROR_DATABASE_FULL = 4314; + //public const uint ERROR_MEDIA_INCOMPATIBLE = 4315; + //public const uint ERROR_RESOURCE_NOT_PRESENT = 4316; + //public const uint ERROR_INVALID_OPERATION = 4317; + //public const uint ERROR_MEDIA_NOT_AVAILABLE = 4318; + //public const uint ERROR_DEVICE_NOT_AVAILABLE = 4319; + //public const uint ERROR_REQUEST_REFUSED = 4320; + //public const uint ERROR_INVALID_DRIVE_OBJECT = 4321; + //public const uint ERROR_LIBRARY_FULL = 4322; + //public const uint ERROR_MEDIUM_NOT_ACCESSIBLE = 4323; + //public const uint ERROR_UNABLE_TO_LOAD_MEDIUM = 4324; + //public const uint ERROR_UNABLE_TO_INVENTORY_DRIVE = 4325; + //public const uint ERROR_UNABLE_TO_INVENTORY_SLOT = 4326; + //public const uint ERROR_UNABLE_TO_INVENTORY_TRANSPORT = 4327; + //public const uint ERROR_TRANSPORT_FULL = 4328; + //public const uint ERROR_CONTROLLING_IEPORT = 4329; + //public const uint ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA = 4330; + //public const uint ERROR_CLEANER_SLOT_SET = 4331; + //public const uint ERROR_CLEANER_SLOT_NOT_SET = 4332; + //public const uint ERROR_CLEANER_CARTRIDGE_SPENT = 4333; + //public const uint ERROR_UNEXPECTED_OMID = 4334; + //public const uint ERROR_CANT_DELETE_LAST_ITEM = 4335; + //public const uint ERROR_MESSAGE_EXCEEDS_MAX_SIZE = 4336; + //public const uint ERROR_VOLUME_CONTAINS_SYS_FILES = 4337; + //public const uint ERROR_INDIGENOUS_TYPE = 4338; + //public const uint ERROR_NO_SUPPORTING_DRIVES = 4339; + //public const uint ERROR_CLEANER_CARTRIDGE_INSTALLED = 4340; + //public const uint ERROR_IEPORT_FULL = 4341; + //public const uint ERROR_FILE_OFFLINE = 4350; + //public const uint ERROR_REMOTE_STORAGE_NOT_ACTIVE = 4351; + //public const uint ERROR_REMOTE_STORAGE_MEDIA_ERROR = 4352; + + /// (4390) The file or directory is not a reparse point. + public const uint ERROR_NOT_A_REPARSE_POINT = 4390; + + //public const uint ERROR_REPARSE_ATTRIBUTE_CONFLICT = 4391; + //public const uint ERROR_INVALID_REPARSE_DATA = 4392; + //public const uint ERROR_REPARSE_TAG_INVALID = 4393; + //public const uint ERROR_REPARSE_TAG_MISMATCH = 4394; + //public const uint ERROR_VOLUME_NOT_SIS_ENABLED = 4500; + //public const uint ERROR_DEPENDENT_RESOURCE_EXISTS = 5001; + //public const uint ERROR_DEPENDENCY_NOT_FOUND = 5002; + //public const uint ERROR_DEPENDENCY_ALREADY_EXISTS = 5003; + //public const uint ERROR_RESOURCE_NOT_ONLINE = 5004; + //public const uint ERROR_HOST_NODE_NOT_AVAILABLE = 5005; + //public const uint ERROR_RESOURCE_NOT_AVAILABLE = 5006; + //public const uint ERROR_RESOURCE_NOT_FOUND = 5007; + //public const uint ERROR_SHUTDOWN_CLUSTER = 5008; + //public const uint ERROR_CANT_EVICT_ACTIVE_NODE = 5009; + //public const uint ERROR_OBJECT_ALREADY_EXISTS = 5010; + //public const uint ERROR_OBJECT_IN_LIST = 5011; + //public const uint ERROR_GROUP_NOT_AVAILABLE = 5012; + //public const uint ERROR_GROUP_NOT_FOUND = 5013; + //public const uint ERROR_GROUP_NOT_ONLINE = 5014; + //public const uint ERROR_HOST_NODE_NOT_RESOURCE_OWNER = 5015; + //public const uint ERROR_HOST_NODE_NOT_GROUP_OWNER = 5016; + //public const uint ERROR_RESMON_CREATE_FAILED = 5017; + //public const uint ERROR_RESMON_ONLINE_FAILED = 5018; + //public const uint ERROR_RESOURCE_ONLINE = 5019; + //public const uint ERROR_QUORUM_RESOURCE = 5020; + //public const uint ERROR_NOT_QUORUM_CAPABLE = 5021; + //public const uint ERROR_CLUSTER_SHUTTING_DOWN = 5022; + //public const uint ERROR_INVALID_STATE = 5023; + //public const uint ERROR_RESOURCE_PROPERTIES_STORED = 5024; + //public const uint ERROR_NOT_QUORUM_CLASS = 5025; + //public const uint ERROR_CORE_RESOURCE = 5026; + //public const uint ERROR_QUORUM_RESOURCE_ONLINE_FAILED = 5027; + //public const uint ERROR_QUORUMLOG_OPEN_FAILED = 5028; + //public const uint ERROR_CLUSTERLOG_CORRUPT = 5029; + //public const uint ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE = 5030; + //public const uint ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE = 5031; + //public const uint ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND = 5032; + //public const uint ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE = 5033; + //public const uint ERROR_QUORUM_OWNER_ALIVE = 5034; + //public const uint ERROR_NETWORK_NOT_AVAILABLE = 5035; + //public const uint ERROR_NODE_NOT_AVAILABLE = 5036; + //public const uint ERROR_ALL_NODES_NOT_AVAILABLE = 5037; + //public const uint ERROR_RESOURCE_FAILED = 5038; + //public const uint ERROR_CLUSTER_INVALID_NODE = 5039; + //public const uint ERROR_CLUSTER_NODE_EXISTS = 5040; + //public const uint ERROR_CLUSTER_JOIN_IN_PROGRESS = 5041; + //public const uint ERROR_CLUSTER_NODE_NOT_FOUND = 5042; + //public const uint ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND = 5043; + //public const uint ERROR_CLUSTER_NETWORK_EXISTS = 5044; + //public const uint ERROR_CLUSTER_NETWORK_NOT_FOUND = 5045; + //public const uint ERROR_CLUSTER_NETINTERFACE_EXISTS = 5046; + //public const uint ERROR_CLUSTER_NETINTERFACE_NOT_FOUND = 5047; + //public const uint ERROR_CLUSTER_INVALID_REQUEST = 5048; + //public const uint ERROR_CLUSTER_INVALID_NETWORK_PROVIDER = 5049; + //public const uint ERROR_CLUSTER_NODE_DOWN = 5050; + //public const uint ERROR_CLUSTER_NODE_UNREACHABLE = 5051; + //public const uint ERROR_CLUSTER_NODE_NOT_MEMBER = 5052; + //public const uint ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS = 5053; + //public const uint ERROR_CLUSTER_INVALID_NETWORK = 5054; + //public const uint ERROR_CLUSTER_NODE_UP = 5056; + //public const uint ERROR_CLUSTER_IPADDR_IN_USE = 5057; + //public const uint ERROR_CLUSTER_NODE_NOT_PAUSED = 5058; + //public const uint ERROR_CLUSTER_NO_SECURITY_CONTEXT = 5059; + //public const uint ERROR_CLUSTER_NETWORK_NOT_INTERNAL = 5060; + //public const uint ERROR_CLUSTER_NODE_ALREADY_UP = 5061; + //public const uint ERROR_CLUSTER_NODE_ALREADY_DOWN = 5062; + //public const uint ERROR_CLUSTER_NETWORK_ALREADY_ONLINE = 5063; + //public const uint ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE = 5064; + //public const uint ERROR_CLUSTER_NODE_ALREADY_MEMBER = 5065; + //public const uint ERROR_CLUSTER_LAST_INTERNAL_NETWORK = 5066; + //public const uint ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS = 5067; + //public const uint ERROR_INVALID_OPERATION_ON_QUORUM = 5068; + //public const uint ERROR_DEPENDENCY_NOT_ALLOWED = 5069; + //public const uint ERROR_CLUSTER_NODE_PAUSED = 5070; + //public const uint ERROR_NODE_CANT_HOST_RESOURCE = 5071; + //public const uint ERROR_CLUSTER_NODE_NOT_READY = 5072; + //public const uint ERROR_CLUSTER_NODE_SHUTTING_DOWN = 5073; + //public const uint ERROR_CLUSTER_JOIN_ABORTED = 5074; + //public const uint ERROR_CLUSTER_INCOMPATIBLE_VERSIONS = 5075; + //public const uint ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED = 5076; + //public const uint ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED = 5077; + //public const uint ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND = 5078; + //public const uint ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED = 5079; + //public const uint ERROR_CLUSTER_RESNAME_NOT_FOUND = 5080; + //public const uint ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED = 5081; + //public const uint ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST = 5082; + //public const uint ERROR_CLUSTER_DATABASE_SEQMISMATCH = 5083; + //public const uint ERROR_RESMON_INVALID_STATE = 5084; + //public const uint ERROR_CLUSTER_GUM_NOT_LOCKER = 5085; + //public const uint ERROR_QUORUM_DISK_NOT_FOUND = 5086; + //public const uint ERROR_DATABASE_BACKUP_CORRUPT = 5087; + //public const uint ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT = 5088; + //public const uint ERROR_RESOURCE_PROPERTY_UNCHANGEABLE = 5089; + //public const uint ERROR_CLUSTER_MEMBERSHIP_INVALID_STATE = 5890; + //public const uint ERROR_CLUSTER_QUORUMLOG_NOT_FOUND = 5891; + //public const uint ERROR_CLUSTER_MEMBERSHIP_HALT = 5892; + //public const uint ERROR_CLUSTER_INSTANCE_ID_MISMATCH = 5893; + //public const uint ERROR_CLUSTER_NETWORK_NOT_FOUND_FOR_IP = 5894; + //public const uint ERROR_CLUSTER_PROPERTY_DATA_TYPE_MISMATCH = 5895; + //public const uint ERROR_CLUSTER_EVICT_WITHOUT_CLEANUP = 5896; + //public const uint ERROR_CLUSTER_PARAMETER_MISMATCH = 5897; + //public const uint ERROR_NODE_CANNOT_BE_CLUSTERED = 5898; + //public const uint ERROR_CLUSTER_WRONG_OS_VERSION = 5899; + //public const uint ERROR_CLUSTER_CANT_CREATE_DUP_CLUSTER_NAME = 5900; + //public const uint ERROR_CLUSCFG_ALREADY_COMMITTED = 5901; + //public const uint ERROR_CLUSCFG_ROLLBACK_FAILED = 5902; + //public const uint ERROR_CLUSCFG_SYSTEM_DISK_DRIVE_LETTER_CONFLICT = 5903; + //public const uint ERROR_CLUSTER_OLD_VERSION = 5904; + //public const uint ERROR_CLUSTER_MISMATCHED_COMPUTER_ACCT_NAME = 5905; + //public const uint ERROR_ENCRYPTION_FAILED = 6000; + //public const uint ERROR_DECRYPTION_FAILED = 6001; + //public const uint ERROR_FILE_ENCRYPTED = 6002; + //public const uint ERROR_NO_RECOVERY_POLICY = 6003; + //public const uint ERROR_NO_EFS = 6004; + //public const uint ERROR_WRONG_EFS = 6005; + //public const uint ERROR_NO_USER_KEYS = 6006; + //public const uint ERROR_FILE_NOT_ENCRYPTED = 6007; + //public const uint ERROR_NOT_EXPORT_FORMAT = 6008; + + + /// (6009) The specified file is read only. + public const uint ERROR_FILE_READ_ONLY = 6009; + + //public const uint ERROR_DIR_EFS_DISALLOWED = 6010; + //public const uint ERROR_EFS_SERVER_NOT_TRUSTED = 6011; + + /// (6012) Recovery policy configured for this system contains invalid recovery certificate. + public const uint ERROR_BAD_RECOVERY_POLICY = 6012; + + //public const uint ERROR_EFS_ALG_BLOB_TOO_BIG = 6013; + //public const uint ERROR_VOLUME_NOT_SUPPORT_EFS = 6014; + //public const uint ERROR_EFS_DISABLED = 6015; + //public const uint ERROR_EFS_VERSION_NOT_SUPPORT = 6016; + //public const uint ERROR_NO_BROWSER_SERVERS_FOUND = 6118; + //public const uint SCHED_E_SERVICE_NOT_LOCALSYSTEM = 6200; + + /// (6700) The transaction handle associated with this operation is not valid. + public const uint ERROR_INVALID_TRANSACTION = 6700; + + /// (6701) The requested operation was made in the context + /// of a transaction that is no longer active. + /// + public const uint ERROR_TRANSACTION_NOT_ACTIVE = 6701; + + /// (6702) The requested operation is not valid + /// on the Transaction object in its current state. + /// + public const uint ERROR_TRANSACTION_REQUEST_NOT_VALID = 6702; + + /// (6703) The caller has called a response API, but the response is not expected + /// because the TM did not issue the corresponding request to the caller. + /// + public const uint ERROR_TRANSACTION_NOT_REQUESTED = 6703; + + /// (6704) It is too late to perform the requested operation, + /// since the Transaction has already been aborted. + /// + public const uint ERROR_TRANSACTION_ALREADY_ABORTED = 6704; + + /// (6705) It is too late to perform the requested operation, + /// since the Transaction has already been committed. + /// + public const uint ERROR_TRANSACTION_ALREADY_COMMITTED = 6705; + + /// (6800) The function attempted to use a name + /// that is reserved for use by another transaction. + /// + public const uint ERROR_TRANSACTIONAL_CONFLICT = 6800; + + /// (6805) The remote server or share does not support transacted file operations. + public const uint ERROR_TRANSACTIONS_UNSUPPORTED_REMOTE = 6805; + + //public const uint ERROR_CTX_WINSTATION_NAME_INVALID = 7001; + //public const uint ERROR_CTX_INVALID_PD = 7002; + //public const uint ERROR_CTX_PD_NOT_FOUND = 7003; + //public const uint ERROR_CTX_WD_NOT_FOUND = 7004; + //public const uint ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY = 7005; + //public const uint ERROR_CTX_SERVICE_NAME_COLLISION = 7006; + //public const uint ERROR_CTX_CLOSE_PENDING = 7007; + //public const uint ERROR_CTX_NO_OUTBUF = 7008; + //public const uint ERROR_CTX_MODEM_INF_NOT_FOUND = 7009; + //public const uint ERROR_CTX_INVALID_MODEMNAME = 7010; + //public const uint ERROR_CTX_MODEM_RESPONSE_ERROR = 7011; + //public const uint ERROR_CTX_MODEM_RESPONSE_TIMEOUT = 7012; + //public const uint ERROR_CTX_MODEM_RESPONSE_NO_CARRIER = 7013; + //public const uint ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE = 7014; + //public const uint ERROR_CTX_MODEM_RESPONSE_BUSY = 7015; + //public const uint ERROR_CTX_MODEM_RESPONSE_VOICE = 7016; + //public const uint ERROR_CTX_TD_ERROR = 7017; + //public const uint ERROR_CTX_WINSTATION_NOT_FOUND = 7022; + //public const uint ERROR_CTX_WINSTATION_ALREADY_EXISTS = 7023; + //public const uint ERROR_CTX_WINSTATION_BUSY = 7024; + //public const uint ERROR_CTX_BAD_VIDEO_MODE = 7025; + //public const uint ERROR_CTX_GRAPHICS_INVALID = 7035; + //public const uint ERROR_CTX_LOGON_DISABLED = 7037; + //public const uint ERROR_CTX_NOT_CONSOLE = 7038; + //public const uint ERROR_CTX_CLIENT_QUERY_TIMEOUT = 7040; + //public const uint ERROR_CTX_CONSOLE_DISCONNECT = 7041; + //public const uint ERROR_CTX_CONSOLE_CONNECT = 7042; + //public const uint ERROR_CTX_SHADOW_DENIED = 7044; + //public const uint ERROR_CTX_WINSTATION_ACCESS_DENIED = 7045; + //public const uint ERROR_CTX_INVALID_WD = 7049; + //public const uint ERROR_CTX_SHADOW_INVALID = 7050; + //public const uint ERROR_CTX_SHADOW_DISABLED = 7051; + //public const uint ERROR_CTX_CLIENT_LICENSE_IN_USE = 7052; + //public const uint ERROR_CTX_CLIENT_LICENSE_NOT_SET = 7053; + //public const uint ERROR_CTX_LICENSE_NOT_AVAILABLE = 7054; + //public const uint ERROR_CTX_LICENSE_CLIENT_INVALID = 7055; + //public const uint ERROR_CTX_LICENSE_EXPIRED = 7056; + //public const uint ERROR_CTX_SHADOW_NOT_RUNNING = 7057; + //public const uint ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE = 7058; + //public const uint ERROR_ACTIVATION_COUNT_EXCEEDED = 7059; + //public const uint FRS_ERR_INVALID_API_SEQUENCE = 8001; + //public const uint FRS_ERR_STARTING_SERVICE = 8002; + //public const uint FRS_ERR_STOPPING_SERVICE = 8003; + //public const uint FRS_ERR_INTERNAL_API = 8004; + //public const uint FRS_ERR_INTERNAL = 8005; + //public const uint FRS_ERR_SERVICE_COMM = 8006; + //public const uint FRS_ERR_INSUFFICIENT_PRIV = 8007; + //public const uint FRS_ERR_AUTHENTICATION = 8008; + //public const uint FRS_ERR_PARENT_INSUFFICIENT_PRIV = 8009; + //public const uint FRS_ERR_PARENT_AUTHENTICATION = 8010; + //public const uint FRS_ERR_CHILD_TO_PARENT_COMM = 8011; + //public const uint FRS_ERR_PARENT_TO_CHILD_COMM = 8012; + //public const uint FRS_ERR_SYSVOL_POPULATE = 8013; + //public const uint FRS_ERR_SYSVOL_POPULATE_TIMEOUT = 8014; + //public const uint FRS_ERR_SYSVOL_IS_BUSY = 8015; + //public const uint FRS_ERR_SYSVOL_DEMOTE = 8016; + //public const uint FRS_ERR_INVALID_SERVICE_PARAMETER = 8017; + //public const uint ERROR_DS_NOT_INSTALLED = 8200; + //public const uint ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY = 8201; + //public const uint ERROR_DS_NO_ATTRIBUTE_OR_VALUE = 8202; + //public const uint ERROR_DS_INVALID_ATTRIBUTE_SYNTAX = 8203; + //public const uint ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED = 8204; + //public const uint ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS = 8205; + //public const uint ERROR_DS_BUSY = 8206; + //public const uint ERROR_DS_UNAVAILABLE = 8207; + //public const uint ERROR_DS_NO_RIDS_ALLOCATED = 8208; + //public const uint ERROR_DS_NO_MORE_RIDS = 8209; + //public const uint ERROR_DS_INCORRECT_ROLE_OWNER = 8210; + //public const uint ERROR_DS_RIDMGR_INIT_ERROR = 8211; + //public const uint ERROR_DS_OBJ_CLASS_VIOLATION = 8212; + //public const uint ERROR_DS_CANT_ON_NON_LEAF = 8213; + //public const uint ERROR_DS_CANT_ON_RDN = 8214; + //public const uint ERROR_DS_CANT_MOD_OBJ_CLASS = 8215; + //public const uint ERROR_DS_CROSS_DOM_MOVE_ERROR = 8216; + //public const uint ERROR_DS_GC_NOT_AVAILABLE = 8217; + //public const uint ERROR_SHARED_POLICY = 8218; + //public const uint ERROR_POLICY_OBJECT_NOT_FOUND = 8219; + //public const uint ERROR_POLICY_ONLY_IN_DS = 8220; + //public const uint ERROR_PROMOTION_ACTIVE = 8221; + //public const uint ERROR_NO_PROMOTION_ACTIVE = 8222; + //public const uint ERROR_DS_OPERATIONS_ERROR = 8224; + //public const uint ERROR_DS_PROTOCOL_ERROR = 8225; + //public const uint ERROR_DS_TIMELIMIT_EXCEEDED = 8226; + //public const uint ERROR_DS_SIZELIMIT_EXCEEDED = 8227; + //public const uint ERROR_DS_ADMIN_LIMIT_EXCEEDED = 8228; + //public const uint ERROR_DS_COMPARE_FALSE = 8229; + //public const uint ERROR_DS_COMPARE_TRUE = 8230; + //public const uint ERROR_DS_AUTH_METHOD_NOT_SUPPORTED = 8231; + //public const uint ERROR_DS_STRONG_AUTH_REQUIRED = 8232; + //public const uint ERROR_DS_INAPPROPRIATE_AUTH = 8233; + //public const uint ERROR_DS_AUTH_UNKNOWN = 8234; + //public const uint ERROR_DS_REFERRAL = 8235; + //public const uint ERROR_DS_UNAVAILABLE_CRIT_EXTENSION = 8236; + //public const uint ERROR_DS_CONFIDENTIALITY_REQUIRED = 8237; + //public const uint ERROR_DS_INAPPROPRIATE_MATCHING = 8238; + //public const uint ERROR_DS_CONSTRAINT_VIOLATION = 8239; + //public const uint ERROR_DS_NO_SUCH_OBJECT = 8240; + //public const uint ERROR_DS_ALIAS_PROBLEM = 8241; + //public const uint ERROR_DS_INVALID_DN_SYNTAX = 8242; + //public const uint ERROR_DS_IS_LEAF = 8243; + //public const uint ERROR_DS_ALIAS_DEREF_PROBLEM = 8244; + //public const uint ERROR_DS_UNWILLING_TO_PERFORM = 8245; + //public const uint ERROR_DS_LOOP_DETECT = 8246; + //public const uint ERROR_DS_NAMING_VIOLATION = 8247; + //public const uint ERROR_DS_OBJECT_RESULTS_TOO_LARGE = 8248; + //public const uint ERROR_DS_AFFECTS_MULTIPLE_DSAS = 8249; + //public const uint ERROR_DS_SERVER_DOWN = 8250; + //public const uint ERROR_DS_LOCAL_ERROR = 8251; + //public const uint ERROR_DS_ENCODING_ERROR = 8252; + //public const uint ERROR_DS_DECODING_ERROR = 8253; + //public const uint ERROR_DS_FILTER_UNKNOWN = 8254; + //public const uint ERROR_DS_PARAM_ERROR = 8255; + //public const uint ERROR_DS_NOT_SUPPORTED = 8256; + //public const uint ERROR_DS_NO_RESULTS_RETURNED = 8257; + //public const uint ERROR_DS_CONTROL_NOT_FOUND = 8258; + //public const uint ERROR_DS_CLIENT_LOOP = 8259; + //public const uint ERROR_DS_REFERRAL_LIMIT_EXCEEDED = 8260; + //public const uint ERROR_DS_SORT_CONTROL_MISSING = 8261; + //public const uint ERROR_DS_OFFSET_RANGE_ERROR = 8262; + //public const uint ERROR_DS_ROOT_MUST_BE_NC = 8301; + //public const uint ERROR_DS_ADD_REPLICA_INHIBITED = 8302; + //public const uint ERROR_DS_ATT_NOT_DEF_IN_SCHEMA = 8303; + //public const uint ERROR_DS_MAX_OBJ_SIZE_EXCEEDED = 8304; + //public const uint ERROR_DS_OBJ_STRING_NAME_EXISTS = 8305; + //public const uint ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA = 8306; + //public const uint ERROR_DS_RDN_DOESNT_MATCH_SCHEMA = 8307; + //public const uint ERROR_DS_NO_REQUESTED_ATTS_FOUND = 8308; + //public const uint ERROR_DS_USER_BUFFER_TO_SMALL = 8309; + //public const uint ERROR_DS_ATT_IS_NOT_ON_OBJ = 8310; + //public const uint ERROR_DS_ILLEGAL_MOD_OPERATION = 8311; + //public const uint ERROR_DS_OBJ_TOO_LARGE = 8312; + //public const uint ERROR_DS_BAD_INSTANCE_TYPE = 8313; + //public const uint ERROR_DS_MASTERDSA_REQUIRED = 8314; + //public const uint ERROR_DS_OBJECT_CLASS_REQUIRED = 8315; + //public const uint ERROR_DS_MISSING_REQUIRED_ATT = 8316; + //public const uint ERROR_DS_ATT_NOT_DEF_FOR_CLASS = 8317; + //public const uint ERROR_DS_ATT_ALREADY_EXISTS = 8318; + //public const uint ERROR_DS_CANT_ADD_ATT_VALUES = 8320; + //public const uint ERROR_DS_SINGLE_VALUE_CONSTRAINT = 8321; + //public const uint ERROR_DS_RANGE_CONSTRAINT = 8322; + //public const uint ERROR_DS_ATT_VAL_ALREADY_EXISTS = 8323; + //public const uint ERROR_DS_CANT_REM_MISSING_ATT = 8324; + //public const uint ERROR_DS_CANT_REM_MISSING_ATT_VAL = 8325; + //public const uint ERROR_DS_ROOT_CANT_BE_SUBREF = 8326; + //public const uint ERROR_DS_NO_CHAINING = 8327; + //public const uint ERROR_DS_NO_CHAINED_EVAL = 8328; + //public const uint ERROR_DS_NO_PARENT_OBJECT = 8329; + //public const uint ERROR_DS_PARENT_IS_AN_ALIAS = 8330; + //public const uint ERROR_DS_CANT_MIX_MASTER_AND_REPS = 8331; + //public const uint ERROR_DS_CHILDREN_EXIST = 8332; + //public const uint ERROR_DS_OBJ_NOT_FOUND = 8333; + //public const uint ERROR_DS_ALIASED_OBJ_MISSING = 8334; + //public const uint ERROR_DS_BAD_NAME_SYNTAX = 8335; + //public const uint ERROR_DS_ALIAS_POINTS_TO_ALIAS = 8336; + //public const uint ERROR_DS_CANT_DEREF_ALIAS = 8337; + //public const uint ERROR_DS_OUT_OF_SCOPE = 8338; + //public const uint ERROR_DS_OBJECT_BEING_REMOVED = 8339; + //public const uint ERROR_DS_CANT_DELETE_DSA_OBJ = 8340; + //public const uint ERROR_DS_GENERIC_ERROR = 8341; + //public const uint ERROR_DS_DSA_MUST_BE_INT_MASTER = 8342; + //public const uint ERROR_DS_CLASS_NOT_DSA = 8343; + //public const uint ERROR_DS_INSUFF_ACCESS_RIGHTS = 8344; + //public const uint ERROR_DS_ILLEGAL_SUPERIOR = 8345; + //public const uint ERROR_DS_ATTRIBUTE_OWNED_BY_SAM = 8346; + //public const uint ERROR_DS_NAME_TOO_MANY_PARTS = 8347; + //public const uint ERROR_DS_NAME_TOO_LONG = 8348; + //public const uint ERROR_DS_NAME_VALUE_TOO_LONG = 8349; + //public const uint ERROR_DS_NAME_UNPARSEABLE = 8350; + //public const uint ERROR_DS_NAME_TYPE_UNKNOWN = 8351; + //public const uint ERROR_DS_NOT_AN_OBJECT = 8352; + //public const uint ERROR_DS_SEC_DESC_TOO_SHORT = 8353; + //public const uint ERROR_DS_SEC_DESC_INVALID = 8354; + //public const uint ERROR_DS_NO_DELETED_NAME = 8355; + //public const uint ERROR_DS_SUBREF_MUST_HAVE_PARENT = 8356; + //public const uint ERROR_DS_NCNAME_MUST_BE_NC = 8357; + //public const uint ERROR_DS_CANT_ADD_SYSTEM_ONLY = 8358; + //public const uint ERROR_DS_CLASS_MUST_BE_CONCRETE = 8359; + //public const uint ERROR_DS_INVALID_DMD = 8360; + //public const uint ERROR_DS_OBJ_GUID_EXISTS = 8361; + //public const uint ERROR_DS_NOT_ON_BACKLINK = 8362; + //public const uint ERROR_DS_NO_CROSSREF_FOR_NC = 8363; + //public const uint ERROR_DS_SHUTTING_DOWN = 8364; + //public const uint ERROR_DS_UNKNOWN_OPERATION = 8365; + //public const uint ERROR_DS_INVALID_ROLE_OWNER = 8366; + //public const uint ERROR_DS_COULDNT_CONTACT_FSMO = 8367; + //public const uint ERROR_DS_CROSS_NC_DN_RENAME = 8368; + //public const uint ERROR_DS_CANT_MOD_SYSTEM_ONLY = 8369; + //public const uint ERROR_DS_REPLICATOR_ONLY = 8370; + //public const uint ERROR_DS_OBJ_CLASS_NOT_DEFINED = 8371; + //public const uint ERROR_DS_OBJ_CLASS_NOT_SUBCLASS = 8372; + //public const uint ERROR_DS_NAME_REFERENCE_INVALID = 8373; + //public const uint ERROR_DS_CROSS_REF_EXISTS = 8374; + //public const uint ERROR_DS_CANT_DEL_MASTER_CROSSREF = 8375; + //public const uint ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD = 8376; + //public const uint ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX = 8377; + //public const uint ERROR_DS_DUP_RDN = 8378; + //public const uint ERROR_DS_DUP_OID = 8379; + //public const uint ERROR_DS_DUP_MAPI_ID = 8380; + //public const uint ERROR_DS_DUP_SCHEMA_ID_GUID = 8381; + //public const uint ERROR_DS_DUP_LDAP_DISPLAY_NAME = 8382; + //public const uint ERROR_DS_SEMANTIC_ATT_TEST = 8383; + //public const uint ERROR_DS_SYNTAX_MISMATCH = 8384; + //public const uint ERROR_DS_EXISTS_IN_MUST_HAVE = 8385; + //public const uint ERROR_DS_EXISTS_IN_MAY_HAVE = 8386; + //public const uint ERROR_DS_NONEXISTENT_MAY_HAVE = 8387; + //public const uint ERROR_DS_NONEXISTENT_MUST_HAVE = 8388; + //public const uint ERROR_DS_AUX_CLS_TEST_FAIL = 8389; + //public const uint ERROR_DS_NONEXISTENT_POSS_SUP = 8390; + //public const uint ERROR_DS_SUB_CLS_TEST_FAIL = 8391; + //public const uint ERROR_DS_BAD_RDN_ATT_ID_SYNTAX = 8392; + //public const uint ERROR_DS_EXISTS_IN_AUX_CLS = 8393; + //public const uint ERROR_DS_EXISTS_IN_SUB_CLS = 8394; + //public const uint ERROR_DS_EXISTS_IN_POSS_SUP = 8395; + //public const uint ERROR_DS_RECALCSCHEMA_FAILED = 8396; + //public const uint ERROR_DS_TREE_DELETE_NOT_FINISHED = 8397; + //public const uint ERROR_DS_CANT_DELETE = 8398; + //public const uint ERROR_DS_ATT_SCHEMA_REQ_ID = 8399; + //public const uint ERROR_DS_BAD_ATT_SCHEMA_SYNTAX = 8400; + //public const uint ERROR_DS_CANT_CACHE_ATT = 8401; + //public const uint ERROR_DS_CANT_CACHE_CLASS = 8402; + //public const uint ERROR_DS_CANT_REMOVE_ATT_CACHE = 8403; + //public const uint ERROR_DS_CANT_REMOVE_CLASS_CACHE = 8404; + //public const uint ERROR_DS_CANT_RETRIEVE_DN = 8405; + //public const uint ERROR_DS_MISSING_SUPREF = 8406; + //public const uint ERROR_DS_CANT_RETRIEVE_INSTANCE = 8407; + //public const uint ERROR_DS_CODE_INCONSISTENCY = 8408; + //public const uint ERROR_DS_DATABASE_ERROR = 8409; + //public const uint ERROR_DS_GOVERNSID_MISSING = 8410; + //public const uint ERROR_DS_MISSING_EXPECTED_ATT = 8411; + //public const uint ERROR_DS_NCNAME_MISSING_CR_REF = 8412; + //public const uint ERROR_DS_SECURITY_CHECKING_ERROR = 8413; + //public const uint ERROR_DS_SCHEMA_NOT_LOADED = 8414; + //public const uint ERROR_DS_SCHEMA_ALLOC_FAILED = 8415; + //public const uint ERROR_DS_ATT_SCHEMA_REQ_SYNTAX = 8416; + //public const uint ERROR_DS_GCVERIFY_ERROR = 8417; + //public const uint ERROR_DS_DRA_SCHEMA_MISMATCH = 8418; + //public const uint ERROR_DS_CANT_FIND_DSA_OBJ = 8419; + //public const uint ERROR_DS_CANT_FIND_EXPECTED_NC = 8420; + //public const uint ERROR_DS_CANT_FIND_NC_IN_CACHE = 8421; + //public const uint ERROR_DS_CANT_RETRIEVE_CHILD = 8422; + //public const uint ERROR_DS_SECURITY_ILLEGAL_MODIFY = 8423; + //public const uint ERROR_DS_CANT_REPLACE_HIDDEN_REC = 8424; + //public const uint ERROR_DS_BAD_HIERARCHY_FILE = 8425; + //public const uint ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED = 8426; + //public const uint ERROR_DS_CONFIG_PARAM_MISSING = 8427; + //public const uint ERROR_DS_COUNTING_AB_INDICES_FAILED = 8428; + //public const uint ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED = 8429; + //public const uint ERROR_DS_INTERNAL_FAILURE = 8430; + //public const uint ERROR_DS_UNKNOWN_ERROR = 8431; + //public const uint ERROR_DS_ROOT_REQUIRES_CLASS_TOP = 8432; + //public const uint ERROR_DS_REFUSING_FSMO_ROLES = 8433; + //public const uint ERROR_DS_MISSING_FSMO_SETTINGS = 8434; + //public const uint ERROR_DS_UNABLE_TO_SURRENDER_ROLES = 8435; + //public const uint ERROR_DS_DRA_GENERIC = 8436; + //public const uint ERROR_DS_DRA_INVALID_PARAMETER = 8437; + //public const uint ERROR_DS_DRA_BUSY = 8438; + //public const uint ERROR_DS_DRA_BAD_DN = 8439; + //public const uint ERROR_DS_DRA_BAD_NC = 8440; + //public const uint ERROR_DS_DRA_DN_EXISTS = 8441; + //public const uint ERROR_DS_DRA_INTERNAL_ERROR = 8442; + //public const uint ERROR_DS_DRA_INCONSISTENT_DIT = 8443; + //public const uint ERROR_DS_DRA_CONNECTION_FAILED = 8444; + //public const uint ERROR_DS_DRA_BAD_INSTANCE_TYPE = 8445; + //public const uint ERROR_DS_DRA_OUT_OF_MEM = 8446; + //public const uint ERROR_DS_DRA_MAIL_PROBLEM = 8447; + //public const uint ERROR_DS_DRA_REF_ALREADY_EXISTS = 8448; + //public const uint ERROR_DS_DRA_REF_NOT_FOUND = 8449; + //public const uint ERROR_DS_DRA_OBJ_IS_REP_SOURCE = 8450; + //public const uint ERROR_DS_DRA_DB_ERROR = 8451; + //public const uint ERROR_DS_DRA_NO_REPLICA = 8452; + //public const uint ERROR_DS_DRA_ACCESS_DENIED = 8453; + //public const uint ERROR_DS_DRA_NOT_SUPPORTED = 8454; + //public const uint ERROR_DS_DRA_RPC_CANCELLED = 8455; + //public const uint ERROR_DS_DRA_SOURCE_DISABLED = 8456; + //public const uint ERROR_DS_DRA_SINK_DISABLED = 8457; + //public const uint ERROR_DS_DRA_NAME_COLLISION = 8458; + //public const uint ERROR_DS_DRA_SOURCE_REINSTALLED = 8459; + //public const uint ERROR_DS_DRA_MISSING_PARENT = 8460; + //public const uint ERROR_DS_DRA_PREEMPTED = 8461; + //public const uint ERROR_DS_DRA_ABANDON_SYNC = 8462; + //public const uint ERROR_DS_DRA_SHUTDOWN = 8463; + //public const uint ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET = 8464; + //public const uint ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA = 8465; + //public const uint ERROR_DS_DRA_EXTN_CONNECTION_FAILED = 8466; + //public const uint ERROR_DS_INSTALL_SCHEMA_MISMATCH = 8467; + //public const uint ERROR_DS_DUP_LINK_ID = 8468; + //public const uint ERROR_DS_NAME_ERROR_RESOLVING = 8469; + //public const uint ERROR_DS_NAME_ERROR_NOT_FOUND = 8470; + //public const uint ERROR_DS_NAME_ERROR_NOT_UNIQUE = 8471; + //public const uint ERROR_DS_NAME_ERROR_NO_MAPPING = 8472; + //public const uint ERROR_DS_NAME_ERROR_DOMAIN_ONLY = 8473; + //public const uint ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING = 8474; + //public const uint ERROR_DS_CONSTRUCTED_ATT_MOD = 8475; + //public const uint ERROR_DS_WRONG_OM_OBJ_CLASS = 8476; + //public const uint ERROR_DS_DRA_REPL_PENDING = 8477; + //public const uint ERROR_DS_DS_REQUIRED = 8478; + //public const uint ERROR_DS_INVALID_LDAP_DISPLAY_NAME = 8479; + //public const uint ERROR_DS_NON_BASE_SEARCH = 8480; + //public const uint ERROR_DS_CANT_RETRIEVE_ATTS = 8481; + //public const uint ERROR_DS_BACKLINK_WITHOUT_LINK = 8482; + //public const uint ERROR_DS_EPOCH_MISMATCH = 8483; + //public const uint ERROR_DS_SRC_NAME_MISMATCH = 8484; + //public const uint ERROR_DS_SRC_AND_DST_NC_IDENTICAL = 8485; + //public const uint ERROR_DS_DST_NC_MISMATCH = 8486; + //public const uint ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC = 8487; + //public const uint ERROR_DS_SRC_GUID_MISMATCH = 8488; + //public const uint ERROR_DS_CANT_MOVE_DELETED_OBJECT = 8489; + //public const uint ERROR_DS_PDC_OPERATION_IN_PROGRESS = 8490; + //public const uint ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD = 8491; + //public const uint ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION = 8492; + //public const uint ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS = 8493; + //public const uint ERROR_DS_NC_MUST_HAVE_NC_PARENT = 8494; + //public const uint ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE = 8495; + //public const uint ERROR_DS_DST_DOMAIN_NOT_NATIVE = 8496; + //public const uint ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER = 8497; + //public const uint ERROR_DS_CANT_MOVE_ACCOUNT_GROUP = 8498; + //public const uint ERROR_DS_CANT_MOVE_RESOURCE_GROUP = 8499; + //public const uint ERROR_DS_INVALID_SEARCH_FLAG = 8500; + //public const uint ERROR_DS_NO_TREE_DELETE_ABOVE_NC = 8501; + //public const uint ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE = 8502; + //public const uint ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE = 8503; + //public const uint ERROR_DS_SAM_INIT_FAILURE = 8504; + //public const uint ERROR_DS_SENSITIVE_GROUP_VIOLATION = 8505; + //public const uint ERROR_DS_CANT_MOD_PRIMARYGROUPID = 8506; + //public const uint ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD = 8507; + //public const uint ERROR_DS_NONSAFE_SCHEMA_CHANGE = 8508; + //public const uint ERROR_DS_SCHEMA_UPDATE_DISALLOWED = 8509; + //public const uint ERROR_DS_CANT_CREATE_UNDER_SCHEMA = 8510; + //public const uint ERROR_DS_INSTALL_NO_SRC_SCH_VERSION = 8511; + //public const uint ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE = 8512; + //public const uint ERROR_DS_INVALID_GROUP_TYPE = 8513; + //public const uint ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN = 8514; + //public const uint ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN = 8515; + //public const uint ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER = 8516; + //public const uint ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER = 8517; + //public const uint ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER = 8518; + //public const uint ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER = 8519; + //public const uint ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER = 8520; + //public const uint ERROR_DS_HAVE_PRIMARY_MEMBERS = 8521; + //public const uint ERROR_DS_STRING_SD_CONVERSION_FAILED = 8522; + //public const uint ERROR_DS_NAMING_MASTER_GC = 8523; + //public const uint ERROR_DS_DNS_LOOKUP_FAILURE = 8524; + //public const uint ERROR_DS_COULDNT_UPDATE_SPNS = 8525; + //public const uint ERROR_DS_CANT_RETRIEVE_SD = 8526; + //public const uint ERROR_DS_KEY_NOT_UNIQUE = 8527; + //public const uint ERROR_DS_WRONG_LINKED_ATT_SYNTAX = 8528; + //public const uint ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD = 8529; + //public const uint ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY = 8530; + //public const uint ERROR_DS_CANT_START = 8531; + //public const uint ERROR_DS_INIT_FAILURE = 8532; + //public const uint ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION = 8533; + //public const uint ERROR_DS_SOURCE_DOMAIN_IN_FOREST = 8534; + //public const uint ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST = 8535; + //public const uint ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED = 8536; + //public const uint ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN = 8537; + //public const uint ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER = 8538; + //public const uint ERROR_DS_SRC_SID_EXISTS_IN_FOREST = 8539; + //public const uint ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH = 8540; + //public const uint ERROR_SAM_INIT_FAILURE = 8541; + //public const uint ERROR_DS_DRA_SCHEMA_INFO_SHIP = 8542; + //public const uint ERROR_DS_DRA_SCHEMA_CONFLICT = 8543; + //public const uint ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT = 8544; + //public const uint ERROR_DS_DRA_OBJ_NC_MISMATCH = 8545; + //public const uint ERROR_DS_NC_STILL_HAS_DSAS = 8546; + //public const uint ERROR_DS_GC_REQUIRED = 8547; + //public const uint ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY = 8548; + //public const uint ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS = 8549; + //public const uint ERROR_DS_CANT_ADD_TO_GC = 8550; + //public const uint ERROR_DS_NO_CHECKPOINT_WITH_PDC = 8551; + //public const uint ERROR_DS_SOURCE_AUDITING_NOT_ENABLED = 8552; + //public const uint ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC = 8553; + //public const uint ERROR_DS_INVALID_NAME_FOR_SPN = 8554; + //public const uint ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS = 8555; + //public const uint ERROR_DS_UNICODEPWD_NOT_IN_QUOTES = 8556; + //public const uint ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED = 8557; + //public const uint ERROR_DS_MUST_BE_RUN_ON_DST_DC = 8558; + //public const uint ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER = 8559; + //public const uint ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ = 8560; + //public const uint ERROR_DS_INIT_FAILURE_CONSOLE = 8561; + //public const uint ERROR_DS_SAM_INIT_FAILURE_CONSOLE = 8562; + //public const uint ERROR_DS_FOREST_VERSION_TOO_HIGH = 8563; + //public const uint ERROR_DS_DOMAIN_VERSION_TOO_HIGH = 8564; + //public const uint ERROR_DS_FOREST_VERSION_TOO_LOW = 8565; + //public const uint ERROR_DS_DOMAIN_VERSION_TOO_LOW = 8566; + //public const uint ERROR_DS_INCOMPATIBLE_VERSION = 8567; + //public const uint ERROR_DS_LOW_DSA_VERSION = 8568; + //public const uint ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN = 8569; + //public const uint ERROR_DS_NOT_SUPPORTED_SORT_ORDER = 8570; + //public const uint ERROR_DS_NAME_NOT_UNIQUE = 8571; + //public const uint ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4 = 8572; + //public const uint ERROR_DS_OUT_OF_VERSION_STORE = 8573; + //public const uint ERROR_DS_INCOMPATIBLE_CONTROLS_USED = 8574; + //public const uint ERROR_DS_NO_REF_DOMAIN = 8575; + //public const uint ERROR_DS_RESERVED_LINK_ID = 8576; + //public const uint ERROR_DS_LINK_ID_NOT_AVAILABLE = 8577; + //public const uint ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER = 8578; + //public const uint ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE = 8579; + //public const uint ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC = 8580; + //public const uint ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG = 8581; + //public const uint ERROR_DS_MODIFYDN_WRONG_GRANDPARENT = 8582; + //public const uint ERROR_DS_NAME_ERROR_TRUST_REFERRAL = 8583; + //public const uint ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER = 8584; + //public const uint ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD = 8585; + //public const uint ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2 = 8586; + //public const uint ERROR_DS_THREAD_LIMIT_EXCEEDED = 8587; + //public const uint ERROR_DS_NOT_CLOSEST = 8588; + //public const uint ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF = 8589; + //public const uint ERROR_DS_SINGLE_USER_MODE_FAILED = 8590; + //public const uint ERROR_DS_NTDSCRIPT_SYNTAX_ERROR = 8591; + //public const uint ERROR_DS_NTDSCRIPT_PROCESS_ERROR = 8592; + //public const uint ERROR_DS_DIFFERENT_REPL_EPOCHS = 8593; + //public const uint ERROR_DS_DRS_EXTENSIONS_CHANGED = 8594; + //public const uint ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR = 8595; + //public const uint ERROR_DS_NO_MSDS_INTID = 8596; + //public const uint ERROR_DS_DUP_MSDS_INTID = 8597; + //public const uint ERROR_DS_EXISTS_IN_RDNATTID = 8598; + //public const uint ERROR_DS_AUTHORIZATION_FAILED = 8599; + //public const uint ERROR_DS_INVALID_SCRIPT = 8600; + //public const uint ERROR_DS_REMOTE_CROSSREF_OP_FAILED = 8601; + //public const uint ERROR_DS_CROSS_REF_BUSY = 8602; + //public const uint ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN = 8603; + //public const uint ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC = 8604; + //public const uint ERROR_DS_DUPLICATE_ID_FOUND = 8605; + //public const uint ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT = 8606; + //public const uint ERROR_DS_GROUP_CONVERSION_ERROR = 8607; + //public const uint ERROR_DS_CANT_MOVE_APP_BASIC_GROUP = 8608; + //public const uint ERROR_DS_CANT_MOVE_APP_QUERY_GROUP = 8609; + //public const uint ERROR_DS_ROLE_NOT_VERIFIED = 8610; + //public const uint ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL = 8611; + //public const uint ERROR_DS_DOMAIN_RENAME_IN_PROGRESS = 8612; + //public const uint ERROR_DS_EXISTING_AD_CHILD_NC = 8613; + //public const uint ERROR_DS_REPL_LIFETIME_EXCEEDED = 8614; + //public const uint ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER = 8615; + //public const uint ERROR_DS_LDAP_SEND_QUEUE_FULL = 8616; + //public const uint ERROR_DS_DRA_OUT_SCHEDULE_WINDOW = 8617; + //public const uint DNS_ERROR_RESPONSE_CODES_BASE = 9000; + //public const uint DNS_ERROR_RCODE_NO_ERROR = NO_ERROR; + //public const uint DNS_ERROR_MASK = 0x00002328; + //public const uint DNS_ERROR_RCODE_FORMAT_ERROR = 9001; + //public const uint DNS_ERROR_RCODE_SERVER_FAILURE = 9002; + //public const uint DNS_ERROR_RCODE_NAME_ERROR = 9003; + //public const uint DNS_ERROR_RCODE_NOT_IMPLEMENTED = 9004; + //public const uint DNS_ERROR_RCODE_REFUSED = 9005; + //public const uint DNS_ERROR_RCODE_YXDOMAIN = 9006; + //public const uint DNS_ERROR_RCODE_YXRRSET = 9007; + //public const uint DNS_ERROR_RCODE_NXRRSET = 9008; + //public const uint DNS_ERROR_RCODE_NOTAUTH = 9009; + //public const uint DNS_ERROR_RCODE_NOTZONE = 9010; + //public const uint DNS_ERROR_RCODE_BADSIG = 9016; + //public const uint DNS_ERROR_RCODE_BADKEY = 9017; + //public const uint DNS_ERROR_RCODE_BADTIME = 9018; + //public const uint DNS_ERROR_RCODE_LAST = DNS_ERROR_RCODE_BADTIME; + //public const uint DNS_ERROR_PACKET_FMT_BASE = 9500; + //public const uint DNS_INFO_NO_RECORDS = 9501; + //public const uint DNS_ERROR_BAD_PACKET = 9502; + //public const uint DNS_ERROR_NO_PACKET = 9503; + //public const uint DNS_ERROR_RCODE = 9504; + //public const uint DNS_ERROR_UNSECURE_PACKET = 9505; + //public const uint DNS_STATUS_PACKET_UNSECURE = DNS_ERROR_UNSECURE_PACKET; + //public const uint DNS_ERROR_NO_MEMORY = ERROR_OUTOFMEMORY; + //public const uint DNS_ERROR_INVALID_NAME = ERROR_INVALID_NAME; + //public const uint DNS_ERROR_INVALID_DATA = ERROR_INVALID_DATA; + //public const uint DNS_ERROR_GENERAL_API_BASE = 9550; + //public const uint DNS_ERROR_INVALID_TYPE = 9551; + //public const uint DNS_ERROR_INVALID_IP_ADDRESS = 9552; + //public const uint DNS_ERROR_INVALID_PROPERTY = 9553; + //public const uint DNS_ERROR_TRY_AGAIN_LATER = 9554; + //public const uint DNS_ERROR_NOT_UNIQUE = 9555; + //public const uint DNS_ERROR_NON_RFC_NAME = 9556; + //public const uint DNS_STATUS_FQDN = 9557; + //public const uint DNS_STATUS_DOTTED_NAME = 9558; + //public const uint DNS_STATUS_SINGLE_PART_NAME = 9559; + //public const uint DNS_ERROR_INVALID_NAME_CHAR = 9560; + //public const uint DNS_ERROR_NUMERIC_NAME = 9561; + //public const uint DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER = 9562; + //public const uint DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION = 9563; + //public const uint DNS_ERROR_CANNOT_FIND_ROOT_HINTS = 9564; + //public const uint DNS_ERROR_INCONSISTENT_ROOT_HINTS = 9565; + //public const uint DNS_ERROR_ZONE_BASE = 9600; + //public const uint DNS_ERROR_ZONE_DOES_NOT_EXIST = 9601; + //public const uint DNS_ERROR_NO_ZONE_INFO = 9602; + //public const uint DNS_ERROR_INVALID_ZONE_OPERATION = 9603; + //public const uint DNS_ERROR_ZONE_CONFIGURATION_ERROR = 9604; + //public const uint DNS_ERROR_ZONE_HAS_NO_SOA_RECORD = 9605; + //public const uint DNS_ERROR_ZONE_HAS_NO_NS_RECORDS = 9606; + //public const uint DNS_ERROR_ZONE_LOCKED = 9607; + //public const uint DNS_ERROR_ZONE_CREATION_FAILED = 9608; + //public const uint DNS_ERROR_ZONE_ALREADY_EXISTS = 9609; + //public const uint DNS_ERROR_AUTOZONE_ALREADY_EXISTS = 9610; + //public const uint DNS_ERROR_INVALID_ZONE_TYPE = 9611; + //public const uint DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP = 9612; + //public const uint DNS_ERROR_ZONE_NOT_SECONDARY = 9613; + //public const uint DNS_ERROR_NEED_SECONDARY_ADDRESSES = 9614; + //public const uint DNS_ERROR_WINS_INIT_FAILED = 9615; + //public const uint DNS_ERROR_NEED_WINS_SERVERS = 9616; + //public const uint DNS_ERROR_NBSTAT_INIT_FAILED = 9617; + //public const uint DNS_ERROR_SOA_DELETE_INVALID = 9618; + //public const uint DNS_ERROR_FORWARDER_ALREADY_EXISTS = 9619; + //public const uint DNS_ERROR_ZONE_REQUIRES_MASTER_IP = 9620; + //public const uint DNS_ERROR_ZONE_IS_SHUTDOWN = 9621; + //public const uint DNS_ERROR_DATAFILE_BASE = 9650; + //public const uint DNS_ERROR_PRIMARY_REQUIRES_DATAFILE = 9651; + //public const uint DNS_ERROR_INVALID_DATAFILE_NAME = 9652; + //public const uint DNS_ERROR_DATAFILE_OPEN_FAILURE = 9653; + //public const uint DNS_ERROR_FILE_WRITEBACK_FAILED = 9654; + //public const uint DNS_ERROR_DATAFILE_PARSING = 9655; + //public const uint DNS_ERROR_DATABASE_BASE = 9700; + //public const uint DNS_ERROR_RECORD_DOES_NOT_EXIST = 9701; + //public const uint DNS_ERROR_RECORD_FORMAT = 9702; + //public const uint DNS_ERROR_NODE_CREATION_FAILED = 9703; + //public const uint DNS_ERROR_UNKNOWN_RECORD_TYPE = 9704; + //public const uint DNS_ERROR_RECORD_TIMED_OUT = 9705; + //public const uint DNS_ERROR_NAME_NOT_IN_ZONE = 9706; + //public const uint DNS_ERROR_CNAME_LOOP = 9707; + //public const uint DNS_ERROR_NODE_IS_CNAME = 9708; + //public const uint DNS_ERROR_CNAME_COLLISION = 9709; + //public const uint DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT = 9710; + //public const uint DNS_ERROR_RECORD_ALREADY_EXISTS = 9711; + //public const uint DNS_ERROR_SECONDARY_DATA = 9712; + //public const uint DNS_ERROR_NO_CREATE_CACHE_DATA = 9713; + //public const uint DNS_ERROR_NAME_DOES_NOT_EXIST = 9714; + //public const uint DNS_WARNING_PTR_CREATE_FAILED = 9715; + //public const uint DNS_WARNING_DOMAIN_UNDELETED = 9716; + //public const uint DNS_ERROR_DS_UNAVAILABLE = 9717; + //public const uint DNS_ERROR_DS_ZONE_ALREADY_EXISTS = 9718; + //public const uint DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE = 9719; + //public const uint DNS_ERROR_OPERATION_BASE = 9750; + //public const uint DNS_INFO_AXFR_COMPLETE = 9751; + //public const uint DNS_ERROR_AXFR = 9752; + //public const uint DNS_INFO_ADDED_LOCAL_WINS = 9753; + //public const uint DNS_ERROR_SECURE_BASE = 9800; + //public const uint DNS_STATUS_CONTINUE_NEEDED = 9801; + //public const uint DNS_ERROR_SETUP_BASE = 9850; + //public const uint DNS_ERROR_NO_TCPIP = 9851; + //public const uint DNS_ERROR_NO_DNS_SERVERS = 9852; + //public const uint DNS_ERROR_DP_BASE = 9900; + //public const uint DNS_ERROR_DP_DOES_NOT_EXIST = 9901; + //public const uint DNS_ERROR_DP_ALREADY_EXISTS = 9902; + //public const uint DNS_ERROR_DP_NOT_ENLISTED = 9903; + //public const uint DNS_ERROR_DP_ALREADY_ENLISTED = 9904; + //public const uint DNS_ERROR_DP_NOT_AVAILABLE = 9905; + //public const uint DNS_ERROR_DP_FSMO_ERROR = 9906; + //public const uint WSABASEERR = 10000; + //public const uint WSAEINTR = 10004; + //public const uint WSAEBADF = 10009; + //public const uint WSAEACCES = 10013; + //public const uint WSAEFAULT = 10014; + //public const uint WSAEINVAL = 10022; + //public const uint WSAEMFILE = 10024; + //public const uint WSAEWOULDBLOCK = 10035; + //public const uint WSAEINPROGRESS = 10036; + //public const uint WSAEALREADY = 10037; + //public const uint WSAENOTSOCK = 10038; + //public const uint WSAEDESTADDRREQ = 10039; + //public const uint WSAEMSGSIZE = 10040; + //public const uint WSAEPROTOTYPE = 10041; + //public const uint WSAENOPROTOOPT = 10042; + //public const uint WSAEPROTONOSUPPORT = 10043; + //public const uint WSAESOCKTNOSUPPORT = 10044; + //public const uint WSAEOPNOTSUPP = 10045; + //public const uint WSAEPFNOSUPPORT = 10046; + //public const uint WSAEAFNOSUPPORT = 10047; + //public const uint WSAEADDRINUSE = 10048; + //public const uint WSAEADDRNOTAVAIL = 10049; + //public const uint WSAENETDOWN = 10050; + //public const uint WSAENETUNREACH = 10051; + //public const uint WSAENETRESET = 10052; + //public const uint WSAECONNABORTED = 10053; + //public const uint WSAECONNRESET = 10054; + //public const uint WSAENOBUFS = 10055; + //public const uint WSAEISCONN = 10056; + //public const uint WSAENOTCONN = 10057; + //public const uint WSAESHUTDOWN = 10058; + //public const uint WSAETOOMANYREFS = 10059; + //public const uint WSAETIMEDOUT = 10060; + //public const uint WSAECONNREFUSED = 10061; + //public const uint WSAELOOP = 10062; + //public const uint WSAENAMETOOLONG = 10063; + //public const uint WSAEHOSTDOWN = 10064; + //public const uint WSAEHOSTUNREACH = 10065; + //public const uint WSAENOTEMPTY = 10066; + //public const uint WSAEPROCLIM = 10067; + //public const uint WSAEUSERS = 10068; + //public const uint WSAEDQUOT = 10069; + //public const uint WSAESTALE = 10070; + //public const uint WSAEREMOTE = 10071; + //public const uint WSASYSNOTREADY = 10091; + //public const uint WSAVERNOTSUPPORTED = 10092; + //public const uint WSANOTINITIALISED = 10093; + //public const uint WSAEDISCON = 10101; + //public const uint WSAENOMORE = 10102; + //public const uint WSAECANCELLED = 10103; + //public const uint WSAEINVALIDPROCTABLE = 10104; + //public const uint WSAEINVALIDPROVIDER = 10105; + //public const uint WSAEPROVIDERFAILEDINIT = 10106; + //public const uint WSASYSCALLFAILURE = 10107; + //public const uint WSASERVICE_NOT_FOUND = 10108; + //public const uint WSATYPE_NOT_FOUND = 10109; + //public const uint WSA_E_NO_MORE = 10110; + //public const uint WSA_E_CANCELLED = 10111; + //public const uint WSAEREFUSED = 10112; + //public const uint WSAHOST_NOT_FOUND = 11001; + //public const uint WSATRY_AGAIN = 11002; + //public const uint WSANO_RECOVERY = 11003; + //public const uint WSANO_DATA = 11004; + //public const uint WSA_QOS_RECEIVERS = 11005; + //public const uint WSA_QOS_SENDERS = 11006; + //public const uint WSA_QOS_NO_SENDERS = 11007; + //public const uint WSA_QOS_NO_RECEIVERS = 11008; + //public const uint WSA_QOS_REQUEST_CONFIRMED = 11009; + //public const uint WSA_QOS_ADMISSION_FAILURE = 11010; + //public const uint WSA_QOS_POLICY_FAILURE = 11011; + //public const uint WSA_QOS_BAD_STYLE = 11012; + //public const uint WSA_QOS_BAD_OBJECT = 11013; + //public const uint WSA_QOS_TRAFFIC_CTRL_ERROR = 11014; + //public const uint WSA_QOS_GENERIC_ERROR = 11015; + //public const uint WSA_QOS_ESERVICETYPE = 11016; + //public const uint WSA_QOS_EFLOWSPEC = 11017; + //public const uint WSA_QOS_EPROVSPECBUF = 11018; + //public const uint WSA_QOS_EFILTERSTYLE = 11019; + //public const uint WSA_QOS_EFILTERTYPE = 11020; + //public const uint WSA_QOS_EFILTERCOUNT = 11021; + //public const uint WSA_QOS_EOBJLENGTH = 11022; + //public const uint WSA_QOS_EFLOWCOUNT = 11023; + //public const uint WSA_QOS_EUNKOWNPSOBJ = 11024; + //public const uint WSA_QOS_EPOLICYOBJ = 11025; + //public const uint WSA_QOS_EFLOWDESC = 11026; + //public const uint WSA_QOS_EPSFLOWSPEC = 11027; + //public const uint WSA_QOS_EPSFILTERSPEC = 11028; + //public const uint WSA_QOS_ESDMODEOBJ = 11029; + //public const uint WSA_QOS_ESHAPERATEOBJ = 11030; + //public const uint WSA_QOS_RESERVED_PETYPE = 11031; + //public const uint ERROR_SXS_SECTION_NOT_FOUND = 14000; + //public const uint ERROR_SXS_CANT_GEN_ACTCTX = 14001; + //public const uint ERROR_SXS_INVALID_ACTCTXDATA_FORMAT = 14002; + //public const uint ERROR_SXS_ASSEMBLY_NOT_FOUND = 14003; + //public const uint ERROR_SXS_MANIFEST_FORMAT_ERROR = 14004; + //public const uint ERROR_SXS_MANIFEST_PARSE_ERROR = 14005; + //public const uint ERROR_SXS_ACTIVATION_CONTEXT_DISABLED = 14006; + //public const uint ERROR_SXS_KEY_NOT_FOUND = 14007; + //public const uint ERROR_SXS_VERSION_CONFLICT = 14008; + //public const uint ERROR_SXS_WRONG_SECTION_TYPE = 14009; + //public const uint ERROR_SXS_THREAD_QUERIES_DISABLED = 14010; + //public const uint ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET = 14011; + //public const uint ERROR_SXS_UNKNOWN_ENCODING_GROUP = 14012; + //public const uint ERROR_SXS_UNKNOWN_ENCODING = 14013; + //public const uint ERROR_SXS_INVALID_XML_NAMESPACE_URI = 14014; + //public const uint ERROR_SXS_ROOT_MANIFEST_DEPENDENCY_NOT_INSTALLED = 14015; + //public const uint ERROR_SXS_LEAF_MANIFEST_DEPENDENCY_NOT_INSTALLED = 14016; + //public const uint ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE = 14017; + //public const uint ERROR_SXS_MANIFEST_MISSING_REQUIRED_DEFAULT_NAMESPACE = 14018; + //public const uint ERROR_SXS_MANIFEST_INVALID_REQUIRED_DEFAULT_NAMESPACE = 14019; + //public const uint ERROR_SXS_PRIVATE_MANIFEST_CROSS_PATH_WITH_REPARSE_POINT = 14020; + //public const uint ERROR_SXS_DUPLICATE_DLL_NAME = 14021; + //public const uint ERROR_SXS_DUPLICATE_WINDOWCLASS_NAME = 14022; + //public const uint ERROR_SXS_DUPLICATE_CLSID = 14023; + //public const uint ERROR_SXS_DUPLICATE_IID = 14024; + //public const uint ERROR_SXS_DUPLICATE_TLBID = 14025; + //public const uint ERROR_SXS_DUPLICATE_PROGID = 14026; + //public const uint ERROR_SXS_DUPLICATE_ASSEMBLY_NAME = 14027; + //public const uint ERROR_SXS_FILE_HASH_MISMATCH = 14028; + //public const uint ERROR_SXS_POLICY_PARSE_ERROR = 14029; + //public const uint ERROR_SXS_XML_E_MISSINGQUOTE = 14030; + //public const uint ERROR_SXS_XML_E_COMMENTSYNTAX = 14031; + //public const uint ERROR_SXS_XML_E_BADSTARTNAMECHAR = 14032; + //public const uint ERROR_SXS_XML_E_BADNAMECHAR = 14033; + //public const uint ERROR_SXS_XML_E_BADCHARINSTRING = 14034; + //public const uint ERROR_SXS_XML_E_XMLDECLSYNTAX = 14035; + //public const uint ERROR_SXS_XML_E_BADCHARDATA = 14036; + //public const uint ERROR_SXS_XML_E_MISSINGWHITESPACE = 14037; + //public const uint ERROR_SXS_XML_E_EXPECTINGTAGEND = 14038; + //public const uint ERROR_SXS_XML_E_MISSINGSEMICOLON = 14039; + //public const uint ERROR_SXS_XML_E_UNBALANCEDPAREN = 14040; + //public const uint ERROR_SXS_XML_E_INTERNALERROR = 14041; + //public const uint ERROR_SXS_XML_E_UNEXPECTED_WHITESPACE = 14042; + //public const uint ERROR_SXS_XML_E_INCOMPLETE_ENCODING = 14043; + //public const uint ERROR_SXS_XML_E_MISSING_PAREN = 14044; + //public const uint ERROR_SXS_XML_E_EXPECTINGCLOSEQUOTE = 14045; + //public const uint ERROR_SXS_XML_E_MULTIPLE_COLONS = 14046; + //public const uint ERROR_SXS_XML_E_INVALID_DECIMAL = 14047; + //public const uint ERROR_SXS_XML_E_INVALID_HEXIDECIMAL = 14048; + //public const uint ERROR_SXS_XML_E_INVALID_UNICODE = 14049; + //public const uint ERROR_SXS_XML_E_WHITESPACEORQUESTIONMARK = 14050; + //public const uint ERROR_SXS_XML_E_UNEXPECTEDENDTAG = 14051; + //public const uint ERROR_SXS_XML_E_UNCLOSEDTAG = 14052; + //public const uint ERROR_SXS_XML_E_DUPLICATEATTRIBUTE = 14053; + //public const uint ERROR_SXS_XML_E_MULTIPLEROOTS = 14054; + //public const uint ERROR_SXS_XML_E_INVALIDATROOTLEVEL = 14055; + //public const uint ERROR_SXS_XML_E_BADXMLDECL = 14056; + //public const uint ERROR_SXS_XML_E_MISSINGROOT = 14057; + //public const uint ERROR_SXS_XML_E_UNEXPECTEDEOF = 14058; + //public const uint ERROR_SXS_XML_E_BADPEREFINSUBSET = 14059; + //public const uint ERROR_SXS_XML_E_UNCLOSEDSTARTTAG = 14060; + //public const uint ERROR_SXS_XML_E_UNCLOSEDENDTAG = 14061; + //public const uint ERROR_SXS_XML_E_UNCLOSEDSTRING = 14062; + //public const uint ERROR_SXS_XML_E_UNCLOSEDCOMMENT = 14063; + //public const uint ERROR_SXS_XML_E_UNCLOSEDDECL = 14064; + //public const uint ERROR_SXS_XML_E_UNCLOSEDCDATA = 14065; + //public const uint ERROR_SXS_XML_E_RESERVEDNAMESPACE = 14066; + //public const uint ERROR_SXS_XML_E_INVALIDENCODING = 14067; + //public const uint ERROR_SXS_XML_E_INVALIDSWITCH = 14068; + //public const uint ERROR_SXS_XML_E_BADXMLCASE = 14069; + //public const uint ERROR_SXS_XML_E_INVALID_STANDALONE = 14070; + //public const uint ERROR_SXS_XML_E_UNEXPECTED_STANDALONE = 14071; + //public const uint ERROR_SXS_XML_E_INVALID_VERSION = 14072; + //public const uint ERROR_SXS_XML_E_MISSINGEQUALS = 14073; + //public const uint ERROR_SXS_PROTECTION_RECOVERY_FAILED = 14074; + //public const uint ERROR_SXS_PROTECTION_PUBLIC_KEY_TOO_SHORT = 14075; + //public const uint ERROR_SXS_PROTECTION_CATALOG_NOT_VALID = 14076; + //public const uint ERROR_SXS_UNTRANSLATABLE_HRESULT = 14077; + //public const uint ERROR_SXS_PROTECTION_CATALOG_FILE_MISSING = 14078; + //public const uint ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE = 14079; + //public const uint ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME = 14080; + //public const uint ERROR_IPSEC_QM_POLICY_EXISTS = 13000; + //public const uint ERROR_IPSEC_QM_POLICY_NOT_FOUND = 13001; + //public const uint ERROR_IPSEC_QM_POLICY_IN_USE = 13002; + //public const uint ERROR_IPSEC_MM_POLICY_EXISTS = 13003; + //public const uint ERROR_IPSEC_MM_POLICY_NOT_FOUND = 13004; + //public const uint ERROR_IPSEC_MM_POLICY_IN_USE = 13005; + //public const uint ERROR_IPSEC_MM_FILTER_EXISTS = 13006; + //public const uint ERROR_IPSEC_MM_FILTER_NOT_FOUND = 13007; + //public const uint ERROR_IPSEC_TRANSPORT_FILTER_EXISTS = 13008; + //public const uint ERROR_IPSEC_TRANSPORT_FILTER_NOT_FOUND = 13009; + //public const uint ERROR_IPSEC_MM_AUTH_EXISTS = 13010; + //public const uint ERROR_IPSEC_MM_AUTH_NOT_FOUND = 13011; + //public const uint ERROR_IPSEC_MM_AUTH_IN_USE = 13012; + //public const uint ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND = 13013; + //public const uint ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND = 13014; + //public const uint ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND = 13015; + //public const uint ERROR_IPSEC_TUNNEL_FILTER_EXISTS = 13016; + //public const uint ERROR_IPSEC_TUNNEL_FILTER_NOT_FOUND = 13017; + //public const uint ERROR_IPSEC_MM_FILTER_PENDING_DELETION = 13018; + //public const uint ERROR_IPSEC_TRANSPORT_FILTER_PENDING_DELETION = 13019; + //public const uint ERROR_IPSEC_TUNNEL_FILTER_PENDING_DELETION = 13020; + //public const uint ERROR_IPSEC_MM_POLICY_PENDING_DELETION = 13021; + //public const uint ERROR_IPSEC_MM_AUTH_PENDING_DELETION = 13022; + //public const uint ERROR_IPSEC_QM_POLICY_PENDING_DELETION = 13023; + //public const uint WARNING_IPSEC_MM_POLICY_PRUNED = 13024; + //public const uint WARNING_IPSEC_QM_POLICY_PRUNED = 13025; + //public const uint ERROR_IPSEC_IKE_NEG_STATUS_BEGIN = 13800; + //public const uint ERROR_IPSEC_IKE_AUTH_FAIL = 13801; + //public const uint ERROR_IPSEC_IKE_ATTRIB_FAIL = 13802; + //public const uint ERROR_IPSEC_IKE_NEGOTIATION_PENDING = 13803; + //public const uint ERROR_IPSEC_IKE_GENERAL_PROCESSING_ERROR = 13804; + //public const uint ERROR_IPSEC_IKE_TIMED_OUT = 13805; + //public const uint ERROR_IPSEC_IKE_NO_CERT = 13806; + //public const uint ERROR_IPSEC_IKE_SA_DELETED = 13807; + //public const uint ERROR_IPSEC_IKE_SA_REAPED = 13808; + //public const uint ERROR_IPSEC_IKE_MM_ACQUIRE_DROP = 13809; + //public const uint ERROR_IPSEC_IKE_QM_ACQUIRE_DROP = 13810; + //public const uint ERROR_IPSEC_IKE_QUEUE_DROP_MM = 13811; + //public const uint ERROR_IPSEC_IKE_QUEUE_DROP_NO_MM = 13812; + //public const uint ERROR_IPSEC_IKE_DROP_NO_RESPONSE = 13813; + //public const uint ERROR_IPSEC_IKE_MM_DELAY_DROP = 13814; + //public const uint ERROR_IPSEC_IKE_QM_DELAY_DROP = 13815; + //public const uint ERROR_IPSEC_IKE_ERROR = 13816; + //public const uint ERROR_IPSEC_IKE_CRL_FAILED = 13817; + //public const uint ERROR_IPSEC_IKE_INVALID_KEY_USAGE = 13818; + //public const uint ERROR_IPSEC_IKE_INVALID_CERT_TYPE = 13819; + //public const uint ERROR_IPSEC_IKE_NO_PRIVATE_KEY = 13820; + //public const uint ERROR_IPSEC_IKE_DH_FAIL = 13822; + //public const uint ERROR_IPSEC_IKE_INVALID_HEADER = 13824; + //public const uint ERROR_IPSEC_IKE_NO_POLICY = 13825; + //public const uint ERROR_IPSEC_IKE_INVALID_SIGNATURE = 13826; + //public const uint ERROR_IPSEC_IKE_KERBEROS_ERROR = 13827; + //public const uint ERROR_IPSEC_IKE_NO_PUBLIC_KEY = 13828; + //public const uint ERROR_IPSEC_IKE_PROCESS_ERR = 13829; + //public const uint ERROR_IPSEC_IKE_PROCESS_ERR_SA = 13830; + //public const uint ERROR_IPSEC_IKE_PROCESS_ERR_PROP = 13831; + //public const uint ERROR_IPSEC_IKE_PROCESS_ERR_TRANS = 13832; + //public const uint ERROR_IPSEC_IKE_PROCESS_ERR_KE = 13833; + //public const uint ERROR_IPSEC_IKE_PROCESS_ERR_ID = 13834; + //public const uint ERROR_IPSEC_IKE_PROCESS_ERR_CERT = 13835; + //public const uint ERROR_IPSEC_IKE_PROCESS_ERR_CERT_REQ = 13836; + //public const uint ERROR_IPSEC_IKE_PROCESS_ERR_HASH = 13837; + //public const uint ERROR_IPSEC_IKE_PROCESS_ERR_SIG = 13838; + //public const uint ERROR_IPSEC_IKE_PROCESS_ERR_NONCE = 13839; + //public const uint ERROR_IPSEC_IKE_PROCESS_ERR_NOTIFY = 13840; + //public const uint ERROR_IPSEC_IKE_PROCESS_ERR_DELETE = 13841; + //public const uint ERROR_IPSEC_IKE_PROCESS_ERR_VENDOR = 13842; + //public const uint ERROR_IPSEC_IKE_INVALID_PAYLOAD = 13843; + //public const uint ERROR_IPSEC_IKE_LOAD_SOFT_SA = 13844; + //public const uint ERROR_IPSEC_IKE_SOFT_SA_TORN_DOWN = 13845; + //public const uint ERROR_IPSEC_IKE_INVALID_COOKIE = 13846; + //public const uint ERROR_IPSEC_IKE_NO_PEER_CERT = 13847; + //public const uint ERROR_IPSEC_IKE_PEER_CRL_FAILED = 13848; + //public const uint ERROR_IPSEC_IKE_POLICY_CHANGE = 13849; + //public const uint ERROR_IPSEC_IKE_NO_MM_POLICY = 13850; + //public const uint ERROR_IPSEC_IKE_NOTCBPRIV = 13851; + //public const uint ERROR_IPSEC_IKE_SECLOADFAIL = 13852; + //public const uint ERROR_IPSEC_IKE_FAILSSPINIT = 13853; + //public const uint ERROR_IPSEC_IKE_FAILQUERYSSP = 13854; + //public const uint ERROR_IPSEC_IKE_SRVACQFAIL = 13855; + //public const uint ERROR_IPSEC_IKE_SRVQUERYCRED = 13856; + //public const uint ERROR_IPSEC_IKE_GETSPIFAIL = 13857; + //public const uint ERROR_IPSEC_IKE_INVALID_FILTER = 13858; + //public const uint ERROR_IPSEC_IKE_OUT_OF_MEMORY = 13859; + //public const uint ERROR_IPSEC_IKE_ADD_UPDATE_KEY_FAILED = 13860; + //public const uint ERROR_IPSEC_IKE_INVALID_POLICY = 13861; + //public const uint ERROR_IPSEC_IKE_UNKNOWN_DOI = 13862; + //public const uint ERROR_IPSEC_IKE_INVALID_SITUATION = 13863; + //public const uint ERROR_IPSEC_IKE_DH_FAILURE = 13864; + //public const uint ERROR_IPSEC_IKE_INVALID_GROUP = 13865; + //public const uint ERROR_IPSEC_IKE_ENCRYPT = 13866; + //public const uint ERROR_IPSEC_IKE_DECRYPT = 13867; + //public const uint ERROR_IPSEC_IKE_POLICY_MATCH = 13868; + //public const uint ERROR_IPSEC_IKE_UNSUPPORTED_ID = 13869; + //public const uint ERROR_IPSEC_IKE_INVALID_HASH = 13870; + //public const uint ERROR_IPSEC_IKE_INVALID_HASH_ALG = 13871; + //public const uint ERROR_IPSEC_IKE_INVALID_HASH_SIZE = 13872; + //public const uint ERROR_IPSEC_IKE_INVALID_ENCRYPT_ALG = 13873; + //public const uint ERROR_IPSEC_IKE_INVALID_AUTH_ALG = 13874; + //public const uint ERROR_IPSEC_IKE_INVALID_SIG = 13875; + //public const uint ERROR_IPSEC_IKE_LOAD_FAILED = 13876; + //public const uint ERROR_IPSEC_IKE_RPC_DELETE = 13877; + //public const uint ERROR_IPSEC_IKE_BENIGN_REINIT = 13878; + //public const uint ERROR_IPSEC_IKE_INVALID_RESPONDER_LIFETIME_NOTIFY = 13879; + //public const uint ERROR_IPSEC_IKE_INVALID_CERT_KEYLEN = 13881; + //public const uint ERROR_IPSEC_IKE_MM_LIMIT = 13882; + //public const uint ERROR_IPSEC_IKE_NEGOTIATION_DISABLED = 13883; + //public const uint ERROR_IPSEC_IKE_NEG_STATUS_END = 13884; + //public const uint SEVERITY_SUCCESS = 0; + //public const uint SEVERITY_ERROR = 1; + //public const uint NOERROR = 0; + + //public const uint E_UNEXPECTED = 0x8000FFFF; + //public const uint E_NOTIMPL = 0x80004001; + //public const uint E_OUTOFMEMORY = 0x8007000E; + //public const uint E_INVALIDARG = 0x80070057; + //public const uint E_NOINTERFACE = 0x80004002; + public const uint E_POINTER = 0x80004003; + //public const uint E_HANDLE = 0x80070006; + //public const uint E_ABORT = 0x80004004; + //public const uint E_FAIL = 0x80004005; + //public const uint E_ACCESSDENIED = 0x80070005; + //public const uint E_PENDING = 0x8000000A; + //public const uint CO_E_INIT_TLS = 0x80004006; + //public const uint CO_E_INIT_SHARED_ALLOCATOR = 0x80004007; + //public const uint CO_E_INIT_MEMORY_ALLOCATOR = 0x80004008; + //public const uint CO_E_INIT_CLASS_CACHE = 0x80004009; + //public const uint CO_E_INIT_RPC_CHANNEL = 0x8000400A; + //public const uint CO_E_INIT_TLS_SET_CHANNEL_CONTROL = 0x8000400B; + //public const uint CO_E_INIT_TLS_CHANNEL_CONTROL = 0x8000400C; + //public const uint CO_E_INIT_UNACCEPTED_USER_ALLOCATOR = 0x8000400D; + //public const uint CO_E_INIT_SCM_MUTEX_EXISTS = 0x8000400E; + //public const uint CO_E_INIT_SCM_FILE_MAPPING_EXISTS = 0x8000400F; + //public const uint CO_E_INIT_SCM_MAP_VIEW_OF_FILE = 0x80004010; + //public const uint CO_E_INIT_SCM_EXEC_FAILURE = 0x80004011; + //public const uint CO_E_INIT_ONLY_SINGLE_THREADED = 0x80004012; + //public const uint CO_E_CANT_REMOTE = 0x80004013; + //public const uint CO_E_BAD_SERVER_NAME = 0x80004014; + //public const uint CO_E_WRONG_SERVER_IDENTITY = 0x80004015; + //public const uint CO_E_OLE1DDE_DISABLED = 0x80004016; + //public const uint CO_E_RUNAS_SYNTAX = 0x80004017; + //public const uint CO_E_CREATEPROCESS_FAILURE = 0x80004018; + //public const uint CO_E_RUNAS_CREATEPROCESS_FAILURE = 0x80004019; + //public const uint CO_E_RUNAS_LOGON_FAILURE = 0x8000401A; + //public const uint CO_E_LAUNCH_PERMSSION_DENIED = 0x8000401B; + //public const uint CO_E_START_SERVICE_FAILURE = 0x8000401C; + //public const uint CO_E_REMOTE_COMMUNICATION_FAILURE = 0x8000401D; + //public const uint CO_E_SERVER_START_TIMEOUT = 0x8000401E; + //public const uint CO_E_CLSREG_INCONSISTENT = 0x8000401F; + //public const uint CO_E_IIDREG_INCONSISTENT = 0x80004020; + //public const uint CO_E_NOT_SUPPORTED = 0x80004021; + //public const uint CO_E_RELOAD_DLL = 0x80004022; + //public const uint CO_E_MSI_ERROR = 0x80004023; + //public const uint CO_E_ATTEMPT_TO_CREATE_OUTSIDE_CLIENT_CONTEXT = 0x80004024; + //public const uint CO_E_SERVER_PAUSED = 0x80004025; + //public const uint CO_E_SERVER_NOT_PAUSED = 0x80004026; + //public const uint CO_E_CLASS_DISABLED = 0x80004027; + //public const uint CO_E_CLRNOTAVAILABLE = 0x80004028; + //public const uint CO_E_ASYNC_WORK_REJECTED = 0x80004029; + //public const uint CO_E_SERVER_INIT_TIMEOUT = 0x8000402A; + //public const uint CO_E_NO_SECCTX_IN_ACTIVATE = 0x8000402B; + //public const uint CO_E_TRACKER_CONFIG = 0x80004030; + //public const uint CO_E_THREADPOOL_CONFIG = 0x80004031; + //public const uint CO_E_SXS_CONFIG = 0x80004032; + //public const uint CO_E_MALFORMED_SPN = 0x80004033; + + /// (0) The operation completed successfully. + public const uint S_OK = 0x00000000; + + //public const uint S_FALSE = 0x00000001; + //public const uint OLE_E_FIRST = 0x80040000; + //public const uint OLE_E_LAST = 0x800400FF; + //public const uint OLE_S_FIRST = 0x00040000; + //public const uint OLE_S_LAST = 0x000400FF; + //public const uint OLE_E_OLEVERB = 0x80040000; + //public const uint OLE_E_ADVF = 0x80040001; + //public const uint OLE_E_ENUM_NOMORE = 0x80040002; + //public const uint OLE_E_ADVISENOTSUPPORTED = 0x80040003; + //public const uint OLE_E_NOCONNECTION = 0x80040004; + //public const uint OLE_E_NOTRUNNING = 0x80040005; + //public const uint OLE_E_NOCACHE = 0x80040006; + //public const uint OLE_E_BLANK = 0x80040007; + //public const uint OLE_E_CLASSDIFF = 0x80040008; + //public const uint OLE_E_CANT_GETMONIKER = 0x80040009; + //public const uint OLE_E_CANT_BINDTOSOURCE = 0x8004000A; + //public const uint OLE_E_STATIC = 0x8004000B; + //public const uint OLE_E_PROMPTSAVECANCELLED = 0x8004000C; + //public const uint OLE_E_INVALIDRECT = 0x8004000D; + //public const uint OLE_E_WRONGCOMPOBJ = 0x8004000E; + //public const uint OLE_E_INVALIDHWND = 0x8004000F; + //public const uint OLE_E_NOT_INPLACEACTIVE = 0x80040010; + //public const uint OLE_E_CANTCONVERT = 0x80040011; + //public const uint OLE_E_NOSTORAGE = 0x80040012; + //public const uint DV_E_FORMATETC = 0x80040064; + //public const uint DV_E_DVTARGETDEVICE = 0x80040065; + //public const uint DV_E_STGMEDIUM = 0x80040066; + //public const uint DV_E_STATDATA = 0x80040067; + //public const uint DV_E_LINDEX = 0x80040068; + //public const uint DV_E_TYMED = 0x80040069; + //public const uint DV_E_CLIPFORMAT = 0x8004006A; + //public const uint DV_E_DVASPECT = 0x8004006B; + //public const uint DV_E_DVTARGETDEVICE_SIZE = 0x8004006C; + //public const uint DV_E_NOIVIEWOBJECT = 0x8004006D; + //public const uint DRAGDROP_E_FIRST = 0x80040100; + //public const uint DRAGDROP_E_LAST = 0x8004010F; + //public const uint DRAGDROP_S_FIRST = 0x00040100; + //public const uint DRAGDROP_S_LAST = 0x0004010F; + //public const uint DRAGDROP_E_NOTREGISTERED = 0x80040100; + //public const uint DRAGDROP_E_ALREADYREGISTERED = 0x80040101; + //public const uint DRAGDROP_E_INVALIDHWND = 0x80040102; + //public const uint CLASSFACTORY_E_FIRST = 0x80040110; + //public const uint CLASSFACTORY_E_LAST = 0x8004011F; + //public const uint CLASSFACTORY_S_FIRST = 0x00040110; + //public const uint CLASSFACTORY_S_LAST = 0x0004011F; + //public const uint CLASS_E_NOAGGREGATION = 0x80040110; + //public const uint CLASS_E_CLASSNOTAVAILABLE = 0x80040111; + //public const uint CLASS_E_NOTLICENSED = 0x80040112; + //public const uint MARSHAL_E_FIRST = 0x80040120; + //public const uint MARSHAL_E_LAST = 0x8004012F; + //public const uint MARSHAL_S_FIRST = 0x00040120; + //public const uint MARSHAL_S_LAST = 0x0004012F; + //public const uint DATA_E_FIRST = 0x80040130; + //public const uint DATA_E_LAST = 0x8004013F; + //public const uint DATA_S_FIRST = 0x00040130; + //public const uint DATA_S_LAST = 0x0004013F; + //public const uint VIEW_E_FIRST = 0x80040140; + //public const uint VIEW_E_LAST = 0x8004014F; + //public const uint VIEW_S_FIRST = 0x00040140; + //public const uint VIEW_S_LAST = 0x0004014F; + //public const uint VIEW_E_DRAW = 0x80040140; + //public const uint REGDB_E_FIRST = 0x80040150; + //public const uint REGDB_E_LAST = 0x8004015F; + //public const uint REGDB_S_FIRST = 0x00040150; + //public const uint REGDB_S_LAST = 0x0004015F; + //public const uint REGDB_E_READREGDB = 0x80040150; + //public const uint REGDB_E_WRITEREGDB = 0x80040151; + //public const uint REGDB_E_KEYMISSING = 0x80040152; + //public const uint REGDB_E_INVALIDVALUE = 0x80040153; + //public const uint REGDB_E_CLASSNOTREG = 0x80040154; + //public const uint REGDB_E_IIDNOTREG = 0x80040155; + //public const uint REGDB_E_BADTHREADINGMODEL = 0x80040156; + //public const uint CAT_E_FIRST = 0x80040160; + //public const uint CAT_E_LAST = 0x80040161; + //public const uint CAT_E_CATIDNOEXIST = 0x80040160; + //public const uint CAT_E_NODESCRIPTION = 0x80040161; + //public const uint CS_E_FIRST = 0x80040164; + //public const uint CS_E_LAST = 0x8004016F; + //public const uint CS_E_PACKAGE_NOTFOUND = 0x80040164; + //public const uint CS_E_NOT_DELETABLE = 0x80040165; + //public const uint CS_E_CLASS_NOTFOUND = 0x80040166; + //public const uint CS_E_INVALID_VERSION = 0x80040167; + //public const uint CS_E_NO_CLASSSTORE = 0x80040168; + //public const uint CS_E_OBJECT_NOTFOUND = 0x80040169; + //public const uint CS_E_OBJECT_ALREADY_EXISTS = 0x8004016A; + //public const uint CS_E_INVALID_PATH = 0x8004016B; + //public const uint CS_E_NETWORK_ERROR = 0x8004016C; + //public const uint CS_E_ADMIN_LIMIT_EXCEEDED = 0x8004016D; + //public const uint CS_E_SCHEMA_MISMATCH = 0x8004016E; + //public const uint CS_E_INTERNAL_ERROR = 0x8004016F; + //public const uint CACHE_E_FIRST = 0x80040170; + //public const uint CACHE_E_LAST = 0x8004017F; + //public const uint CACHE_S_FIRST = 0x00040170; + //public const uint CACHE_S_LAST = 0x0004017F; + //public const uint CACHE_E_NOCACHE_UPDATED = 0x80040170; + //public const uint OLEOBJ_E_FIRST = 0x80040180; + //public const uint OLEOBJ_E_LAST = 0x8004018F; + //public const uint OLEOBJ_S_FIRST = 0x00040180; + //public const uint OLEOBJ_S_LAST = 0x0004018F; + //public const uint OLEOBJ_E_NOVERBS = 0x80040180; + //public const uint OLEOBJ_E_INVALIDVERB = 0x80040181; + //public const uint CLIENTSITE_E_FIRST = 0x80040190; + //public const uint CLIENTSITE_E_LAST = 0x8004019F; + //public const uint CLIENTSITE_S_FIRST = 0x00040190; + //public const uint CLIENTSITE_S_LAST = 0x0004019F; + //public const uint INPLACE_E_NOTUNDOABLE = 0x800401A0; + //public const uint INPLACE_E_NOTOOLSPACE = 0x800401A1; + //public const uint INPLACE_E_FIRST = 0x800401A0; + //public const uint INPLACE_E_LAST = 0x800401AF; + //public const uint INPLACE_S_FIRST = 0x000401A0; + //public const uint INPLACE_S_LAST = 0x000401AF; + //public const uint ENUM_E_FIRST = 0x800401B0; + //public const uint ENUM_E_LAST = 0x800401BF; + //public const uint ENUM_S_FIRST = 0x000401B0; + //public const uint ENUM_S_LAST = 0x000401BF; + //public const uint CONVERT10_E_FIRST = 0x800401C0; + //public const uint CONVERT10_E_LAST = 0x800401CF; + //public const uint CONVERT10_S_FIRST = 0x000401C0; + //public const uint CONVERT10_S_LAST = 0x000401CF; + //public const uint CONVERT10_E_OLESTREAM_GET = 0x800401C0; + //public const uint CONVERT10_E_OLESTREAM_PUT = 0x800401C1; + //public const uint CONVERT10_E_OLESTREAM_FMT = 0x800401C2; + //public const uint CONVERT10_E_OLESTREAM_BITMAP_TO_DIB = 0x800401C3; + //public const uint CONVERT10_E_STG_FMT = 0x800401C4; + //public const uint CONVERT10_E_STG_NO_STD_STREAM = 0x800401C5; + //public const uint CONVERT10_E_STG_DIB_TO_BITMAP = 0x800401C6; + //public const uint CLIPBRD_E_FIRST = 0x800401D0; + //public const uint CLIPBRD_E_LAST = 0x800401DF; + //public const uint CLIPBRD_S_FIRST = 0x000401D0; + //public const uint CLIPBRD_S_LAST = 0x000401DF; + //public const uint CLIPBRD_E_CANT_OPEN = 0x800401D0; + //public const uint CLIPBRD_E_CANT_EMPTY = 0x800401D1; + //public const uint CLIPBRD_E_CANT_SET = 0x800401D2; + //public const uint CLIPBRD_E_BAD_DATA = 0x800401D3; + //public const uint CLIPBRD_E_CANT_CLOSE = 0x800401D4; + //public const uint MK_E_FIRST = 0x800401E0; + //public const uint MK_E_LAST = 0x800401EF; + //public const uint MK_S_FIRST = 0x000401E0; + //public const uint MK_S_LAST = 0x000401EF; + //public const uint MK_E_CONNECTMANUALLY = 0x800401E0; + //public const uint MK_E_EXCEEDEDDEADLINE = 0x800401E1; + //public const uint MK_E_NEEDGENERIC = 0x800401E2; + //public const uint MK_E_UNAVAILABLE = 0x800401E3; + //public const uint MK_E_SYNTAX = 0x800401E4; + //public const uint MK_E_NOOBJECT = 0x800401E5; + //public const uint MK_E_INVALIDEXTENSION = 0x800401E6; + //public const uint MK_E_INTERMEDIATEINTERFACENOTSUPPORTED = 0x800401E7; + //public const uint MK_E_NOTBINDABLE = 0x800401E8; + //public const uint MK_E_NOTBOUND = 0x800401E9; + //public const uint MK_E_CANTOPENFILE = 0x800401EA; + //public const uint MK_E_MUSTBOTHERUSER = 0x800401EB; + //public const uint MK_E_NOINVERSE = 0x800401EC; + //public const uint MK_E_NOSTORAGE = 0x800401ED; + //public const uint MK_E_NOPREFIX = 0x800401EE; + //public const uint MK_E_ENUMERATION_FAILED = 0x800401EF; + //public const uint CO_E_FIRST = 0x800401F0; + //public const uint CO_E_LAST = 0x800401FF; + //public const uint CO_S_FIRST = 0x000401F0; + //public const uint CO_S_LAST = 0x000401FF; + //public const uint CO_E_NOTINITIALIZED = 0x800401F0; + //public const uint CO_E_ALREADYINITIALIZED = 0x800401F1; + //public const uint CO_E_CANTDETERMINECLASS = 0x800401F2; + //public const uint CO_E_CLASSSTRING = 0x800401F3; + //public const uint CO_E_IIDSTRING = 0x800401F4; + //public const uint CO_E_APPNOTFOUND = 0x800401F5; + //public const uint CO_E_APPSINGLEUSE = 0x800401F6; + //public const uint CO_E_ERRORINAPP = 0x800401F7; + //public const uint CO_E_DLLNOTFOUND = 0x800401F8; + //public const uint CO_E_ERRORINDLL = 0x800401F9; + //public const uint CO_E_WRONGOSFORAPP = 0x800401FA; + //public const uint CO_E_OBJNOTREG = 0x800401FB; + //public const uint CO_E_OBJISREG = 0x800401FC; + //public const uint CO_E_OBJNOTCONNECTED = 0x800401FD; + //public const uint CO_E_APPDIDNTREG = 0x800401FE; + //public const uint CO_E_RELEASED = 0x800401FF; + //public const uint EVENT_E_FIRST = 0x80040200; + //public const uint EVENT_E_LAST = 0x8004021F; + //public const uint EVENT_S_FIRST = 0x00040200; + //public const uint EVENT_S_LAST = 0x0004021F; + //public const uint EVENT_S_SOME_SUBSCRIBERS_FAILED = 0x00040200; + //public const uint EVENT_E_ALL_SUBSCRIBERS_FAILED = 0x80040201; + //public const uint EVENT_S_NOSUBSCRIBERS = 0x00040202; + //public const uint EVENT_E_QUERYSYNTAX = 0x80040203; + //public const uint EVENT_E_QUERYFIELD = 0x80040204; + //public const uint EVENT_E_INTERNALEXCEPTION = 0x80040205; + //public const uint EVENT_E_INTERNALERROR = 0x80040206; + //public const uint EVENT_E_INVALID_PER_USER_SID = 0x80040207; + //public const uint EVENT_E_USER_EXCEPTION = 0x80040208; + //public const uint EVENT_E_TOO_MANY_METHODS = 0x80040209; + //public const uint EVENT_E_MISSING_EVENTCLASS = 0x8004020A; + //public const uint EVENT_E_NOT_ALL_REMOVED = 0x8004020B; + //public const uint EVENT_E_COMPLUS_NOT_INSTALLED = 0x8004020C; + //public const uint EVENT_E_CANT_MODIFY_OR_DELETE_UNCONFIGURED_OBJECT = 0x8004020D; + //public const uint EVENT_E_CANT_MODIFY_OR_DELETE_CONFIGURED_OBJECT = 0x8004020E; + //public const uint EVENT_E_INVALID_EVENT_CLASS_PARTITION = 0x8004020F; + //public const uint EVENT_E_PER_USER_SID_NOT_LOGGED_ON = 0x80040210; + //public const uint XACT_E_FIRST = 0x8004D000; + //public const uint XACT_E_LAST = 0x8004D029; + //public const uint XACT_S_FIRST = 0x0004D000; + //public const uint XACT_S_LAST = 0x0004D010; + //public const uint XACT_E_ALREADYOTHERSINGLEPHASE = 0x8004D000; + //public const uint XACT_E_CANTRETAIN = 0x8004D001; + //public const uint XACT_E_COMMITFAILED = 0x8004D002; + //public const uint XACT_E_COMMITPREVENTED = 0x8004D003; + //public const uint XACT_E_HEURISTICABORT = 0x8004D004; + //public const uint XACT_E_HEURISTICCOMMIT = 0x8004D005; + //public const uint XACT_E_HEURISTICDAMAGE = 0x8004D006; + //public const uint XACT_E_HEURISTICDANGER = 0x8004D007; + //public const uint XACT_E_ISOLATIONLEVEL = 0x8004D008; + //public const uint XACT_E_NOASYNC = 0x8004D009; + //public const uint XACT_E_NOENLIST = 0x8004D00A; + //public const uint XACT_E_NOISORETAIN = 0x8004D00B; + //public const uint XACT_E_NORESOURCE = 0x8004D00C; + //public const uint XACT_E_NOTCURRENT = 0x8004D00D; + //public const uint XACT_E_NOTRANSACTION = 0x8004D00E; + //public const uint XACT_E_NOTSUPPORTED = 0x8004D00F; + //public const uint XACT_E_UNKNOWNRMGRID = 0x8004D010; + //public const uint XACT_E_WRONGSTATE = 0x8004D011; + //public const uint XACT_E_WRONGUOW = 0x8004D012; + //public const uint XACT_E_XTIONEXISTS = 0x8004D013; + //public const uint XACT_E_NOIMPORTOBJECT = 0x8004D014; + //public const uint XACT_E_INVALIDCOOKIE = 0x8004D015; + //public const uint XACT_E_INDOUBT = 0x8004D016; + //public const uint XACT_E_NOTIMEOUT = 0x8004D017; + //public const uint XACT_E_ALREADYINPROGRESS = 0x8004D018; + //public const uint XACT_E_ABORTED = 0x8004D019; + //public const uint XACT_E_LOGFULL = 0x8004D01A; + //public const uint XACT_E_TMNOTAVAILABLE = 0x8004D01B; + //public const uint XACT_E_CONNECTION_DOWN = 0x8004D01C; + //public const uint XACT_E_CONNECTION_DENIED = 0x8004D01D; + //public const uint XACT_E_REENLISTTIMEOUT = 0x8004D01E; + //public const uint XACT_E_TIP_CONNECT_FAILED = 0x8004D01F; + //public const uint XACT_E_TIP_PROTOCOL_ERROR = 0x8004D020; + //public const uint XACT_E_TIP_PULL_FAILED = 0x8004D021; + //public const uint XACT_E_DEST_TMNOTAVAILABLE = 0x8004D022; + //public const uint XACT_E_TIP_DISABLED = 0x8004D023; + //public const uint XACT_E_NETWORK_TX_DISABLED = 0x8004D024; + //public const uint XACT_E_PARTNER_NETWORK_TX_DISABLED = 0x8004D025; + //public const uint XACT_E_XA_TX_DISABLED = 0x8004D026; + //public const uint XACT_E_UNABLE_TO_READ_DTC_CONFIG = 0x8004D027; + //public const uint XACT_E_UNABLE_TO_LOAD_DTC_PROXY = 0x8004D028; + //public const uint XACT_E_ABORTING = 0x8004D029; + //public const uint XACT_E_CLERKNOTFOUND = 0x8004D080; + //public const uint XACT_E_CLERKEXISTS = 0x8004D081; + //public const uint XACT_E_RECOVERYINPROGRESS = 0x8004D082; + //public const uint XACT_E_TRANSACTIONCLOSED = 0x8004D083; + //public const uint XACT_E_INVALIDLSN = 0x8004D084; + //public const uint XACT_E_REPLAYREQUEST = 0x8004D085; + //public const uint XACT_S_ASYNC = 0x0004D000; + //public const uint XACT_S_DEFECT = 0x0004D001; + //public const uint XACT_S_READONLY = 0x0004D002; + //public const uint XACT_S_SOMENORETAIN = 0x0004D003; + //public const uint XACT_S_OKINFORM = 0x0004D004; + //public const uint XACT_S_MADECHANGESCONTENT = 0x0004D005; + //public const uint XACT_S_MADECHANGESINFORM = 0x0004D006; + //public const uint XACT_S_ALLNORETAIN = 0x0004D007; + //public const uint XACT_S_ABORTING = 0x0004D008; + //public const uint XACT_S_SINGLEPHASE = 0x0004D009; + //public const uint XACT_S_LOCALLY_OK = 0x0004D00A; + //public const uint XACT_S_LASTRESOURCEMANAGER = 0x0004D010; + //public const uint CONTEXT_E_FIRST = 0x8004E000; + //public const uint CONTEXT_E_LAST = 0x8004E02F; + //public const uint CONTEXT_S_FIRST = 0x0004E000; + //public const uint CONTEXT_S_LAST = 0x0004E02F; + //public const uint CONTEXT_E_ABORTED = 0x8004E002; + //public const uint CONTEXT_E_ABORTING = 0x8004E003; + //public const uint CONTEXT_E_NOCONTEXT = 0x8004E004; + //public const uint CONTEXT_E_WOULD_DEADLOCK = 0x8004E005; + //public const uint CONTEXT_E_SYNCH_TIMEOUT = 0x8004E006; + //public const uint CONTEXT_E_OLDREF = 0x8004E007; + //public const uint CONTEXT_E_ROLENOTFOUND = 0x8004E00C; + //public const uint CONTEXT_E_TMNOTAVAILABLE = 0x8004E00F; + //public const uint CO_E_ACTIVATIONFAILED = 0x8004E021; + //public const uint CO_E_ACTIVATIONFAILED_EVENTLOGGED = 0x8004E022; + //public const uint CO_E_ACTIVATIONFAILED_CATALOGERROR = 0x8004E023; + //public const uint CO_E_ACTIVATIONFAILED_TIMEOUT = 0x8004E024; + //public const uint CO_E_INITIALIZATIONFAILED = 0x8004E025; + //public const uint CONTEXT_E_NOJIT = 0x8004E026; + //public const uint CONTEXT_E_NOTRANSACTION = 0x8004E027; + //public const uint CO_E_THREADINGMODEL_CHANGED = 0x8004E028; + //public const uint CO_E_NOIISINTRINSICS = 0x8004E029; + //public const uint CO_E_NOCOOKIES = 0x8004E02A; + //public const uint CO_E_DBERROR = 0x8004E02B; + //public const uint CO_E_NOTPOOLED = 0x8004E02C; + //public const uint CO_E_NOTCONSTRUCTED = 0x8004E02D; + //public const uint CO_E_NOSYNCHRONIZATION = 0x8004E02E; + //public const uint CO_E_ISOLEVELMISMATCH = 0x8004E02F; + //public const uint OLE_S_USEREG = 0x00040000; + //public const uint OLE_S_STATIC = 0x00040001; + //public const uint OLE_S_MAC_CLIPFORMAT = 0x00040002; + //public const uint DRAGDROP_S_DROP = 0x00040100; + //public const uint DRAGDROP_S_CANCEL = 0x00040101; + //public const uint DRAGDROP_S_USEDEFAULTCURSORS = 0x00040102; + //public const uint DATA_S_SAMEFORMATETC = 0x00040130; + //public const uint VIEW_S_ALREADY_FROZEN = 0x00040140; + //public const uint CACHE_S_FORMATETC_NOTSUPPORTED = 0x00040170; + //public const uint CACHE_S_SAMECACHE = 0x00040171; + //public const uint CACHE_S_SOMECACHES_NOTUPDATED = 0x00040172; + //public const uint OLEOBJ_S_INVALIDVERB = 0x00040180; + //public const uint OLEOBJ_S_CANNOT_DOVERB_NOW = 0x00040181; + //public const uint OLEOBJ_S_INVALIDHWND = 0x00040182; + //public const uint INPLACE_S_TRUNCATED = 0x000401A0; + //public const uint CONVERT10_S_NO_PRESENTATION = 0x000401C0; + //public const uint MK_S_REDUCED_TO_SELF = 0x000401E2; + //public const uint MK_S_ME = 0x000401E4; + //public const uint MK_S_HIM = 0x000401E5; + //public const uint MK_S_US = 0x000401E6; + //public const uint MK_S_MONIKERALREADYREGISTERED = 0x000401E7; + //public const uint SCHED_S_TASK_READY = 0x00041300; + //public const uint SCHED_S_TASK_RUNNING = 0x00041301; + //public const uint SCHED_S_TASK_DISABLED = 0x00041302; + //public const uint SCHED_S_TASK_HAS_NOT_RUN = 0x00041303; + //public const uint SCHED_S_TASK_NO_MORE_RUNS = 0x00041304; + //public const uint SCHED_S_TASK_NOT_SCHEDULED = 0x00041305; + //public const uint SCHED_S_TASK_TERMINATED = 0x00041306; + //public const uint SCHED_S_TASK_NO_VALID_TRIGGERS = 0x00041307; + //public const uint SCHED_S_EVENT_TRIGGER = 0x00041308; + //public const uint SCHED_E_TRIGGER_NOT_FOUND = 0x80041309; + //public const uint SCHED_E_TASK_NOT_READY = 0x8004130A; + //public const uint SCHED_E_TASK_NOT_RUNNING = 0x8004130B; + //public const uint SCHED_E_SERVICE_NOT_INSTALLED = 0x8004130C; + //public const uint SCHED_E_CANNOT_OPEN_TASK = 0x8004130D; + //public const uint SCHED_E_INVALID_TASK = 0x8004130E; + //public const uint SCHED_E_ACCOUNT_INFORMATION_NOT_SET = 0x8004130F; + //public const uint SCHED_E_ACCOUNT_NAME_NOT_FOUND = 0x80041310; + //public const uint SCHED_E_ACCOUNT_DBASE_CORRUPT = 0x80041311; + //public const uint SCHED_E_NO_SECURITY_SERVICES = 0x80041312; + //public const uint SCHED_E_UNKNOWN_OBJECT_VERSION = 0x80041313; + //public const uint SCHED_E_UNSUPPORTED_ACCOUNT_OPTION = 0x80041314; + //public const uint SCHED_E_SERVICE_NOT_RUNNING = 0x80041315; + //public const uint CO_E_CLASS_CREATE_FAILED = 0x80080001; + //public const uint CO_E_SCM_ERROR = 0x80080002; + //public const uint CO_E_SCM_RPC_FAILURE = 0x80080003; + //public const uint CO_E_BAD_PATH = 0x80080004; + //public const uint CO_E_SERVER_EXEC_FAILURE = 0x80080005; + //public const uint CO_E_OBJSRV_RPC_FAILURE = 0x80080006; + //public const uint MK_E_NO_NORMALIZED = 0x80080007; + //public const uint CO_E_SERVER_STOPPING = 0x80080008; + //public const uint MEM_E_INVALID_ROOT = 0x80080009; + //public const uint MEM_E_INVALID_LINK = 0x80080010; + //public const uint MEM_E_INVALID_SIZE = 0x80080011; + //public const uint CO_S_NOTALLINTERFACES = 0x00080012; + //public const uint CO_S_MACHINENAMENOTFOUND = 0x00080013; + //public const uint DISP_E_UNKNOWNINTERFACE = 0x80020001; + //public const uint DISP_E_MEMBERNOTFOUND = 0x80020003; + //public const uint DISP_E_PARAMNOTFOUND = 0x80020004; + //public const uint DISP_E_TYPEMISMATCH = 0x80020005; + //public const uint DISP_E_UNKNOWNNAME = 0x80020006; + //public const uint DISP_E_NONAMEDARGS = 0x80020007; + //public const uint DISP_E_BADVARTYPE = 0x80020008; + //public const uint DISP_E_EXCEPTION = 0x80020009; + //public const uint DISP_E_OVERFLOW = 0x8002000A; + //public const uint DISP_E_BADINDEX = 0x8002000B; + //public const uint DISP_E_UNKNOWNLCID = 0x8002000C; + //public const uint DISP_E_ARRAYISLOCKED = 0x8002000D; + //public const uint DISP_E_BADPARAMCOUNT = 0x8002000E; + //public const uint DISP_E_PARAMNOTOPTIONAL = 0x8002000F; + //public const uint DISP_E_BADCALLEE = 0x80020010; + //public const uint DISP_E_NOTACOLLECTION = 0x80020011; + //public const uint DISP_E_DIVBYZERO = 0x80020012; + //public const uint DISP_E_BUFFERTOOSMALL = 0x80020013; + //public const uint TYPE_E_BUFFERTOOSMALL = 0x80028016; + //public const uint TYPE_E_FIELDNOTFOUND = 0x80028017; + //public const uint TYPE_E_INVDATAREAD = 0x80028018; + //public const uint TYPE_E_UNSUPFORMAT = 0x80028019; + //public const uint TYPE_E_REGISTRYACCESS = 0x8002801C; + //public const uint TYPE_E_LIBNOTREGISTERED = 0x8002801D; + //public const uint TYPE_E_UNDEFINEDTYPE = 0x80028027; + //public const uint TYPE_E_QUALIFIEDNAMEDISALLOWED = 0x80028028; + //public const uint TYPE_E_INVALIDSTATE = 0x80028029; + //public const uint TYPE_E_WRONGTYPEKIND = 0x8002802A; + //public const uint TYPE_E_ELEMENTNOTFOUND = 0x8002802B; + //public const uint TYPE_E_AMBIGUOUSNAME = 0x8002802C; + //public const uint TYPE_E_NAMECONFLICT = 0x8002802D; + //public const uint TYPE_E_UNKNOWNLCID = 0x8002802E; + //public const uint TYPE_E_DLLFUNCTIONNOTFOUND = 0x8002802F; + //public const uint TYPE_E_BADMODULEKIND = 0x800288BD; + //public const uint TYPE_E_SIZETOOBIG = 0x800288C5; + //public const uint TYPE_E_DUPLICATEID = 0x800288C6; + //public const uint TYPE_E_INVALIDID = 0x800288CF; + //public const uint TYPE_E_TYPEMISMATCH = 0x80028CA0; + //public const uint TYPE_E_OUTOFBOUNDS = 0x80028CA1; + //public const uint TYPE_E_IOERROR = 0x80028CA2; + //public const uint TYPE_E_CANTCREATETMPFILE = 0x80028CA3; + //public const uint TYPE_E_CANTLOADLIBRARY = 0x80029C4A; + //public const uint TYPE_E_INCONSISTENTPROPFUNCS = 0x80029C83; + //public const uint TYPE_E_CIRCULARTYPE = 0x80029C84; + //public const uint STG_E_INVALIDFUNCTION = 0x80030001; + //public const uint STG_E_FILENOTFOUND = 0x80030002; + //public const uint STG_E_PATHNOTFOUND = 0x80030003; + //public const uint STG_E_TOOMANYOPENFILES = 0x80030004; + //public const uint STG_E_ACCESSDENIED = 0x80030005; + //public const uint STG_E_INVALIDHANDLE = 0x80030006; + //public const uint STG_E_INSUFFICIENTMEMORY = 0x80030008; + //public const uint STG_E_INVALIDPOINTER = 0x80030009; + //public const uint STG_E_NOMOREFILES = 0x80030012; + //public const uint STG_E_DISKISWRITEPROTECTED = 0x80030013; + //public const uint STG_E_SEEKERROR = 0x80030019; + //public const uint STG_E_WRITEFAULT = 0x8003001D; + //public const uint STG_E_READFAULT = 0x8003001E; + //public const uint STG_E_SHAREVIOLATION = 0x80030020; + //public const uint STG_E_LOCKVIOLATION = 0x80030021; + //public const uint STG_E_FILEALREADYEXISTS = 0x80030050; + //public const uint STG_E_INVALIDPARAMETER = 0x80030057; + //public const uint STG_E_MEDIUMFULL = 0x80030070; + //public const uint STG_E_PROPSETMISMATCHED = 0x800300F0; + //public const uint STG_E_ABNORMALAPIEXIT = 0x800300FA; + //public const uint STG_E_INVALIDHEADER = 0x800300FB; + //public const uint STG_E_INVALIDNAME = 0x800300FC; + //public const uint STG_E_UNKNOWN = 0x800300FD; + //public const uint STG_E_UNIMPLEMENTEDFUNCTION = 0x800300FE; + //public const uint STG_E_INVALIDFLAG = 0x800300FF; + //public const uint STG_E_INUSE = 0x80030100; + //public const uint STG_E_NOTCURRENT = 0x80030101; + //public const uint STG_E_REVERTED = 0x80030102; + //public const uint STG_E_CANTSAVE = 0x80030103; + //public const uint STG_E_OLDFORMAT = 0x80030104; + //public const uint STG_E_OLDDLL = 0x80030105; + //public const uint STG_E_SHAREREQUIRED = 0x80030106; + //public const uint STG_E_NOTFILEBASEDSTORAGE = 0x80030107; + //public const uint STG_E_EXTANTMARSHALLINGS = 0x80030108; + //public const uint STG_E_DOCFILECORRUPT = 0x80030109; + //public const uint STG_E_BADBASEADDRESS = 0x80030110; + //public const uint STG_E_DOCFILETOOLARGE = 0x80030111; + //public const uint STG_E_NOTSIMPLEFORMAT = 0x80030112; + //public const uint STG_E_INCOMPLETE = 0x80030201; + //public const uint STG_E_TERMINATED = 0x80030202; + //public const uint STG_S_CONVERTED = 0x00030200; + //public const uint STG_S_BLOCK = 0x00030201; + //public const uint STG_S_RETRYNOW = 0x00030202; + //public const uint STG_S_MONITORING = 0x00030203; + //public const uint STG_S_MULTIPLEOPENS = 0x00030204; + //public const uint STG_S_CONSOLIDATIONFAILED = 0x00030205; + //public const uint STG_S_CANNOTCONSOLIDATE = 0x00030206; + //public const uint STG_E_STATUS_COPY_PROTECTION_FAILURE = 0x80030305; + //public const uint STG_E_CSS_AUTHENTICATION_FAILURE = 0x80030306; + //public const uint STG_E_CSS_KEY_NOT_PRESENT = 0x80030307; + //public const uint STG_E_CSS_KEY_NOT_ESTABLISHED = 0x80030308; + //public const uint STG_E_CSS_SCRAMBLED_SECTOR = 0x80030309; + //public const uint STG_E_CSS_REGION_MISMATCH = 0x8003030A; + //public const uint STG_E_RESETS_EXHAUSTED = 0x8003030B; + //public const uint RPC_E_CALL_REJECTED = 0x80010001; + //public const uint RPC_E_CALL_CANCELED = 0x80010002; + //public const uint RPC_E_CANTPOST_INSENDCALL = 0x80010003; + //public const uint RPC_E_CANTCALLOUT_INASYNCCALL = 0x80010004; + //public const uint RPC_E_CANTCALLOUT_INEXTERNALCALL = 0x80010005; + //public const uint RPC_E_CONNECTION_TERMINATED = 0x80010006; + //public const uint RPC_E_SERVER_DIED = 0x80010007; + //public const uint RPC_E_CLIENT_DIED = 0x80010008; + //public const uint RPC_E_INVALID_DATAPACKET = 0x80010009; + //public const uint RPC_E_CANTTRANSMIT_CALL = 0x8001000A; + //public const uint RPC_E_CLIENT_CANTMARSHAL_DATA = 0x8001000B; + //public const uint RPC_E_CLIENT_CANTUNMARSHAL_DATA = 0x8001000C; + //public const uint RPC_E_SERVER_CANTMARSHAL_DATA = 0x8001000D; + //public const uint RPC_E_SERVER_CANTUNMARSHAL_DATA = 0x8001000E; + //public const uint RPC_E_INVALID_DATA = 0x8001000F; + //public const uint RPC_E_INVALID_PARAMETER = 0x80010010; + //public const uint RPC_E_CANTCALLOUT_AGAIN = 0x80010011; + //public const uint RPC_E_SERVER_DIED_DNE = 0x80010012; + //public const uint RPC_E_SYS_CALL_FAILED = 0x80010100; + //public const uint RPC_E_OUT_OF_RESOURCES = 0x80010101; + //public const uint RPC_E_ATTEMPTED_MULTITHREAD = 0x80010102; + //public const uint RPC_E_NOT_REGISTERED = 0x80010103; + //public const uint RPC_E_FAULT = 0x80010104; + //public const uint RPC_E_SERVERFAULT = 0x80010105; + //public const uint RPC_E_CHANGED_MODE = 0x80010106; + //public const uint RPC_E_INVALIDMETHOD = 0x80010107; + //public const uint RPC_E_DISCONNECTED = 0x80010108; + //public const uint RPC_E_RETRY = 0x80010109; + //public const uint RPC_E_SERVERCALL_RETRYLATER = 0x8001010A; + //public const uint RPC_E_SERVERCALL_REJECTED = 0x8001010B; + //public const uint RPC_E_INVALID_CALLDATA = 0x8001010C; + //public const uint RPC_E_CANTCALLOUT_ININPUTSYNCCALL = 0x8001010D; + //public const uint RPC_E_WRONG_THREAD = 0x8001010E; + //public const uint RPC_E_THREAD_NOT_INIT = 0x8001010F; + //public const uint RPC_E_VERSION_MISMATCH = 0x80010110; + //public const uint RPC_E_INVALID_HEADER = 0x80010111; + //public const uint RPC_E_INVALID_EXTENSION = 0x80010112; + //public const uint RPC_E_INVALID_IPID = 0x80010113; + //public const uint RPC_E_INVALID_OBJECT = 0x80010114; + //public const uint RPC_S_CALLPENDING = 0x80010115; + //public const uint RPC_S_WAITONTIMER = 0x80010116; + //public const uint RPC_E_CALL_COMPLETE = 0x80010117; + //public const uint RPC_E_UNSECURE_CALL = 0x80010118; + //public const uint RPC_E_TOO_LATE = 0x80010119; + //public const uint RPC_E_NO_GOOD_SECURITY_PACKAGES = 0x8001011A; + //public const uint RPC_E_ACCESS_DENIED = 0x8001011B; + //public const uint RPC_E_REMOTE_DISABLED = 0x8001011C; + //public const uint RPC_E_INVALID_OBJREF = 0x8001011D; + //public const uint RPC_E_NO_CONTEXT = 0x8001011E; + //public const uint RPC_E_TIMEOUT = 0x8001011F; + //public const uint RPC_E_NO_SYNC = 0x80010120; + //public const uint RPC_E_FULLSIC_REQUIRED = 0x80010121; + //public const uint RPC_E_INVALID_STD_NAME = 0x80010122; + //public const uint CO_E_FAILEDTOIMPERSONATE = 0x80010123; + //public const uint CO_E_FAILEDTOGETSECCTX = 0x80010124; + //public const uint CO_E_FAILEDTOOPENTHREADTOKEN = 0x80010125; + //public const uint CO_E_FAILEDTOGETTOKENINFO = 0x80010126; + //public const uint CO_E_TRUSTEEDOESNTMATCHCLIENT = 0x80010127; + //public const uint CO_E_FAILEDTOQUERYCLIENTBLANKET = 0x80010128; + //public const uint CO_E_FAILEDTOSETDACL = 0x80010129; + //public const uint CO_E_ACCESSCHECKFAILED = 0x8001012A; + //public const uint CO_E_NETACCESSAPIFAILED = 0x8001012B; + //public const uint CO_E_WRONGTRUSTEENAMESYNTAX = 0x8001012C; + //public const uint CO_E_INVALIDSID = 0x8001012D; + //public const uint CO_E_CONVERSIONFAILED = 0x8001012E; + //public const uint CO_E_NOMATCHINGSIDFOUND = 0x8001012F; + //public const uint CO_E_LOOKUPACCSIDFAILED = 0x80010130; + //public const uint CO_E_NOMATCHINGNAMEFOUND = 0x80010131; + //public const uint CO_E_LOOKUPACCNAMEFAILED = 0x80010132; + //public const uint CO_E_SETSERLHNDLFAILED = 0x80010133; + //public const uint CO_E_FAILEDTOGETWINDIR = 0x80010134; + //public const uint CO_E_PATHTOOLONG = 0x80010135; + //public const uint CO_E_FAILEDTOGENUUID = 0x80010136; + //public const uint CO_E_FAILEDTOCREATEFILE = 0x80010137; + //public const uint CO_E_FAILEDTOCLOSEHANDLE = 0x80010138; + //public const uint CO_E_EXCEEDSYSACLLIMIT = 0x80010139; + //public const uint CO_E_ACESINWRONGORDER = 0x8001013A; + //public const uint CO_E_INCOMPATIBLESTREAMVERSION = 0x8001013B; + //public const uint CO_E_FAILEDTOOPENPROCESSTOKEN = 0x8001013C; + //public const uint CO_E_DECODEFAILED = 0x8001013D; + //public const uint CO_E_ACNOTINITIALIZED = 0x8001013F; + //public const uint CO_E_CANCEL_DISABLED = 0x80010140; + //public const uint RPC_E_UNEXPECTED = 0x8001FFFF; + //public const uint ERROR_AUDITING_DISABLED = 0xC0090001; + //public const uint ERROR_ALL_SIDS_FILTERED = 0xC0090002; + //public const uint NTE_BAD_UID = 0x80090001; + //public const uint NTE_BAD_HASH = 0x80090002; + //public const uint NTE_BAD_KEY = 0x80090003; + //public const uint NTE_BAD_LEN = 0x80090004; + //public const uint NTE_BAD_DATA = 0x80090005; + //public const uint NTE_BAD_SIGNATURE = 0x80090006; + //public const uint NTE_BAD_VER = 0x80090007; + //public const uint NTE_BAD_ALGID = 0x80090008; + //public const uint NTE_BAD_FLAGS = 0x80090009; + //public const uint NTE_BAD_TYPE = 0x8009000A; + //public const uint NTE_BAD_KEY_STATE = 0x8009000B; + //public const uint NTE_BAD_HASH_STATE = 0x8009000C; + //public const uint NTE_NO_KEY = 0x8009000D; + //public const uint NTE_NO_MEMORY = 0x8009000E; + //public const uint NTE_EXISTS = 0x8009000F; + //public const uint NTE_PERM = 0x80090010; + //public const uint NTE_NOT_FOUND = 0x80090011; + //public const uint NTE_DOUBLE_ENCRYPT = 0x80090012; + //public const uint NTE_BAD_PROVIDER = 0x80090013; + //public const uint NTE_BAD_PROV_TYPE = 0x80090014; + //public const uint NTE_BAD_PUBLIC_KEY = 0x80090015; + //public const uint NTE_BAD_KEYSET = 0x80090016; + //public const uint NTE_PROV_TYPE_NOT_DEF = 0x80090017; + //public const uint NTE_PROV_TYPE_ENTRY_BAD = 0x80090018; + //public const uint NTE_KEYSET_NOT_DEF = 0x80090019; + //public const uint NTE_KEYSET_ENTRY_BAD = 0x8009001A; + //public const uint NTE_PROV_TYPE_NO_MATCH = 0x8009001B; + //public const uint NTE_SIGNATURE_FILE_BAD = 0x8009001C; + //public const uint NTE_PROVIDER_DLL_FAIL = 0x8009001D; + //public const uint NTE_PROV_DLL_NOT_FOUND = 0x8009001E; + //public const uint NTE_BAD_KEYSET_PARAM = 0x8009001F; + //public const uint NTE_FAIL = 0x80090020; + //public const uint NTE_SYS_ERR = 0x80090021; + //public const uint NTE_SILENT_CONTEXT = 0x80090022; + //public const uint NTE_TOKEN_KEYSET_STORAGE_FULL = 0x80090023; + //public const uint NTE_TEMPORARY_PROFILE = 0x80090024; + //public const uint NTE_FIXEDPARAMETER = 0x80090025; + //public const uint SEC_E_INSUFFICIENT_MEMORY = 0x80090300; + //public const uint SEC_E_INVALID_HANDLE = 0x80090301; + //public const uint SEC_E_UNSUPPORTED_FUNCTION = 0x80090302; + //public const uint SEC_E_TARGET_UNKNOWN = 0x80090303; + //public const uint SEC_E_INTERNAL_ERROR = 0x80090304; + //public const uint SEC_E_SECPKG_NOT_FOUND = 0x80090305; + //public const uint SEC_E_NOT_OWNER = 0x80090306; + //public const uint SEC_E_CANNOT_INSTALL = 0x80090307; + //public const uint SEC_E_INVALID_TOKEN = 0x80090308; + //public const uint SEC_E_CANNOT_PACK = 0x80090309; + //public const uint SEC_E_QOP_NOT_SUPPORTED = 0x8009030A; + //public const uint SEC_E_NO_IMPERSONATION = 0x8009030B; + //public const uint SEC_E_LOGON_DENIED = 0x8009030C; + //public const uint SEC_E_UNKNOWN_CREDENTIALS = 0x8009030D; + //public const uint SEC_E_NO_CREDENTIALS = 0x8009030E; + //public const uint SEC_E_MESSAGE_ALTERED = 0x8009030F; + //public const uint SEC_E_OUT_OF_SEQUENCE = 0x80090310; + //public const uint SEC_E_NO_AUTHENTICATING_AUTHORITY = 0x80090311; + //public const uint SEC_I_CONTINUE_NEEDED = 0x00090312; + //public const uint SEC_I_COMPLETE_NEEDED = 0x00090313; + //public const uint SEC_I_COMPLETE_AND_CONTINUE = 0x00090314; + //public const uint SEC_I_LOCAL_LOGON = 0x00090315; + //public const uint SEC_E_BAD_PKGID = 0x80090316; + //public const uint SEC_E_CONTEXT_EXPIRED = 0x80090317; + //public const uint SEC_I_CONTEXT_EXPIRED = 0x00090317; + //public const uint SEC_E_INCOMPLETE_MESSAGE = 0x80090318; + //public const uint SEC_E_INCOMPLETE_CREDENTIALS = 0x80090320; + //public const uint SEC_E_BUFFER_TOO_SMALL = 0x80090321; + //public const uint SEC_I_INCOMPLETE_CREDENTIALS = 0x00090320; + //public const uint SEC_I_RENEGOTIATE = 0x00090321; + //public const uint SEC_E_WRONG_PRINCIPAL = 0x80090322; + //public const uint SEC_I_NO_LSA_CONTEXT = 0x00090323; + //public const uint SEC_E_TIME_SKEW = 0x80090324; + //public const uint SEC_E_UNTRUSTED_ROOT = 0x80090325; + //public const uint SEC_E_ILLEGAL_MESSAGE = 0x80090326; + //public const uint SEC_E_CERT_UNKNOWN = 0x80090327; + //public const uint SEC_E_CERT_EXPIRED = 0x80090328; + //public const uint SEC_E_ENCRYPT_FAILURE = 0x80090329; + //public const uint SEC_E_DECRYPT_FAILURE = 0x80090330; + //public const uint SEC_E_ALGORITHM_MISMATCH = 0x80090331; + //public const uint SEC_E_SECURITY_QOS_FAILED = 0x80090332; + //public const uint SEC_E_UNFINISHED_CONTEXT_DELETED = 0x80090333; + //public const uint SEC_E_NO_TGT_REPLY = 0x80090334; + //public const uint SEC_E_NO_IP_ADDRESSES = 0x80090335; + //public const uint SEC_E_WRONG_CREDENTIAL_HANDLE = 0x80090336; + //public const uint SEC_E_CRYPTO_SYSTEM_INVALID = 0x80090337; + //public const uint SEC_E_MAX_REFERRALS_EXCEEDED = 0x80090338; + //public const uint SEC_E_MUST_BE_KDC = 0x80090339; + //public const uint SEC_E_STRONG_CRYPTO_NOT_SUPPORTED = 0x8009033A; + //public const uint SEC_E_TOO_MANY_PRINCIPALS = 0x8009033B; + //public const uint SEC_E_NO_PA_DATA = 0x8009033C; + //public const uint SEC_E_PKINIT_NAME_MISMATCH = 0x8009033D; + //public const uint SEC_E_SMARTCARD_LOGON_REQUIRED = 0x8009033E; + //public const uint SEC_E_SHUTDOWN_IN_PROGRESS = 0x8009033F; + //public const uint SEC_E_KDC_INVALID_REQUEST = 0x80090340; + //public const uint SEC_E_KDC_UNABLE_TO_REFER = 0x80090341; + //public const uint SEC_E_KDC_UNKNOWN_ETYPE = 0x80090342; + //public const uint SEC_E_UNSUPPORTED_PREAUTH = 0x80090343; + //public const uint SEC_E_DELEGATION_REQUIRED = 0x80090345; + //public const uint SEC_E_BAD_BINDINGS = 0x80090346; + //public const uint SEC_E_MULTIPLE_ACCOUNTS = 0x80090347; + //public const uint SEC_E_NO_KERB_KEY = 0x80090348; + //public const uint SEC_E_CERT_WRONG_USAGE = 0x80090349; + //public const uint SEC_E_DOWNGRADE_DETECTED = 0x80090350; + //public const uint SEC_E_SMARTCARD_CERT_REVOKED = 0x80090351; + //public const uint SEC_E_ISSUING_CA_UNTRUSTED = 0x80090352; + //public const uint SEC_E_REVOCATION_OFFLINE_C = 0x80090353; + //public const uint SEC_E_PKINIT_CLIENT_FAILURE = 0x80090354; + //public const uint SEC_E_SMARTCARD_CERT_EXPIRED = 0x80090355; + //public const uint SEC_E_NO_S4U_PROT_SUPPORT = 0x80090356; + //public const uint SEC_E_CROSSREALM_DELEGATION_FAILURE = 0x80090357; + //public const uint SEC_E_REVOCATION_OFFLINE_KDC = 0x80090358; + //public const uint SEC_E_ISSUING_CA_UNTRUSTED_KDC = 0x80090359; + //public const uint SEC_E_KDC_CERT_EXPIRED = 0x8009035A; + //public const uint SEC_E_KDC_CERT_REVOKED = 0x8009035B; + //public const uint SEC_E_NO_SPM = SEC_E_INTERNAL_ERROR; + //public const uint SEC_E_NOT_SUPPORTED = SEC_E_UNSUPPORTED_FUNCTION; + //public const uint CRYPT_E_MSG_ERROR = 0x80091001; + //public const uint CRYPT_E_UNKNOWN_ALGO = 0x80091002; + //public const uint CRYPT_E_OID_FORMAT = 0x80091003; + //public const uint CRYPT_E_INVALID_MSG_TYPE = 0x80091004; + //public const uint CRYPT_E_UNEXPECTED_ENCODING = 0x80091005; + //public const uint CRYPT_E_AUTH_ATTR_MISSING = 0x80091006; + //public const uint CRYPT_E_HASH_VALUE = 0x80091007; + //public const uint CRYPT_E_INVALID_INDEX = 0x80091008; + //public const uint CRYPT_E_ALREADY_DECRYPTED = 0x80091009; + //public const uint CRYPT_E_NOT_DECRYPTED = 0x8009100A; + //public const uint CRYPT_E_RECIPIENT_NOT_FOUND = 0x8009100B; + //public const uint CRYPT_E_CONTROL_TYPE = 0x8009100C; + //public const uint CRYPT_E_ISSUER_SERIALNUMBER = 0x8009100D; + //public const uint CRYPT_E_SIGNER_NOT_FOUND = 0x8009100E; + //public const uint CRYPT_E_ATTRIBUTES_MISSING = 0x8009100F; + //public const uint CRYPT_E_STREAM_MSG_NOT_READY = 0x80091010; + //public const uint CRYPT_E_STREAM_INSUFFICIENT_DATA = 0x80091011; + //public const uint CRYPT_I_NEW_PROTECTION_REQUIRED = 0x00091012; + //public const uint CRYPT_E_BAD_LEN = 0x80092001; + //public const uint CRYPT_E_BAD_ENCODE = 0x80092002; + //public const uint CRYPT_E_FILE_ERROR = 0x80092003; + //public const uint CRYPT_E_NOT_FOUND = 0x80092004; + //public const uint CRYPT_E_EXISTS = 0x80092005; + //public const uint CRYPT_E_NO_PROVIDER = 0x80092006; + //public const uint CRYPT_E_SELF_SIGNED = 0x80092007; + //public const uint CRYPT_E_DELETED_PREV = 0x80092008; + //public const uint CRYPT_E_NO_MATCH = 0x80092009; + //public const uint CRYPT_E_UNEXPECTED_MSG_TYPE = 0x8009200A; + //public const uint CRYPT_E_NO_KEY_PROPERTY = 0x8009200B; + //public const uint CRYPT_E_NO_DECRYPT_CERT = 0x8009200C; + //public const uint CRYPT_E_BAD_MSG = 0x8009200D; + //public const uint CRYPT_E_NO_SIGNER = 0x8009200E; + //public const uint CRYPT_E_PENDING_CLOSE = 0x8009200F; + //public const uint CRYPT_E_REVOKED = 0x80092010; + //public const uint CRYPT_E_NO_REVOCATION_DLL = 0x80092011; + //public const uint CRYPT_E_NO_REVOCATION_CHECK = 0x80092012; + //public const uint CRYPT_E_REVOCATION_OFFLINE = 0x80092013; + //public const uint CRYPT_E_NOT_IN_REVOCATION_DATABASE = 0x80092014; + //public const uint CRYPT_E_INVALID_NUMERIC_STRING = 0x80092020; + //public const uint CRYPT_E_INVALID_PRINTABLE_STRING = 0x80092021; + //public const uint CRYPT_E_INVALID_IA5_STRING = 0x80092022; + //public const uint CRYPT_E_INVALID_X500_STRING = 0x80092023; + //public const uint CRYPT_E_NOT_CHAR_STRING = 0x80092024; + //public const uint CRYPT_E_FILERESIZED = 0x80092025; + //public const uint CRYPT_E_SECURITY_SETTINGS = 0x80092026; + //public const uint CRYPT_E_NO_VERIFY_USAGE_DLL = 0x80092027; + //public const uint CRYPT_E_NO_VERIFY_USAGE_CHECK = 0x80092028; + //public const uint CRYPT_E_VERIFY_USAGE_OFFLINE = 0x80092029; + //public const uint CRYPT_E_NOT_IN_CTL = 0x8009202A; + //public const uint CRYPT_E_NO_TRUSTED_SIGNER = 0x8009202B; + //public const uint CRYPT_E_MISSING_PUBKEY_PARA = 0x8009202C; + //public const uint CRYPT_E_OSS_ERROR = 0x80093000; + //public const uint OSS_MORE_BUF = 0x80093001; + //public const uint OSS_NEGATIVE_longEGER = 0x80093002; + //public const uint OSS_PDU_RANGE = 0x80093003; + //public const uint OSS_MORE_INPUT = 0x80093004; + //public const uint OSS_DATA_ERROR = 0x80093005; + //public const uint OSS_BAD_ARG = 0x80093006; + //public const uint OSS_BAD_VERSION = 0x80093007; + //public const uint OSS_OUT_MEMORY = 0x80093008; + //public const uint OSS_PDU_MISMATCH = 0x80093009; + //public const uint OSS_LIMITED = 0x8009300A; + //public const uint OSS_BAD_PTR = 0x8009300B; + //public const uint OSS_BAD_TIME = 0x8009300C; + //public const uint OSS_INDEFINITE_NOT_SUPPORTED = 0x8009300D; + //public const uint OSS_MEM_ERROR = 0x8009300E; + //public const uint OSS_BAD_TABLE = 0x8009300F; + //public const uint OSS_TOO_LONG = 0x80093010; + //public const uint OSS_CONSTRAINT_VIOLATED = 0x80093011; + //public const uint OSS_FATAL_ERROR = 0x80093012; + //public const uint OSS_ACCESS_SERIALIZATION_ERROR = 0x80093013; + //public const uint OSS_NULL_TBL = 0x80093014; + //public const uint OSS_NULL_FCN = 0x80093015; + //public const uint OSS_BAD_ENCRULES = 0x80093016; + //public const uint OSS_UNAVAIL_ENCRULES = 0x80093017; + //public const uint OSS_CANT_OPEN_TRACE_WINDOW = 0x80093018; + //public const uint OSS_UNIMPLEMENTED = 0x80093019; + //public const uint OSS_OID_DLL_NOT_LINKED = 0x8009301A; + //public const uint OSS_CANT_OPEN_TRACE_FILE = 0x8009301B; + //public const uint OSS_TRACE_FILE_ALREADY_OPEN = 0x8009301C; + //public const uint OSS_TABLE_MISMATCH = 0x8009301D; + //public const uint OSS_TYPE_NOT_SUPPORTED = 0x8009301E; + //public const uint OSS_REAL_DLL_NOT_LINKED = 0x8009301F; + //public const uint OSS_REAL_CODE_NOT_LINKED = 0x80093020; + //public const uint OSS_OUT_OF_RANGE = 0x80093021; + //public const uint OSS_COPIER_DLL_NOT_LINKED = 0x80093022; + //public const uint OSS_CONSTRAINT_DLL_NOT_LINKED = 0x80093023; + //public const uint OSS_COMPARATOR_DLL_NOT_LINKED = 0x80093024; + //public const uint OSS_COMPARATOR_CODE_NOT_LINKED = 0x80093025; + //public const uint OSS_MEM_MGR_DLL_NOT_LINKED = 0x80093026; + //public const uint OSS_PDV_DLL_NOT_LINKED = 0x80093027; + //public const uint OSS_PDV_CODE_NOT_LINKED = 0x80093028; + //public const uint OSS_API_DLL_NOT_LINKED = 0x80093029; + //public const uint OSS_BERDER_DLL_NOT_LINKED = 0x8009302A; + //public const uint OSS_PER_DLL_NOT_LINKED = 0x8009302B; + //public const uint OSS_OPEN_TYPE_ERROR = 0x8009302C; + //public const uint OSS_MUTEX_NOT_CREATED = 0x8009302D; + //public const uint OSS_CANT_CLOSE_TRACE_FILE = 0x8009302E; + //public const uint CRYPT_E_ASN1_ERROR = 0x80093100; + //public const uint CRYPT_E_ASN1_INTERNAL = 0x80093101; + //public const uint CRYPT_E_ASN1_EOD = 0x80093102; + //public const uint CRYPT_E_ASN1_CORRUPT = 0x80093103; + //public const uint CRYPT_E_ASN1_LARGE = 0x80093104; + //public const uint CRYPT_E_ASN1_CONSTRAINT = 0x80093105; + //public const uint CRYPT_E_ASN1_MEMORY = 0x80093106; + //public const uint CRYPT_E_ASN1_OVERFLOW = 0x80093107; + //public const uint CRYPT_E_ASN1_BADPDU = 0x80093108; + //public const uint CRYPT_E_ASN1_BADARGS = 0x80093109; + //public const uint CRYPT_E_ASN1_BADREAL = 0x8009310A; + //public const uint CRYPT_E_ASN1_BADTAG = 0x8009310B; + //public const uint CRYPT_E_ASN1_CHOICE = 0x8009310C; + //public const uint CRYPT_E_ASN1_RULE = 0x8009310D; + //public const uint CRYPT_E_ASN1_UTF8 = 0x8009310E; + //public const uint CRYPT_E_ASN1_PDU_TYPE = 0x80093133; + //public const uint CRYPT_E_ASN1_NYI = 0x80093134; + //public const uint CRYPT_E_ASN1_EXTENDED = 0x80093201; + //public const uint CRYPT_E_ASN1_NOEOD = 0x80093202; + //public const uint CERTSRV_E_BAD_REQUESTSUBJECT = 0x80094001; + //public const uint CERTSRV_E_NO_REQUEST = 0x80094002; + //public const uint CERTSRV_E_BAD_REQUESTSTATUS = 0x80094003; + //public const uint CERTSRV_E_PROPERTY_EMPTY = 0x80094004; + //public const uint CERTSRV_E_INVALID_CA_CERTIFICATE = 0x80094005; + //public const uint CERTSRV_E_SERVER_SUSPENDED = 0x80094006; + //public const uint CERTSRV_E_ENCODING_LENGTH = 0x80094007; + //public const uint CERTSRV_E_ROLECONFLICT = 0x80094008; + //public const uint CERTSRV_E_RESTRICTEDOFFICER = 0x80094009; + //public const uint CERTSRV_E_KEY_ARCHIVAL_NOT_CONFIGURED = 0x8009400A; + //public const uint CERTSRV_E_NO_VALID_KRA = 0x8009400B; + //public const uint CERTSRV_E_BAD_REQUEST_KEY_ARCHIVAL = 0x8009400C; + //public const uint CERTSRV_E_NO_CAADMIN_DEFINED = 0x8009400D; + //public const uint CERTSRV_E_BAD_RENEWAL_CERT_ATTRIBUTE = 0x8009400E; + //public const uint CERTSRV_E_NO_DB_SESSIONS = 0x8009400F; + //public const uint CERTSRV_E_ALIGNMENT_FAULT = 0x80094010; + //public const uint CERTSRV_E_ENROLL_DENIED = 0x80094011; + //public const uint CERTSRV_E_TEMPLATE_DENIED = 0x80094012; + //public const uint CERTSRV_E_DOWNLEVEL_DC_SSL_OR_UPGRADE = 0x80094013; + //public const uint CERTSRV_E_UNSUPPORTED_CERT_TYPE = 0x80094800; + //public const uint CERTSRV_E_NO_CERT_TYPE = 0x80094801; + //public const uint CERTSRV_E_TEMPLATE_CONFLICT = 0x80094802; + //public const uint CERTSRV_E_SUBJECT_ALT_NAME_REQUIRED = 0x80094803; + //public const uint CERTSRV_E_ARCHIVED_KEY_REQUIRED = 0x80094804; + //public const uint CERTSRV_E_SMIME_REQUIRED = 0x80094805; + //public const uint CERTSRV_E_BAD_RENEWAL_SUBJECT = 0x80094806; + //public const uint CERTSRV_E_BAD_TEMPLATE_VERSION = 0x80094807; + //public const uint CERTSRV_E_TEMPLATE_POLICY_REQUIRED = 0x80094808; + //public const uint CERTSRV_E_SIGNATURE_POLICY_REQUIRED = 0x80094809; + //public const uint CERTSRV_E_SIGNATURE_COUNT = 0x8009480A; + //public const uint CERTSRV_E_SIGNATURE_REJECTED = 0x8009480B; + //public const uint CERTSRV_E_ISSUANCE_POLICY_REQUIRED = 0x8009480C; + //public const uint CERTSRV_E_SUBJECT_UPN_REQUIRED = 0x8009480D; + //public const uint CERTSRV_E_SUBJECT_DIRECTORY_GUID_REQUIRED = 0x8009480E; + //public const uint CERTSRV_E_SUBJECT_DNS_REQUIRED = 0x8009480F; + //public const uint CERTSRV_E_ARCHIVED_KEY_UNEXPECTED = 0x80094810; + //public const uint CERTSRV_E_KEY_LENGTH = 0x80094811; + //public const uint CERTSRV_E_SUBJECT_EMAIL_REQUIRED = 0x80094812; + //public const uint CERTSRV_E_UNKNOWN_CERT_TYPE = 0x80094813; + //public const uint CERTSRV_E_CERT_TYPE_OVERLAP = 0x80094814; + //public const uint XENROLL_E_KEY_NOT_EXPORTABLE = 0x80095000; + //public const uint XENROLL_E_CANNOT_ADD_ROOT_CERT = 0x80095001; + //public const uint XENROLL_E_RESPONSE_KA_HASH_NOT_FOUND = 0x80095002; + //public const uint XENROLL_E_RESPONSE_UNEXPECTED_KA_HASH = 0x80095003; + //public const uint XENROLL_E_RESPONSE_KA_HASH_MISMATCH = 0x80095004; + //public const uint XENROLL_E_KEYSPEC_SMIME_MISMATCH = 0x80095005; + //public const uint TRUST_E_SYSTEM_ERROR = 0x80096001; + //public const uint TRUST_E_NO_SIGNER_CERT = 0x80096002; + //public const uint TRUST_E_COUNTER_SIGNER = 0x80096003; + //public const uint TRUST_E_CERT_SIGNATURE = 0x80096004; + //public const uint TRUST_E_TIME_STAMP = 0x80096005; + //public const uint TRUST_E_BAD_DIGEST = 0x80096010; + //public const uint TRUST_E_BASIC_CONSTRAINTS = 0x80096019; + //public const uint TRUST_E_FINANCIAL_CRITERIA = 0x8009601E; + //public const uint MSSIPOTF_E_OUTOFMEMRANGE = 0x80097001; + //public const uint MSSIPOTF_E_CANTGETOBJECT = 0x80097002; + //public const uint MSSIPOTF_E_NOHEADTABLE = 0x80097003; + //public const uint MSSIPOTF_E_BAD_MAGICNUMBER = 0x80097004; + //public const uint MSSIPOTF_E_BAD_OFFSET_TABLE = 0x80097005; + //public const uint MSSIPOTF_E_TABLE_TAGORDER = 0x80097006; + //public const uint MSSIPOTF_E_TABLE_LONGWORD = 0x80097007; + //public const uint MSSIPOTF_E_BAD_FIRST_TABLE_PLACEMENT = 0x80097008; + //public const uint MSSIPOTF_E_TABLES_OVERLAP = 0x80097009; + //public const uint MSSIPOTF_E_TABLE_PADBYTES = 0x8009700A; + //public const uint MSSIPOTF_E_FILETOOSMALL = 0x8009700B; + //public const uint MSSIPOTF_E_TABLE_CHECKSUM = 0x8009700C; + //public const uint MSSIPOTF_E_FILE_CHECKSUM = 0x8009700D; + //public const uint MSSIPOTF_E_FAILED_POLICY = 0x80097010; + //public const uint MSSIPOTF_E_FAILED_HINTS_CHECK = 0x80097011; + //public const uint MSSIPOTF_E_NOT_OPENTYPE = 0x80097012; + //public const uint MSSIPOTF_E_FILE = 0x80097013; + //public const uint MSSIPOTF_E_CRYPT = 0x80097014; + //public const uint MSSIPOTF_E_BADVERSION = 0x80097015; + //public const uint MSSIPOTF_E_DSIG_STRUCTURE = 0x80097016; + //public const uint MSSIPOTF_E_PCONST_CHECK = 0x80097017; + //public const uint MSSIPOTF_E_STRUCTURE = 0x80097018; + //public const uint NTE_OP_OK = 0; + //public const uint TRUST_E_PROVIDER_UNKNOWN = 0x800B0001; + //public const uint TRUST_E_ACTION_UNKNOWN = 0x800B0002; + //public const uint TRUST_E_SUBJECT_FORM_UNKNOWN = 0x800B0003; + //public const uint TRUST_E_SUBJECT_NOT_TRUSTED = 0x800B0004; + //public const uint DIGSIG_E_ENCODE = 0x800B0005; + //public const uint DIGSIG_E_DECODE = 0x800B0006; + //public const uint DIGSIG_E_EXTENSIBILITY = 0x800B0007; + //public const uint DIGSIG_E_CRYPTO = 0x800B0008; + //public const uint PERSIST_E_SIZEDEFINITE = 0x800B0009; + //public const uint PERSIST_E_SIZEINDEFINITE = 0x800B000A; + //public const uint PERSIST_E_NOTSELFSIZING = 0x800B000B; + //public const uint TRUST_E_NOSIGNATURE = 0x800B0100; + //public const uint CERT_E_EXPIRED = 0x800B0101; + //public const uint CERT_E_VALIDITYPERIODNESTING = 0x800B0102; + //public const uint CERT_E_ROLE = 0x800B0103; + //public const uint CERT_E_PATHLENCONST = 0x800B0104; + //public const uint CERT_E_CRITICAL = 0x800B0105; + //public const uint CERT_E_PURPOSE = 0x800B0106; + //public const uint CERT_E_ISSUERCHAINING = 0x800B0107; + //public const uint CERT_E_MALFORMED = 0x800B0108; + //public const uint CERT_E_UNTRUSTEDROOT = 0x800B0109; + //public const uint CERT_E_CHAINING = 0x800B010A; + //public const uint TRUST_E_FAIL = 0x800B010B; + //public const uint CERT_E_REVOKED = 0x800B010C; + //public const uint CERT_E_UNTRUSTEDTESTROOT = 0x800B010D; + //public const uint CERT_E_REVOCATION_FAILURE = 0x800B010E; + //public const uint CERT_E_CN_NO_MATCH = 0x800B010F; + //public const uint CERT_E_WRONG_USAGE = 0x800B0110; + //public const uint TRUST_E_EXPLICIT_DISTRUST = 0x800B0111; + //public const uint CERT_E_UNTRUSTEDCA = 0x800B0112; + //public const uint CERT_E_INVALID_POLICY = 0x800B0113; + //public const uint CERT_E_INVALID_NAME = 0x800B0114; + //public const uint SPAPI_E_EXPECTED_SECTION_NAME = 0x800F0000; + //public const uint SPAPI_E_BAD_SECTION_NAME_LINE = 0x800F0001; + //public const uint SPAPI_E_SECTION_NAME_TOO_LONG = 0x800F0002; + //public const uint SPAPI_E_GENERAL_SYNTAX = 0x800F0003; + //public const uint SPAPI_E_WRONG_INF_STYLE = 0x800F0100; + //public const uint SPAPI_E_SECTION_NOT_FOUND = 0x800F0101; + //public const uint SPAPI_E_LINE_NOT_FOUND = 0x800F0102; + //public const uint SPAPI_E_NO_BACKUP = 0x800F0103; + //public const uint SPAPI_E_NO_ASSOCIATED_CLASS = 0x800F0200; + //public const uint SPAPI_E_CLASS_MISMATCH = 0x800F0201; + //public const uint SPAPI_E_DUPLICATE_FOUND = 0x800F0202; + //public const uint SPAPI_E_NO_DRIVER_SELECTED = 0x800F0203; + //public const uint SPAPI_E_KEY_DOES_NOT_EXIST = 0x800F0204; + //public const uint SPAPI_E_INVALID_DEVINST_NAME = 0x800F0205; + //public const uint SPAPI_E_INVALID_CLASS = 0x800F0206; + //public const uint SPAPI_E_DEVINST_ALREADY_EXISTS = 0x800F0207; + //public const uint SPAPI_E_DEVINFO_NOT_REGISTERED = 0x800F0208; + //public const uint SPAPI_E_INVALID_REG_PROPERTY = 0x800F0209; + //public const uint SPAPI_E_NO_INF = 0x800F020A; + //public const uint SPAPI_E_NO_SUCH_DEVINST = 0x800F020B; + //public const uint SPAPI_E_CANT_LOAD_CLASS_ICON = 0x800F020C; + //public const uint SPAPI_E_INVALID_CLASS_INSTALLER = 0x800F020D; + //public const uint SPAPI_E_DI_DO_DEFAULT = 0x800F020E; + //public const uint SPAPI_E_DI_NOFILECOPY = 0x800F020F; + //public const uint SPAPI_E_INVALID_HWPROFILE = 0x800F0210; + //public const uint SPAPI_E_NO_DEVICE_SELECTED = 0x800F0211; + //public const uint SPAPI_E_DEVINFO_LIST_LOCKED = 0x800F0212; + //public const uint SPAPI_E_DEVINFO_DATA_LOCKED = 0x800F0213; + //public const uint SPAPI_E_DI_BAD_PATH = 0x800F0214; + //public const uint SPAPI_E_NO_CLASSINSTALL_PARAMS = 0x800F0215; + //public const uint SPAPI_E_FILEQUEUE_LOCKED = 0x800F0216; + //public const uint SPAPI_E_BAD_SERVICE_INSTALLSECT = 0x800F0217; + //public const uint SPAPI_E_NO_CLASS_DRIVER_LIST = 0x800F0218; + //public const uint SPAPI_E_NO_ASSOCIATED_SERVICE = 0x800F0219; + //public const uint SPAPI_E_NO_DEFAULT_DEVICE_INTERFACE = 0x800F021A; + //public const uint SPAPI_E_DEVICE_INTERFACE_ACTIVE = 0x800F021B; + //public const uint SPAPI_E_DEVICE_INTERFACE_REMOVED = 0x800F021C; + //public const uint SPAPI_E_BAD_INTERFACE_INSTALLSECT = 0x800F021D; + //public const uint SPAPI_E_NO_SUCH_INTERFACE_CLASS = 0x800F021E; + //public const uint SPAPI_E_INVALID_REFERENCE_STRING = 0x800F021F; + //public const uint SPAPI_E_INVALID_MACHINENAME = 0x800F0220; + //public const uint SPAPI_E_REMOTE_COMM_FAILURE = 0x800F0221; + //public const uint SPAPI_E_MACHINE_UNAVAILABLE = 0x800F0222; + //public const uint SPAPI_E_NO_CONFIGMGR_SERVICES = 0x800F0223; + //public const uint SPAPI_E_INVALID_PROPPAGE_PROVIDER = 0x800F0224; + //public const uint SPAPI_E_NO_SUCH_DEVICE_INTERFACE = 0x800F0225; + //public const uint SPAPI_E_DI_POSTPROCESSING_REQUIRED = 0x800F0226; + //public const uint SPAPI_E_INVALID_COINSTALLER = 0x800F0227; + //public const uint SPAPI_E_NO_COMPAT_DRIVERS = 0x800F0228; + //public const uint SPAPI_E_NO_DEVICE_ICON = 0x800F0229; + //public const uint SPAPI_E_INVALID_INF_LOGCONFIG = 0x800F022A; + //public const uint SPAPI_E_DI_DONT_INSTALL = 0x800F022B; + //public const uint SPAPI_E_INVALID_FILTER_DRIVER = 0x800F022C; + //public const uint SPAPI_E_NON_WINDOWS_NT_DRIVER = 0x800F022D; + //public const uint SPAPI_E_NON_WINDOWS_DRIVER = 0x800F022E; + //public const uint SPAPI_E_NO_CATALOG_FOR_OEM_INF = 0x800F022F; + //public const uint SPAPI_E_DEVINSTALL_QUEUE_NONNATIVE = 0x800F0230; + //public const uint SPAPI_E_NOT_DISABLEABLE = 0x800F0231; + //public const uint SPAPI_E_CANT_REMOVE_DEVINST = 0x800F0232; + //public const uint SPAPI_E_INVALID_TARGET = 0x800F0233; + //public const uint SPAPI_E_DRIVER_NONNATIVE = 0x800F0234; + //public const uint SPAPI_E_IN_WOW64 = 0x800F0235; + //public const uint SPAPI_E_SET_SYSTEM_RESTORE_POINT = 0x800F0236; + //public const uint SPAPI_E_INCORRECTLY_COPIED_INF = 0x800F0237; + //public const uint SPAPI_E_SCE_DISABLED = 0x800F0238; + //public const uint SPAPI_E_UNKNOWN_EXCEPTION = 0x800F0239; + //public const uint SPAPI_E_PNP_REGISTRY_ERROR = 0x800F023A; + //public const uint SPAPI_E_REMOTE_REQUEST_UNSUPPORTED = 0x800F023B; + //public const uint SPAPI_E_NOT_AN_INSTALLED_OEM_INF = 0x800F023C; + //public const uint SPAPI_E_INF_IN_USE_BY_DEVICES = 0x800F023D; + //public const uint SPAPI_E_DI_FUNCTION_OBSOLETE = 0x800F023E; + //public const uint SPAPI_E_NO_AUTHENTICODE_CATALOG = 0x800F023F; + //public const uint SPAPI_E_AUTHENTICODE_DISALLOWED = 0x800F0240; + //public const uint SPAPI_E_AUTHENTICODE_TRUSTED_PUBLISHER = 0x800F0241; + //public const uint SPAPI_E_AUTHENTICODE_TRUST_NOT_ESTABLISHED = 0x800F0242; + //public const uint SPAPI_E_AUTHENTICODE_PUBLISHER_NOT_TRUSTED = 0x800F0243; + //public const uint SPAPI_E_SIGNATURE_OSATTRIBUTE_MISMATCH = 0x800F0244; + //public const uint SPAPI_E_ONLY_VALIDATE_VIA_AUTHENTICODE = 0x800F0245; + //public const uint SPAPI_E_UNRECOVERABLE_STACK_OVERFLOW = 0x800F0300; + //public const uint SPAPI_E_ERROR_NOT_INSTALLED = 0x800F1000; + //public const uint SCARD_S_SUCCESS = NO_ERROR; + //public const uint SCARD_F_INTERNAL_ERROR = 0x80100001; + //public const uint SCARD_E_CANCELLED = 0x80100002; + //public const uint SCARD_E_INVALID_HANDLE = 0x80100003; + //public const uint SCARD_E_INVALID_PARAMETER = 0x80100004; + //public const uint SCARD_E_INVALID_TARGET = 0x80100005; + //public const uint SCARD_E_NO_MEMORY = 0x80100006; + //public const uint SCARD_F_WAITED_TOO_LONG = 0x80100007; + //public const uint SCARD_E_INSUFFICIENT_BUFFER = 0x80100008; + //public const uint SCARD_E_UNKNOWN_READER = 0x80100009; + //public const uint SCARD_E_TIMEOUT = 0x8010000A; + //public const uint SCARD_E_SHARING_VIOLATION = 0x8010000B; + //public const uint SCARD_E_NO_SMARTCARD = 0x8010000C; + //public const uint SCARD_E_UNKNOWN_CARD = 0x8010000D; + //public const uint SCARD_E_CANT_DISPOSE = 0x8010000E; + //public const uint SCARD_E_PROTO_MISMATCH = 0x8010000F; + //public const uint SCARD_E_NOT_READY = 0x80100010; + //public const uint SCARD_E_INVALID_VALUE = 0x80100011; + //public const uint SCARD_E_SYSTEM_CANCELLED = 0x80100012; + //public const uint SCARD_F_COMM_ERROR = 0x80100013; + //public const uint SCARD_F_UNKNOWN_ERROR = 0x80100014; + //public const uint SCARD_E_INVALID_ATR = 0x80100015; + //public const uint SCARD_E_NOT_TRANSACTED = 0x80100016; + //public const uint SCARD_E_READER_UNAVAILABLE = 0x80100017; + //public const uint SCARD_P_SHUTDOWN = 0x80100018; + //public const uint SCARD_E_PCI_TOO_SMALL = 0x80100019; + //public const uint SCARD_E_READER_UNSUPPORTED = 0x8010001A; + //public const uint SCARD_E_DUPLICATE_READER = 0x8010001B; + //public const uint SCARD_E_CARD_UNSUPPORTED = 0x8010001C; + //public const uint SCARD_E_NO_SERVICE = 0x8010001D; + //public const uint SCARD_E_SERVICE_STOPPED = 0x8010001E; + //public const uint SCARD_E_UNEXPECTED = 0x8010001F; + //public const uint SCARD_E_ICC_INSTALLATION = 0x80100020; + //public const uint SCARD_E_ICC_CREATEORDER = 0x80100021; + //public const uint SCARD_E_UNSUPPORTED_FEATURE = 0x80100022; + //public const uint SCARD_E_DIR_NOT_FOUND = 0x80100023; + //public const uint SCARD_E_FILE_NOT_FOUND = 0x80100024; + //public const uint SCARD_E_NO_DIR = 0x80100025; + //public const uint SCARD_E_NO_FILE = 0x80100026; + //public const uint SCARD_E_NO_ACCESS = 0x80100027; + //public const uint SCARD_E_WRITE_TOO_MANY = 0x80100028; + //public const uint SCARD_E_BAD_SEEK = 0x80100029; + //public const uint SCARD_E_INVALID_CHV = 0x8010002A; + //public const uint SCARD_E_UNKNOWN_RES_MNG = 0x8010002B; + //public const uint SCARD_E_NO_SUCH_CERTIFICATE = 0x8010002C; + //public const uint SCARD_E_CERTIFICATE_UNAVAILABLE = 0x8010002D; + //public const uint SCARD_E_NO_READERS_AVAILABLE = 0x8010002E; + //public const uint SCARD_E_COMM_DATA_LOST = 0x8010002F; + //public const uint SCARD_E_NO_KEY_CONTAINER = 0x80100030; + //public const uint SCARD_E_SERVER_TOO_BUSY = 0x80100031; + //public const uint SCARD_W_UNSUPPORTED_CARD = 0x80100065; + //public const uint SCARD_W_UNRESPONSIVE_CARD = 0x80100066; + //public const uint SCARD_W_UNPOWERED_CARD = 0x80100067; + //public const uint SCARD_W_RESET_CARD = 0x80100068; + //public const uint SCARD_W_REMOVED_CARD = 0x80100069; + //public const uint SCARD_W_SECURITY_VIOLATION = 0x8010006A; + //public const uint SCARD_W_WRONG_CHV = 0x8010006B; + //public const uint SCARD_W_CHV_BLOCKED = 0x8010006C; + //public const uint SCARD_W_EOF = 0x8010006D; + //public const uint SCARD_W_CANCELLED_BY_USER = 0x8010006E; + //public const uint SCARD_W_CARD_NOT_AUTHENTICATED = 0x8010006F; + //public const uint COMADMIN_E_OBJECTERRORS = 0x80110401; + //public const uint COMADMIN_E_OBJECTINVALID = 0x80110402; + //public const uint COMADMIN_E_KEYMISSING = 0x80110403; + //public const uint COMADMIN_E_ALREADYINSTALLED = 0x80110404; + //public const uint COMADMIN_E_APP_FILE_WRITEFAIL = 0x80110407; + //public const uint COMADMIN_E_APP_FILE_READFAIL = 0x80110408; + //public const uint COMADMIN_E_APP_FILE_VERSION = 0x80110409; + //public const uint COMADMIN_E_BADPATH = 0x8011040A; + //public const uint COMADMIN_E_APPLICATIONEXISTS = 0x8011040B; + //public const uint COMADMIN_E_ROLEEXISTS = 0x8011040C; + //public const uint COMADMIN_E_CANTCOPYFILE = 0x8011040D; + //public const uint COMADMIN_E_NOUSER = 0x8011040F; + //public const uint COMADMIN_E_INVALIDUSERIDS = 0x80110410; + //public const uint COMADMIN_E_NOREGISTRYCLSID = 0x80110411; + //public const uint COMADMIN_E_BADREGISTRYPROGID = 0x80110412; + //public const uint COMADMIN_E_AUTHENTICATIONLEVEL = 0x80110413; + //public const uint COMADMIN_E_USERPASSWDNOTVALID = 0x80110414; + //public const uint COMADMIN_E_CLSIDORIIDMISMATCH = 0x80110418; + //public const uint COMADMIN_E_REMOTEINTERFACE = 0x80110419; + //public const uint COMADMIN_E_DLLREGISTERSERVER = 0x8011041A; + //public const uint COMADMIN_E_NOSERVERSHARE = 0x8011041B; + //public const uint COMADMIN_E_DLLLOADFAILED = 0x8011041D; + //public const uint COMADMIN_E_BADREGISTRYLIBID = 0x8011041E; + //public const uint COMADMIN_E_APPDIRNOTFOUND = 0x8011041F; + //public const uint COMADMIN_E_REGISTRARFAILED = 0x80110423; + //public const uint COMADMIN_E_COMPFILE_DOESNOTEXIST = 0x80110424; + //public const uint COMADMIN_E_COMPFILE_LOADDLLFAIL = 0x80110425; + //public const uint COMADMIN_E_COMPFILE_GETCLASSOBJ = 0x80110426; + //public const uint COMADMIN_E_COMPFILE_CLASSNOTAVAIL = 0x80110427; + //public const uint COMADMIN_E_COMPFILE_BADTLB = 0x80110428; + //public const uint COMADMIN_E_COMPFILE_NOTINSTALLABLE = 0x80110429; + //public const uint COMADMIN_E_NOTCHANGEABLE = 0x8011042A; + //public const uint COMADMIN_E_NOTDELETEABLE = 0x8011042B; + //public const uint COMADMIN_E_SESSION = 0x8011042C; + //public const uint COMADMIN_E_COMP_MOVE_LOCKED = 0x8011042D; + //public const uint COMADMIN_E_COMP_MOVE_BAD_DEST = 0x8011042E; + //public const uint COMADMIN_E_REGISTERTLB = 0x80110430; + //public const uint COMADMIN_E_SYSTEMAPP = 0x80110433; + //public const uint COMADMIN_E_COMPFILE_NOREGISTRAR = 0x80110434; + //public const uint COMADMIN_E_COREQCOMPINSTALLED = 0x80110435; + //public const uint COMADMIN_E_SERVICENOTINSTALLED = 0x80110436; + //public const uint COMADMIN_E_PROPERTYSAVEFAILED = 0x80110437; + //public const uint COMADMIN_E_OBJECTEXISTS = 0x80110438; + //public const uint COMADMIN_E_COMPONENTEXISTS = 0x80110439; + //public const uint COMADMIN_E_REGFILE_CORRUPT = 0x8011043B; + //public const uint COMADMIN_E_PROPERTY_OVERFLOW = 0x8011043C; + //public const uint COMADMIN_E_NOTINREGISTRY = 0x8011043E; + //public const uint COMADMIN_E_OBJECTNOTPOOLABLE = 0x8011043F; + //public const uint COMADMIN_E_APPLID_MATCHES_CLSID = 0x80110446; + //public const uint COMADMIN_E_ROLE_DOES_NOT_EXIST = 0x80110447; + //public const uint COMADMIN_E_START_APP_NEEDS_COMPONENTS = 0x80110448; + //public const uint COMADMIN_E_REQUIRES_DIFFERENT_PLATFORM = 0x80110449; + //public const uint COMADMIN_E_CAN_NOT_EXPORT_APP_PROXY = 0x8011044A; + //public const uint COMADMIN_E_CAN_NOT_START_APP = 0x8011044B; + //public const uint COMADMIN_E_CAN_NOT_EXPORT_SYS_APP = 0x8011044C; + //public const uint COMADMIN_E_CANT_SUBSCRIBE_TO_COMPONENT = 0x8011044D; + //public const uint COMADMIN_E_EVENTCLASS_CANT_BE_SUBSCRIBER = 0x8011044E; + //public const uint COMADMIN_E_LIB_APP_PROXY_INCOMPATIBLE = 0x8011044F; + //public const uint COMADMIN_E_BASE_PARTITION_ONLY = 0x80110450; + //public const uint COMADMIN_E_START_APP_DISABLED = 0x80110451; + //public const uint COMADMIN_E_CAT_DUPLICATE_PARTITION_NAME = 0x80110457; + //public const uint COMADMIN_E_CAT_INVALID_PARTITION_NAME = 0x80110458; + //public const uint COMADMIN_E_CAT_PARTITION_IN_USE = 0x80110459; + //public const uint COMADMIN_E_FILE_PARTITION_DUPLICATE_FILES = 0x8011045A; + //public const uint COMADMIN_E_CAT_IMPORTED_COMPONENTS_NOT_ALLOWED = 0x8011045B; + //public const uint COMADMIN_E_AMBIGUOUS_APPLICATION_NAME = 0x8011045C; + //public const uint COMADMIN_E_AMBIGUOUS_PARTITION_NAME = 0x8011045D; + //public const uint COMADMIN_E_REGDB_NOTINITIALIZED = 0x80110472; + //public const uint COMADMIN_E_REGDB_NOTOPEN = 0x80110473; + //public const uint COMADMIN_E_REGDB_SYSTEMERR = 0x80110474; + //public const uint COMADMIN_E_REGDB_ALREADYRUNNING = 0x80110475; + //public const uint COMADMIN_E_MIG_VERSIONNOTSUPPORTED = 0x80110480; + //public const uint COMADMIN_E_MIG_SCHEMANOTFOUND = 0x80110481; + //public const uint COMADMIN_E_CAT_BITNESSMISMATCH = 0x80110482; + //public const uint COMADMIN_E_CAT_UNACCEPTABLEBITNESS = 0x80110483; + //public const uint COMADMIN_E_CAT_WRONGAPPBITNESS = 0x80110484; + //public const uint COMADMIN_E_CAT_PAUSE_RESUME_NOT_SUPPORTED = 0x80110485; + //public const uint COMADMIN_E_CAT_SERVERFAULT = 0x80110486; + //public const uint COMQC_E_APPLICATION_NOT_QUEUED = 0x80110600; + //public const uint COMQC_E_NO_QUEUEABLE_INTERFACES = 0x80110601; + //public const uint COMQC_E_QUEUING_SERVICE_NOT_AVAILABLE = 0x80110602; + //public const uint COMQC_E_NO_IPERSISTSTREAM = 0x80110603; + //public const uint COMQC_E_BAD_MESSAGE = 0x80110604; + //public const uint COMQC_E_UNAUTHENTICATED = 0x80110605; + //public const uint COMQC_E_UNTRUSTED_ENQUEUER = 0x80110606; + //public const uint MSDTC_E_DUPLICATE_RESOURCE = 0x80110701; + //public const uint COMADMIN_E_OBJECT_PARENT_MISSING = 0x80110808; + //public const uint COMADMIN_E_OBJECT_DOES_NOT_EXIST = 0x80110809; + //public const uint COMADMIN_E_APP_NOT_RUNNING = 0x8011080A; + //public const uint COMADMIN_E_INVALID_PARTITION = 0x8011080B; + //public const uint COMADMIN_E_SVCAPP_NOT_POOLABLE_OR_RECYCLABLE = 0x8011080D; + //public const uint COMADMIN_E_USER_IN_SET = 0x8011080E; + //public const uint COMADMIN_E_CANTRECYCLELIBRARYAPPS = 0x8011080F; + //public const uint COMADMIN_E_CANTRECYCLESERVICEAPPS = 0x80110811; + //public const uint COMADMIN_E_PROCESSALREADYRECYCLED = 0x80110812; + //public const uint COMADMIN_E_PAUSEDPROCESSMAYNOTBERECYCLED = 0x80110813; + //public const uint COMADMIN_E_CANTMAKEINPROCSERVICE = 0x80110814; + //public const uint COMADMIN_E_PROGIDINUSEBYCLSID = 0x80110815; + //public const uint COMADMIN_E_DEFAULT_PARTITION_NOT_IN_SET = 0x80110816; + //public const uint COMADMIN_E_RECYCLEDPROCESSMAYNOTBEPAUSED = 0x80110817; + //public const uint COMADMIN_E_PARTITION_ACCESSDENIED = 0x80110818; + //public const uint COMADMIN_E_PARTITION_MSI_ONLY = 0x80110819; + //public const uint COMADMIN_E_LEGACYCOMPS_NOT_ALLOWED_IN_1_0_FORMAT = 0x8011081A; + //public const uint COMADMIN_E_LEGACYCOMPS_NOT_ALLOWED_IN_NONBASE_PARTITIONS = 0x8011081B; + //public const uint COMADMIN_E_COMP_MOVE_SOURCE = 0x8011081C; + //public const uint COMADMIN_E_COMP_MOVE_DEST = 0x8011081D; + //public const uint COMADMIN_E_COMP_MOVE_PRIVATE = 0x8011081E; + //public const uint COMADMIN_E_BASEPARTITION_REQUIRED_IN_SET = 0x8011081F; + //public const uint COMADMIN_E_CANNOT_ALIAS_EVENTCLASS = 0x80110820; + //public const uint COMADMIN_E_PRIVATE_ACCESSDENIED = 0x80110821; + //public const uint COMADMIN_E_SAFERINVALID = 0x80110822; + //public const uint COMADMIN_E_REGISTRY_ACCESSDENIED = 0x80110823; + //public const uint COMADMIN_E_PARTITIONS_DISABLED = 0x80110824; + + + #region Network Management Error Codes + + // http://msdn.microsoft.com/en-us/library/windows/desktop/aa370674%28v=vs.85%29.aspx + + /// (0) The operation completed successfully. + public const uint NERR_Success = 0; + + ///// The workstation driver is not installed. + //public const uint NERR_NetNotStarted = 2102; + + ///// The server could not be located. + //public const uint NERR_UnknownServer = 2103; + + ///// An internal error occurred. The network cannot access a shared memory segment. + //public const uint NERR_ShareMem = 2104; + + ///// A network resource shortage occurred. + //public const uint NERR_NoNetworkResource = 2105; + + ///// This operation is not supported on workstations. + //public const uint NERR_RemoteOnly = 2106; + + ///// The device is not connected. + //public const uint NERR_DevNotRedirected = 2107; + + ///// The Server service is not started. + //public const uint NERR_ServerNotStarted = 2114; + + ///// The queue is empty. + //public const uint NERR_ItemNotFound = 2115; + + ///// The device or directory does not exist. + //public const uint NERR_UnknownDevDir = 2116; + + ///// The operation is invalid on a redirected resource. + //public const uint NERR_RedirectedPath = 2117; + + ///// The name has already been shared. + //public const uint NERR_DuplicateShare = 2118; + + ///// The server is currently out of the requested resource. + //public const uint NERR_NoRoom = 2119; + + ///// Requested addition of items exceeds the maximum allowed. + //public const uint NERR_TooManyItems = 2121; + + ///// The Peer service supports only two simultaneous users. + //public const uint NERR_InvalidMaxUsers = 2122; + + ///// The API return buffer is too small. + //public const uint NERR_BufTooSmall = 2123; + + ///// A remote API error occurred. + //public const uint NERR_RemoteErr = 2127; + + ///// An error occurred when opening or reading the configuration file. + //public const uint NERR_LanmanIniError = 2131; + + ///// A general network error occurred. + //public const uint NERR_NetworkError = 2136; + + ///// The Workstation service is in an inconsistent state. Restart the computer before restarting the Workstation service. + //public const uint NERR_WkstaInconsistentState = 2137; + + ///// The Workstation service has not been started. + //public const uint NERR_WkstaNotStarted = 2138; + + ///// The requested information is not available. + //public const uint NERR_BrowserNotStarted = 2139; + + ///// An internal error occurred. + //public const uint NERR_InternalError = 2140; + + ///// The server is not configured for transactions. + //public const uint NERR_BadTransactConfig = 2141; + + ///// The requested API is not supported on the remote server. + //public const uint NERR_InvalidAPI = 2142; + + ///// The event name is invalid. + //public const uint NERR_BadEventName = 2143; + + ///// The computer name already exists on the network. Change it and restart the computer. + //public const uint NERR_DupNameReboot = 2144; + + ///// The specified component could not be found in the configuration information. + //public const uint NERR_CfgCompNotFound = 2146; + + ///// The specified parameter could not be found in the configuration information. + //public const uint NERR_CfgParamNotFound = 2147; + + ///// A line in the configuration file is too long. + //public const uint NERR_LineTooLong = 2149; + + ///// The printer does not exist. + //public const uint NERR_QNotFound = 2150; + + ///// The print job does not exist. + //public const uint NERR_JobNotFound = 2151; + + ///// The printer destination cannot be found. + //public const uint NERR_DestNotFound = 2152; + + ///// The printer destination already exists. + //public const uint NERR_DestExists = 2153; + + ///// The printer queue already exists. + //public const uint NERR_QExists = 2154; + + ///// No more printers can be added. + //public const uint NERR_QNoRoom = 2155; + + ///// No more print jobs can be added. + //public const uint NERR_JobNoRoom = 2156; + + ///// No more printer destinations can be added. + //public const uint NERR_DestNoRoom = 2157; + + ///// This printer destination is idle and cannot accept control operations. + //public const uint NERR_DestIdle = 2158; + + ///// This printer destination request contains an invalid control function. + //public const uint NERR_DestInvalidOp = 2159; + + ///// The print processor is not responding. + //public const uint NERR_ProcNoRespond = 2160; + + ///// The spooler is not running. + //public const uint NERR_SpoolerNotLoaded = 2161; + + ///// This operation cannot be performed on the print destination in its current state. + //public const uint NERR_DestInvalidState = 2162; + + ///// This operation cannot be performed on the printer queue in its current state. + //public const uint NERR_QinvalidState = 2163; + + ///// This operation cannot be performed on the print job in its current state. + //public const uint NERR_JobInvalidState = 2164; + + ///// A spooler memory allocation failure occurred. + //public const uint NERR_SpoolNoMemory = 2165; + + ///// The device driver does not exist. + //public const uint NERR_DriverNotFound = 2166; + + ///// The data type is not supported by the print processor. + //public const uint NERR_DataTypeInvalid = 2167; + + ///// The print processor is not installed. + //public const uint NERR_ProcNotFound = 2168; + + ///// The service database is locked. + //public const uint NERR_ServiceTableLocked = 2180; + + ///// The service table is full. + //public const uint NERR_ServiceTableFull = 2181; + + ///// The requested service has already been started. + //public const uint NERR_ServiceInstalled = 2182; + + ///// The service does not respond to control actions. + //public const uint NERR_ServiceEntryLocked = 2183; + + ///// The service has not been started. + //public const uint NERR_ServiceNotInstalled = 2184; + + ///// The service name is invalid. + //public const uint NERR_BadServiceName = 2185; + + ///// The service is not responding to the control function. + //public const uint NERR_ServiceCtlTimeout = 2186; + + ///// The service control is busy. + //public const uint NERR_ServiceCtlBusy = 2187; + + ///// The configuration file contains an invalid service program name. + //public const uint NERR_BadServiceProgName = 2188; + + ///// The service could not be controlled in its present state. + //public const uint NERR_ServiceNotCtrl = 2189; + + ///// The service ended abnormally. + //public const uint NERR_ServiceKillProc = 2190; + + ///// The requested pause or stop is not valid for this service. + //public const uint NERR_ServiceCtlNotValid = 2191; + + ///// The service control dispatcher could not find the service name in the dispatch table. + //public const uint NERR_NotInDispatchTbl = 2192; + + ///// The service control dispatcher pipe read failed. + //public const uint NERR_BadControlRecv = 2193; + + ///// A thread for the new service could not be created. + //public const uint NERR_ServiceNotStarting = 2194; + + ///// This workstation is already logged on to the local-area network. + //public const uint NERR_AlreadyLoggedOn = 2200; + + ///// The workstation is not logged on to the local-area network. + //public const uint NERR_NotLoggedOn = 2201; + + ///// The user name or group name parameter is invalid. + //public const uint NERR_BadUsername = 2202; + + ///// The password parameter is invalid. + //public const uint NERR_BadPassword = 2203; + + ///// @W The logon processor did not add the message alias. + //public const uint NERR_UnableToAddName_W = 2204; + + ///// The logon processor did not add the message alias. + //public const uint NERR_UnableToAddName_F = 2205; + + ///// @W The logoff processor did not delete the message alias. + //public const uint NERR_UnableToDelName_W = 2206; + + ///// The logoff processor did not delete the message alias. + //public const uint NERR_UnableToDelName_F = 2207; + + ///// Network logons are paused. + //public const uint NERR_LogonsPaused = 2209; + + ///// A centralized logon-server conflict occurred. + //public const uint NERR_LogonServerConflict = 2210; + + ///// The server is configured without a valid user path. + //public const uint NERR_LogonNoUserPath = 2211; + + ///// An error occurred while loading or running the logon script. + //public const uint NERR_LogonScriptError = 2212; + + ///// The logon server was not specified. Your computer will be logged on as STANDALONE. + //public const uint NERR_StandaloneLogon = 2214; + + ///// The logon server could not be found. + //public const uint NERR_LogonServerNotFound = 2215; + + ///// There is already a logon domain for this computer. + //public const uint NERR_LogonDomainExists = 2216; + + ///// The logon server could not validate the logon. + //public const uint NERR_NonValidatedLogon = 2217; + + ///// The security database could not be found. + //public const uint NERR_ACFNotFound = 2219; + + ///// The group name could not be found. + //public const uint NERR_GroupNotFound = 2220; + + ///// The user name could not be found. + //public const uint NERR_UserNotFound = 2221; + + ///// The resource name could not be found. + //public const uint NERR_ResourceNotFound = 2222; + + ///// The group already exists. + //public const uint NERR_GroupExists = 2223; + + ///// The user account already exists. + //public const uint NERR_UserExists = 2224; + + ///// The resource permission list already exists. + //public const uint NERR_ResourceExists = 2225; + + ///// This operation is only allowed on the primary domain controller of the domain. + //public const uint NERR_NotPrimary = 2226; + + ///// The security database has not been started. + //public const uint NERR_ACFNotLoaded = 2227; + + ///// There are too many names in the user accounts database. + //public const uint NERR_ACFNoRoom = 2228; + + ///// A disk I/O failure occurred. + //public const uint NERR_ACFFileIOFail = 2229; + + ///// The limit of 64 entries per resource was exceeded. + //public const uint NERR_ACFTooManyLists = 2230; + + ///// Deleting a user with a session is not allowed. + //public const uint NERR_UserLogon = 2231; + + ///// The parent directory could not be located. + //public const uint NERR_ACFNoParent = 2232; + + ///// Unable to add to the security database session cache segment. + //public const uint NERR_CanNotGrowSegment = 2233; + + ///// This operation is not allowed on this special group. + //public const uint NERR_SpeGroupOp = 2234; + + ///// This user is not cached in user accounts database session cache. + //public const uint NERR_NotInCache = 2235; + + ///// The user already belongs to this group. + //public const uint NERR_UserInGroup = 2236; + + ///// The user does not belong to this group. + //public const uint NERR_UserNotInGroup = 2237; + + ///// This user account is undefined. + //public const uint NERR_AccountUndefined = 2238; + + ///// This user account has expired. + //public const uint NERR_AccountExpired = 2239; + + ///// The user is not allowed to log on from this workstation. + //public const uint NERR_InvalidWorkstation = 2240; + + ///// The user is not allowed to log on at this time. + //public const uint NERR_InvalidLogonHours = 2241; + + ///// The password of this user has expired. + //public const uint NERR_PasswordExpired = 2242; + + ///// The password of this user cannot change. + //public const uint NERR_PasswordCantChange = 2243; + + ///// This password cannot be used now. + //public const uint NERR_PasswordHistConflict = 2244; + + ///// The password does not meet the password policy requirements. Check the minimum password length, password complexity and password history requirements. + //public const uint NERR_PasswordTooShort = 2245; + + ///// The password of this user is too recent to change. + //public const uint NERR_PasswordTooRecent = 2246; + + ///// The security database is corrupted. + //public const uint NERR_InvalidDatabase = 2247; + + ///// No updates are necessary to this replicant network/local security database. + //public const uint NERR_DatabaseUpToDate = 2248; + + ///// This replicant database is outdated; synchronization is required. + //public const uint NERR_SyncRequired = 2249; + + /// (2250) The network connection could not be found. + public const uint NERR_UseNotFound = 2250; + + ///// This asg_type is invalid. + //public const uint NERR_BadAsgType = 2251; + + ///// This device is currently being shared. + //public const uint NERR_DeviceIsShared = 2252; + + ///// The computer name could not be added as a message alias. The name may already exist on the network. + //public const uint NERR_NoComputerName = 2270; + + ///// The Messenger service is already started. + //public const uint NERR_MsgAlreadyStarted = 2271; + + ///// The Messenger service failed to start. + //public const uint NERR_MsgInitFailed = 2272; + + ///// The message alias could not be found on the network. + //public const uint NERR_NameNotFound = 2273; + + ///// This message alias has already been forwarded. + //public const uint NERR_AlreadyForwarded = 2274; + + ///// This message alias has been added but is still forwarded. + //public const uint NERR_AddForwarded = 2275; + + ///// This message alias already exists locally. + //public const uint NERR_AlreadyExists = 2276; + + ///// The maximum number of added message aliases has been exceeded. + //public const uint NERR_TooManyNames = 2277; + + ///// The computer name could not be deleted. + //public const uint NERR_DelComputerName = 2278; + + ///// Messages cannot be forwarded back to the same workstation. + //public const uint NERR_LocalForward = 2279; + + ///// An error occurred in the domain message processor. + //public const uint NERR_GrpMsgProcessor = 2280; + + ///// The message was sent, but the recipient has paused the Messenger service. + //public const uint NERR_PausedRemote = 2281; + + ///// The message was sent but not received. + //public const uint NERR_BadReceive = 2282; + + ///// The message alias is currently in use. Try again later. + //public const uint NERR_NameInUse = 2283; + + ///// The Messenger service has not been started. + //public const uint NERR_MsgNotStarted = 2284; + + ///// The name is not on the local computer. + //public const uint NERR_NotLocalName = 2285; + + ///// The forwarded message alias could not be found on the network. + //public const uint NERR_NoForwardName = 2286; + + ///// The message alias table on the remote station is full. + //public const uint NERR_RemoteFull = 2287; + + ///// Messages for this alias are not currently being forwarded. + //public const uint NERR_NameNotForwarded = 2288; + + ///// The broadcast message was truncated. + //public const uint NERR_TruncatedBroadcast = 2289; + + ///// This is an invalid device name. + //public const uint NERR_InvalidDevice = 2294; + + ///// A write fault occurred. + //public const uint NERR_WriteFault = 2295; + + ///// A duplicate message alias exists on the network. + //public const uint NERR_DuplicateName = 2297; + + ///// @W This message alias will be deleted later. + //public const uint NERR_DeleteLater = 2298; + + ///// The message alias was not successfully deleted from all networks. + //public const uint NERR_IncompleteDel = 2299; + + ///// This operation is not supported on computers with multiple networks. + //public const uint NERR_MultipleNets = 2300; + + /// (2310) This shared resource does not exist. + public const uint NERR_NetNameNotFound = 2310; + + ///// This device is not shared. + //public const uint NERR_DeviceNotShared = 2311; + + ///// A session does not exist with that computer name. + //public const uint NERR_ClientNameNotFound = 2312; + + /// (2314) There is not an open file with that identification number. + public const uint NERR_FileIdNotFound = 2314; + + ///// A failure occurred when executing a remote administration command. + //public const uint NERR_ExecFailure = 2315; + + ///// A failure occurred when opening a remote temporary file. + //public const uint NERR_TmpFile = 2316; + + ///// The data returned from a remote administration command has been truncated to 64K. + //public const uint NERR_TooMuchData = 2317; + + ///// This device cannot be shared as both a spooled and a non-spooled resource. + //public const uint NERR_DeviceShareConflict = 2318; + + ///// The information in the list of servers may be incorrect. + //public const uint NERR_BrowserTableIncomplete = 2319; + + ///// The computer is not active in this domain. + //public const uint NERR_NotLocalDomain = 2320; + + ///// The share must be removed from the Distributed File System before it can be deleted. + //public const uint NERR_IsDfsShare = 2321; + + ///// The operation is invalid for this device. + //public const uint NERR_DevInvalidOpCode = 2331; + + ///// This device cannot be shared. + //public const uint NERR_DevNotFound = 2332; + + ///// This device was not open. + //public const uint NERR_DevNotOpen = 2333; + + ///// This device name list is invalid. + //public const uint NERR_BadQueueDevString = 2334; + + ///// The queue priority is invalid. + //public const uint NERR_BadQueuePriority = 2335; + + ///// There are no shared communication devices. + //public const uint NERR_NoCommDevs = 2337; + + ///// The queue you specified does not exist. + //public const uint NERR_QueueNotFound = 2338; + + ///// This list of devices is invalid. + //public const uint NERR_BadDevString = 2340; + + ///// The requested device is invalid. + //public const uint NERR_BadDev = 2341; + + ///// This device is already in use by the spooler. + //public const uint NERR_InUseBySpooler = 2342; + + ///// This device is already in use as a communication device. + //public const uint NERR_CommDevInUse = 2343; + + ///// This computer name is invalid. + //public const uint NERR_InvalidComputer = 2351; + + ///// The string and prefix specified are too long. + //public const uint NERR_MaxLenExceeded = 2354; + + ///// This path component is invalid. + //public const uint NERR_BadComponent = 2356; + + ///// Could not determine the type of input. + //public const uint NERR_CantType = 2357; + + ///// The buffer for types is not big enough. + //public const uint NERR_TooManyEntries = 2362; + + ///// Profile files cannot exceed 64K. + //public const uint NERR_ProfileFileTooBig = 2370; + + ///// The start offset is out of range. + //public const uint NERR_ProfileOffset = 2371; + + ///// The system cannot delete current connections to network resources. + //public const uint NERR_ProfileCleanup = 2372; + + ///// The system was unable to parse the command line in this file. + //public const uint NERR_ProfileUnknownCmd = 2373; + + ///// An error occurred while loading the profile file. + //public const uint NERR_ProfileLoadErr = 2374; + + ///// @W Errors occurred while saving the profile file. The profile was partially saved. + //public const uint NERR_ProfileSaveErr = 2375; + + ///// Log file %1 is full. + //public const uint NERR_LogOverflow = 2377; + + ///// This log file has changed between reads. + //public const uint NERR_LogFileChanged = 2378; + + ///// Log file %1 is corrupt. + //public const uint NERR_LogFileCorrupt = 2379; + + ///// The source path cannot be a directory. + //public const uint NERR_SourceIsDir = 2380; + + ///// The source path is illegal. + //public const uint NERR_BadSource = 2381; + + ///// The destination path is illegal. + //public const uint NERR_BadDest = 2382; + + ///// The source and destination paths are on different servers. + //public const uint NERR_DifferentServers = 2383; + + ///// The Run server you requested is paused. + //public const uint NERR_RunSrvPaused = 2385; + + ///// An error occurred when communicating with a Run server. + //public const uint NERR_ErrCommRunSrv = 2389; + + ///// An error occurred when starting a background process. + //public const uint NERR_ErrorExecingGhost = 2391; + + ///// The shared resource you are connected to could not be found. + //public const uint NERR_ShareNotFound = 2392; + + ///// The LAN adapter number is invalid. + //public const uint NERR_InvalidLana = 2400; + + ///// There are open files on the connection. + //public const uint NERR_OpenFiles = 2401; + + ///// Active connections still exist. + //public const uint NERR_ActiveConns = 2402; + + ///// This share name or password is invalid. + //public const uint NERR_BadPasswordCore = 2403; + + ///// The device is being accessed by an active process. + //public const uint NERR_DevInUse = 2404; + + ///// The drive letter is in use locally. + //public const uint NERR_LocalDrive = 2405; + + ///// The specified client is already registered for the specified event. + //public const uint NERR_AlertExists = 2430; + + ///// The alert table is full. + //public const uint NERR_TooManyAlerts = 2431; + + ///// An invalid or nonexistent alert name was raised. + //public const uint NERR_NoSuchAlert = 2432; + + ///// The alert recipient is invalid. + //public const uint NERR_BadRecipient = 2433; + + ///// A user's session with this server has been deleted + //public const uint NERR_AcctLimitExceeded = 2434; + + ///// The log file does not contain the requested record number. + //public const uint NERR_InvalidLogSeek = 2440; + + ///// The user accounts database is not configured correctly. + //public const uint NERR_BadUasConfig = 2450; + + ///// This operation is not permitted when the Netlogon service is running. + //public const uint NERR_InvalidUASOp = 2451; + + ///// This operation is not allowed on the last administrative account. + //public const uint NERR_LastAdmin = 2452; + + ///// Could not find domain controller for this domain. + //public const uint NERR_DCNotFound = 2453; + + ///// Could not set logon information for this user. + //public const uint NERR_LogonTrackingError = 2454; + + ///// The Netlogon service has not been started. + //public const uint NERR_NetlogonNotStarted = 2455; + + ///// Unable to add to the user accounts database. + //public const uint NERR_CanNotGrowUASFile = 2456; + + ///// This server's clock is not synchronized with the primary domain controller's clock. + //public const uint NERR_TimeDiffAtDC = 2457; + + ///// A password mismatch has been detected. + //public const uint NERR_PasswordMismatch = 2458; + + ///// The server identification does not specify a valid server. + //public const uint NERR_NoSuchServer = 2460; + + ///// The session identification does not specify a valid session. + //public const uint NERR_NoSuchSession = 2461; + + ///// The connection identification does not specify a valid connection. + //public const uint NERR_NoSuchConnection = 2462; + + ///// There is no space for another entry in the table of available servers. + //public const uint NERR_TooManyServers = 2463; + + ///// The server has reached the maximum number of sessions it supports. + //public const uint NERR_TooManySessions = 2464; + + ///// The server has reached the maximum number of connections it supports. + //public const uint NERR_TooManyConnections = 2465; + + ///// The server cannot open more files because it has reached its maximum number. + //public const uint NERR_TooManyFiles = 2466; + + ///// There are no alternate servers registered on this server. + //public const uint NERR_NoAlternateServers = 2467; + + ///// Try down-level (remote admin protocol) version of API instead. + //public const uint NERR_TryDownLevel = 2470; + + ///// The UPS driver could not be accessed by the UPS service. + //public const uint NERR_UPSDriverNotStarted = 2480; + + ///// The UPS service is not configured correctly. + //public const uint NERR_UPSInvalidConfig = 2481; + + ///// The UPS service could not access the specified Comm Port. + //public const uint NERR_UPSInvalidCommPort = 2482; + + ///// The UPS indicated a line fail or low battery situation. Service not started. + //public const uint NERR_UPSSignalAsserted = 2483; + + ///// The UPS service failed to perform a system shut down. + //public const uint NERR_UPSShutdownFailed = 2484; + + ///// The program below returned an MS-DOS error code: + //public const uint NERR_BadDosRetCode = 2500; + + ///// The program below needs more memory: + //public const uint NERR_ProgNeedsExtraMem = 2501; + + ///// The program below called an unsupported MS-DOS function: + //public const uint NERR_BadDosFunction = 2502; + + ///// The workstation failed to boot. + //public const uint NERR_RemoteBootFailed = 2503; + + ///// The file below is corrupt. + //public const uint NERR_BadFileCheckSum = 2504; + + ///// No loader is specified in the boot-block definition file. + //public const uint NERR_NoRplBootSystem = 2505; + + ///// NetBIOS returned an error: The NCB and SMB are dumped above. + //public const uint NERR_RplLoadrNetBiosErr = 2506; + + ///// A disk I/O error occurred. + //public const uint NERR_RplLoadrDiskErr = 2507; + + ///// Image parameter substitution failed. + //public const uint NERR_ImageParamErr = 2508; + + ///// Too many image parameters cross disk sector boundaries. + //public const uint NERR_TooManyImageParams = 2509; + + ///// The image was not generated from an MS-DOS diskette formatted with /S. + //public const uint NERR_NonDosFloppyUsed = 2510; + + ///// Remote boot will be restarted later. + //public const uint NERR_RplBootRestart = 2511; + + ///// The call to the Remoteboot server failed. + //public const uint NERR_RplSrvrCallFailed = 2512; + + ///// Cannot connect to the Remoteboot server. + //public const uint NERR_CantConnectRplSrvr = 2513; + + ///// Cannot open image file on the Remoteboot server. + //public const uint NERR_CantOpenImageFile = 2514; + + ///// Connecting to the Remoteboot server... + //public const uint NERR_CallingRplSrvr = 2515; + + ///// Connecting to the Remoteboot server... + //public const uint NERR_StartingRplBoot = 2516; + + ///// Remote boot service was stopped; check the error log for the cause of the problem. + //public const uint NERR_RplBootServiceTerm = 2517; + + ///// Remote boot startup failed; check the error log for the cause of the problem. + //public const uint NERR_RplBootStartFailed = 2518; + + ////// A second connection to a Remoteboot resource is not allowed. + //public const uint NERR_RplConnected = 2519; + + ///// The browser service was configured with MaintainServerList=No. + //public const uint NERR_BrowserConfiguredToNotRun = 2550; + + ///// Service failed to start since none of the network adapters started with this service. + //public const uint NERR_RplNoAdaptersStarted = 2610; + + ///// Service failed to start due to bad startup information in the registry. + //public const uint NERR_RplBadRegistry = 2611; + + ///// Service failed to start because its database is absent or corrupt. + //public const uint NERR_RplBadDatabase = 2612; + + ///// Service failed to start because RPLFILES share is absent. + //public const uint NERR_RplRplfilesShare = 2613; + + ///// Service failed to start because RPLUSER group is absent. + //public const uint NERR_RplNotRplServer = 2614; + + ///// Cannot enumerate service records. + //public const uint NERR_RplCannotEnum = 2615; + + ///// Workstation record information has been corrupted. + //public const uint NERR_RplWkstaInfoCorrupted = 2616; + + ///// Workstation record was not found. + //public const uint NERR_RplWkstaNotFound = 2617; + + ///// Workstation name is in use by some other workstation. + //public const uint NERR_RplWkstaNameUnavailable = 2618; + + ///// Profile record information has been corrupted. + //public const uint NERR_RplProfileInfoCorrupted = 2619; + + ///// Profile record was not found. + //public const uint NERR_RplProfileNotFound = 2620; + + ///// Profile name is in use by some other profile. + //public const uint NERR_RplProfileNameUnavailable = 2621; + + ///// There are workstations using this profile. + //public const uint NERR_RplProfileNotEmpty = 2622; + + ///// Configuration record information has been corrupted. + //public const uint NERR_RplConfigInfoCorrupted = 2623; + + ///// Configuration record was not found. + //public const uint NERR_RplConfigNotFound = 2624; + + ///// Adapter ID record information has been corrupted. + //public const uint NERR_RplAdapterInfoCorrupted = 2625; + + ///// An internal service error has occurred. + //public const uint NERR_RplInternal = 2626; + + ///// Vendor ID record information has been corrupted. + //public const uint NERR_RplVendorInfoCorrupted = 2627; + + ///// Boot block record information has been corrupted. + //public const uint NERR_RplBootInfoCorrupted = 2628; + + ///// The user account for this workstation record is missing. + //public const uint NERR_RplWkstaNeedsUserAcct = 2629; + + ///// The RPLUSER local group could not be found. + //public const uint NERR_RplNeedsRPLUSERAcct = 2630; + + ///// Boot block record was not found. + //public const uint NERR_RplBootNotFound = 2631; + + ///// Chosen profile is incompatible with this workstation. + //public const uint NERR_RplIncompatibleProfile = 2632; + + ///// Chosen network adapter ID is in use by some other workstation. + //public const uint NERR_RplAdapterNameUnavailable = 2633; + + ///// There are profiles using this configuration. + //public const uint NERR_RplConfigNotEmpty = 2634; + + ///// There are workstations, profiles, or configurations using this boot block. + //public const uint NERR_RplBootInUse = 2635; + + ///// Service failed to backup Remoteboot database. + //public const uint NERR_RplBackupDatabase = 2636; + + ///// Adapter record was not found. + //public const uint NERR_RplAdapterNotFound = 2637; + + ///// Vendor record was not found. + //public const uint NERR_RplVendorNotFound = 2638; + + ///// Vendor name is in use by some other vendor record. + //public const uint NERR_RplVendorNameUnavailable = 2639; + + ///// (boot name, vendor ID) is in use by some other boot block record. + //public const uint NERR_RplBootNameUnavailable = 2640; + + ///// Configuration name is in use by some other configuration. + //public const uint NERR_RplConfigNameUnavailable = 2641; + + ///// The internal database maintained by the Dfs service is corrupt. + //public const uint NERR_DfsInternalCorruption = 2660; + + ///// One of the records in the internal Dfs database is corrupt. + //public const uint NERR_DfsVolumeDataCorrupt = 2661; + + ///// There is no DFS name whose entry path matches the input Entry Path. + //public const uint NERR_DfsNoSuchVolume = 2662; + + ///// A root or link with the given name already exists. + //public const uint NERR_DfsVolumeAlreadyExists = 2663; + + ///// The server share specified is already shared in the Dfs. + //public const uint NERR_DfsAlreadyShared = 2664; + + ///// The indicated server share does not support the indicated DFS namespace. + //public const uint NERR_DfsNoSuchShare = 2665; + + ///// The operation is not valid on this portion of the namespace. + //public const uint NERR_DfsNotALeafVolume = 2666; + + ///// The operation is not valid on this portion of the namespace. + //public const uint NERR_DfsLeafVolume = 2667; + + ///// The operation is ambiguous because the link has multiple servers. + //public const uint NERR_DfsVolumeHasMultipleServers = 2668; + + ///// Unable to create a link. + //public const uint NERR_DfsCantCreateJunctionPoint = 2669; + + ///// The server is not Dfs Aware. + //public const uint NERR_DfsServerNotDfsAware = 2670; + + ///// The specified rename target path is invalid. + //public const uint NERR_DfsBadRenamePath = 2671; + + ///// The specified DFS link is offline. + //public const uint NERR_DfsVolumeIsOffline = 2672; + + ///// The specified server is not a server for this link. + //public const uint NERR_DfsNoSuchServer = 2673; + + ///// A cycle in the Dfs name was detected. + //public const uint NERR_DfsCyclicalName = 2674; + + ///// The operation is not supported on a server-based Dfs. + //public const uint NERR_DfsNotSupportedInServerDfs = 2675; + + ///// This link is already supported by the specified server-share. + //public const uint NERR_DfsDuplicateService = 2676; + + ///// Can't remove the last server-share supporting this root or link. + //public const uint NERR_DfsCantRemoveLastServerShare = 2677; + + ///// The operation is not supported for an Inter-DFS link. + //public const uint NERR_DfsVolumeIsInterDfs = 2678; + + ///// The internal state of the Dfs Service has become inconsistent. + //public const uint NERR_DfsInconsistent = 2679; + + ///// The Dfs Service has been installed on the specified server. + //public const uint NERR_DfsServerUpgraded = 2680; + + ///// The Dfs data being reconciled is identical. + //public const uint NERR_DfsDataIsIdentical = 2681; + + ///// The DFS root cannot be deleted. Uninstall DFS if required. + //public const uint NERR_DfsCantRemoveDfsRoot = 2682; + + ///// A child or parent directory of the share is already in a Dfs. + //public const uint NERR_DfsChildOrParentInDfs = 2683; + + ///// Dfs internal error. + //public const uint NERR_DfsInternalError = 2690; + + ///// This computer is already joined to a domain. + //public const uint NERR_SetupAlreadyJoined = 2691; + + ///// This computer is not currently joined to a domain. + //public const uint NERR_SetupNotJoined = 2692; + + ///// This computer is a domain controller and cannot be unjoined from a domain. + //public const uint NERR_SetupDomainController = 2693; + + ///// The destination domain controller does not support creating machine accounts in OUs. + //public const uint NERR_DefaultJoinRequired = 2694; + + ///// The specified workgroup name is invalid. + //public const uint NERR_InvalidWorkgroupName = 2695; + + ///// The specified computer name is incompatible with the default language used on the domain controller. + //public const uint NERR_NameUsesIncompatibleCodePage = 2696; + + ///// The specified computer account could not be found. + //public const uint NERR_ComputerAccountNotFound = 2697; + + ///// This version of Windows cannot be joined to a domain. + //public const uint NERR_PersonalSku = 2698; + + ///// The password must change at the next logon. + //public const uint NERR_PasswordMustChange = 2701; + + ///// The account is locked out. + //public const uint NERR_AccountLockedOut = 2702; + + ///// The password is too long. + //public const uint NERR_PasswordTooLong = 2703; + + ///// The password does not meet the complexity policy. + //public const uint NERR_PasswordNotComplexEnough = 2704; + + ///// The password does not meet the requirements of the password filter DLLs. + //public const uint NERR_PasswordFilterError = 2705; + + ///// The offline join completion information was not found. + //public const uint NERR_NoOfflineJoinInfo = 2709; + + ///// The offline join completion information was bad. + //public const uint NERR_BadOfflineJoinInfo = 2710; + + ///// Unable to create offline join information. Please ensure you have access to the specified path location and permissions to modify its contents. Running as an elevated administrator may be required. + //public const uint NERR_CantCreateJoinInfo = 2711; + + ///// The domain join info being saved was incomplete or bad. + //public const uint NERR_BadDomainJoinInfo = 2712; + + ///// Offline join operation successfully completed but a restart is needed. + //public const uint NERR_JoinPerformedMustRestart = 2713; + + ///// There was no offline join operation pending. + //public const uint NERR_NoJoinPending = 2714; + + ///// Unable to set one or more requested machine or domain name values on the local computer. + //public const uint NERR_ValuesNotSet = 2715; + + ///// Could not verify the current machine's hostname against the saved value in the join completion information. + //public const uint NERR_CantVerifyHostname = 2716; + + ///// Unable to load the specified offline registry hive. Please ensure you have access to the specified path location and permissions to modify its contents. Running as an elevated administrator may be required. + //public const uint NERR_CantLoadOfflineHive = 2717; + + ///// The minimum session security requirements for this operation were not met. + //public const uint NERR_ConnectionInsecure = 2718; + + ///// Computer account provisioning blob version is not supported. + //public const uint NERR_RplBootInUse = 2719; + + #endregion // Network Management Error Codes + + #region Configuration Manager Error Codes + + /// (0) The operation completed successfully. + public const uint CR_SUCCESS = 0; + + //public const uint CR_DEFAULT = 1; + //public const uint CR_OUT_OF_MEMORY = 2; + //public const uint CR_INVALID_POINTER = 3; + //public const uint CR_INVALID_FLAG = 4; + //public const uint CR_INVALID_DEVNODE = 5; + //public const uint CR_INVALID_DEVINST = CR_INVALID_DEVNODE; + //public const uint CR_INVALID_RES_DES = 6; + //public const uint CR_INVALID_LOG_CONF = 7; + //public const uint CR_INVALID_ARBITRATOR = 8; + //public const uint CR_INVALID_NODELIST = 9; + //public const uint CR_DEVNODE_HAS_REQS = 10; + //public const uint CR_DEVINST_HAS_REQS = CR_DEVNODE_HAS_REQS; + //public const uint CR_INVALID_RESOURCEID = 11; + //public const uint CR_DLVXD_NOT_FOUND = 12; // WIN 95 ONLY + //public const uint CR_NO_SUCH_DEVNODE = 13; + //public const uint CR_NO_SUCH_DEVINST = CR_NO_SUCH_DEVNODE; + //public const uint CR_NO_MORE_LOG_CONF = 14; + //public const uint CR_NO_MORE_RES_DES = 15; + //public const uint CR_ALREADY_SUCH_DEVNODE = 16; + //public const uint CR_ALREADY_SUCH_DEVINST = CR_ALREADY_SUCH_DEVNODE; + //public const uint CR_INVALID_RANGE_LIST = 17; + //public const uint CR_INVALID_RANGE = 18; + //public const uint CR_FAILURE = 19; + //public const uint CR_NO_SUCH_LOGICAL_DEV = 20; + //public const uint CR_CREATE_BLOCKED = 21; + //public const uint CR_NOT_SYSTEM_VM = 22; // WIN 95 ONLY + //public const uint CR_REMOVE_VETOED = 23; + //public const uint CR_APM_VETOED = 24; + //public const uint CR_INVALID_LOAD_TYPE = 25; + //public const uint CR_BUFFER_SMALL = 26; + //public const uint CR_NO_ARBITRATOR = 27; + //public const uint CR_NO_REGISTRY_HANDLE = 28; + //public const uint CR_REGISTRY_ERROR = 29; + //public const uint CR_INVALID_DEVICE_ID = 30; + //public const uint CR_INVALID_DATA = 31; + //public const uint CR_INVALID_API = 32; + //public const uint CR_DEVLOADER_NOT_READY = 33; + //public const uint CR_NEED_RESTART = 34; + //public const uint CR_NO_MORE_HW_PROFILES = 35; + //public const uint CR_DEVICE_NOT_THERE = 36; + //public const uint CR_NO_SUCH_VALUE = 37; + //public const uint CR_WRONG_TYPE = 38; + //public const uint CR_INVALID_PRIORITY = 39; + //public const uint CR_NOT_DISABLEABLE = 40; + //public const uint CR_FREE_RESOURCES = 41; + //public const uint CR_QUERY_VETOED = 42; + //public const uint CR_CANT_SHARE_IRQ = 43; + //public const uint CR_NO_DEPENDENT = 44; + //public const uint CR_SAME_RESOURCES = 45; + //public const uint CR_NO_SUCH_REGISTRY_KEY = 46; + //public const uint CR_INVALID_MACHINENAME = 47; // NT ONLY + //public const uint CR_REMOTE_COMM_FAILURE = 48; // NT ONLY + //public const uint CR_MACHINE_UNAVAILABLE = 49; // NT ONLY + //public const uint CR_NO_CM_SERVICES = 50; // NT ONLY + //public const uint CR_ACCESS_DENIED = 51; // NT ONLY + //public const uint CR_CALL_NOT_IMPLEMENTED = 52; + //public const uint CR_INVALID_PROPERTY = 53; + //public const uint CR_DEVICE_INTERFACE_ACTIVE = 54; + //public const uint CR_NO_SUCH_DEVICE_INTERFACE = 55; + //public const uint CR_INVALID_REFERENCE_STRING = 56; + //public const uint NUM_CR_RESULTS = 57; + + #endregion // Configuration Manager Error Codes + } +} diff --git a/AlphaFS/app.config b/AlphaFS/app.config new file mode 100644 index 0000000..bd4cf43 --- /dev/null +++ b/AlphaFS/app.config @@ -0,0 +1,3 @@ + + + diff --git a/AlphaFS/packages.config b/AlphaFS/packages.config new file mode 100644 index 0000000..f7ed71d --- /dev/null +++ b/AlphaFS/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Log/Log.cs b/Log/Log.cs new file mode 100644 index 0000000..0a1e301 --- /dev/null +++ b/Log/Log.cs @@ -0,0 +1,253 @@ +using System; +using System.Diagnostics; + +namespace Log +{ + #region Log + + namespace Log + { + public class ParameterCountMismatchArgumentCountException : Exception + { + public ParameterCountMismatchArgumentCountException() + : base() { } + + public ParameterCountMismatchArgumentCountException(string message) + : base(message) + { } + } + + public class Log : Microsoft.VisualBasic.Logging.Log, IDisposable + { + public Log() + : base() + { + if (!string.IsNullOrEmpty(System.Configuration.ConfigurationManager.AppSettings["LogPath"])) + { + string LogPath = System.Configuration.ConfigurationManager.AppSettings["LogPath"]; + string LogName = System.Reflection.Assembly.GetCallingAssembly().GetName().Name; + DefaultFileLogWriter.CustomLocation = System.IO.Path.GetDirectoryName(LogPath); + DefaultFileLogWriter.BaseFileName = LogName; + DefaultFileLogWriter.Location = Microsoft.VisualBasic.Logging.LogFileLocation.Custom; + DefaultFileLogWriter.CustomLocation = LogPath; + } + else if (System.Reflection.Assembly.GetEntryAssembly() != null) + { + DefaultFileLogWriter.Location = Microsoft.VisualBasic.Logging.LogFileLocation.ExecutableDirectory; + } + + DefaultFileLogWriter.Append = true; + DefaultFileLogWriter.AutoFlush = true; + DefaultFileLogWriter.Delimiter = ";"; + DefaultFileLogWriter.MaxFileSize = 2621440000; //2500 MB + DefaultFileLogWriter.ReserveDiskSpace = 1048576000; //1000 MB + DefaultFileLogWriter.LogFileCreationSchedule = Microsoft.VisualBasic.Logging.LogFileCreationScheduleOption.Daily; + if (System.Configuration.ConfigurationManager.AppSettings["Debug"] == "true") + TraceSource.Switch.Level = SourceLevels.All; + else + TraceSource.Switch.Level = SourceLevels.Information; + + WriteEntry("Starting log..."); + WriteEntry("Log instance created"); + } + + public Log(string name) + : this() + { + DefaultFileLogWriter.BaseFileName = name; + } + + public Log(string name, string logPath, SourceLevels level) + : this() + { + DefaultFileLogWriter.CustomLocation = System.IO.Path.GetDirectoryName(logPath); + DefaultFileLogWriter.BaseFileName = name; + DefaultFileLogWriter.Location = Microsoft.VisualBasic.Logging.LogFileLocation.Custom; + DefaultFileLogWriter.CustomLocation = logPath; + DefaultFileLogWriter.Append = true; + DefaultFileLogWriter.AutoFlush = true; + DefaultFileLogWriter.Delimiter = ";"; + DefaultFileLogWriter.MaxFileSize = 2621440000; //2500 MB + DefaultFileLogWriter.ReserveDiskSpace = 1048576000; //1000 MB + DefaultFileLogWriter.LogFileCreationSchedule = Microsoft.VisualBasic.Logging.LogFileCreationScheduleOption.Daily; + TraceSource.Switch.Level = level; + + WriteEntry("Starting log..."); + WriteEntry("Log instance created"); + } + + public void Dispose() + { + WriteEntry("Log Class gets disposed."); + WriteEntry("Closing log..."); + DefaultFileLogWriter.Close(); + } + + public void WriteFunctionEntry() + { + string message = string.Empty; + + string callingMethod = new StackFrame(1, true).GetMethod().Name; + string callingClass = new StackFrame(1, true).GetMethod().ReflectedType.Name; + + message = string.Format("{0} : {1}(", callingClass, callingMethod); + + System.Reflection.ParameterInfo[] parameterInfos = new StackFrame(1, true).GetMethod().GetParameters(); + foreach (System.Reflection.ParameterInfo parameterInfo in parameterInfos) + { + message += parameterInfo.ParameterType.Name + " " + parameterInfo.Name + ", "; + } + + //remove the "," at the end of the line + if (message.EndsWith(", ")) { message = message.Substring(0, message.Length - 2); } + + message += ") : entering..."; + + WriteEntry(message, TraceEventType.Verbose); + } + + public void WriteFunctionEntry(params object[] args) + { + string message = string.Empty; + + string callingMethod = new StackFrame(1, true).GetMethod().Name; + string callingClass = new StackFrame(1, true).GetMethod().ReflectedType.Name; + + message = string.Format("{0} : {1}(", callingClass, callingMethod); + + System.Reflection.ParameterInfo[] parameterInfos = new StackFrame(1, true).GetMethod().GetParameters(); + if (parameterInfos.Length != args.Length) + { + throw new ParameterCountMismatchArgumentCountException(); + } + + int parameterIterator = 0; + foreach (System.Reflection.ParameterInfo parameterInfo in parameterInfos) + { + message += parameterInfo.ParameterType.Name + " " + parameterInfo.Name; + message += string.Format("={0}, ", + args[parameterIterator] != null ? + args[parameterIterator].ToString() : + "null"); + parameterIterator++; + } + + //remove the "," at the end of the line + if (message.EndsWith(", ")) { message = message.Substring(0, message.Length - 2); } + + message += ") : entering..."; + + WriteEntry(message, TraceEventType.Verbose); + } + + public void WriteFunctionExit() + { + string message = string.Empty; + + string callingMethod = new StackFrame(1, true).GetMethod().Name; + string callingClass = new StackFrame(1, true).GetMethod().ReflectedType.Name; + + message = string.Format("{0} : {1}(", callingClass, callingMethod); + + System.Reflection.ParameterInfo[] parameterInfos = new StackFrame(1, true).GetMethod().GetParameters(); + foreach (System.Reflection.ParameterInfo parameterInfo in parameterInfos) + { + message += parameterInfo.ParameterType.Name + " " + parameterInfo.Name + ", "; + } + + //remove the "," at the end of the line + if (message.EndsWith(", ")) { message = message.Substring(0, message.Length - 2); } + + message += ") : leaving..."; + + WriteEntry(message, TraceEventType.Verbose); + } + + public void WriteFunctionExit(object returnValue) + { + string message = string.Empty; + + string callingMethod = new StackFrame(1, true).GetMethod().Name; + string callingClass = new StackFrame(1, true).GetMethod().ReflectedType.Name; + + message = string.Format("{0} : {1}(", callingClass, callingMethod); + + System.Reflection.ParameterInfo[] parameterInfos = new StackFrame(1, true).GetMethod().GetParameters(); + foreach (System.Reflection.ParameterInfo parameterInfo in parameterInfos) + { + message += parameterInfo.ParameterType.Name + " " + parameterInfo.Name + ", "; + } + + //remove the "," at the end of the line + if (message.EndsWith(", ")) { message = message.Substring(0, message.Length - 2); } + + message += ") : leaving... ReturnValue is " + returnValue.ToString(); + + WriteEntry(message, TraceEventType.Verbose); + } + + public void WriteFunctionExitWithError(Exception ex) + { + string message = string.Empty; + string error = ex.GetType().Name; + if (!string.IsNullOrEmpty(error)) + { + error += ": " + ex.Message; + } + + string callingMethod = new StackFrame(1, true).GetMethod().Name; + string callingClass = new StackFrame(1, true).GetMethod().ReflectedType.Name; + + message = string.Format("{0} : {1}(", callingClass, callingMethod); + + System.Reflection.ParameterInfo[] parameterInfos = new StackFrame(1, true).GetMethod().GetParameters(); + foreach (System.Reflection.ParameterInfo parameterInfo in parameterInfos) + { + message += parameterInfo.ParameterType.Name + " " + parameterInfo.Name + ", "; + } + + //remove the "," at the end of the line + if (message.EndsWith(", ")) { message = message.Substring(0, message.Length - 2); } + + message += ") : leaving with error '" + error + "'"; + + WriteEntry(message, TraceEventType.Error); + } + + private new void WriteEntry(string message, TraceEventType severity) + { + message = string.Format("{0}:{1}:{2}.{3};{4}", + DateTime.Now.Hour, + DateTime.Now.Minute, + DateTime.Now.Second, + DateTime.Now.Millisecond, + message); + base.WriteEntry(message, severity); + } + + private new void WriteEntry(string message) + { + WriteEntry(message, TraceEventType.Information); + } + + public void WriteEntry(string message, TraceEventType severity, params object[] args) + { + string callingMethod = new StackFrame(1, true).GetMethod().Name; + string callingClass = new StackFrame(1, true).GetMethod().ReflectedType.Name; + + message = string.Format(message, args); + string messageHeader = string.Format("{0} : {1}", callingClass, callingMethod); + message = string.Format("{0};{1}", messageHeader, message); + + WriteEntry(message, severity); + } + + private void WriteEntry(string message, params object[] args) + { + message = string.Format(message, args); + WriteEntry(message, TraceEventType.Information); + } + } + } + #endregion Log +} \ No newline at end of file diff --git a/Log/Log.csproj b/Log/Log.csproj new file mode 100644 index 0000000..75519e2 --- /dev/null +++ b/Log/Log.csproj @@ -0,0 +1,59 @@ + + + + + Debug + AnyCPU + {66624E57-402E-44F4-A072-9DB1827A5E20} + Library + Properties + Log + Log + v3.5 + 512 + SAK + SAK + SAK + SAK + Client + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Log/Properties/AssemblyInfo.cs b/Log/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4dfa911 --- /dev/null +++ b/Log/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Log")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Log")] +[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("642209e6-51c3-4e00-936f-e0a41b3c65de")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/NTFSSecurity.sln b/NTFSSecurity.sln new file mode 100644 index 0000000..a562711 --- /dev/null +++ b/NTFSSecurity.sln @@ -0,0 +1,122 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NTFSSecurity", "NTFSSecurity\NTFSSecurity.csproj", "{17768E1A-1422-4BD2-A9A5-42BA9FEB82B8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Security2", "Security2\Security2.csproj", "{B437C364-5BC7-42E4-93F7-0F459A5DF0D0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestClient", "TestClient\TestClient.csproj", "{DE60760F-53BD-4C54-9469-BD96DF0C2B20}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PrivilegeControl", "PrivilegeControl\PrivilegeControl.csproj", "{01EAB41B-B2CE-49FE-AB5A-0F0FF0A9A7EE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProcessPrivileges", "ProcessPrivileges\ProcessPrivileges.csproj", "{410CAEE5-D287-4A18-9B38-BB87397D218D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Log", "Log\Log.csproj", "{66624E57-402E-44F4-A072-9DB1827A5E20}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AlphaFS", "AlphaFS\AlphaFS.csproj", "{F0F9AF1E-D5B5-4D72-804A-5380622FBDEA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NTFSSecurityTest", "NTFSSecurityTest\NTFSSecurityTest.csproj", "{675D40FA-F56C-4ACC-B863-18B4A14F93E0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {17768E1A-1422-4BD2-A9A5-42BA9FEB82B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17768E1A-1422-4BD2-A9A5-42BA9FEB82B8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17768E1A-1422-4BD2-A9A5-42BA9FEB82B8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {17768E1A-1422-4BD2-A9A5-42BA9FEB82B8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {17768E1A-1422-4BD2-A9A5-42BA9FEB82B8}.Debug|x86.ActiveCfg = Debug|Any CPU + {17768E1A-1422-4BD2-A9A5-42BA9FEB82B8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17768E1A-1422-4BD2-A9A5-42BA9FEB82B8}.Release|Any CPU.Build.0 = Release|Any CPU + {17768E1A-1422-4BD2-A9A5-42BA9FEB82B8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {17768E1A-1422-4BD2-A9A5-42BA9FEB82B8}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {17768E1A-1422-4BD2-A9A5-42BA9FEB82B8}.Release|x86.ActiveCfg = Release|Any CPU + {B437C364-5BC7-42E4-93F7-0F459A5DF0D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B437C364-5BC7-42E4-93F7-0F459A5DF0D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B437C364-5BC7-42E4-93F7-0F459A5DF0D0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B437C364-5BC7-42E4-93F7-0F459A5DF0D0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B437C364-5BC7-42E4-93F7-0F459A5DF0D0}.Debug|x86.ActiveCfg = Debug|Any CPU + {B437C364-5BC7-42E4-93F7-0F459A5DF0D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B437C364-5BC7-42E4-93F7-0F459A5DF0D0}.Release|Any CPU.Build.0 = Release|Any CPU + {B437C364-5BC7-42E4-93F7-0F459A5DF0D0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B437C364-5BC7-42E4-93F7-0F459A5DF0D0}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {B437C364-5BC7-42E4-93F7-0F459A5DF0D0}.Release|x86.ActiveCfg = Release|Any CPU + {DE60760F-53BD-4C54-9469-BD96DF0C2B20}.Debug|Any CPU.ActiveCfg = Debug|x86 + {DE60760F-53BD-4C54-9469-BD96DF0C2B20}.Debug|Any CPU.Build.0 = Debug|x86 + {DE60760F-53BD-4C54-9469-BD96DF0C2B20}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 + {DE60760F-53BD-4C54-9469-BD96DF0C2B20}.Debug|Mixed Platforms.Build.0 = Debug|x86 + {DE60760F-53BD-4C54-9469-BD96DF0C2B20}.Debug|x86.ActiveCfg = Debug|x86 + {DE60760F-53BD-4C54-9469-BD96DF0C2B20}.Debug|x86.Build.0 = Debug|x86 + {DE60760F-53BD-4C54-9469-BD96DF0C2B20}.Release|Any CPU.ActiveCfg = Release|x86 + {DE60760F-53BD-4C54-9469-BD96DF0C2B20}.Release|Any CPU.Build.0 = Release|x86 + {DE60760F-53BD-4C54-9469-BD96DF0C2B20}.Release|Mixed Platforms.ActiveCfg = Release|x86 + {DE60760F-53BD-4C54-9469-BD96DF0C2B20}.Release|Mixed Platforms.Build.0 = Release|x86 + {DE60760F-53BD-4C54-9469-BD96DF0C2B20}.Release|x86.ActiveCfg = Release|x86 + {DE60760F-53BD-4C54-9469-BD96DF0C2B20}.Release|x86.Build.0 = Release|x86 + {01EAB41B-B2CE-49FE-AB5A-0F0FF0A9A7EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {01EAB41B-B2CE-49FE-AB5A-0F0FF0A9A7EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {01EAB41B-B2CE-49FE-AB5A-0F0FF0A9A7EE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {01EAB41B-B2CE-49FE-AB5A-0F0FF0A9A7EE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {01EAB41B-B2CE-49FE-AB5A-0F0FF0A9A7EE}.Debug|x86.ActiveCfg = Debug|Any CPU + {01EAB41B-B2CE-49FE-AB5A-0F0FF0A9A7EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {01EAB41B-B2CE-49FE-AB5A-0F0FF0A9A7EE}.Release|Any CPU.Build.0 = Release|Any CPU + {01EAB41B-B2CE-49FE-AB5A-0F0FF0A9A7EE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {01EAB41B-B2CE-49FE-AB5A-0F0FF0A9A7EE}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {01EAB41B-B2CE-49FE-AB5A-0F0FF0A9A7EE}.Release|x86.ActiveCfg = Release|Any CPU + {410CAEE5-D287-4A18-9B38-BB87397D218D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {410CAEE5-D287-4A18-9B38-BB87397D218D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {410CAEE5-D287-4A18-9B38-BB87397D218D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {410CAEE5-D287-4A18-9B38-BB87397D218D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {410CAEE5-D287-4A18-9B38-BB87397D218D}.Debug|x86.ActiveCfg = Debug|Any CPU + {410CAEE5-D287-4A18-9B38-BB87397D218D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {410CAEE5-D287-4A18-9B38-BB87397D218D}.Release|Any CPU.Build.0 = Release|Any CPU + {410CAEE5-D287-4A18-9B38-BB87397D218D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {410CAEE5-D287-4A18-9B38-BB87397D218D}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {410CAEE5-D287-4A18-9B38-BB87397D218D}.Release|x86.ActiveCfg = Release|Any CPU + {66624E57-402E-44F4-A072-9DB1827A5E20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {66624E57-402E-44F4-A072-9DB1827A5E20}.Debug|Any CPU.Build.0 = Debug|Any CPU + {66624E57-402E-44F4-A072-9DB1827A5E20}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {66624E57-402E-44F4-A072-9DB1827A5E20}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {66624E57-402E-44F4-A072-9DB1827A5E20}.Debug|x86.ActiveCfg = Debug|Any CPU + {66624E57-402E-44F4-A072-9DB1827A5E20}.Release|Any CPU.ActiveCfg = Release|Any CPU + {66624E57-402E-44F4-A072-9DB1827A5E20}.Release|Any CPU.Build.0 = Release|Any CPU + {66624E57-402E-44F4-A072-9DB1827A5E20}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {66624E57-402E-44F4-A072-9DB1827A5E20}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {66624E57-402E-44F4-A072-9DB1827A5E20}.Release|x86.ActiveCfg = Release|Any CPU + {F0F9AF1E-D5B5-4D72-804A-5380622FBDEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F0F9AF1E-D5B5-4D72-804A-5380622FBDEA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F0F9AF1E-D5B5-4D72-804A-5380622FBDEA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {F0F9AF1E-D5B5-4D72-804A-5380622FBDEA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {F0F9AF1E-D5B5-4D72-804A-5380622FBDEA}.Debug|x86.ActiveCfg = Debug|Any CPU + {F0F9AF1E-D5B5-4D72-804A-5380622FBDEA}.Debug|x86.Build.0 = Debug|Any CPU + {F0F9AF1E-D5B5-4D72-804A-5380622FBDEA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F0F9AF1E-D5B5-4D72-804A-5380622FBDEA}.Release|Any CPU.Build.0 = Release|Any CPU + {F0F9AF1E-D5B5-4D72-804A-5380622FBDEA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {F0F9AF1E-D5B5-4D72-804A-5380622FBDEA}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {F0F9AF1E-D5B5-4D72-804A-5380622FBDEA}.Release|x86.ActiveCfg = Release|Any CPU + {F0F9AF1E-D5B5-4D72-804A-5380622FBDEA}.Release|x86.Build.0 = Release|Any CPU + {675D40FA-F56C-4ACC-B863-18B4A14F93E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {675D40FA-F56C-4ACC-B863-18B4A14F93E0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {675D40FA-F56C-4ACC-B863-18B4A14F93E0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {675D40FA-F56C-4ACC-B863-18B4A14F93E0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {675D40FA-F56C-4ACC-B863-18B4A14F93E0}.Debug|x86.ActiveCfg = Debug|Any CPU + {675D40FA-F56C-4ACC-B863-18B4A14F93E0}.Debug|x86.Build.0 = Debug|Any CPU + {675D40FA-F56C-4ACC-B863-18B4A14F93E0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {675D40FA-F56C-4ACC-B863-18B4A14F93E0}.Release|Any CPU.Build.0 = Release|Any CPU + {675D40FA-F56C-4ACC-B863-18B4A14F93E0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {675D40FA-F56C-4ACC-B863-18B4A14F93E0}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {675D40FA-F56C-4ACC-B863-18B4A14F93E0}.Release|x86.ActiveCfg = Release|Any CPU + {675D40FA-F56C-4ACC-B863-18B4A14F93E0}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/NTFSSecurity/AccessCmdlets/AddAccess.cs b/NTFSSecurity/AccessCmdlets/AddAccess.cs new file mode 100644 index 0000000..b48f7f8 --- /dev/null +++ b/NTFSSecurity/AccessCmdlets/AddAccess.cs @@ -0,0 +1,184 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Linq; +using System.Management.Automation; +using System.Security.AccessControl; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Add, "NTFSAccess", DefaultParameterSetName = "PathComplex")] + [OutputType(typeof(FileSystemAccessRule2))] + public class AddAccess : BaseCmdletWithPrivControl + { + private IdentityReference2[] account; + private FileSystemRights2 accessRights; + private AccessControlType accessType = AccessControlType.Allow; + private InheritanceFlags inheritanceFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit; + private PropagationFlags propagationFlags = PropagationFlags.None; + private ApplyTo appliesTo = ApplyTo.ThisFolderSubfoldersAndFiles; + private bool passThru; + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "PathSimple")] + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "PathComplex")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SDSimple")] + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SDComplex")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 2, ValueFromPipelineByPropertyName = true)] + [Alias("IdentityReference, ID")] + public IdentityReference2[] Account + { + get { return account; } + set { account = value; } + } + + [Parameter(Mandatory = true, Position = 3, ValueFromPipelineByPropertyName = true)] + [Alias("FileSystemRights")] + public FileSystemRights2 AccessRights + { + get { return accessRights; } + set { accessRights = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true)] + [Alias("AccessControlType")] + public AccessControlType AccessType + { + get { return accessType; } + set { accessType = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "PathComplex")] + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "SDComplex")] + public InheritanceFlags InheritanceFlags + { + get { return inheritanceFlags; } + set { inheritanceFlags = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "PathComplex")] + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "SDComplex")] + public PropagationFlags PropagationFlags + { + get { return propagationFlags; } + set { propagationFlags = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "PathSimple")] + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "SDSimple")] + public ApplyTo AppliesTo + { + get { return appliesTo; } + set { appliesTo = value; } + } + + [Parameter] + public SwitchParameter PassThru + { + get { return passThru; } + set { passThru = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + } + + protected override void ProcessRecord() + { + if (ParameterSetName.EndsWith("Simple")) + { + FileSystemSecurity2.ConvertToFileSystemFlags(appliesTo, out inheritanceFlags, out propagationFlags); + } + + if (ParameterSetName.StartsWith("Path")) + { + FileSystemInfo item = null; + + foreach (var path in paths) + { + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + FileSystemAccessRule2.AddFileSystemAccessRule(item, account.ToList(), accessRights, accessType, inheritanceFlags, propagationFlags); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + FileSystemAccessRule2.AddFileSystemAccessRule(item, account.ToList(), accessRights, accessType, inheritanceFlags, propagationFlags); + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "AddAceError", ErrorCategory.WriteError, path)); + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "AddAceError", ErrorCategory.WriteError, path)); + } + + if (passThru == true) + { + FileSystemAccessRule2.GetFileSystemAccessRules(item, true, true).ForEach(ace => WriteObject(ace)); + } + } + } + else + { + foreach (var sd in securityDescriptors) + { + FileSystemAccessRule2.AddFileSystemAccessRule(sd, account.ToList(), accessRights, accessType, inheritanceFlags, propagationFlags); + + if (passThru == true) + { + FileSystemAccessRule2.GetFileSystemAccessRules(sd, true, true).ForEach(ace => WriteObject(ace)); + } + } + } + + } + protected override void EndProcessing() + { + base.EndProcessing(); + } + } +} diff --git a/NTFSSecurity/AccessCmdlets/ClearAccess.cs b/NTFSSecurity/AccessCmdlets/ClearAccess.cs new file mode 100644 index 0000000..20b1943 --- /dev/null +++ b/NTFSSecurity/AccessCmdlets/ClearAccess.cs @@ -0,0 +1,118 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Clear, "NTFSAccess", DefaultParameterSetName = "Path")] + public class ClearAccess : BaseCmdletWithPrivControl + { + private SwitchParameter disableInheritance; + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SD")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + [Parameter] + public SwitchParameter DisableInheritance + { + get { return disableInheritance; } + set { disableInheritance = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + } + + protected override void ProcessRecord() + { + + if (ParameterSetName == "Path") + { + FileSystemInfo item = null; + + foreach (var path in paths) + { + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + FileSystemAccessRule2.RemoveFileSystemAccessRuleAll(item); + if (disableInheritance) + FileSystemInheritanceInfo.DisableAccessInheritance(item, true); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + FileSystemAccessRule2.RemoveFileSystemAccessRuleAll(item); + if (disableInheritance) + FileSystemInheritanceInfo.DisableAccessInheritance(item, true); + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "ClearAclError", ErrorCategory.WriteError, path)); + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ClearAclError", ErrorCategory.WriteError, path)); + } + } + } + else + { + foreach (var sd in securityDescriptors) + { + FileSystemAccessRule2.RemoveFileSystemAccessRuleAll(sd); + if (disableInheritance) + FileSystemInheritanceInfo.DisableAccessInheritance(sd, true); + } + } + + } + + protected override void EndProcessing() + { + base.EndProcessing(); + } + } +} diff --git a/NTFSSecurity/AccessCmdlets/GetAccess.cs b/NTFSSecurity/AccessCmdlets/GetAccess.cs new file mode 100644 index 0000000..0f091b4 --- /dev/null +++ b/NTFSSecurity/AccessCmdlets/GetAccess.cs @@ -0,0 +1,155 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Get, "NTFSAccess", DefaultParameterSetName = "Path")] + [OutputType(typeof(FileSystemAccessRule2))] + public class GetAccess : BaseCmdletWithPrivControl + { + private bool excludeInherited; + private bool excludeExplicit; + private IdentityReference2 account; + + protected bool getInheritedFrom = false; + + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SD")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + [Parameter(ValueFromRemainingArguments = true)] + [Alias("IdentityReference, ID")] + [ValidateNotNullOrEmpty] + public IdentityReference2 Account + { + get { return account; } + set { account = value; } + } + + [Parameter] + public SwitchParameter ExcludeExplicit + { + get { return excludeExplicit; } + set { excludeExplicit = value; } + } + + [Parameter] + public SwitchParameter ExcludeInherited + { + get { return excludeInherited; } + set { excludeInherited = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + + getInheritedFrom = (bool)((System.Collections.Hashtable)MyInvocation.MyCommand.Module.PrivateData)["GetInheritedFrom"]; + + if (paths.Count == 0) + { + paths = new List() { GetVariableValue("PWD").ToString() }; + } + } + + protected override void ProcessRecord() + { + IEnumerable acl = null; + FileSystemInfo item = null; + + if (ParameterSetName == "Path") + { + foreach (var path in paths) + { + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + acl = FileSystemAccessRule2.GetFileSystemAccessRules(item, !excludeExplicit, !excludeInherited, getInheritedFrom); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + acl = FileSystemAccessRule2.GetFileSystemAccessRules(item, !excludeExplicit, !excludeInherited, getInheritedFrom); + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "ReadSecurityError", ErrorCategory.WriteError, path)); + continue; + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadSecurityError", ErrorCategory.OpenError, path)); + continue; + } + finally + { + if (acl != null) + { + if (account != null) + { + acl = acl.Where(ace => ace.Account == account); + } + + acl.ForEach(ace => WriteObject(ace)); + } + } + } + } + else + { + foreach (var sd in securityDescriptors) + { + acl = FileSystemAccessRule2.GetFileSystemAccessRules(sd, !excludeExplicit, !excludeInherited, getInheritedFrom); + + if (account != null) + { + acl = acl.Where(ace => ace.Account == account); + } + + acl.ForEach(ace => WriteObject(ace)); + } + } + } + } +} diff --git a/NTFSSecurity/AccessCmdlets/GetEffectiveAccess.cs b/NTFSSecurity/AccessCmdlets/GetEffectiveAccess.cs new file mode 100644 index 0000000..d91a873 --- /dev/null +++ b/NTFSSecurity/AccessCmdlets/GetEffectiveAccess.cs @@ -0,0 +1,194 @@ +using Alphaleonis.Win32.Filesystem; +using ProcessPrivileges; +using Security2; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Get, "NTFSEffectiveAccess", DefaultParameterSetName = "Path")] + [OutputType(typeof(FileSystemAccessRule2))] + public class GetEffectiveAccess : BaseCmdletWithPrivControl + { + private IdentityReference2 account = System.Security.Principal.WindowsIdentity.GetCurrent().User.Value; + private SwitchParameter excludeNoneAccessEntries; + private string serverName = "localhost"; + private IEnumerable securityPrivilege; + + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SecurityDescriptor")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + [Parameter(Position = 2, ValueFromPipelineByPropertyName = true)] + [Alias("NTAccount", "IdentityReference")] + [ValidateNotNullOrEmpty] + public IdentityReference2 Account + { + get { return account; } + set { account = value; } + } + + [Parameter] + public string ServerName + { + get { return serverName; } + set { serverName = value; } + } + + [Parameter()] + public SwitchParameter ExcludeNoneAccessEntries + { + get { return excludeNoneAccessEntries; } + set { excludeNoneAccessEntries = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + + if (paths == null) + { + paths = new List() { GetVariableValue("PWD").ToString() }; + } + + var securityPrivilege = privControl.GetPrivileges().Where(priv => priv.Privilege == ProcessPrivileges.Privilege.Security); + if (securityPrivilege.Count() == 0) + { + this.WriteWarning("The user does not hold the Security Privliege and might not be able to read the effective permissions"); + } + else + { + if (securityPrivilege.FirstOrDefault().PrivilegeState == PrivilegeState.Disabled) + { + this.WriteWarning("The user does hold the Security Privilege but it is disabled. Hence getting effective permissions might not be possible. Use 'Enable-Privileges' to enable it"); + } + } + } + + protected override void ProcessRecord() + { + FileSystemInfo item = null; + + foreach (var path in paths) + { + EffectiveAccessInfo result = null; + + try + { + item = this.GetFileSystemInfo2(path); + } + catch (Exception ex) + { + this.WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + result = EffectiveAccess.GetEffectiveAccess(item, account, serverName); + + if (!result.FromRemote) + { + WriteWarning("The effective rights can only be computed based on group membership on this" + + " computer. For more accurate results, calculate effective access rights on " + + "the target computer"); + } + if (result.OperationFailed && securityPrivilege == null) + { + var ex = new Exception(string.Format("Could not get effective permissions from machine '{0}' maybe because the 'Security' privilege is not enabled which might be required. Enable the priviliges using 'Enable-Privileges'. The error was '{1}'", serverName, result.AuthzException.Message), result.AuthzException); + WriteError(new ErrorRecord(ex, "GetEffectiveAccessError", ErrorCategory.ReadError, item)); + continue; + } + else if (result.OperationFailed) + { + var ex = new Exception(string.Format("Could not get effective permissions from machine '{0}'. The error is '{1}'", serverName, result.AuthzException.Message), result.AuthzException); + WriteError(new ErrorRecord(ex, "GetEffectiveAccessError", ErrorCategory.ReadError, item)); + continue; + } + + if (excludeNoneAccessEntries && result.Ace.AccessRights == FileSystemRights2.None) + continue; + } + //not sure if the following catch block willb be invoked, testing needed. + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + //-------------------- + + result = EffectiveAccess.GetEffectiveAccess(item, account, serverName); + + if (!result.FromRemote) + { + WriteWarning("The effective rights can only be computed based on group membership on this" + + " computer. For more accurate results, calculate effective access rights on " + + "the target computer"); + } + if (result.OperationFailed && securityPrivilege == null) + { + var ex = new Exception(string.Format("Could not get effective permissions from machine '{0}' maybe because the 'Security' privilege is not enabled which might be required. Enable the priviliges using 'Enable-Privileges'. The error was '{1}'", serverName, result.AuthzException.Message), result.AuthzException); + WriteError(new ErrorRecord(ex, "GetEffectiveAccessError", ErrorCategory.ReadError, item)); + continue; + } + else if (result.OperationFailed) + { + var ex = new Exception(string.Format("Could not get effective permissions from machine '{0}'. The error is '{1}'", serverName, result.AuthzException.Message), result.AuthzException); + WriteError(new ErrorRecord(ex, "GetEffectiveAccessError", ErrorCategory.ReadError, item)); + continue; + } + + if (excludeNoneAccessEntries && result.Ace.AccessRights == FileSystemRights2.None) + continue; + + //-------------------- + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + this.WriteError(new ErrorRecord(ex2, "ReadSecurityError", ErrorCategory.WriteError, path)); + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadEffectivePermissionError", ErrorCategory.ReadError, path)); + } + finally + { + if (result != null) + { + WriteObject(result.Ace); + } + } + } + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/AccessCmdlets/GetOrphanedAccess.cs b/NTFSSecurity/AccessCmdlets/GetOrphanedAccess.cs new file mode 100644 index 0000000..3e7ba2d --- /dev/null +++ b/NTFSSecurity/AccessCmdlets/GetOrphanedAccess.cs @@ -0,0 +1,80 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Get, "NTFSOrphanedAccess")] + [OutputType(typeof(FileSystemAccessRule2))] + public class GetOrphanedAccess : GetAccess + { + int orphanedSidCount = 0; + + protected override void ProcessRecord() + { + IEnumerable acl = null; + FileSystemInfo item = null; + + foreach (var path in paths) + { + try + { + item = this.GetFileSystemInfo2(path); + } + catch (Exception ex) + { + this.WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + acl = FileSystemAccessRule2.GetFileSystemAccessRules(item, !ExcludeExplicit, !ExcludeInherited, getInheritedFrom); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + acl = FileSystemAccessRule2.GetFileSystemAccessRules(item, !ExcludeExplicit, !ExcludeInherited, getInheritedFrom); + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + this.WriteError(new ErrorRecord(ex2, "AddAceError", ErrorCategory.WriteError, path)); + } + } + catch (Exception ex) + { + this.WriteWarning(string.Format("Could not read item {0}. The error was: {1}", path, ex.Message)); + } + finally + { + if (acl != null) + { + var orphanedAces = acl.Where(ace => string.IsNullOrEmpty(ace.Account.AccountName)); + orphanedSidCount += orphanedAces.Count(); + + WriteVerbose(string.Format("Item {0} knows about {1} orphaned SIDs in its ACL", path, orphanedAces.Count())); + + orphanedAces.ForEach(ace => WriteObject(ace)); + } + } + } + } + + protected override void EndProcessing() + { + WriteVerbose(string.Format("Total orphaned Access Control Enties: {0}", orphanedSidCount)); + base.EndProcessing(); + } + } +} diff --git a/NTFSSecurity/AccessCmdlets/RemoveAccess.cs b/NTFSSecurity/AccessCmdlets/RemoveAccess.cs new file mode 100644 index 0000000..d7770a8 --- /dev/null +++ b/NTFSSecurity/AccessCmdlets/RemoveAccess.cs @@ -0,0 +1,189 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Linq; +using System.Management.Automation; +using System.Security.AccessControl; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Remove, "NTFSAccess", DefaultParameterSetName = "PathComplex")] + [OutputType(typeof(FileSystemAccessRule2))] + public class RemoveAccess : BaseCmdletWithPrivControl + { + private IdentityReference2[] account; + private FileSystemRights2 accessRights; + private AccessControlType accessType = AccessControlType.Allow; + private InheritanceFlags inheritanceFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit; + private PropagationFlags propagationFlags = PropagationFlags.None; + private ApplyTo appliesTo; + private bool removeSpecific; + private bool passThru; + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "PathSimple")] + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "PathComplex")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SDSimple")] + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SDComplex")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 2, ValueFromPipelineByPropertyName = true)] + [Alias("IdentityReference, ID")] + public IdentityReference2[] Account + { + get { return account; } + set { account = value; } + } + + [Parameter(Mandatory = true, Position = 3, ValueFromPipelineByPropertyName = true)] + [Alias("FileSystemRights")] + public FileSystemRights2 AccessRights + { + get { return accessRights; } + set { accessRights = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true)] + [Alias("AccessControlType")] + public AccessControlType AccessType + { + get { return accessType; } + set { accessType = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "PathComplex")] + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "SDComplex")] + public InheritanceFlags InheritanceFlags + { + get { return inheritanceFlags; } + set { inheritanceFlags = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "PathComplex")] + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "SDComplex")] + public PropagationFlags PropagationFlags + { + get { return propagationFlags; } + set { propagationFlags = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "PathSimple")] + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "SDSimple")] + public ApplyTo AppliesTo + { + get { return appliesTo; } + set { appliesTo = value; } + } + + [Parameter] + public SwitchParameter PassThru + { + get { return passThru; } + set { passThru = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + } + + protected override void ProcessRecord() + { + if (ParameterSetName.EndsWith("Simple")) + { + FileSystemSecurity2.ConvertToFileSystemFlags(appliesTo, out inheritanceFlags, out propagationFlags); + } + + if (ParameterSetName.StartsWith("Path")) + { + foreach (var path in paths) + { + FileSystemInfo item = null; + + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + } + + if (ParameterSetName == "PathSimple") + { + FileSystemSecurity2.ConvertToFileSystemFlags(appliesTo, out inheritanceFlags, out propagationFlags); + } + + try + { + FileSystemAccessRule2.RemoveFileSystemAccessRule(item, account.ToList(), accessRights, accessType, inheritanceFlags, propagationFlags); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + FileSystemAccessRule2.RemoveFileSystemAccessRule(item, account.ToList(), accessRights, accessType, inheritanceFlags, propagationFlags); + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "RemoveAceError", ErrorCategory.WriteError, path)); + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "RemoveAceError", ErrorCategory.WriteError, path)); + } + + if (passThru == true) + { + FileSystemAccessRule2.GetFileSystemAccessRules(item, true, true).ForEach(ace => WriteObject(ace)); + } + } + } + else + { + foreach (var sd in securityDescriptors) + { + FileSystemAccessRule2.RemoveFileSystemAccessRule(sd, account.ToList(), accessRights, accessType, inheritanceFlags, propagationFlags); + + if (passThru == true) + { + FileSystemAccessRule2.GetFileSystemAccessRules(sd, true, true).ForEach(ace => WriteObject(ace)); + } + } + } + } + + protected override void EndProcessing() + { + base.EndProcessing(); + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/AuditCmdlets/AddAudit.cs b/NTFSSecurity/AuditCmdlets/AddAudit.cs new file mode 100644 index 0000000..2d2d140 --- /dev/null +++ b/NTFSSecurity/AuditCmdlets/AddAudit.cs @@ -0,0 +1,183 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Linq; +using System.Management.Automation; +using System.Security.AccessControl; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Add, "NTFSAudit", DefaultParameterSetName = "PathComplex")] + [OutputType(typeof(FileSystemAccessRule2))] + public class AddAudit : BaseCmdletWithPrivControl + { + private IdentityReference2[] account; + private FileSystemRights2 accessRights; + private AuditFlags auditFlags = AuditFlags.Failure | AuditFlags.Success; + private InheritanceFlags inheritanceFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit; + private PropagationFlags propagationFlags = PropagationFlags.None; + private ApplyTo appliesTo = ApplyTo.ThisFolderSubfoldersAndFiles; + private bool passThru; + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "PathSimple")] + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "PathComplex")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SDSimple")] + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SDComplex")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 2, ValueFromPipelineByPropertyName = true)] + [Alias("IdentityReference, ID")] + public IdentityReference2[] Account + { + get { return account; } + set { account = value; } + } + + [Parameter(Mandatory = true, Position = 2, ValueFromPipelineByPropertyName = true)] + [Alias("FileSystemRights")] + public FileSystemRights2 AccessRights + { + get { return accessRights; } + set { accessRights = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true)] + public AuditFlags AuditFlags + { + get { return auditFlags; } + set { auditFlags = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "PathComplex")] + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "SDComplex")] + public InheritanceFlags InheritanceFlags + { + get { return inheritanceFlags; } + set { inheritanceFlags = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "PathComplex")] + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "SDComplex")] + public PropagationFlags PropagationFlags + { + get { return propagationFlags; } + set { propagationFlags = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "PathSimple")] + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "SDSimple")] + public ApplyTo AppliesTo + { + get { return appliesTo; } + set { appliesTo = value; } + } + + [Parameter] + public SwitchParameter PassThru + { + get { return passThru; } + set { passThru = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + } + + protected override void ProcessRecord() + { + if (ParameterSetName.EndsWith("Simple")) + { + FileSystemSecurity2.ConvertToFileSystemFlags(appliesTo, out inheritanceFlags, out propagationFlags); + } + + if (ParameterSetName.StartsWith("Path")) + { + FileSystemInfo item = null; + + foreach (var path in paths) + { + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + FileSystemAuditRule2.AddFileSystemAuditRule(item, account.ToList(), accessRights, auditFlags, inheritanceFlags, propagationFlags); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + FileSystemAuditRule2.AddFileSystemAuditRule(item, account.ToList(), accessRights, auditFlags, inheritanceFlags, propagationFlags); + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "AddAceError", ErrorCategory.WriteError, path)); + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "AddAceError", ErrorCategory.WriteError, path)); + } + + if (passThru == true) + { + FileSystemAuditRule2.GetFileSystemAuditRules(item, true, true).ForEach(ace => WriteObject(ace)); + } + } + } + else + { + foreach (var sd in securityDescriptors) + { + FileSystemAuditRule2.AddFileSystemAuditRule(sd, account.ToList(), accessRights, auditFlags, inheritanceFlags, propagationFlags); + + if (passThru == true) + { + FileSystemAccessRule2.GetFileSystemAccessRules(sd, true, true).ForEach(ace => WriteObject(ace)); + } + } + } + + } + protected override void EndProcessing() + { + base.EndProcessing(); + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/AuditCmdlets/ClearAudit.cs b/NTFSSecurity/AuditCmdlets/ClearAudit.cs new file mode 100644 index 0000000..c34bb29 --- /dev/null +++ b/NTFSSecurity/AuditCmdlets/ClearAudit.cs @@ -0,0 +1,118 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Clear, "NTFSAudit", DefaultParameterSetName = "Path")] + public class ClearAudit : BaseCmdletWithPrivControl + { + private SwitchParameter disableInheritance; + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SD")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + [Parameter] + public SwitchParameter DisableInheritance + { + get { return disableInheritance; } + set { disableInheritance = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + } + + protected override void ProcessRecord() + { + + if (ParameterSetName == "Path") + { + FileSystemInfo item = null; + + foreach (var path in paths) + { + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + FileSystemAuditRule2.RemoveFileSystemAuditRuleAll(item); + if (disableInheritance) + FileSystemInheritanceInfo.DisableAuditInheritance(item, true); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + FileSystemAuditRule2.RemoveFileSystemAuditRuleAll(item); + if (disableInheritance) + FileSystemInheritanceInfo.DisableAuditInheritance(item, true); + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "ClearAclError", ErrorCategory.WriteError, path)); + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ClearAclError", ErrorCategory.WriteError, path)); + } + } + } + else + { + foreach (var sd in securityDescriptors) + { + FileSystemAuditRule2.RemoveFileSystemAuditRuleAll(sd); + if (disableInheritance) + FileSystemInheritanceInfo.DisableAuditInheritance(sd, true); + } + } + + } + + protected override void EndProcessing() + { + base.EndProcessing(); + } + } +} diff --git a/NTFSSecurity/AuditCmdlets/Get-OrphanedAudit.cs b/NTFSSecurity/AuditCmdlets/Get-OrphanedAudit.cs new file mode 100644 index 0000000..91ce03f --- /dev/null +++ b/NTFSSecurity/AuditCmdlets/Get-OrphanedAudit.cs @@ -0,0 +1,56 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Management.Automation; + +namespace NTFSSecurity.AuditCmdlets +{ + [Cmdlet(VerbsCommon.Get, "NTFSOrphanedAudit")] + [OutputType(typeof(FileSystemAuditRule2))] + public class GetOrphanedAudit : GetAudit + { + int orphanedSidCount = 0; + + protected override void ProcessRecord() + { + IEnumerable acl; + FileSystemInfo item = null; + + foreach (var p in paths) + { + try + { + item = this.GetFileSystemInfo2(p); + } + catch (Exception ex) + { + this.WriteError(new ErrorRecord(ex, "ReadError", ErrorCategory.OpenError, p)); + continue; + } + + try + { + acl = FileSystemAuditRule2.GetFileSystemAuditRules(item, !ExcludeExplicit, !ExcludeInherited, getInheritedFrom); + + var orphanedAces = acl.Where(ace => string.IsNullOrEmpty(ace.Account.AccountName)); + orphanedSidCount += orphanedAces.Count(); + + this.WriteVerbose(string.Format("Item {0} knows about {1} orphaned SIDs in its ACL", p, orphanedAces.Count())); + this.WriteObject(orphanedAces); + } + catch (Exception ex) + { + this.WriteWarning(string.Format("Could not read item {0}. The error was: {1}", p, ex.Message)); + } + } + } + + protected override void EndProcessing() + { + WriteVerbose(string.Format("Total orphaned Access Control Enties: {0}", orphanedSidCount)); + base.EndProcessing(); + } + } +} diff --git a/NTFSSecurity/AuditCmdlets/GetAudit.cs b/NTFSSecurity/AuditCmdlets/GetAudit.cs new file mode 100644 index 0000000..1f8cd61 --- /dev/null +++ b/NTFSSecurity/AuditCmdlets/GetAudit.cs @@ -0,0 +1,155 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Get, "NTFSAudit")] + [OutputType(typeof(FileSystemAuditRule2))] + public class GetAudit : BaseCmdletWithPrivControl + { + private bool excludeInherited; + private bool excludeExplicit; + private IdentityReference2 account; + + protected bool getInheritedFrom = false; + + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SD")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + [Parameter(ValueFromRemainingArguments = true)] + [Alias("IdentityReference, ID")] + [ValidateNotNullOrEmpty] + public IdentityReference2 Account + { + get { return account; } + set { account = value; } + } + + [Parameter] + public SwitchParameter ExcludeExplicit + { + get { return excludeExplicit; } + set { excludeExplicit = value; } + } + + [Parameter] + public SwitchParameter ExcludeInherited + { + get { return excludeInherited; } + set { excludeInherited = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + + getInheritedFrom = (bool)((System.Collections.Hashtable)MyInvocation.MyCommand.Module.PrivateData)["GetInheritedFrom"]; + + if (paths.Count == 0) + { + paths = new List() { GetVariableValue("PWD").ToString() }; + } + } + + protected override void ProcessRecord() + { + IEnumerable acl = null; + FileSystemInfo item = null; + + if (ParameterSetName == "Path") + { + foreach (var path in paths) + { + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + acl = FileSystemAuditRule2.GetFileSystemAuditRules(item, !excludeExplicit, !excludeInherited, getInheritedFrom); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + acl = FileSystemAuditRule2.GetFileSystemAuditRules(item, !excludeExplicit, !excludeInherited, getInheritedFrom); + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "ReadSecurityError", ErrorCategory.WriteError, path)); + continue; + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadSecurityError", ErrorCategory.OpenError, path)); + continue; + } + finally + { + if (acl != null) + { + if (account != null) + { + acl = acl.Where(ace => ace.Account == account); + } + + acl.ForEach(ace => WriteObject(ace)); + } + } + } + } + else + { + foreach (var sd in securityDescriptors) + { + acl = FileSystemAuditRule2.GetFileSystemAuditRules(sd, !excludeExplicit, !excludeInherited, getInheritedFrom); + + if (account != null) + { + acl = acl.Where(ace => ace.Account == account); + } + + acl.ForEach(ace => WriteObject(ace)); + } + } + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/AuditCmdlets/RemoveAudit.cs b/NTFSSecurity/AuditCmdlets/RemoveAudit.cs new file mode 100644 index 0000000..dcff030 --- /dev/null +++ b/NTFSSecurity/AuditCmdlets/RemoveAudit.cs @@ -0,0 +1,188 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Linq; +using System.Management.Automation; +using System.Security.AccessControl; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Remove, "NTFSAudit", DefaultParameterSetName = "PathComplex")] + [OutputType(typeof(FileSystemAccessRule2))] + public class RemoveAudit : BaseCmdletWithPrivControl + { + private IdentityReference2[] account; + private FileSystemRights2 accessRights; + private AuditFlags auditFlags = AuditFlags.Failure | AuditFlags.Success; + private InheritanceFlags inheritanceFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit; + private PropagationFlags propagationFlags = PropagationFlags.None; + private ApplyTo appliesTo; + private bool removeSpecific; + private bool passThru; + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "PathSimple")] + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "PathComplex")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SDSimple")] + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SDComplex")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 2, ValueFromPipelineByPropertyName = true)] + [Alias("IdentityReference, ID")] + public IdentityReference2[] Account + { + get { return account; } + set { account = value; } + } + + [Parameter(Mandatory = true, Position = 3, ValueFromPipelineByPropertyName = true)] + [Alias("FileSystemRights")] + public FileSystemRights2 AccessRights + { + get { return accessRights; } + set { accessRights = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true)] + public AuditFlags AuditFlags + { + get { return auditFlags; } + set { auditFlags = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "PathComplex")] + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "SDComplex")] + public InheritanceFlags InheritanceFlags + { + get { return inheritanceFlags; } + set { inheritanceFlags = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "PathComplex")] + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "SDComplex")] + public PropagationFlags PropagationFlags + { + get { return propagationFlags; } + set { propagationFlags = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "PathSimple")] + [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = "SDSimple")] + public ApplyTo AppliesTo + { + get { return appliesTo; } + set { appliesTo = value; } + } + + [Parameter] + public SwitchParameter PassThru + { + get { return passThru; } + set { passThru = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + } + + protected override void ProcessRecord() + { + if (ParameterSetName.EndsWith("Simple")) + { + FileSystemSecurity2.ConvertToFileSystemFlags(appliesTo, out inheritanceFlags, out propagationFlags); + } + + if (ParameterSetName.StartsWith("Path")) + { + foreach (var path in paths) + { + FileSystemInfo item = null; + + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + } + + if (ParameterSetName == "PathSimple") + { + FileSystemSecurity2.ConvertToFileSystemFlags(appliesTo, out inheritanceFlags, out propagationFlags); + } + + try + { + FileSystemAuditRule2.RemoveFileSystemAuditRule(item, account.ToList(), accessRights, auditFlags, inheritanceFlags, propagationFlags); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + FileSystemAuditRule2.RemoveFileSystemAuditRule(item, account.ToList(), accessRights, auditFlags, inheritanceFlags, propagationFlags); + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "RemoveAceError", ErrorCategory.WriteError, path)); + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "RemoveAceError", ErrorCategory.WriteError, path)); + } + + if (passThru == true) + { + FileSystemAccessRule2.GetFileSystemAccessRules(item, true, true).ForEach(ace => WriteObject(ace)); + } + } + } + else + { + foreach (var sd in securityDescriptors) + { + FileSystemAuditRule2.RemoveFileSystemAuditRule(sd, account.ToList(), accessRights, auditFlags, inheritanceFlags, propagationFlags); + + if (passThru == true) + { + FileSystemAuditRule2.GetFileSystemAuditRules(sd, true, true).ForEach(ace => WriteObject(ace)); + } + } + } + } + + protected override void EndProcessing() + { + base.EndProcessing(); + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/BaseCmdlets.cs b/NTFSSecurity/BaseCmdlets.cs new file mode 100644 index 0000000..7480a2a --- /dev/null +++ b/NTFSSecurity/BaseCmdlets.cs @@ -0,0 +1,321 @@ +using System.Management.Automation; +using Security2; +using ProcessPrivileges; +using System.Linq; +using System.Collections.Generic; +using System; +using System.Collections; + +namespace NTFSSecurity +{ + public class BaseCmdlet : PSCmdlet + { + protected List paths = new List(); + protected List securityDescriptors = new List(); + + protected override void BeginProcessing() + { + base.BeginProcessing(); + } + + protected override void ProcessRecord() + { + base.ProcessRecord(); + } + + #region GetFileSystemInfo + protected System.IO.FileSystemInfo GetFileSystemInfo(string path) + { + string currentLocation = GetVariableValue("PWD").ToString(); + + if (path == ".") + { + path = currentLocation; + } + if (path.StartsWith("..")) + { + path = System.IO.Path.Combine( + string.Join("\\", currentLocation.Split('\\').Take(currentLocation.Split('\\').Count() - path.Split('\\').Count(s => s == "..")).ToArray()), + string.Join("\\", path.Split('\\').Where(e => e != "..").ToArray())); + } + else if (path.StartsWith(".")) + { + //combine . and .\path\subpath + path = System.IO.Path.Combine(currentLocation, path.Substring(2)); + } + else if (path.StartsWith("\\")) + { + //do nothing + } + else + { + ////combine . and \path\subpath or path\subpath + path = System.IO.Path.Combine(currentLocation, path.Substring(0)); + } + + if (System.IO.File.Exists(path)) + { + return new System.IO.FileInfo(path); + } + else if (System.IO.Directory.Exists(path)) + { + return new System.IO.DirectoryInfo(path); + } + else + { + throw new System.IO.FileNotFoundException(); + } + } + #endregion + + #region GetFileSystemInfo2 + protected Alphaleonis.Win32.Filesystem.FileSystemInfo GetFileSystemInfo2(string path) + { + path = GetRelativePath(path); + + if (Alphaleonis.Win32.Filesystem.File.Exists(path)) + { + return new Alphaleonis.Win32.Filesystem.FileInfo(path); + } + else if (Alphaleonis.Win32.Filesystem.Directory.Exists(path)) + { + return new Alphaleonis.Win32.Filesystem.DirectoryInfo(path); + } + else + { + throw new System.IO.FileNotFoundException(); + } + } + #endregion + + #region TryGetFileSystemInfo2 + protected bool TryGetFileSystemInfo2(string path, out Alphaleonis.Win32.Filesystem.FileSystemInfo item) + { + path = GetRelativePath(path); + item = null; + + if (Alphaleonis.Win32.Filesystem.File.Exists(path)) + { + item = new Alphaleonis.Win32.Filesystem.FileInfo(path); + } + else if (Alphaleonis.Win32.Filesystem.Directory.Exists(path)) + { + item = new Alphaleonis.Win32.Filesystem.DirectoryInfo(path); + } + else + { + return false; + } + + return true; + } + #endregion + + #region GetRelativePath + protected string GetRelativePath(string path) + { + string currentLocation = GetVariableValue("PWD").ToString(); + + if (string.IsNullOrEmpty(path)) + { + path = currentLocation; + } + else if (path == ".") + { + path = currentLocation; + } + else if (path.StartsWith("..")) + { + path = System.IO.Path.Combine( + string.Join("\\", currentLocation.Split('\\').Take(currentLocation.Split('\\').Count() - path.Split('\\').Count(s => s == "..")).ToArray()), + string.Join("\\", path.Split('\\').Where(e => e != "..").ToArray())); + } + else if (path.StartsWith(".")) + { + //combine . and .\path\subpath + path = System.IO.Path.Combine(currentLocation, path.Substring(2)); + } + else if (path.StartsWith("\\")) + { + //do nothing + } + else + { + ////combine . and \path\subpath or path\subpath + path = System.IO.Path.Combine(currentLocation, path); + } + + return path; + } + #endregion + } + + public class BaseCmdletWithPrivControl : BaseCmdlet + { + protected PrivilegeAndAttributesCollection privileges = null; + protected PrivilegeControl privControl = new PrivilegeControl(); + private List enabledPrivileges = new List(); + Hashtable privateData = null; + + protected override void BeginProcessing() + { + privateData = (Hashtable)MyInvocation.MyCommand.Module.PrivateData; + + if ((bool)privateData["EnablePrivileges"]) + { + WriteVerbose("EnablePrivileges enabled in PrivateDate"); + EnableFileSystemPrivileges(true); + } + } + + protected override void EndProcessing() + { + if ((bool)privateData["EnablePrivileges"]) + { + WriteVerbose("EnablePrivileges enabled in PrivateDate"); + + //disable all privileges that have been enabled by this cmdlet + WriteVerbose(string.Format("Disabeling all {0} enabled privileges...", enabledPrivileges.Count)); + foreach (var privilege in enabledPrivileges) + { + DisablePrivilege((Privilege)Enum.Parse(typeof(Privilege), privilege)); + WriteVerbose(string.Format("\t{0} disabled", privilege)); + } + WriteVerbose(string.Format("...finished")); + } + } + + protected void EnablePrivilege(Privilege privilege) + { + //throw an exception if the specified prililege is not held by the client + if (!privileges.Any(p => p.Privilege == privilege)) + throw new System.Security.AccessControl.PrivilegeNotHeldException(privilege.ToString()); + + //if the privilege is disabled + if (privileges.Single(p => p.Privilege == privilege).PrivilegeState == PrivilegeState.Disabled) + { + WriteDebug(string.Format("The privilege {0} is disabled...", privilege)); + //activate it + privControl.EnablePrivilege(privilege); + WriteDebug(string.Format("..enabled")); + //remember the privilege so that we can automatically disable it after the cmdlet finished processing + enabledPrivileges.Add(privilege.ToString()); + + privileges = privControl.GetPrivileges(); + } + } + + public void DisablePrivilege(Privilege privilege) + { + //if the privilege is enabled + if (privileges.Single(p => p.Privilege == privilege).PrivilegeState == PrivilegeState.Enabled) + privControl.DisablePrivilege(privilege); + } + + protected bool TryEnablePrivilege(Privilege privilege) + { + try + { + EnablePrivilege(privilege); + return true; + } + catch(Exception ex) + { + WriteDebug(string.Format("Could not enable privilege {0}. The error was: {1}", privilege, ex.Message)); + return false; + } + } + + protected bool TryDisablePrivilege(Privilege privilege) + { + try + { + DisablePrivilege(privilege); + return true; + } + catch + { + WriteDebug(string.Format("Could not disable privilege {0}.", privilege)); + return false; + } + } + + protected void EnableFileSystemPrivileges(bool quite = true) + { + privileges = (new PrivilegeControl()).GetPrivileges(); + + if (!TryEnablePrivilege(Privilege.TakeOwnership)) + WriteDebug("The privilige 'TakeOwnership' could not be enabled. Make sure your user account does have this privilige"); + + if (!TryEnablePrivilege(Privilege.Restore)) + WriteDebug("The privilige 'Restore' could not be enabled. Make sure your user account does have this privilige"); + + if (!TryEnablePrivilege(Privilege.Backup)) + WriteDebug("The privilige 'Backup' could not be enabled. Make sure your user account does have this privilige"); + + if (!TryEnablePrivilege(Privilege.Security)) + WriteDebug("The privilige 'Security' could not be enabled. Make sure your user account does have this privilige"); + + if (!quite) + { + if (privControl.GetPrivileges() + .Where(p => p.PrivilegeState == PrivilegeState.Enabled) + .Where(p => + (p.Privilege == Privilege.TakeOwnership) | + (p.Privilege == Privilege.Restore) | + (p.Privilege == Privilege.Backup) | + (p.Privilege == Privilege.Security)).Count() == 4) + { + WriteVerbose("The privileges 'Backup', 'Restore', 'TakeOwnership' and 'Security' are now enabled giving you access to all files and folders. Use Disable-Privileges to disable them and Get-Privileges for an overview."); + } + else + { + WriteError(new ErrorRecord(new AdjustPriviledgeException("Could not enable requested privileges. Cmdlets of NTFSSecurity will only work on resources you have access to."), "Enable Privilege Error", ErrorCategory.SecurityError, null)); + return; + } + } + } + + protected void DisableFileSystemPrivileges() + { + var privileges = privControl.GetPrivileges(); + + if (privileges.Where(p => p.Privilege == Privilege.TakeOwnership) != null) + if (!TryDisablePrivilege(Privilege.TakeOwnership)) + WriteWarning("The privilige 'TakeOwnership' could not be disabled."); + else + WriteDebug("The privilige 'TakeOwnership' was disabled."); + + if (privileges.Where(p => p.Privilege == Privilege.Restore) != null) + if (!TryDisablePrivilege(Privilege.Restore)) + WriteWarning("The privilige 'Restore' could not be disabled."); + else + WriteDebug("The privilige 'Restore' was disabled."); + + if (privileges.Where(p => p.Privilege == Privilege.Backup) != null) + if (!TryDisablePrivilege(Privilege.Backup)) + WriteWarning("The privilige 'Backup' could not be disabled."); + else + WriteDebug("The privilige 'Backup' was disabled."); + + if (!TryDisablePrivilege(Privilege.Security)) + WriteWarning("The privilige 'Security' could not be disabled."); + else + WriteDebug("The privilige 'Security' was disabled."); + } + + protected void WriteWarning(string text, params string[] args) + { + base.WriteWarning(string.Format(text, args)); + } + protected void WriteVerbose(string text, params string[] args) + { + base.WriteVerbose(string.Format(text, args)); + } + + protected void WriteDebug(string text, params string[] args) + { + base.WriteDebug(string.Format(text, args)); + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/CodeMembers.cs b/NTFSSecurity/CodeMembers.cs new file mode 100644 index 0000000..ee5b634 --- /dev/null +++ b/NTFSSecurity/CodeMembers.cs @@ -0,0 +1,64 @@ +using Alphaleonis.Win32.Filesystem; +using System.Management.Automation; + +namespace NTFSSecurity +{ + public class FileSystemCodeMembers + { + public static string Mode(PSObject obj) + { + if (obj == null) + { + return string.Empty; + } + FileSystemInfo item = (FileSystemInfo)obj.BaseObject; + if (item == null) + { + return string.Empty; + } + + string text = ""; + if ((item.Attributes & System.IO.FileAttributes.Directory) == System.IO.FileAttributes.Directory) + { + text += "d"; + } + else + { + text += "-"; + } + if ((item.Attributes & System.IO.FileAttributes.Archive) == System.IO.FileAttributes.Archive) + { + text += "a"; + } + else + { + text += "-"; + } + if ((item.Attributes & System.IO.FileAttributes.ReadOnly) == System.IO.FileAttributes.ReadOnly) + { + text += "r"; + } + else + { + text += "-"; + } + if ((item.Attributes & System.IO.FileAttributes.Hidden) == System.IO.FileAttributes.Hidden) + { + text += "h"; + } + else + { + text += "-"; + } + if ((item.Attributes & System.IO.FileAttributes.System) == System.IO.FileAttributes.System) + { + text += "s"; + } + else + { + text += "-"; + } + return text; + } + } +} diff --git a/NTFSSecurity/Extensions.cs b/NTFSSecurity/Extensions.cs new file mode 100644 index 0000000..5ae4956 --- /dev/null +++ b/NTFSSecurity/Extensions.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using Alphaleonis.Win32.Filesystem; + +namespace NTFSSecurity +{ + public static class Extensions + { + public static void ForEach(this IEnumerable source, Action action) + { + if (source == null) { throw new ArgumentException(); } + if (action == null) { throw new ArgumentException(); } + + foreach (T element in source) + { + action(element); + } + } + + public static FileSystemInfo GetParent(this FileSystemInfo item) + { + var parentPath = System.IO.Path.GetDirectoryName(item.FullName); + + if (File.Exists(parentPath)) + { + return new FileInfo(parentPath); + } + else if (Directory.Exists(parentPath)) + { + return new DirectoryInfo(parentPath); + } + else + { + throw new System.IO.FileNotFoundException(); + } + } + + public static System.IO.FileSystemInfo GetParent(this System.IO.FileSystemInfo item) + { + var parentPath = System.IO.Path.GetDirectoryName(item.FullName); + + if (File.Exists(parentPath)) + { + return new System.IO.FileInfo(parentPath); + } + else if (Directory.Exists(parentPath)) + { + return new System.IO.DirectoryInfo(parentPath); + } + else + { + throw new System.IO.FileNotFoundException(); + } + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/Help/NTFSSecurity.Help.pshproj b/NTFSSecurity/Help/NTFSSecurity.Help.pshproj new file mode 100644 index 0000000..e811fa7 --- /dev/null +++ b/NTFSSecurity/Help/NTFSSecurity.Help.pshproj @@ -0,0 +1,2786 @@ + + + NTFSSecurity + 3.2.3 + Windows PowerShell Module for managing file and folder security on NTFS volumes + true + false + + + + Add-NTFSAccess + + + + + + + + + + + + + + + + + + + Add-NTFSAccess [-Path] <String[]> [-Account] <IdentityReference2[]> [-AccessRights] <FileSystemRights2> [-AccessType <AccessControlType>] [-InheritanceFlags <InheritanceFlags>] [-PropagationFlags <PropagationFlags>] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Add-NTFSAccess [-Path] <String[]> [-Account] <IdentityReference2[]> [-AccessRights] <FileSystemRights2> [-AccessType <AccessControlType>] [-AppliesTo <ApplyTo>] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Add-NTFSAccess [-SecurityDescriptor] <FileSystemSecurity2[]> [-Account] <IdentityReference2[]> [-AccessRights] <FileSystemRights2> [-AccessType <AccessControlType>] [-AppliesTo <ApplyTo>] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Add-NTFSAccess [-SecurityDescriptor] <FileSystemSecurity2[]> [-Account] <IdentityReference2[]> [-AccessRights] <FileSystemRights2> [-AccessType <AccessControlType>] [-InheritanceFlags <InheritanceFlags>] [-PropagationFlags <PropagationFlags>] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + Account + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + + + IdentityReference, ID + + + + + + AccessRights + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + + + FileSystemRights + + + + + + AccessType + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + + + AccessControlType + + + + + + InheritanceFlags + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ParameterAttribute + + + + + + + PropagationFlags + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ParameterAttribute + + + + + + + PassThru + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + AppliesTo + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ParameterAttribute + + + + + + + SecurityDescriptor + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + + + + + + + + false + + + Add-NTFSAudit + + + + + + + + + + + + + + + + + Add-NTFSAudit [-Account] <IdentityReference2> [-AccessRights] <FileSystemRights> [-Type <AuditFlags>] [-InheritanceFlags <InheritanceFlags>] [-PropagationFlags <PropagationFlags>] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Add-NTFSAudit [-Account] <IdentityReference2> [-AccessRights] <FileSystemRights> [-Type <AuditFlags>] [-AppliesTo <ApplyTo>] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Account + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + + + IdentityReference, ID + + + + + + AccessRights + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + + + FileSystemRights + + + + + + Type + + System.Management.Automation.ParameterAttribute + + + + + + + InheritanceFlags + + System.Management.Automation.ParameterAttribute + + + + + + + PropagationFlags + + System.Management.Automation.ParameterAttribute + + + + + + + PassThru + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + AppliesTo + + System.Management.Automation.ParameterAttribute + + + + + + + + + + false + + + Copy-NTFSAccess + + + + + + + + + + + + + + + + Copy-NTFSAccess [-Path] <String> [-DestinationPath] <String> [-Account <IdentityReference2[]>] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + DestinationPath + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + + + + + Account + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + + + IdentityReference, ID + + + + + + PassThru + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + + + + false + + + Disable-NTFSAccessInheritance + + + + + + + + + + + + + + + + + Disable-NTFSAccessInheritance [[-Path] <String[]>] [-RemoveInheritedAccessRules] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Disable-NTFSAccessInheritance [-SecurityDescriptor] <FileSystemSecurity2[]> [-RemoveInheritedAccessRules] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + RemoveInheritedAccessRules + + System.Management.Automation.ParameterAttribute + + + + + + + PassThru + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + SecurityDescriptor + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + + + + + + + + false + + + Disable-NTFSAuditInheritance + + + + + + + + + + + + + + + + + Disable-NTFSAuditInheritance [[-Path] <String[]>] [-RemoveInheritedAccessRules] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Disable-NTFSAuditInheritance [-SecurityDescriptor] <FileSystemSecurity2[]> [-RemoveInheritedAccessRules] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + RemoveInheritedAccessRules + + System.Management.Automation.ParameterAttribute + + + + + + + PassThru + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + SecurityDescriptor + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + + + + + + + + false + + + Disable-Privileges + + + + + + + + + + + + + + + + Disable-Privileges [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + PassThru + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + + + + false + + + Enable-NTFSAccessInheritance + + + + + + + + + + + + + + + + + Enable-NTFSAccessInheritance [[-Path] <String[]>] [-PassThru] [-RemoveExplicitAccessRules] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Enable-NTFSAccessInheritance [-SecurityDescriptor] <FileSystemSecurity2[]> [-PassThru] [-RemoveExplicitAccessRules] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + PassThru + + System.Management.Automation.ParameterAttribute + + + + + + + RemoveExplicitAccessRules + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + SecurityDescriptor + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + + + + + + + + false + + + Enable-NTFSAuditInheritance + + + + + + + + + + + + + + + + + Enable-NTFSAuditInheritance [[-Path] <String[]>] [-PassThru] [-RemoveExplicitAccessRules] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Enable-NTFSAuditInheritance [-SecurityDescriptor] <FileSystemSecurity2[]> [-PassThru] [-RemoveExplicitAccessRules] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + PassThru + + System.Management.Automation.ParameterAttribute + + + + + + + RemoveExplicitAccessRules + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + SecurityDescriptor + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + + + + + + + + false + + + Enable-Privileges + + + + + + + + + + + + + + + + Enable-Privileges [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + PassThru + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + + + + false + + + Get-ChildItem2 + + Gets the items and child items in one or more specified locations. + The Get-ChildItem2 cmdlet gets the items in one or more specified locations. If the item is a container, it gets the items inside the container, known as child items. You can use the Recurse parameter to get items in all child containers. + +Get-ChildItem2 does not have a 248 character limit on the path. It does not use the FileSystem provider but AlphaFS (https://github.com/alphaleonis/AlphaFS/) which is faster. + +Get-ChildItem2 supports only locations on the file system. Get-ChildItem2 cmdlet gets the directories, subdirectories, and files. In a file system directory, it gets subdirectories and files. + +By default, Get-ChildItem2 gets non-hidden items, but you can use the Directory, File, Hidden, ReadOnly, and System parameters to get only items with these attributes. To create a complex attribute search, use the Attributes parameter. If you use these parameters, Get-ChildItem gets only the items that meet all search conditions, as though the parameters were connected by an AND operator. + You can also refer to Get-ChildItem2 by its built-in alias dir2. + +Get-ChildItem2 does not get hidden items by default. To get hidden items, use the Force parameter. + System.String[] + + You can pipe a file system path (in quotation marks) to Get-ChildItem2. + Alphaleonis.Win32.Filesystem.DirectoryInfo, Alphaleonis.Win32.Filesystem.FileInfo, System.String + + + + + + + + Get-ChildItem2 [[-Path] <String[]>] [[-Filter] <String>] [-Recurse] [-Directory] [-File] [-Attributes <FileAttributes>] [-Hidden] [-System] [-ReadOnly] [-Force] [-SkipMountPoints] [-SkipSymbolicLinks] [-Depth <Nullable`1[Int32]>] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + Specifies a path to one or more locations. Wildcards are NOT permitted. The default location is the current directory (.). + + + + Filter + + System.Management.Automation.ParameterAttribute + + + Specifies a wildcard filter. The value of this parameter qualifies the Path parameter. Filters are more efficient than other parameters, because the provider applies them when retrieving the objects, rather than having Windows PowerShell filter the objects after they are retrieved. + + + + Recurse + + System.Management.Automation.ParameterAttribute + + + Gets the items in the specified locations and in all child items of the locations. + + + + Directory + + System.Management.Automation.ParameterAttribute + + + Gets directories (folders). + +To get only directories, use the Directory parameter and omit the File parameter. To exclude directories, use the File parameter and omit the Directory parameter, or use the Attributes parameter. + + + + File + + System.Management.Automation.ParameterAttribute + + + Gets files. + +To get only files, use the File parameter and omit the Directory parameter. To exclude files, use the Directory parameter and omit the File parameter, or use the Attributes parameter. + + + + Attributes + + System.Management.Automation.ParameterAttribute + + + Gets files and folders with the specified attributes. This parameter supports all attributes and lets you specify complex combinations of attributes. + +To find files and folders with commonly used attributes, you can use the Attributes parameter, or the Directory, File, Hidden, ReadOnly, and System switch parameters. + +The Attributes parameter supports the following attributes: Archive, Compressed, Device, Directory, Encrypted, Hidden, Normal, NotContentIndexed, Offline, ReadOnly, ReparsePoint, SparseFile, System, and Temporary. For a description of these attributes, see the FileAttributes enumeration at http://go.microsoft.com/fwlink/?LinkId=201508. + + + + SkipMountPoints + + System.Management.Automation.ParameterAttribute + + + Skips mount points. + +Use this switch to not follow mount points when doing a recursive listing. + + + + SkipSymbolicLinks + + System.Management.Automation.ParameterAttribute + + + Skips symbolic links. + +Use this switch to not follow symbolic links when doing a recursive listing. + + + + Depth + + System.Management.Automation.ParameterAttribute + + + Limits the depth in a recursive listing. + +If you need only a certain level of subfolders, use this parameter. For example, if you only need the content of the current folder + the content of all subfolders, specify a depth of 1. + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + Hidden + + System.Management.Automation.ParameterAttribute + + + Gets only hidden files and directories (folders). By default, Get-ChildItem gets only non-hidden items, but you can use the Force parameter to include hidden items in the results. + +To get only hidden items, use the Hidden parameter or the Hidden value of the Attributes parameter. To exclude hidden items, omit the Hidden parameter or use the Attributes parameter. + + + + System + + System.Management.Automation.ParameterAttribute + + + Gets only system files and directories (folders). + +To get only system files and folders, use the System parameter or the System value of the Attributes parameter. To exclude system files and folders, use the Attributes parameter. + + + + ReadOnly + + System.Management.Automation.ParameterAttribute + + + Gets only read-only files and directories (folders). + +To get only read-only items, use the ReadOnly parameter or the ReadOnly value of the Attributes parameter. To exclude read-only items, use the Attributes parameter. + + + + Force + + System.Management.Automation.ParameterAttribute + + + Gets hidden files and folders. By default, hidden files and folder are excluded. You can also get hidden files and folders by using the Hidden parameter or the Hidden value of the Attributes parameter. + + + + + + Example 1 + C:\PS> Get-ChildItem2 + This command gets the files and subdirectories in the current directory. If the current directory does not have child items, the command does not return any results. + + + + Example 2 + C:\PS> Get-Childitem -System -File -Recurse + This command gets system files in the current directory and its subdirectories. + + + + Example 3 + PS C:\> Get-ChildItem2 -Path D:\LabSources\ -Force -Depth 2 + Gets all items from the folder D:\LabSources up to a level of 2. The Force switch makes the command to return also hidden items. + + + + + + false + + + Get-DiskSpace + + Retrieves a statistic about a file system drive. + Get-DiskSpace retrieves a drive and usage statistic of a given drive. The information provided is AvailableFreeSpacePercent, AvailableFreeSpaceUnitSizeClusterSize, DriveName, TotalSizeUnitSize, UsedSpacePercent, UsedSpaceUnitSize, FreeBytesAvailable, TotalNumberOfBytes, TotalNumberOfFreeBytes, BytesPerSector, NumberOfFreeClusters, SectorsPerCluster, TotalNumberOfClusters. + + + System.String + + + Alphaleonis.Win32.Filesystem.DiskSpaceInfo + + + + + + + + Get-DiskSpace [[-DriveLetter] <String[]>] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + DriveLetter + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidatePatternAttribute + + + The drive to get the statistic from. + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + + + Example 1 + PS C:\> Get-DiskSpace -DriveLetter d: + Get the drive statistic of drive D:. + AvailableFreeSpacePercent : 75.73% +AvailableFreeSpaceUnitSize : 361.07 GB +ClusterSize : 4096 +DriveName : d:\ +TotalSizeUnitSize : 476.81 GB +UsedSpacePercent : 24.27% +UsedSpaceUnitSize : 115.74 GB +FreeBytesAvailable : 387699257344 +TotalNumberOfBytes : 511974567936 +TotalNumberOfFreeBytes : 387699257344 +BytesPerSector : 512 +NumberOfFreeClusters : 94653139 +SectorsPerCluster : 8 +TotalNumberOfClusters : 124993791 + + + + + false + + + Get-Item2 + + Gets files and folders. + The Get-Item2 cmdlet gets the item at the specified location. It does not get the contents of the item at the location. + +Get-ChildItem2 does not have a 248 character limit on the path. It does not use the FileSystem provider but AlphaFS (https://github.com/alphaleonis/AlphaFS/) which is faster. + +The Get-Item cmdlet works only on the file system and gets files and folders. + + You can also refer to Get-Item2 by its built-in alias gi2. + System.String[] + + You can pipe a file system path (in quotation marks) to Get-ChildItem2. + Alphaleonis.Win32.Filesystem.DirectoryInfo, Alphaleonis.Win32.Filesystem.FileInfo, System.String + + + + + + + + Get-Item2 [[-Path] <String[]>] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + Specifies a path to one or more locations. Wildcards are NOT permitted. The default location is the current directory (.). + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + + + Example 1 + PS C:\> Get-Item2 + Gets the current folder. + Directory: + + +Mode Inherits LastWriteTime Size(M) Name +---- -------- ------------- ------- ---- +d--hs True 8/4/2015 11:00 PM <DIR> C:\ + + + Example 2 + PS C:\> Get-Item2 -Path C:\Windows + Gets the Windows folder. + Directory: C:\ + + +Mode Inherits LastWriteTime Size(M) Name +---- -------- ------------- ------- ---- +d---- True 8/4/2015 10:18 PM <DIR> Windows + + + + + false + + + Get-NTFSAccess + + + + + + + + + + + + + + + + + Get-NTFSAccess [[-Path] <String[]>] [-Account <IdentityReference2>] [-ExcludeExplicit] [-ExcludeInherited] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Get-NTFSAccess [-SecurityDescriptor] <FileSystemSecurity2[]> [-Account <IdentityReference2>] [-ExcludeExplicit] [-ExcludeInherited] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + Account + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + IdentityReference, ID + + + + + + ExcludeExplicit + + System.Management.Automation.ParameterAttribute + + + + + + + ExcludeInherited + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + SecurityDescriptor + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + + + + + + + + false + + + Get-NTFSAudit + + + + + + + + + + + + + + + + Get-NTFSAudit [-Account <IdentityReference2>] [-ExcludeExplicit] [-ExcludeInherited] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Account + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + IdentityReference, ID + + + + + + ExcludeExplicit + + System.Management.Automation.ParameterAttribute + + + + + + + ExcludeInherited + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + + + + false + + + Get-NTFSEffectiveAccess + + + + + + + + + + + + + + + + + Get-NTFSEffectiveAccess [[-Path] <String[]>] [[-Account] <IdentityReference2>] [-ServerName <String>] [-ExcludeNoneAccessEntries] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Get-NTFSEffectiveAccess [-SecurityDescriptor] <FileSystemSecurity2[]> [[-Account] <IdentityReference2>] [-ServerName <String>] [-ExcludeNoneAccessEntries] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + Account + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + NTAccount + IdentityReference + + + + + + ServerName + + System.Management.Automation.ParameterAttribute + + + + + + + ExcludeNoneAccessEntries + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + SecurityDescriptor + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + + + + + + + + false + + + Get-NTFSInheritance + + + + + + + + + + + + + + + + + Get-NTFSInheritance [[-Path] <String[]>] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Get-NTFSInheritance [-SecurityDescriptor] <FileSystemSecurity2[]> [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + SecurityDescriptor + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + + + + + + + + false + + + Get-NTFSOrphanedAccess + + + + + + + + + + + + + + + + + Get-NTFSOrphanedAccess [[-Path] <String[]>] [-Account <IdentityReference2>] [-ExcludeExplicit] [-ExcludeInherited] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Get-NTFSOrphanedAccess [-SecurityDescriptor] <FileSystemSecurity2[]> [-Account <IdentityReference2>] [-ExcludeExplicit] [-ExcludeInherited] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + Account + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + IdentityReference, ID + + + + + + ExcludeExplicit + + System.Management.Automation.ParameterAttribute + + + + + + + ExcludeInherited + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + SecurityDescriptor + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + + + + + + + + false + + + Get-NTFSOrphanedAudit + + + + + + + + + + + + + + + + Get-NTFSOrphanedAudit [-Account <IdentityReference2>] [-ExcludeExplicit] [-ExcludeInherited] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Account + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + IdentityReference, ID + + + + + + ExcludeExplicit + + System.Management.Automation.ParameterAttribute + + + + + + + ExcludeInherited + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + + + + false + + + Get-NTFSOwner + + + + + + + + + + + + + + + + + Get-NTFSOwner [[-Path] <String[]>] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Get-NTFSOwner [-SecurityDescriptor] <FileSystemSecurity2[]> [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + SecurityDescriptor + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + + + + + + + + false + + + Get-NTFSSecurityDescriptor + + + + + + + + + + + + + + + + Get-NTFSSecurityDescriptor [[-Path] <String[]>] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + + + + false + + + Get-Privileges + + + + + + + + + + + + + + + + Get-Privileges [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + + + + false + + + Get-SimpleAccess + + + + + + + + + + + + + + + + + Get-SimpleAccess [-IncludeRootFolder] [[-Path] <String[]>] [-Account <IdentityReference2>] [-ExcludeExplicit] [-ExcludeInherited] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Get-SimpleAccess [-IncludeRootFolder] [-SecurityDescriptor] <FileSystemSecurity2[]> [-Account <IdentityReference2>] [-ExcludeExplicit] [-ExcludeInherited] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + IncludeRootFolder + + System.Management.Automation.ParameterAttribute + + + + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + Account + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + IdentityReference, ID + + + + + + ExcludeExplicit + + System.Management.Automation.ParameterAttribute + + + + + + + ExcludeInherited + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + SecurityDescriptor + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + + + + + + + + false + + + Remove-Item2 + + + + + + + + + + + + + + + + Remove-Item2 [[-Path] <String[]>] [-Force] [-Recurse] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + Force + + System.Management.Automation.ParameterAttribute + + + + + + + Recurse + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + + + + false + + + Remove-NTFSAccess + + + + + + + + + + + + + + + + + + + Remove-NTFSAccess [-Path] <String[]> [-Account] <IdentityReference2[]> [-AccessRights] <FileSystemRights2> [-AccessType <AccessControlType>] [-InheritanceFlags <InheritanceFlags>] [-PropagationFlags <PropagationFlags>] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Remove-NTFSAccess [-Path] <String[]> [-Account] <IdentityReference2[]> [-AccessRights] <FileSystemRights2> [-AccessType <AccessControlType>] [-AppliesTo <ApplyTo>] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Remove-NTFSAccess [-SecurityDescriptor] <FileSystemSecurity2[]> [-Account] <IdentityReference2[]> [-AccessRights] <FileSystemRights2> [-AccessType <AccessControlType>] [-AppliesTo <ApplyTo>] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Remove-NTFSAccess [-SecurityDescriptor] <FileSystemSecurity2[]> [-Account] <IdentityReference2[]> [-AccessRights] <FileSystemRights2> [-AccessType <AccessControlType>] [-InheritanceFlags <InheritanceFlags>] [-PropagationFlags <PropagationFlags>] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + Account + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + + + IdentityReference, ID + + + + + + AccessRights + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + + + FileSystemRights + + + + + + AccessType + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + + + AccessControlType + + + + + + InheritanceFlags + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ParameterAttribute + + + + + + + PropagationFlags + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ParameterAttribute + + + + + + + PassThru + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + AppliesTo + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ParameterAttribute + + + + + + + SecurityDescriptor + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + + + + + + + + false + + + Remove-NTFSAudit + + + + + + + + + + + + + + + + + Remove-NTFSAudit [-Account] <IdentityReference2> [-AccessRights] <FileSystemRights2> [-Type <AuditFlags>] [-InheritanceFlags <InheritanceFlags>] [-PropagationFlags <PropagationFlags>] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Remove-NTFSAudit [-Account] <IdentityReference2> [-AccessRights] <FileSystemRights2> [-Type <AuditFlags>] [-AppliesTo <ApplyTo>] [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Account + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + + + IdentityReference, ID + + + + + + AccessRights + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + + + FileSystemRights + + + + + + Type + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + + + AuditFlags + + + + + + InheritanceFlags + + System.Management.Automation.ParameterAttribute + + + + + + + PropagationFlags + + System.Management.Automation.ParameterAttribute + + + + + + + PassThru + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + AppliesTo + + System.Management.Automation.ParameterAttribute + + + + + + + + + + false + + + Set-NTFSOwner + + + + + + + + + + + + + + + + + Set-NTFSOwner [[-Path] <String[]>] [-Account] <IdentityReference2> [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Set-NTFSOwner [-SecurityDescriptor] <FileSystemSecurity2[]> [-Account] <IdentityReference2> [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + Account + + System.Management.Automation.ParameterAttribute + + + + + + + PassThru + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + SecurityDescriptor + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + + + + + + + + false + + + Set-NTFSSecurityDescriptor + + + + + + + + + + + + + + + + Set-NTFSSecurityDescriptor [-SecurityDescriptor] <FileSystemSecurity2[]> [-PassThru] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + SecurityDescriptor + + System.Management.Automation.ParameterAttribute + + + + + + + PassThru + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + + + + false + + + Show-SimpleAccess + + + + + + + + + + + + + + + + + Show-SimpleAccess [-IncludeRootFolder] [[-Path] <String[]>] [-Account <IdentityReference2>] [-ExcludeExplicit] [-ExcludeInherited] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + Show-SimpleAccess [-IncludeRootFolder] [-SecurityDescriptor] <FileSystemSecurity2[]> [-Account <IdentityReference2>] [-ExcludeExplicit] [-ExcludeInherited] [-InformationAction <ActionPreference>] [-InformationVariable <String>] + + + + IncludeRootFolder + + System.Management.Automation.ParameterAttribute + + + + + + + Path + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + System.Management.Automation.AliasAttribute + + + FullName + + + + + + Account + + System.Management.Automation.ParameterAttribute + System.Management.Automation.AliasAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + IdentityReference, ID + + + + + + ExcludeExplicit + + System.Management.Automation.ParameterAttribute + + + + + + + ExcludeInherited + + System.Management.Automation.ParameterAttribute + + + + + + + InformationAction + + System.Management.Automation.AliasAttribute + System.Management.Automation.ParameterAttribute + + + infa + + + + + + InformationVariable + + System.Management.Automation.ParameterAttribute + System.Management.Automation.Internal.CommonParameters+ValidateVariableName + System.Management.Automation.AliasAttribute + + + iv + + + + + + SecurityDescriptor + + System.Management.Automation.ParameterAttribute + System.Management.Automation.ValidateNotNullOrEmptyAttribute + + + + + + + + + + false + + + \ No newline at end of file diff --git a/NTFSSecurity/InheritanceCmdlets/DisableAccessInheritance.cs b/NTFSSecurity/InheritanceCmdlets/DisableAccessInheritance.cs new file mode 100644 index 0000000..a849da2 --- /dev/null +++ b/NTFSSecurity/InheritanceCmdlets/DisableAccessInheritance.cs @@ -0,0 +1,128 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsLifecycle.Disable, "NTFSAccessInheritance", DefaultParameterSetName = "Path")] + public class DisableAccessInheritance : BaseCmdletWithPrivControl + { + private bool removeInheritedAccessRules; + private bool passThru; + + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SecurityDescriptor")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + [Parameter] + public SwitchParameter RemoveInheritedAccessRules + { + get { return removeInheritedAccessRules; } + set { removeInheritedAccessRules = value; } + } + + [Parameter] + public SwitchParameter PassThru + { + get { return passThru; } + set { passThru = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + EnableFileSystemPrivileges(true); + } + + protected override void ProcessRecord() + { + if (ParameterSetName == "Path") + { + foreach (var path in paths) + { + FileSystemInfo item = null; + + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + FileSystemInheritanceInfo.DisableAccessInheritance(item, removeInheritedAccessRules); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + FileSystemInheritanceInfo.DisableAccessInheritance(item, removeInheritedAccessRules); + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "ModifySdError", ErrorCategory.WriteError, path)); + continue; + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ModifySdError", ErrorCategory.WriteError, path)); + continue; + } + finally + { + if (passThru) + { + FileSystemInheritanceInfo.GetFileSystemInheritanceInfo(item); + } + } + } + } + else + { + foreach (var sd in securityDescriptors) + { + FileSystemInheritanceInfo.DisableAccessInheritance(sd, removeInheritedAccessRules); + + if (passThru) + { + FileSystemInheritanceInfo.GetFileSystemInheritanceInfo(sd); + } + } + } + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/InheritanceCmdlets/DisableAuditInheritance.cs b/NTFSSecurity/InheritanceCmdlets/DisableAuditInheritance.cs new file mode 100644 index 0000000..00f7ca1 --- /dev/null +++ b/NTFSSecurity/InheritanceCmdlets/DisableAuditInheritance.cs @@ -0,0 +1,129 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Management.Automation; + +namespace NTFSSecurity +{ + + [Cmdlet(VerbsLifecycle.Disable, "NTFSAuditInheritance", DefaultParameterSetName = "Path")] + public class DisableAuditInheritance : BaseCmdletWithPrivControl + { + private bool removeInheritedAccessRules; + private bool passThru; + + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SecurityDescriptor")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + [Parameter] + public SwitchParameter RemoveInheritedAccessRules + { + get { return removeInheritedAccessRules; } + set { removeInheritedAccessRules = value; } + } + + [Parameter] + public SwitchParameter PassThru + { + get { return passThru; } + set { passThru = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + EnableFileSystemPrivileges(true); + } + + protected override void ProcessRecord() + { + if (ParameterSetName == "Path") + { + foreach (var path in paths) + { + FileSystemInfo item = null; + + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + FileSystemInheritanceInfo.DisableAuditInheritance(item, removeInheritedAccessRules); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + FileSystemInheritanceInfo.DisableAuditInheritance(item, removeInheritedAccessRules); + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "ModifySdError", ErrorCategory.WriteError, path)); + continue; + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ModifySdError", ErrorCategory.WriteError, path)); + continue; + } + finally + { + if (passThru) + { + FileSystemInheritanceInfo.GetFileSystemInheritanceInfo(item); + } + } + } + } + else + { + foreach (var sd in securityDescriptors) + { + FileSystemInheritanceInfo.DisableAuditInheritance(sd, removeInheritedAccessRules); + + if (passThru) + { + FileSystemInheritanceInfo.GetFileSystemInheritanceInfo(sd); + } + } + } + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/InheritanceCmdlets/EnableAccessInheritance.cs b/NTFSSecurity/InheritanceCmdlets/EnableAccessInheritance.cs new file mode 100644 index 0000000..fd5a5bb --- /dev/null +++ b/NTFSSecurity/InheritanceCmdlets/EnableAccessInheritance.cs @@ -0,0 +1,128 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsLifecycle.Enable, "NTFSAccessInheritance", DefaultParameterSetName = "Path")] + public class EnableAccessInheritance : BaseCmdletWithPrivControl + { + private bool removeExplicitAccessRules; + private bool passThru; + + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SecurityDescriptor")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + [Parameter] + public SwitchParameter PassThru + { + get { return passThru; } + set { passThru = value; } + } + + [Parameter] + public SwitchParameter RemoveExplicitAccessRules + { + get { return removeExplicitAccessRules; } + set { removeExplicitAccessRules = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + EnableFileSystemPrivileges(true); + } + + protected override void ProcessRecord() + { + if (ParameterSetName == "Path") + { + foreach (var path in paths) + { + FileSystemInfo item = null; + + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + FileSystemInheritanceInfo.EnableAccessInheritance(item, removeExplicitAccessRules); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + FileSystemInheritanceInfo.EnableAccessInheritance(item, removeExplicitAccessRules); + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "ModifySdError", ErrorCategory.WriteError, path)); + continue; + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ModifySdError", ErrorCategory.WriteError, path)); + continue; + } + finally + { + if (passThru) + { + FileSystemInheritanceInfo.GetFileSystemInheritanceInfo(item); + } + } + } + } + else + { + foreach (var sd in securityDescriptors) + { + FileSystemInheritanceInfo.EnableAccessInheritance(sd, removeExplicitAccessRules); + + if (passThru) + { + FileSystemInheritanceInfo.GetFileSystemInheritanceInfo(sd); + } + } + } + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/InheritanceCmdlets/EnableAuditInheritance.cs b/NTFSSecurity/InheritanceCmdlets/EnableAuditInheritance.cs new file mode 100644 index 0000000..98ab691 --- /dev/null +++ b/NTFSSecurity/InheritanceCmdlets/EnableAuditInheritance.cs @@ -0,0 +1,128 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsLifecycle.Enable, "NTFSAuditInheritance", DefaultParameterSetName = "Path")] + public class EnableAuditInheritance : BaseCmdletWithPrivControl + { + private bool removeExplicitAccessRules; + private bool passThru; + + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SecurityDescriptor")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + [Parameter] + public SwitchParameter PassThru + { + get { return passThru; } + set { passThru = value; } + } + + [Parameter] + public SwitchParameter RemoveExplicitAccessRules + { + get { return removeExplicitAccessRules; } + set { removeExplicitAccessRules = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + EnableFileSystemPrivileges(true); + } + + protected override void ProcessRecord() + { + if (ParameterSetName == "Path") + { + foreach (var path in paths) + { + FileSystemInfo item = null; + + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + FileSystemInheritanceInfo.EnableAuditInheritance(item, removeExplicitAccessRules); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + FileSystemInheritanceInfo.EnableAuditInheritance(item, removeExplicitAccessRules); + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "ModifySdError", ErrorCategory.WriteError, path)); + continue; + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ModifySdError", ErrorCategory.WriteError, path)); + continue; + } + finally + { + if (passThru) + { + FileSystemInheritanceInfo.GetFileSystemInheritanceInfo(item); + } + } + } + } + else + { + foreach (var sd in securityDescriptors) + { + FileSystemInheritanceInfo.EnableAuditInheritance(sd, removeExplicitAccessRules); + + if (passThru) + { + FileSystemInheritanceInfo.GetFileSystemInheritanceInfo(sd); + } + } + } + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/InheritanceCmdlets/GetInheritance.cs b/NTFSSecurity/InheritanceCmdlets/GetInheritance.cs new file mode 100644 index 0000000..895bf79 --- /dev/null +++ b/NTFSSecurity/InheritanceCmdlets/GetInheritance.cs @@ -0,0 +1,119 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Collections.Generic; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Get, "NTFSInheritance", DefaultParameterSetName = "Path")] + [OutputType(typeof(FileSystemInheritanceInfo))] + public class GetInheritance : BaseCmdletWithPrivControl + { + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SecurityDescriptor")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + EnableFileSystemPrivileges(true); + + if (paths.Count == 0) + { + paths = new List() { GetVariableValue("PWD").ToString() }; + } + } + + protected override void ProcessRecord() + { + if (ParameterSetName == "Path") + { + foreach (var path in paths) + { + FileSystemInfo item = null; + FileSystemInheritanceInfo inheritanceInfo = null; + + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + inheritanceInfo = FileSystemInheritanceInfo.GetFileSystemInheritanceInfo(item); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + inheritanceInfo = FileSystemInheritanceInfo.GetFileSystemInheritanceInfo(item); + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "ReadSecurityError", ErrorCategory.WriteError, path)); + continue; + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadSecurityError", ErrorCategory.OpenError, path)); + continue; + } + finally + { + if (inheritanceInfo != null) + { + WriteObject(inheritanceInfo); + } + } + } + } + else + { + foreach (var sd in securityDescriptors) + { + var inheritanceInfo = FileSystemInheritanceInfo.GetFileSystemInheritanceInfo(sd); + + if (inheritanceInfo != null) + { + WriteObject(inheritanceInfo); + } + } + } + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/InheritanceCmdlets/SetInheritance.cs b/NTFSSecurity/InheritanceCmdlets/SetInheritance.cs new file mode 100644 index 0000000..109a2e2 --- /dev/null +++ b/NTFSSecurity/InheritanceCmdlets/SetInheritance.cs @@ -0,0 +1,238 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Set, "NTFSInheritance", DefaultParameterSetName = "Path")] + public class SetInheritance : BaseCmdletWithPrivControl + { + private bool? accessInheritanceEnabled; + private bool? auditInheritanceEnabled; + private bool passThru; + + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SecurityDescriptor")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + [Parameter(ValueFromPipelineByPropertyName = true)] + public bool? AccessInheritanceEnabled + { + get { return accessInheritanceEnabled; } + set { accessInheritanceEnabled = value; } + } + + [Parameter(ValueFromPipelineByPropertyName = true)] + public bool? AuditInheritanceEnabled + { + get { return auditInheritanceEnabled; } + set { auditInheritanceEnabled = value; } + } + + [Parameter] + public SwitchParameter PassThru + { + get { return passThru; } + set { passThru = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + EnableFileSystemPrivileges(true); + } + + protected override void ProcessRecord() + { + if (ParameterSetName == "Path") + { + foreach (var path in paths) + { + FileSystemInfo item = null; + + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + var currentState = FileSystemInheritanceInfo.GetFileSystemInheritanceInfo(item); + + if (currentState.AccessInheritanceEnabled != accessInheritanceEnabled) + { + WriteVerbose("AccessInheritanceEnabled not equal"); + if (accessInheritanceEnabled.Value) + { + WriteVerbose("Calling EnableAccessInheritance"); + FileSystemInheritanceInfo.EnableAccessInheritance(item, false); + } + else + { + WriteVerbose("Calling DisableAccessInheritance"); + FileSystemInheritanceInfo.DisableAccessInheritance(item, true); + } + } + else + WriteVerbose("AccessInheritanceEnabled is equal - no change was done"); + + if (currentState.AuditInheritanceEnabled != auditInheritanceEnabled) + { + WriteVerbose("AuditInheritanceEnabled not equal"); + if (auditInheritanceEnabled.Value) + { + WriteVerbose("Calling EnableAuditInheritance"); + FileSystemInheritanceInfo.EnableAuditInheritance(item, true); + } + else + { + WriteVerbose("Calling DisableAuditInheritance"); + FileSystemInheritanceInfo.DisableAuditInheritance(item, false); + } + } + else + WriteVerbose("AuditInheritanceEnabled is equal - no change was done"); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + var currentState = FileSystemInheritanceInfo.GetFileSystemInheritanceInfo(item); + + if (currentState.AccessInheritanceEnabled != accessInheritanceEnabled) + { + WriteVerbose("AccessInheritanceEnabled not equal"); + if (accessInheritanceEnabled.Value) + { + WriteVerbose("Calling EnableAccessInheritance"); + FileSystemInheritanceInfo.EnableAccessInheritance(item, false); + } + else + { + WriteVerbose("Calling DisableAccessInheritance"); + FileSystemInheritanceInfo.DisableAccessInheritance(item, true); + } + } + else + WriteVerbose("AccessInheritanceEnabled is equal - no change was done"); + + if (currentState.AuditInheritanceEnabled != auditInheritanceEnabled) + { + WriteVerbose("AuditInheritanceEnabled not equal"); + if (auditInheritanceEnabled.Value) + { + WriteVerbose("Calling EnableAuditInheritance"); + FileSystemInheritanceInfo.EnableAuditInheritance(item, true); + } + else + { + WriteVerbose("Calling DisableAuditInheritance"); + FileSystemInheritanceInfo.DisableAuditInheritance(item, false); + } + } + else + WriteVerbose("AuditInheritanceEnabled is equal - no change was done"); + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "ModifySdError", ErrorCategory.WriteError, path)); + continue; + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ModifySdError", ErrorCategory.WriteError, path)); + continue; + } + finally + { + if (passThru) + { + WriteObject(FileSystemInheritanceInfo.GetFileSystemInheritanceInfo(item)); + } + } + } + } + else + { + foreach (var sd in securityDescriptors) + { + var currentState = FileSystemInheritanceInfo.GetFileSystemInheritanceInfo(sd); + + if (currentState.AccessInheritanceEnabled != accessInheritanceEnabled) + { + WriteVerbose("AccessInheritanceEnabled not equal"); + if (accessInheritanceEnabled.Value) + { + WriteVerbose("Calling EnableAccessInheritance"); + FileSystemInheritanceInfo.EnableAccessInheritance(sd, false); + } + else + { + WriteVerbose("Calling DisableAccessInheritance"); + FileSystemInheritanceInfo.DisableAccessInheritance(sd, true); + } + } + else + WriteVerbose("AccessInheritanceEnabled is equal - no change was done"); + + if (currentState.AuditInheritanceEnabled != auditInheritanceEnabled) + { + WriteVerbose("AuditInheritanceEnabled not equal"); + if (auditInheritanceEnabled.Value) + { + WriteVerbose("Calling EnableAuditInheritance"); + FileSystemInheritanceInfo.EnableAuditInheritance(sd, true); + } + else + { + WriteVerbose("Calling DisableAuditInheritance"); + FileSystemInheritanceInfo.DisableAuditInheritance(sd, false); + } + } + else + WriteVerbose("AuditInheritanceEnabled is equal - no change was done"); + + if (passThru) + { + WriteObject(FileSystemInheritanceInfo.GetFileSystemInheritanceInfo(sd)); + } + } + } + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/ItemCmdlets/CopyItem2.cs b/NTFSSecurity/ItemCmdlets/CopyItem2.cs new file mode 100644 index 0000000..9f6bfe6 --- /dev/null +++ b/NTFSSecurity/ItemCmdlets/CopyItem2.cs @@ -0,0 +1,132 @@ +using Alphaleonis.Win32.Filesystem; +using System; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Copy, "Item2", SupportsShouldProcess = true)] + public class CopyItem2 : BaseCmdlet + { + private string destination; + private SwitchParameter force; + private bool passThru; + + [Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Position = 2, Mandatory = true, ValueFromPipelineByPropertyName = true)] + public string Destination + { + get { return destination; } + set { destination = value; } + } + + [Parameter] + public SwitchParameter Force + { + get { return force; } + set { force = value; } + } + + [Parameter] + public bool PassThru + { + get { return passThru; } + set { passThru = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + + destination = GetRelativePath(destination); + WriteVerbose(string.Format("Destination path is '{0}'", destination)); + } + + protected override void ProcessRecord() + { + foreach (var path in paths) + { + WriteVerbose(string.Format("Copying item '{0}'", path)); + + FileSystemInfo item = null; + var actualDestination = string.Empty; + + var resolvedPath = GetRelativePath(path); + + try + { + item = GetFileSystemInfo2(resolvedPath); + } + catch (System.IO.FileNotFoundException ex) + { + WriteError(new ErrorRecord(ex, "FileNotFound", ErrorCategory.ObjectNotFound, resolvedPath)); + return; + } + + //destination is a directory + if (Directory.Exists(destination)) + { + //hence adding the file name to the destination path + actualDestination = System.IO.Path.Combine(destination, System.IO.Path.GetFileName(resolvedPath)); + } + else + { + actualDestination = destination; + } + + if (File.Exists(actualDestination)) + { + WriteError(new ErrorRecord(new AlreadyExistsException(), "DestinationFileAlreadyExists", ErrorCategory.ResourceExists, actualDestination)); + return; + } + + try + { + if (item is FileInfo) + { + if (ShouldProcess(resolvedPath, "Copy File")) + { + ((FileInfo)item).CopyTo(actualDestination, force ? CopyOptions.None : CopyOptions.FailIfExists, PathFormat.RelativePath); + WriteVerbose(string.Format("File '{0}' copied to '{0}'", resolvedPath, destination)); + } + } + else + { + if (ShouldProcess(resolvedPath, "Copy Directory")) + { + ((DirectoryInfo)item).CopyTo(actualDestination, force ? CopyOptions.None : CopyOptions.FailIfExists, PathFormat.RelativePath); + WriteVerbose(string.Format("Directory '{0}' copied to '{0}'", resolvedPath, destination)); + } + } + + if (passThru) + WriteObject(item); + } + catch (System.IO.IOException ex) + { + WriteError(new ErrorRecord(ex, "CopyError", ErrorCategory.InvalidData, resolvedPath)); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "CopyError", ErrorCategory.NotSpecified, resolvedPath)); + } + } + } + + protected override void EndProcessing() + { + base.EndProcessing(); + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/ItemCmdlets/GetChildItem2.cs b/NTFSSecurity/ItemCmdlets/GetChildItem2.cs new file mode 100644 index 0000000..788c035 --- /dev/null +++ b/NTFSSecurity/ItemCmdlets/GetChildItem2.cs @@ -0,0 +1,331 @@ +using Alphaleonis.Win32.Filesystem; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Management.Automation; +using System.Linq; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Get, "ChildItem2")] + [OutputType(typeof(FileInfo), typeof(DirectoryInfo))] + public class GetChildItem2 : BaseCmdlet + { + private string filter = "*"; + private SwitchParameter recurse; + private SwitchParameter directory; + private SwitchParameter file; + private System.IO.FileAttributes attributes; + private SwitchParameter hidden; + private SwitchParameter system; + private SwitchParameter readOnly; + private SwitchParameter force; + private SwitchParameter skipMountPoints; + private SwitchParameter skipSymbolicLinks; + private bool getFileSystemModeProperty = false; + private bool identifyHardLinks = false; + private int? depth; + + WildcardPattern wildcard = null; + + System.Reflection.MethodInfo modeMethodInfo = null; + + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Position = 2)] + public string Filter + { + get { return filter; } + set { filter = value; } + } + + [Parameter] + public SwitchParameter Recurse + { + get { return recurse; } + set { recurse = value; } + } + + [Parameter] + public SwitchParameter Directory + { + get { return directory; } + set { directory = value; } + } + + [Parameter] + public SwitchParameter File + { + get { return file; } + set { file = value; } + } + + [Parameter] + public System.IO.FileAttributes Attributes + { + get { return attributes; } + set { attributes = value; ; } + } + + [Parameter()] + public SwitchParameter Hidden + { + get { return hidden; } + set { hidden = value; } + } + + [Parameter] + public SwitchParameter System + { + get { return system; } + set { system = value; } + } + + [Parameter] + public SwitchParameter ReadOnly + { + get { return readOnly; } + set { readOnly = value; } + } + + [Parameter] + public SwitchParameter Force + { + get { return force; } + set { force = value; } + } + + [Parameter] + public SwitchParameter SkipMountPoints + { + get { return skipMountPoints; } + set { skipMountPoints = value; } + } + + [Parameter] + public SwitchParameter SkipSymbolicLinks + { + get { return skipSymbolicLinks; } + set { skipSymbolicLinks = value; } + } + + [Parameter] + public int? Depth + { + get { return depth; } + set { depth = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + + if (paths.Count == 0) + { + paths = new List() { GetVariableValue("PWD").ToString() }; + } + + wildcard = new WildcardPattern(filter, WildcardOptions.Compiled | WildcardOptions.IgnoreCase); + + modeMethodInfo = typeof(FileSystemCodeMembers).GetMethod("Mode"); + + getFileSystemModeProperty = (bool)((Hashtable)MyInvocation.MyCommand.Module.PrivateData)["GetFileSystemModeProperty"]; + identifyHardLinks = (bool)((Hashtable)MyInvocation.MyCommand.Module.PrivateData)["IdentifyHardLinks"]; + } + + protected override void ProcessRecord() + { + foreach (var path in paths) + { + DirectoryInfo di = null; + + try + { + di = (DirectoryInfo)GetFileSystemInfo2(path); + + } + catch (System.IO.FileNotFoundException ex) + { + WriteError(new ErrorRecord(ex, "FileNotFound", ErrorCategory.ObjectNotFound, path)); + continue; + } + + try + { + WriteFileSystem(di, 0); + } + catch (PipelineStoppedException ex) + { + throw ex; + } + } + } + + private void WriteFileSystem(FileSystemInfo fsi, int currentDepth) + { + var di = fsi as DirectoryInfo; + try + { + if (di != null) + { + if (directory) + { + var files = di.EnumerateDirectories(filter, global::System.IO.SearchOption.TopDirectoryOnly); + WriteFileSystemInfoCollection(files.GetEnumerator()); + } + else if (file) + { + var files = di.EnumerateFiles(filter, global::System.IO.SearchOption.TopDirectoryOnly); + WriteFileSystemInfoCollection(files.GetEnumerator()); + } + else + { + var files = di.EnumerateFileSystemInfos(filter, global::System.IO.SearchOption.TopDirectoryOnly); + WriteFileSystemInfoCollection(files.GetEnumerator()); + } + } + + if (recurse) + { + try + { + var subDis = di.EnumerateDirectories("*", global::System.IO.SearchOption.TopDirectoryOnly); + var subDisEnumerator = subDis.GetEnumerator(); + + foreach (var subDi in subDis) + { + //if ((subDi.Attributes & global::System.IO.FileAttributes.Hidden) == global::System.IO.FileAttributes.Hidden & !hidden) + // continue; + + subDi.RefreshEntryInfo(); + if (subDi.EntryInfo.IsMountPoint && skipMountPoints) { continue; } + if (subDi.EntryInfo.IsSymbolicLink && skipSymbolicLinks) { continue; } + + if (depth.HasValue) + { + if (currentDepth < depth) + WriteFileSystem(subDi, currentDepth + 1); + } + else + WriteFileSystem(subDi, 0); + } + } + catch (PipelineStoppedException ex) + { + throw ex; + } + catch (Exception) + { + WriteVerbose(string.Format("Cannot access folder '{0}' for recursive operation", di)); + } + } + } + catch (UnauthorizedAccessException ex) + { + WriteError(new ErrorRecord(ex, "DirUnauthorizedAccessError", ErrorCategory.PermissionDenied, di.FullName)); + } + catch (PipelineStoppedException ex) + { + throw ex; + } + catch (Exception ex) + { + //System.Management.Automation.BreakException or System.Management.Automation.ContinueException cannot be caught due to its protection level in PowerShell v2 + if (ex.GetType().FullName == "System.Management.Automation.BreakException" | ex.GetType().FullName == "System.Management.Automation.ContinueException") + { + throw ex; + } + WriteError(new ErrorRecord(ex, "DirUnspecifiedError", ErrorCategory.NotSpecified, di.FullName)); + } + } + + protected void WriteFileSystemInfoCollection(IEnumerator fileSystemInfos) + { + while (fileSystemInfos.MoveNext()) + { + FileSystemInfo current = (FileSystemInfo)fileSystemInfos.Current; + if (!wildcard.IsMatch(current.Name)) + { + continue; + } + + var writeItem = force.ToBool(); + + if (MyInvocation.BoundParameters.ContainsKey("Attributes")) + { + if ((current.Attributes & attributes) != attributes) + continue; + + writeItem = true; + } + else + { + if (hidden) + force = true; + + if ((current.Attributes & global::System.IO.FileAttributes.Hidden) != global::System.IO.FileAttributes.Hidden) + writeItem = true; + + if (hidden) + if ((current.Attributes & global::System.IO.FileAttributes.Hidden) != global::System.IO.FileAttributes.Hidden) + writeItem = false; + + if (system) + if ((current.Attributes & global::System.IO.FileAttributes.System) != global::System.IO.FileAttributes.System) + writeItem = false; + + if (readOnly) + if ((current.Attributes & global::System.IO.FileAttributes.ReadOnly) != global::System.IO.FileAttributes.ReadOnly) + writeItem = false; + } + + if (writeItem) + { + PSObject item; + if (current is FileInfo) + { + item = new PSObject((FileInfo)current); + } + else + { + item = new PSObject((DirectoryInfo)current); + } + + //can be disabled for a better performance in the PSD1 file, PrivateData section, GetFileSystemModeProperty = $true / $false + if (getFileSystemModeProperty) + item.Properties.Add(new PSCodeProperty("Mode", modeMethodInfo)); + + if (identifyHardLinks == true && current is FileInfo) + { + try + { + item.Properties.Add(new PSNoteProperty("HardLinkCount", Alphaleonis.Win32.Filesystem.File.EnumerateHardlinks(current.FullName).Count())); + } + catch + { + WriteDebug(string.Format("Could not read hard links for '{0}'", current.FullName)); + } + } + + WriteObject(item); + } + } + } + + protected override void EndProcessing() + { + base.EndProcessing(); + } + } +} diff --git a/NTFSSecurity/ItemCmdlets/GetDiskSpace.cs b/NTFSSecurity/ItemCmdlets/GetDiskSpace.cs new file mode 100644 index 0000000..c5af08d --- /dev/null +++ b/NTFSSecurity/ItemCmdlets/GetDiskSpace.cs @@ -0,0 +1,58 @@ +using Alphaleonis.Win32.Filesystem; +using System.Linq; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Get, "DiskSpace")] + [OutputType(typeof(DiskSpaceInfo))] + public class GetDiskSpace : PSCmdlet + { + private string[] driveLetter; + + [Parameter(Position = 1)] + [ValidatePattern("^[A-Za-z]:$")] + public string[] DriveLetter + { + get { return driveLetter; } + set { driveLetter = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + } + + protected override void ProcessRecord() + { + var volumes = Alphaleonis.Win32.Filesystem.Volume.EnumerateVolumes(); + + if (driveLetter == null) + { + driveLetter = volumes.ToArray(); + } + + foreach (var letter in driveLetter) + { + var diskSpaceInfo = new DiskSpaceInfo(letter); + try + { + diskSpaceInfo.Refresh(); + if (diskSpaceInfo.TotalNumberOfBytes > 0) + { + this.WriteObject(diskSpaceInfo); + } + } + catch + { + this.WriteWarning(string.Format("Could not get drive details for '{0}'", letter)); + } + } + } + + protected override void EndProcessing() + { + base.EndProcessing(); + } + } +} diff --git a/NTFSSecurity/ItemCmdlets/GetItem2.cs b/NTFSSecurity/ItemCmdlets/GetItem2.cs new file mode 100644 index 0000000..f45d82c --- /dev/null +++ b/NTFSSecurity/ItemCmdlets/GetItem2.cs @@ -0,0 +1,61 @@ +using Alphaleonis.Win32.Filesystem; +using System.Collections.Generic; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Get, "Item2")] + [OutputType(typeof(FileInfo), typeof(DirectoryInfo))] + public class GetItem2 : BaseCmdlet + { + System.Reflection.MethodInfo modeMethodInfo = null; + + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + + if (paths.Count == 0) + { + paths = new List() { GetVariableValue("PWD").ToString() }; + } + + modeMethodInfo = typeof(FileSystemCodeMembers).GetMethod("Mode"); + } + + protected override void ProcessRecord() + { + foreach (var path in paths) + { + try + { + var item = new PSObject(GetFileSystemInfo2(path)); + item.Properties.Add(new PSCodeProperty("Mode", modeMethodInfo)); + + WriteObject(item); + } + catch (System.IO.FileNotFoundException ex) + { + WriteError(new ErrorRecord(ex, "FileNotFound", ErrorCategory.ObjectNotFound, path)); + } + } + } + + protected override void EndProcessing() + { + base.EndProcessing(); + } + } +} diff --git a/NTFSSecurity/ItemCmdlets/MoveItem2.cs b/NTFSSecurity/ItemCmdlets/MoveItem2.cs new file mode 100644 index 0000000..aa582e3 --- /dev/null +++ b/NTFSSecurity/ItemCmdlets/MoveItem2.cs @@ -0,0 +1,132 @@ +using Alphaleonis.Win32.Filesystem; +using System; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Move, "Item2", SupportsShouldProcess = true)] + public class MoveItem2 : BaseCmdlet + { + private string destination; + private SwitchParameter force; + private bool passThru; + + [Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Position = 2, Mandatory = true, ValueFromPipelineByPropertyName = true)] + public string Destination + { + get { return destination; } + set { destination = value; } + } + + [Parameter] + public SwitchParameter Force + { + get { return force; } + set { force = value; } + } + + [Parameter] + public bool PassThru + { + get { return passThru; } + set { passThru = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + + destination = GetRelativePath(destination); + WriteVerbose(string.Format("Destination path is '{0}'", destination)); + } + + protected override void ProcessRecord() + { + foreach (var path in paths) + { + WriteVerbose(string.Format("Moving item '{0}'", path)); + + FileSystemInfo item = null; + var actualDestination = string.Empty; + + var resolvedPath = GetRelativePath(path); + + try + { + item = GetFileSystemInfo2(resolvedPath); + } + catch (System.IO.FileNotFoundException ex) + { + WriteError(new ErrorRecord(ex, "FileNotFound", ErrorCategory.ObjectNotFound, resolvedPath)); + return; + } + + //destination is a directory + if (Directory.Exists(destination)) + { + //hence adding the file name to the destination path + actualDestination = System.IO.Path.Combine(destination, System.IO.Path.GetFileName(resolvedPath)); + } + else + { + actualDestination = destination; + } + + if (File.Exists(actualDestination)) + { + WriteError(new ErrorRecord(new AlreadyExistsException(), "DestinationFileAlreadyExists", ErrorCategory.ResourceExists, actualDestination)); + return; + } + + try + { + if (item is FileInfo) + { + if (ShouldProcess(resolvedPath, "Move File")) + { + ((FileInfo)item).MoveTo(actualDestination, MoveOptions.CopyAllowed, PathFormat.RelativePath); + WriteVerbose(string.Format("File '{0}' moved to '{0}'", resolvedPath, destination)); + } + } + else + { + if (ShouldProcess(resolvedPath, "Move Directory")) + { + ((DirectoryInfo)item).MoveTo(actualDestination, MoveOptions.CopyAllowed, PathFormat.RelativePath); + WriteVerbose(string.Format("Directory '{0}' moved to '{0}'", resolvedPath, destination)); + } + } + + if (passThru) + WriteObject(item); + } + catch (System.IO.IOException ex) + { + WriteError(new ErrorRecord(ex, "MoveError", ErrorCategory.InvalidData, resolvedPath)); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "MoveError", ErrorCategory.NotSpecified, resolvedPath)); + } + } + } + + protected override void EndProcessing() + { + base.EndProcessing(); + } + } +} diff --git a/NTFSSecurity/ItemCmdlets/RemoveItem2.cs b/NTFSSecurity/ItemCmdlets/RemoveItem2.cs new file mode 100644 index 0000000..3cc85c2 --- /dev/null +++ b/NTFSSecurity/ItemCmdlets/RemoveItem2.cs @@ -0,0 +1,108 @@ +using Alphaleonis.Win32.Filesystem; +using System; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Remove, "Item2", SupportsShouldProcess = true)] + public class RemoveItem2 : BaseCmdlet + { + private SwitchParameter force; + private SwitchParameter recurse; + private string filter; + private bool passThru; + + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter] + public SwitchParameter Force + { + get { return force; } + set { force = value; } + } + + [Parameter] + public SwitchParameter Recurse + { + get { return recurse; } + set { recurse = value; } + } + + [Parameter] + public SwitchParameter PassThur + { + get { return passThru; } + set { passThru = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + } + + protected override void ProcessRecord() + { + foreach (var path in paths) + { + FileSystemInfo item = null; + + try + { + item = GetFileSystemInfo2(path); + } + catch (System.IO.FileNotFoundException ex) + { + WriteError(new ErrorRecord(ex, "FileNotFound", ErrorCategory.ObjectNotFound, path)); + return; + } + + try + { + if (item is FileInfo) + { + if (ShouldProcess(item.ToString(), "Remove File")) + { + ((FileInfo)item).Delete(force); + WriteVerbose(string.Format("File '{0}' was removed", item.ToString())); + } + } + else + { + if (ShouldProcess(item.ToString(), "Remove Directory")) + { + ((DirectoryInfo)item).Delete(recurse, force); + WriteVerbose(string.Format("Directory '{0}' was removed", item.ToString())); + } + } + + if (passThru) + WriteObject(item); + } + catch (System.IO.IOException ex) + { + WriteError(new ErrorRecord(ex, "DeleteError", ErrorCategory.InvalidData, path)); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "DeleteError", ErrorCategory.NotSpecified, path)); + } + } + } + + protected override void EndProcessing() + { + base.EndProcessing(); + } + } +} diff --git a/NTFSSecurity/LinkCmdlets/GetHardLink.cs b/NTFSSecurity/LinkCmdlets/GetHardLink.cs new file mode 100644 index 0000000..fab966e --- /dev/null +++ b/NTFSSecurity/LinkCmdlets/GetHardLink.cs @@ -0,0 +1,74 @@ +using Alphaleonis.Win32.Filesystem; +using System; +using System.Collections.Generic; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Get, "NTFSHardLink")] + [OutputType(typeof(FileInfo), typeof(DirectoryInfo))] + public class GetHardLink : BaseCmdlet + { + System.Reflection.MethodInfo modeMethodInfo = null; + + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + + if (paths.Count == 0) + { + paths = new List() { GetVariableValue("PWD").ToString() }; + } + + modeMethodInfo = typeof(FileSystemCodeMembers).GetMethod("Mode"); + } + + protected override void ProcessRecord() + { + foreach (var path in paths) + { + try + { + var root = System.IO.Path.GetPathRoot(GetRelativePath(path)); + + //access the path to make sure it exists and is a file + var item = GetFileSystemInfo2(path); + + if (item is DirectoryInfo) + throw new ArgumentException("The item must be a file"); + + var links = File.EnumerateHardlinks(item.FullName); + + foreach (var link in links) + { + var target = new PSObject(GetFileSystemInfo2(System.IO.Path.Combine(root, link.Substring(1)))); + target.Properties.Add(new PSCodeProperty("Mode", modeMethodInfo)); + WriteObject(target); + } + } + catch (System.IO.FileNotFoundException ex) + { + WriteError(new ErrorRecord(ex, "FileNotFound", ErrorCategory.ObjectNotFound, path)); + } + } + } + + protected override void EndProcessing() + { + base.EndProcessing(); + } + } +} diff --git a/NTFSSecurity/LinkCmdlets/NewHardLink.cs b/NTFSSecurity/LinkCmdlets/NewHardLink.cs new file mode 100644 index 0000000..7f9f47d --- /dev/null +++ b/NTFSSecurity/LinkCmdlets/NewHardLink.cs @@ -0,0 +1,96 @@ +using Alphaleonis.Win32.Filesystem; +using System; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.New, "NTFSHardLink")] + [OutputType(typeof(FileInfo), typeof(DirectoryInfo))] + public class NewHardLink : BaseCmdlet + { + string target; + private bool passThru; + System.Reflection.MethodInfo modeMethodInfo = null; + + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string Path + { + get { return paths[0]; } + set + { + paths.Clear(); + paths.Add(value); + } + } + + [Parameter(Position = 2, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public string Target + { + get { return target; } + set { target = value; } + } + + [Parameter] + public SwitchParameter PassThru + { + get { return passThru; } + set { passThru = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + + modeMethodInfo = typeof(FileSystemCodeMembers).GetMethod("Mode"); + } + + protected override void ProcessRecord() + { + var path = paths[0]; + + path = GetRelativePath(path); + target = GetRelativePath(target); + var root = System.IO.Path.GetPathRoot(path); + + try + { + FileSystemInfo temp = null; + + if (TryGetFileSystemInfo2(path, out temp)) + throw new ArgumentException(string.Format("The file '{0}' does already exist, cannot create the link", path)); + + if (!TryGetFileSystemInfo2(target, out temp)) + throw new ArgumentException("The target path exist, cannot create the link"); + else + if (temp is DirectoryInfo) + throw new ArgumentException("The target is not a file, cannot create the link"); + + File.CreateHardlink(path, target); + + if (passThru) + { + var links = File.EnumerateHardlinks(path); + + foreach (var link in links) + { + var target = new PSObject(GetFileSystemInfo2(System.IO.Path.Combine(root, link.Substring(1)))); + target.Properties.Add(new PSCodeProperty("Mode", modeMethodInfo)); + WriteObject(target); + } + } + } + catch (System.IO.FileNotFoundException ex) + { + WriteError(new ErrorRecord(ex, "CreateHardLinkError", ErrorCategory.WriteError, path)); + } + } + + protected override void EndProcessing() + { + base.EndProcessing(); + } + } +} diff --git a/NTFSSecurity/LinkCmdlets/NewSymbolicLink.cs b/NTFSSecurity/LinkCmdlets/NewSymbolicLink.cs new file mode 100644 index 0000000..81d85ca --- /dev/null +++ b/NTFSSecurity/LinkCmdlets/NewSymbolicLink.cs @@ -0,0 +1,87 @@ +using Alphaleonis.Win32.Filesystem; +using System; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.New, "NTFSSymbolicLink")] + [OutputType(typeof(FileInfo), typeof(DirectoryInfo))] + public class NewSymbolicLink : BaseCmdlet + { + string target; + private bool passThru; + System.Reflection.MethodInfo modeMethodInfo = null; + + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string Path + { + get { return paths[0]; } + set + { + paths.Clear(); + paths.Add(value); + } + } + + [Parameter(Position = 2, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public string Target + { + get { return target; } + set { target = value; } + } + + [Parameter] + public SwitchParameter PassThru + { + get { return passThru; } + set { passThru = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + + modeMethodInfo = typeof(FileSystemCodeMembers).GetMethod("Mode"); + } + + protected override void ProcessRecord() + { + var path = paths[0]; + + path = GetRelativePath(path); + target = GetRelativePath(target); + FileSystemInfo targetItem = null; + var root = System.IO.Path.GetPathRoot(path); + + try + { + targetItem = GetFileSystemInfo2(target); + + FileSystemInfo temp; + if (TryGetFileSystemInfo2(path, out temp)) + { + throw new ArgumentException("The path does already exist, cannot create link"); + } + + File.CreateSymbolicLink(path, target, targetItem is FileInfo ? SymbolicLinkTarget.File : SymbolicLinkTarget.Directory); + + if (passThru) + { + WriteObject(new FileInfo(path)); + } + } + catch (System.IO.FileNotFoundException ex) + { + WriteError(new ErrorRecord(ex, "CreateSymbolicLinkError", ErrorCategory.ObjectNotFound, path)); + } + } + + protected override void EndProcessing() + { + base.EndProcessing(); + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/MiscCmdlets/GetFileHash2.cs b/NTFSSecurity/MiscCmdlets/GetFileHash2.cs new file mode 100644 index 0000000..1555a4c --- /dev/null +++ b/NTFSSecurity/MiscCmdlets/GetFileHash2.cs @@ -0,0 +1,99 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Management.Automation; +using Security2.FileSystem.FileInfo; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Get, "FileHash2")] + [OutputType(typeof(FileSystemAccessRule2))] + public class GetFileHash2 : BaseCmdlet + { + private HashAlgorithms algorithm = HashAlgorithms.SHA256; + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Position = 2, ValueFromPipelineByPropertyName = true)] + public HashAlgorithms Algorithm + { + get { return algorithm; } + set { algorithm = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + } + + protected override void ProcessRecord() + { + string hash = string.Empty; + FileSystemInfo item = null; + + foreach (var path in paths) + { + try + { + item = GetFileSystemInfo2(path) as FileInfo; + if (item == null) + return; + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + hash = ((FileInfo)item).GetHash(algorithm); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + hash = ((FileInfo)item).GetHash(algorithm); + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "GetHashError", ErrorCategory.WriteError, path)); + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "GetHashError", ErrorCategory.WriteError, path)); + } + + var result = new PSObject(item); + result.Properties.Add(new PSNoteProperty("Hash", hash)); + result.Properties.Add(new PSNoteProperty("Algorithm", algorithm.ToString())); + result.TypeNames.Insert(0, "Alphaleonis.Win32.Filesystem.FileInfo+Hash"); + WriteObject(result); + } + } + + protected override void EndProcessing() + { + base.EndProcessing(); + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/NTFSSecurity-Help.xml b/NTFSSecurity/NTFSSecurity-Help.xml new file mode 100644 index 0000000..176b9bd --- /dev/null +++ b/NTFSSecurity/NTFSSecurity-Help.xml @@ -0,0 +1,2331 @@ + + + + + + + + Add-Access + + Add permission to the ACL of a file or folder. + + + + + + Add + Access + + + + + + The function adds an ACE to the item's ACL. The cmdlet needs to have the following information for that: + - Path + - Account (SamAccountName or SID) + - AccessRights (Read, Change, FullControl, etc., ...) + - AccessType (Allow or Deny) + - ApplyTo (This folder only, Only files, etc.) + +All the options are explained in the parameter section. + +The function needs to know the file or folder path. The path can be an argument or be piped into the function as string or FileSystemInfo object (result of Get-ChildItem or Get-Item). + + + Add-Access + + Account + + Takes the account that is will be granted permission. This can either be a SID (well known, domain or local) or a account name. The account name must be specified in the syntax 'Domain\UserName'. Well known accounts are not part of the domain or local machine. Use for example 'NT Authority\System' or 'Builtin\Administrators'. + + IdentityReference2 + + + AccessRights + + The right the account shall get. This parameter is of the type System.Security.AccessControl.FileSystemRights so the following values are valid: ListDirectory, ReadData, WriteData, CreateFiles, CreateDirectories, AppendData, ReadExtendedAttributes, WriteExtendedAttributes, Traverse, ExecuteFile,DeleteSubdirectoriesAndFiles, ReadAttributes, WriteAttributes, Write, Delete, ReadPermissions, Read, ReadAndExecute, Modify, ChangePermissions, TakeOwnership, Synchronize, FullControl + + FileSystemRights + + + AccessType + + The type of access you want to give, either Allow or Deny (System.Security.AccessControl.AccessControlType). + + AccessControlType + + + InheritanceFlags + + Defines what child items are going to inherit in terms of permissions. If not defined, permissions will be inherited by files and folders (ContainerInherit | ObjectInherit) + +There are three options: +- None: The permission will not be inherited by any child item +- ContainerInherit: The permission will be inherited only by directories +- ObjectInherit: The permission will be inherited only by files + + InheritanceFlags + + + PropagationFlags + + Specifies how Access Control Entries (ACEs) are propagated to child objects. + +There are three options: +- None: Specifies that no propagation flags are set. +- NoPropagateInherit: Specifies that the ACE is not propagated to child objects. +- InheritOnly: Specifies that the ACE is propagated only to child objects. This includes both container and leaf child objects. + + PropagationFlags + + + PassThru + + Returns the item's access control list by using FileSystemAccessRule2. item's ACE. By default, this cmdlet does not generate any output. + + + + Path + + Specifies the path to a resource. Add-Access adds permissions to the items indicated by the path. Wildcards are not permitted. This parameter accepts input from the pipeline so combining Get-Access with Get-ChildItem or Get-Item is the easiest way if you want to process multiple files or folders. + + String[] + + + + Add-Access + + Account + + Takes the account that is will be granted permission. This can either be a SID (well known, domain or local) or a account name. The account name must be specified in the syntax 'Domain\UserName'. Well known accounts are not part of the domain or local machine. Use for example 'NT Authority\System' or 'Builtin\Administrators'. + + IdentityReference2 + + + AccessRights + + The right the account shall get. This parameter is of the type System.Security.AccessControl.FileSystemRights so the following values are valid: ListDirectory, ReadData, WriteData, CreateFiles, CreateDirectories, AppendData, ReadExtendedAttributes, WriteExtendedAttributes, Traverse, ExecuteFile,DeleteSubdirectoriesAndFiles, ReadAttributes, WriteAttributes, Write, Delete, ReadPermissions, Read, ReadAndExecute, Modify, ChangePermissions, TakeOwnership, Synchronize, FullControl + + FileSystemRights + + + AccessType + + The type of access you want to give, either Allow or Deny (System.Security.AccessControl.AccessControlType). + + AccessControlType + + + AppliesTo + + This parameter controls inheritance and propagation like the "Apply To" drop-down box in the Windows Explorer dialog. The allowed options are: +- ThisFolderOnly +- ThisFolderSubfolderAndFiles +- ThisFolderAndSubfolders +- ThisFolderAndFiles +- SubfolderAndFilesOnly +- SubfolersOnly +- FilesOnly + + ApplyTo + + + PassThru + + Returns the item's access control list by using FileSystemAccessRule2. item's ACE. By default, this cmdlet does not generate any output. + + + + Path + + Specifies the path to a resource. Add-Access adds permissions to the items indicated by the path. Wildcards are not permitted. This parameter accepts input from the pipeline so combining Get-Access with Get-ChildItem or Get-Item is the easiest way if you want to process multiple files or folders. + + String[] + + + + + + Account + + Takes the account that is will be granted permission. This can either be a SID (well known, domain or local) or a account name. The account name must be specified in the syntax 'Domain\UserName'. Well known accounts are not part of the domain or local machine. Use for example 'NT Authority\System' or 'Builtin\Administrators'. + + IdentityReference2 + + IdentityReference2 + + + + + + AccessRights + + The right the account shall get. This parameter is of the type System.Security.AccessControl.FileSystemRights so the following values are valid: ListDirectory, ReadData, WriteData, CreateFiles, CreateDirectories, AppendData, ReadExtendedAttributes, WriteExtendedAttributes, Traverse, ExecuteFile,DeleteSubdirectoriesAndFiles, ReadAttributes, WriteAttributes, Write, Delete, ReadPermissions, Read, ReadAndExecute, Modify, ChangePermissions, TakeOwnership, Synchronize, FullControl + + FileSystemRights + + FileSystemRights + + + + + + AccessType + + The type of access you want to give, either Allow or Deny (System.Security.AccessControl.AccessControlType). + + AccessControlType + + AccessControlType + + + + + + InheritanceFlags + + Defines what child items are going to inherit in terms of permissions. If not defined, permissions will be inherited by files and folders (ContainerInherit | ObjectInherit) + +There are three options: +- None: The permission will not be inherited by any child item +- ContainerInherit: The permission will be inherited only by directories +- ObjectInherit: The permission will be inherited only by files + + InheritanceFlags + + InheritanceFlags + + + + + + PropagationFlags + + Specifies how Access Control Entries (ACEs) are propagated to child objects. + +There are three options: +- None: Specifies that no propagation flags are set. +- NoPropagateInherit: Specifies that the ACE is not propagated to child objects. +- InheritOnly: Specifies that the ACE is propagated only to child objects. This includes both container and leaf child objects. + + PropagationFlags + + PropagationFlags + + + + + + PassThru + + Returns the item's access control list by using FileSystemAccessRule2. item's ACE. By default, this cmdlet does not generate any output. + + + SwitchParameter + + + + + + Path + + Specifies the path to a resource. Add-Access adds permissions to the items indicated by the path. Wildcards are not permitted. This parameter accepts input from the pipeline so combining Get-Access with Get-ChildItem or Get-Item is the easiest way if you want to process multiple files or folders. + + String[] + + String[] + + + + + + AppliesTo + + This parameter controls inheritance and propagation like the "Apply To" drop-down box in the Windows Explorer dialog. The allowed options are: +- ThisFolderOnly +- ThisFolderSubfolderAndFiles +- ThisFolderAndSubfolders +- ThisFolderAndFiles +- SubfolderAndFilesOnly +- SubfolersOnly +- FilesOnly + + ApplyTo + + ApplyTo + + + + + + + + + FileSystemInfo or Strings + + + All parameters accept pipeline input. + + + + + + + + + Null, unless the parameter PassThru is used. + + + Security2.FileSystemAccessRule2 for each ACE on the object, if PassThru is used. + + + + + + + + + + + + + + + + + + +-------------- EXAMPLE 1 -------------- + + C:\PS> +C:\PS> + PS C:\> dir | Add-Ace -Account forest3\test -AccessRights Read -PassThru + + Add read permissions to the test user account. Per default the inheritance is set to files and folders. + + + Path: C:\data\Test (Inheritance enabled) + + Identity Rights Inheritance Type IsInherited + -------- ------ ----------- ---- ----------- + raandree1\Test (S-1-5-21-30... FullControl ContainerInherit,... Allow False + + + + + + + + + + + + +-------------- EXAMPLE 2 -------------- + + C:\PS> +C:\PS> + PS C:\data> dir | Add-Ace -Account raandree1\test -AccessRights Read -AppliesTo ThisFolderOnly -PassThru + + Adds read access to the test account to all items the 'dir' command returns without inheriting the access to files or folder below. + + + Path: C:\data\Test (Inheritance enabled) + + Identity Rights Inheritance Type IsInherited + -------- ------ ----------- ---- ----------- + raandree1\Test (S-1-5-21-30... Read, Synchronize None Allow False + + Path: C:\data\File1.txt (Inheritance enabled) + + Identity Rights Inheritance Type IsInherited + -------- ------ ----------- ---- ----------- + raandree1\Test (S-1-5-21-30... Read, Synchronize None Allow False + + + + + + + + + + + + + + http://gallery.technet.microsoft.com/scriptcenter/1abd77a5-9c0b-4a2b-acef-90dbb2b84e85 + + + + + + + + Copy-Access + + + + + + + + Copy + Access + + + + + + + + + Copy-Access + + Path + + + + String + + + DestinationPath + + + + String + + + Account + + + + IdentityReference2 + + + AccessType + + + + AccessControlType + + + PassThru + + + + + + + + + Path + + + + String + + String + + + + + + DestinationPath + + + + String + + String + + + + + + Account + + + + IdentityReference2 + + IdentityReference2 + + + + + + AccessType + + + + AccessControlType + + AccessControlType + + + + + + PassThru + + + + + SwitchParameter + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Disable-Inheritance + + + + + + + + Disable + Inheritance + + + + + + + + + Disable-Inheritance + + PassThru + + + + + + PreserveInheritedAccessRules + + + + + + Path + + + + String[] + + + + + + PassThru + + + + + SwitchParameter + + + + + + PreserveInheritedAccessRules + + + + + SwitchParameter + + + + + + Path + + + + String[] + + String[] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Enable-Inheritance + + + + + + + + Enable + Inheritance + + + + + + + + + Enable-Inheritance + + PassThru + + + + + + RemoveInheritedAccessRules + + + + + + Path + + + + String[] + + + + + + PassThru + + + + + SwitchParameter + + + + + + RemoveInheritedAccessRules + + + + + SwitchParameter + + + + + + Path + + + + String[] + + String[] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Get-Access + + Gets all Access Control Entries in the item's Discretionary Access Control List. + + + + + + Get + Access + + + + + + The function returns all ACEs defined on the item. You can filter the ACEs using the switches ExcludeExplicit and ExcludeInherited. + +Whether the item inherits the permissions from its parent is indicated in the output as well. + +The function needs to know the file or folder path. The path can be an argument or be piped into the function as string or FileSystemInfo object (result of Get-ChildItem or Get-Item). + + + Get-Access + + Account + + Takes the account that is used to filter the output. Only ACEs are shown that match the given user account. + +This can either be a SID (well known, domain or local) or a account name. The account name must be specified in the syntax 'Domain\UserName'. Well known accounts are not part of the domain or local machine. Use for example 'NT Authority\System' or 'Builtin\Administrators'. + + IdentityReference2 + + + ExcludeExplicit + + If set, only inherited ACEs are returned. + + + + ExcludeInherited + + If set, only explicitly non-inherited ACEs are returned. + + + + Path + + Specifies the path to the resource. Get-Access gets the permissions of the items indicated by the path. Wildcards are not permitted. This parameter also accepts input from the pipeline so combining Get-Access with Get-ChildItem or Get-Item is the easiest way if you want to get the access rights of multiple files and folders. + + String[] + + + + + + Account + + Takes the account that is used to filter the output. Only ACEs are shown that match the given user account. + +This can either be a SID (well known, domain or local) or a account name. The account name must be specified in the syntax 'Domain\UserName'. Well known accounts are not part of the domain or local machine. Use for example 'NT Authority\System' or 'Builtin\Administrators'. + + IdentityReference2 + + IdentityReference2 + + + + + + ExcludeExplicit + + If set, only inherited ACEs are returned. + + + SwitchParameter + + + + + + ExcludeInherited + + If set, only explicitly non-inherited ACEs are returned. + + + SwitchParameter + + + + + + Path + + Specifies the path to the resource. Get-Access gets the permissions of the items indicated by the path. Wildcards are not permitted. This parameter also accepts input from the pipeline so combining Get-Access with Get-ChildItem or Get-Item is the easiest way if you want to get the access rights of multiple files and folders. + + String[] + + String[] + + + + + + + + + System.String + + + You can pipe a string that contains a path. + + + + + + + + + Security2.FileSystemAccessRule2 + + + Get-Ace returns objects that represent the item's Access Control Entries. + + + + + + + + + + + + + + + + + + +-------------- EXAMPLE 1 -------------- + + C:\PS> +C:\PS> + Get-Item c:\ | Get-Access + + Get all ACEs defined on the root of drive C: + + + Path: C:\ (Inheritance disabled) + + Identity Rights Inheritance Type IsInherited + -------- ------ ----------- ---- ----------- + NT AUTHORITY\Authenticated ... AppendData None Allow False + NT AUTHORITY\Authenticated ... -536805376 ContainerIn... Allow False + NT AUTHORITY\SYSTEM (S-1-5-18) FullControl None Allow False + NT AUTHORITY\SYSTEM (S-1-5-18) 268435456 ContainerIn... Allow False + BUILTIN\Administrators (S-1... 268435456 ContainerIn... Allow False + BUILTIN\Administrators (S-1... FullControl None Allow False + BUILTIN\Users (S-1-5-32-545) ReadAndExec... ContainerIn... Allow False + + + + + + + + + + + + +-------------- EXAMPLE 2 -------------- + + C:\PS> +C:\PS> + PS C:\> dir | Where-Object { $_.PSIsContainer } | Get-Ace -ExcludeInherited + + This command returns only explicitly set ACEs on all folders. + + + + + + + + + + + + + + + +-------------- EXMAPLE 3 -------------- + + C:\PS> +C:\PS> + PS C:\> dir | Get-Access -Account Builtin\Users + + This command returns all Access Control Entries whose account match 'Builtin\Users'. + + + Path: C:\Users\raandree\Desktop\ADRAP.docx (Inheritance disabled) + + +Account Access Rights Applies to Type IsInherited +------- ------------- ---------- ---- ----------- +BUILTIN\Users (S-1-5-32-545) Modify, Synch... ThisFolderOnly Allow False + + + + + + + + + + + + + + http://gallery.technet.microsoft.com/scriptcenter/1abd77a5-9c0b-4a2b-acef-90dbb2b84e85 + + + + + + + + Get-EffectiveAccess + + + + + + + + Get + EffectiveAccess + + + + + + + + + Get-EffectiveAccess + + Account + + + + IdentityReference2 + + + Path + + + + String[] + + + + + + Account + + + + IdentityReference2 + + IdentityReference2 + + + + + + Path + + + + String[] + + String[] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Get-Inheritance + + + + + + + + Get + Inheritance + + + + + + + + + Get-Inheritance + + Path + + + + String[] + + + + + + Path + + + + String[] + + String[] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Get-OrphanedAccess + + + + + + + + Get + OrphanedAccess + + + + + + + + + Get-OrphanedAccess + + Account + + + + IdentityReference2 + + + ExcludeExplicit + + + + + + ExcludeInherited + + + + + + Path + + + + String[] + + + + + + Account + + + + IdentityReference2 + + IdentityReference2 + + + + + + ExcludeExplicit + + + + + SwitchParameter + + + + + + ExcludeInherited + + + + + SwitchParameter + + + + + + Path + + + + String[] + + String[] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Get-Owner + + + + + + + + Get + Owner + + + + + + + + + Get-Owner + + Path + + + + String[] + + + + + + Path + + + + String[] + + String[] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Get-SimpleAccess + + + + + + + + Get + SimpleAccess + + + + + + + + + Get-SimpleAccess + + IncludeRootFolder + + + + + + Account + + + + IdentityReference2 + + + ExcludeExplicit + + + + + + ExcludeInherited + + + + + + Path + + + + String[] + + + + + + IncludeRootFolder + + + + + SwitchParameter + + + + + + Account + + + + IdentityReference2 + + IdentityReference2 + + + + + + ExcludeExplicit + + + + + SwitchParameter + + + + + + ExcludeInherited + + + + + SwitchParameter + + + + + + Path + + + + String[] + + String[] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Get-SimpleEffectiveAccess + + + + + + + + Get + SimpleEffectiveAccess + + + + + + + + + Get-SimpleEffectiveAccess + + IncludeRootFolder + + + + + + Account + + + + IdentityReference2 + + + Path + + + + String[] + + + + + + IncludeRootFolder + + + + + SwitchParameter + + + + + + Account + + + + IdentityReference2 + + IdentityReference2 + + + + + + Path + + + + String[] + + String[] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Remove-Access + + + + + + + + Remove + Access + + + + + + + + + Remove-Access + + Account + + + + IdentityReference2 + + + AccessRights + + + + FileSystemRights + + + AccessType + + + + AccessControlType + + + InheritanceFlags + + + + InheritanceFlags + + + PropagationFlags + + + + PropagationFlags + + + PassThru + + + + + + Path + + + + String[] + + + + Remove-Access + + Account + + + + IdentityReference2 + + + AccessRights + + + + FileSystemRights + + + AccessType + + + + AccessControlType + + + AppliesTo + + + + ApplyTo + + + PassThru + + + + + + Path + + + + String[] + + + + + + Account + + + + IdentityReference2 + + IdentityReference2 + + + + + + AccessRights + + + + FileSystemRights + + FileSystemRights + + + + + + AccessType + + + + AccessControlType + + AccessControlType + + + + + + InheritanceFlags + + + + InheritanceFlags + + InheritanceFlags + + + + + + PropagationFlags + + + + PropagationFlags + + PropagationFlags + + + + + + PassThru + + + + + SwitchParameter + + + + + + Path + + + + String[] + + String[] + + + + + + AppliesTo + + + + ApplyTo + + ApplyTo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Set-Owner + + + + + + + + Set + Owner + + + + + + + + + Set-Owner + + Account + + + + IdentityReference2 + + + PassThru + + + + + + Recurse + + + + + + Path + + + + String[] + + + + + + Account + + + + IdentityReference2 + + IdentityReference2 + + + + + + PassThru + + + + + SwitchParameter + + + + + + Recurse + + + + + SwitchParameter + + + + + + Path + + + + String[] + + String[] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Show-SimpleAccess + + + + + + + + Show + SimpleAccess + + + + + + + + + Show-SimpleAccess + + IncludeRootFolder + + + + + + Account + + + + IdentityReference2 + + + ExcludeExplicit + + + + + + ExcludeInherited + + + + + + Path + + + + String[] + + + + + + IncludeRootFolder + + + + + SwitchParameter + + + + + + Account + + + + IdentityReference2 + + IdentityReference2 + + + + + + ExcludeExplicit + + + + + SwitchParameter + + + + + + ExcludeInherited + + + + + SwitchParameter + + + + + + Path + + + + String[] + + String[] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Show-SimpleEffectiveAccess + + + + + + + + Show + SimpleEffectiveAccess + + + + + + + + + Show-SimpleEffectiveAccess + + IncludeRootFolder + + + + + + Account + + + + IdentityReference2 + + + Path + + + + String[] + + + + + + IncludeRootFolder + + + + + SwitchParameter + + + + + + Account + + + + IdentityReference2 + + IdentityReference2 + + + + + + Path + + + + String[] + + String[] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NTFSSecurity/NTFSSecurity.Init.ps1 b/NTFSSecurity/NTFSSecurity.Init.ps1 new file mode 100644 index 0000000..e841d8f --- /dev/null +++ b/NTFSSecurity/NTFSSecurity.Init.ps1 @@ -0,0 +1,81 @@ +#region Internals +#region C# Code +$type_NTFS1 = @' + using System; + using System.IO; + using System.Collections; + using System.Runtime.InteropServices; + using Microsoft.Win32.SafeHandles; + + namespace NTFS + { + public class DriveInfoExt + { + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] + static extern bool GetDiskFreeSpace(string lpRootPathName, + out uint lpSectorsPerCluster, + out uint lpBytesPerSector, + out uint lpNumberOfFreeClusters, + out uint lpTotalNumberOfClusters); + + DriveInfo _drive = null; + uint _sectorsPerCluster = 0; + uint _bytesPerSector = 0; + uint _numberOfFreeClusters = 0; + uint _totalNumberOfClusters = 0; + + public uint SectorsPerCluster { get { return _sectorsPerCluster; } } + public uint BytesPerSector { get { return _bytesPerSector; } } + public uint NumberOfFreeClusters { get { return _numberOfFreeClusters; } } + public uint TotalNumberOfClusters { get { return _totalNumberOfClusters; } } + public DriveInfo Drive { get { return _drive; } } + public string DriveName { get { return _drive.Name; } } + public string VolumeName { get { return _drive.VolumeLabel; } } + + public DriveInfoExt(string DriveName) + { + _drive = new DriveInfo(DriveName); + + GetDiskFreeSpace(_drive.Name, + out _sectorsPerCluster, + out _bytesPerSector, + out _numberOfFreeClusters, + out _totalNumberOfClusters); + } + } + + public class FileInfoExt + { + [DllImport("kernel32.dll", SetLastError = true, EntryPoint = "GetCompressedFileSize")] + static extern uint GetCompressedFileSize(string lpFileName, out uint lpFileSizeHigh); + + public static ulong GetCompressedFileSize(string filename) + { + uint high; + uint low; + low = GetCompressedFileSize(filename, out high); + int error = Marshal.GetLastWin32Error(); + + if (high == 0 && low == 0xFFFFFFFF && error != 0) + { + throw new System.ComponentModel.Win32Exception(error); + } + else + { + return ((ulong)high << 32) + low; + } + } + } + } +'@ +#endregion +#endregion + +Add-Type -TypeDefinition $type_NTFS1 +Add-Type -Path $PSScriptRoot\Security2.dll +Add-Type -Path $PSScriptRoot\PrivilegeControl.dll -ReferencedAssemblies $PSScriptRoot\ProcessPrivileges.dll +Add-Type -Path $PSScriptRoot\ProcessPrivileges.dll + +#using Update-FormatData and not FormatsToProcess in the PSD1 as FormatsToProcess does not offer +#putting format data in front of the default data. This is required to make the new formatter the default ones. +Update-FormatData -PrependPath $PSScriptRoot\NTFSSecurity.format.ps1xml \ No newline at end of file diff --git a/NTFSSecurity/NTFSSecurity.csproj b/NTFSSecurity/NTFSSecurity.csproj new file mode 100644 index 0000000..be01302 --- /dev/null +++ b/NTFSSecurity/NTFSSecurity.csproj @@ -0,0 +1,178 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {17768E1A-1422-4BD2-A9A5-42BA9FEB82B8} + Library + Properties + NTFSSecurity + NTFSSecurity + v3.5 + 512 + Client + SAK + SAK + SAK + SAK + + + true + full + false + ..\..\..\..\..\Program Files\WindowsPowerShell\Modules\NTFSSecurity\ + TRACE;DEBUG + prompt + 4 + false + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + bin\Release\NTFSSecurity.XML + + + + + + + + ..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Form + + + ShowSimpleEffectiveAccess.cs + + + + + True + True + Resources.resx + + + Form + + + ShowSimpleAccess.cs + + + + + {f0f9af1e-d5b5-4d72-804a-5380622fbdea} + AlphaFS + + + {01EAB41B-B2CE-49FE-AB5A-0F0FF0A9A7EE} + PrivilegeControl + + + {410CAEE5-D287-4A18-9B38-BB87397D218D} + ProcessPrivileges + + + {B437C364-5BC7-42E4-93F7-0F459A5DF0D0} + Security2 + + + + + + PreserveNewest + Designer + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + ShowSimpleEffectiveAccess.cs + + + PublicResXFileCodeGenerator + Resources.Designer.cs + + + ShowSimpleAccess.cs + + + + + PreserveNewest + + + + + + + + \ No newline at end of file diff --git a/NTFSSecurity/NTFSSecurity.format.ps1xml b/NTFSSecurity/NTFSSecurity.format.ps1xml new file mode 100644 index 0000000..c82769d --- /dev/null +++ b/NTFSSecurity/NTFSSecurity.format.ps1xml @@ -0,0 +1,500 @@ + + + + + + FileSystemTypes2 + + Alphaleonis.Win32.Filesystem.DirectoryInfo + Alphaleonis.Win32.Filesystem.FileInfo + + + + + + + SimpleFileSystemGrouping + + + + + + 4 + + + + if ($global:tempFullName -ne $_.FullName) + { + "Path: $($_.FullName) (Inheritance $(if ($_.InheritanceEnabled) { "enabled" } else { "disabled" }))" + $global:FullName = $_.FullName + } + + + + + + + + + + + + + SimpleFileSystemAccessRule2Grouping + + + + + + 4 + + + + if ($global:tempFullName -ne $_.FullName) + { + "Path: $($_.FullName)" + $global:FullName = $_.FullName + } + + + + + + + + + + + + + FileSystemTypes2-GroupingFormat + + + + + + 4 + + + + + Split-Path -Path $_.FullName -Parent + + + + + + + + + + + + + + + + + Security2.FileSystemAccessRule2 + + Security2.FileSystemAccessRule2 + + + FullName + SimpleFileSystemGrouping + + + + + 35 + + + + + + + 25 + + + + + + + + + + + + + + + + + + if ((Get-Module NTFSSecurity).PrivateData.ShowAccountSid) + { + '{0} ({1})' -f $_.Account.AccountName, $_.Account.Sid + } + else + { + $_.Account.ToString() + } + + + + AccessRights + + + + [Security2.FileSystemSecurity2]::ConvertToApplyTo($_.InheritanceFlags, $_.PropagationFlags) + + + + AccessControlType + + + IsInherited + + + InheritedFrom + + + + + + + + + Security2.FileSystemAuditRule2 + + Security2.FileSystemAuditRule2 + + + FullName + SimpleFileSystemGrouping + + + + + 35 + + + + + + + 25 + + + + + + + + + + + + + + + + + + if ((Get-Module NTFSSecurity).PrivateData.ShowAccountSid) + { + '{0} ({1})' -f $_.Account.AccountName, $_.Account.Sid + } + else + { + $_.Account.ToString() + } + + + + AccessRights + + + + [Security2.FileSystemSecurity2]::ConvertToApplyTo($_.InheritanceFlags, $_.PropagationFlags) + + + + AuditFlags + + + IsInherited + + + InheritedFrom + + + + + + + + + Security2.SimpleFileSystemAuditRule2 + + Security2.SimpleFileSystemAuditRule2 + + + FullName + SimpleFileSystemGrouping + + + + + 35 + + + + + + + 25 + + + + + + + + + + + + + + + + if ((Get-Module NTFSSecurity).PrivateData.ShowAccountSid) + { + '{0} ({1})' -f $_.Account.AccountName, $_.Account.Sid + } + else + { + $_.Account.ToString() + } + + + + AccessRights + + + + [Security2.FileSystemSecurity2]::ConvertToApplyTo($_.InheritanceFlags, $_.PropagationFlags) + + + + AuditFlags + + + IsInherited + + + + + + + + + Security2.FileSystemEffectivePermissionEntry + + Security2.FileSystemEffectivePermissionEntry + + + + + + + + + + + + + + + + + + + + + + Name + + + AccessAsString + + + AccessMask + + + + if ((Get-Module NTFSSecurity).PrivateData.ShowAccountSid) + { + '{0} ({1})' -f $_.Account.AccountName, $_.Account.Sid + } + else + { + $_.Account.ToString() + } + + + + + + + + + + Security2.FileSystemInheritanceInfo + + Security2.FileSystemInheritanceInfo + + + + + + + + + + + + + + + + + + + Name + + + AccessInheritanceEnabled + + + AuditInheritanceEnabled + + + + + + + + + Children2 + + FileSystemTypes2 + + + if ($_.DirectoryName) { $_.DirectoryName } else { $_.Parent.FullName } + FileSystemTypes2-GroupingFormat + + + + + + 7 + Left + + + + 8 + Right + + + + 25 + Right + + + + 15 + Right + + + + + + + + + + + Mode + + + + !$_.IsInheritanceBlocked + + + + + [String]::Format("{0,10} {1,8}", $_.LastWriteTime.ToString("d"), $_.LastWriteTime.ToString("t")) + + + + + if ($_ -is [Alphaleonis.Win32.Filesystem.FileInfo]) + { + [Math]::Round($_.Length / 1MB, 2).ToString() + } + else + { + " {0,-13}" -f "<DIR>" + } + + + + Name + + + + + + + + + Alphaleonis.Win32.Filesystem.FileInfo+Hash + + Alphaleonis.Win32.Filesystem.FileInfo+Hash + + + + + + + + + + + + + + + + + + + + Algorithm + + + Hash + + + FullName + + + + + + + + + \ No newline at end of file diff --git a/NTFSSecurity/NTFSSecurity.psd1 b/NTFSSecurity/NTFSSecurity.psd1 new file mode 100644 index 0000000..a9c80f7 --- /dev/null +++ b/NTFSSecurity/NTFSSecurity.psd1 @@ -0,0 +1,98 @@ +@{ + ModuleToProcess = 'NTFSSecurity.psm1' + + ModuleVersion = '4.2.3' + + GUID = 'cd303a6c-f405-4dcb-b1ce-fbc2c52264e9' + + Author = 'Raimund Andree' + + CompanyName = 'Raimund Andree' + + Copyright = '2015' + + Description = 'Windows PowerShell Module for managing file and folder security on NTFS volumes' + + PowerShellVersion = '2.0' + + DotNetFrameworkVersion = '3.5' + + ScriptsToProcess = @('NTFSSecurity.Init.ps1') + + TypesToProcess = @('NTFSSecurity.types.ps1xml') + + FormatsToProcess = @() + + NestedModules = @('NTFSSecurity.dll') + + AliasesToExport = '*' + + CmdletsToExport = 'Add-NTFSAccess', + 'Clear-NTFSAccess', + 'Disable-NTFSAccessInheritance', + 'Enable-NTFSAccessInheritance', + 'Get-NTFSAccess', + 'Get-NTFSEffectiveAccess', + 'Get-NTFSOrphanedAccess', + 'Get-NTFSSimpleAccess', + 'Remove-NTFSAccess', + 'Show-NTFSSimpleAccess', + #---------------------------------------------- + 'Add-NTFSAudit', + 'Clear-NTFSAudit', + 'Disable-NTFSAuditInheritance', + 'Enable-NTFSAuditInheritance', + 'Get-NTFSAudit', + 'Get-NTFSOrphanedAudit', + 'Remove-NTFSAudit', + #---------------------------------------------- + 'Disable-NTFSAccessInheritance', + 'Disable-NTFSAuditInheritance', + 'Enable-NTFSAccessInheritance', + 'Enable-NTFSAuditInheritance', + 'Get-NTFSInheritance', + 'Set-NTFSInheritance', + #---------------------------------------------- + 'Get-NTFSOwner', + 'Set-NTFSOwner', + #---------------------------------------------- + 'Get-NTFSSecurityDescriptor', + 'Set-NTFSSecurityDescriptor', + #---------------------------------------------- + 'Disable-Privileges', + 'Enable-Privileges', + 'Get-Privileges', + #---------------------------------------------- + 'Copy-Item2', + 'Get-ChildItem2', + 'Get-Item2', + 'Move-Item2', + 'Remove-Item2', + #---------------------------------------------- + 'Test-Path2', + #---------------------------------------------- + 'Get-NTFSHardLink', + 'New-NTFSHardLink', + 'New-NTFSSymbolicLink', + #---------------------------------------------- + 'Get-DiskSpace', + 'Get-FileHash2' + + ModuleList = @('NTFSSecurity.dll') + + FileList = @('NTFSSecurity.dll', 'NTFSSecurity.types.ps1xml', 'NTFSSecurity.format.ps1xml', 'NTFSSecurity.Init.ps1', 'NTFSSecurity.psm1') + + PrivateData = @{ + EnablePrivileges = $true + GetInheritedFrom = $true + GetFileSystemModeProperty = $true + ShowAccountSid = $false + IdentifyHardLinks = $true + + PSData = @{ + Tags = @('AccessControl', 'ACL', 'DirectorySecurity', 'FileSecurity', 'FileSystem', 'FileSystemSecurity', 'NTFS', 'Module', 'AccessRights') + LicenseUri = 'https://ntfssecurity.codeplex.com/license' + ProjectUri = 'https://ntfssecurity.codeplex.com' + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/NTFSSecurity.psm1 b/NTFSSecurity/NTFSSecurity.psm1 new file mode 100644 index 0000000..acb0828 --- /dev/null +++ b/NTFSSecurity/NTFSSecurity.psm1 @@ -0,0 +1,52 @@ +<# +#Access cmdlets +New-Alias -Name Get-Ace -Value Get-NTFSAccess -ErrorAction SilentlyContinue +New-Alias -Name Get-Access -Value Get-NTFSAccess -ErrorAction SilentlyContinue + +New-Alias -Name Get-EffectiveAccess -Value Get-NTFSEffectiveAccess -ErrorAction SilentlyContinue + +New-Alias -Name Add-Ace -Value Add-NTFSAccess -ErrorAction SilentlyContinue +New-Alias -Name Add-Access -Value Add-NTFSAccess -ErrorAction SilentlyContinue + +New-Alias -Name Remove-Ace -Value Remove-NTFSAccess -ErrorAction SilentlyContinue +New-Alias -Name Remove-Access -Value Remove-NTFSAccess -ErrorAction SilentlyContinue + +New-Alias -Name Get-OrphanedAccess -Value Get-NTFSOrphanedAccess -ErrorAction SilentlyContinue +New-Alias -Name Get-OrphanedAce -Value Get-NTFSOrphanedAccess -ErrorAction SilentlyContinue + +New-Alias -Name Get-AccessInheritance -Value Get-NTFSAccessInheritance -ErrorAction SilentlyContinue + +New-Alias -Name Enable-Inheritance -Value Enable-NTFSAccessInheritance -ErrorAction SilentlyContinue +New-Alias -Name Enable-AccessInheritance -Value Enable-NTFSAccessInheritance -ErrorAction SilentlyContinue + +New-Alias -Name Disable-Inheritance -Value Disable-NTFSAccessInheritance -ErrorAction SilentlyContinue +New-Alias -Name Disable-AccessInheritance -Value Disable-NTFSAccessInheritance -ErrorAction SilentlyContinue + +#Audit cmdlets +New-Alias -Name Get-Audit -Value Get-NTFSAudit -ErrorAction SilentlyContinue + +New-Alias -Name Add-Audit -Value Add-NTFSAudit -ErrorAction SilentlyContinue + +New-Alias -Name Remove-Audit -Value Remove-NTFSAudit -ErrorAction SilentlyContinue + +New-Alias -Name Get-OrphanedAudit -Value Get-NTFSOrphanedAudit -ErrorAction SilentlyContinue + +New-Alias -Name Get-AuditInheritance -Value Get-NTFSAuditInheritance -ErrorAction SilentlyContinue + +New-Alias -Name Enable-AuditInheritance -Value Enable-NTFSAuditInheritance -ErrorAction SilentlyContinue + +New-Alias -Name Disable-AuditInheritance -Value Disable-NTFSAuditInheritance -ErrorAction SilentlyContinue + +#Owner cmdlets +New-Alias -Name Get-Owner -Value Get-NTFSOwner -ErrorAction SilentlyContinue + +New-Alias -Name Set-Owner -Value Set-NTFSOwner -ErrorAction SilentlyContinue +#> + +#Item cmdlets +New-Alias -Name dir2 -Value Get-ChildItem2 -ErrorAction SilentlyContinue +New-Alias -Name gi2 -Value Get-Item2 -ErrorAction SilentlyContinue +New-Alias -Name rm2 -Value Remove-Item2 -ErrorAction SilentlyContinue +New-Alias -Name del2 -Value Remove-Item2 -ErrorAction SilentlyContinue + +Export-ModuleMember -Alias * -Function * -Cmdlet * \ No newline at end of file diff --git a/NTFSSecurity/NTFSSecurity.types.ps1xml b/NTFSSecurity/NTFSSecurity.types.ps1xml new file mode 100644 index 0000000..4944423 --- /dev/null +++ b/NTFSSecurity/NTFSSecurity.types.ps1xml @@ -0,0 +1,155 @@ + + + + + System.IO.FileInfo + + + Owner + + [Security2.IdentityReference2]$this.GetAccessControl().GetOwner([System.Security.Principal.SecurityIdentifier]) + + + + IsInheritanceBlocked + + $this.GetAccessControl([System.Security.AccessControl.AccessControlSections]::Access).AreAccessRulesProtected + + + + LengthOnDisk + + $driveInfo = New-Object NTFS.DriveInfoExt($this.PSDrive.Name + ":") + [Math]::Ceiling($this.Length / ($driveInfo.BytesPerSector * $driveInfo.SectorsPerCluster)) * ($driveInfo.BytesPerSector * $driveInfo.SectorsPerCluster) + + + + Size + LengthOnDisk + + + EnableInheritance + + + + DisableInheritance + + + + GetHash + + + + + + System.IO.DirectoryInfo + + + Owner + + [Security2.IdentityReference2]$this.GetAccessControl().GetOwner([System.Security.Principal.SecurityIdentifier]) + + + + IsInheritanceBlocked + + $this.GetAccessControl([System.Security.AccessControl.AccessControlSections]::Access).AreAccessRulesProtected + + + + EnableInheritance + + + + DisableInheritance + + + + + + + Security2.FileSystemAccessRule2 + + + AccountType + + if (-not [System.Security.Principal.WindowsIdentity]::GetCurrent().Name.ToLower().Contains([System.Environment]::MachineName.ToLower())) + { + try + { + ([ADSI]"LDAP://<SID=$($this.Account.Sid)>").ObjectClass[-1] + } + catch + { + [string]::Empty + } + } + + + + + \ No newline at end of file diff --git a/NTFSSecurity/OtherCmdlets.cs b/NTFSSecurity/OtherCmdlets.cs new file mode 100644 index 0000000..83edb5d --- /dev/null +++ b/NTFSSecurity/OtherCmdlets.cs @@ -0,0 +1,138 @@ +using System.Management.Automation; +using Security2; +using System.IO; +using System.Linq; +using System; +using System.Security.AccessControl; + +namespace NTFSSecurity +{ + #region Enable-Privileges + [Cmdlet(VerbsLifecycle.Enable, "Privileges")] + [OutputType(typeof(ProcessPrivileges.PrivilegeAndAttributes))] + public class EnablePrivileges : BaseCmdletWithPrivControl + { + private bool enablePrivileges = false; + private SwitchParameter passThru; + public string[] Path { get; set; } + + [Parameter] + public SwitchParameter PassThru + { + get { return passThru; } + set { passThru = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + } + + protected override void ProcessRecord() + { + var privateData = (System.Collections.Hashtable)this.MyInvocation.MyCommand.Module.PrivateData; + var psCallStack = (CallStackFrame)this.InvokeCommand.InvokeScript("Get-PSCallStack")[1].BaseObject; + + try + { + enablePrivileges = (bool)privateData["EnablePrivileges"]; + } + catch (Exception ex) + { + throw new ParseException("Could not parse the module's PrivateData field in the module's psd1 file. Please refer to the documentation for further details", ex); + } + + //if the command is called from NTFSSecurity.Init.ps1 and EnablePrivileges is set to true in the NTFSSecurity.psd1 or if the cmdlet is called from somewhere else + if ((psCallStack.InvocationInfo.MyCommand.Name == "NTFSSecurity.Init.ps1" && enablePrivileges == true)) + { + this.EnableFileSystemPrivileges(false); + } + else if (psCallStack.InvocationInfo.MyCommand.Name != "NTFSSecurity.Init.ps1") + { + this.EnableFileSystemPrivileges(false); + } + + if (passThru) + { + this.WriteObject(this.privControl.GetPrivileges()); + } + } + + protected override void EndProcessing() + { + //nothing as we want to keep the privileges enabled + } + } + #endregion Enable-Privileges + + #region Disable-Privileges + [Cmdlet(VerbsLifecycle.Disable, "Privileges")] + [OutputType(typeof(ProcessPrivileges.PrivilegeAndAttributes))] + public class DisablePrivileges : BaseCmdletWithPrivControl + { + private SwitchParameter passThru; + public string[] Path { get; set; } + + [Parameter] + public SwitchParameter PassThru + { + get { return passThru; } + set { passThru = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + } + + protected override void ProcessRecord() + { + if (this.privControl.GetPrivileges() + .Where(p => p.PrivilegeState == ProcessPrivileges.PrivilegeState.Enabled) + .Where(p => ( + p.Privilege == ProcessPrivileges.Privilege.TakeOwnership) | + (p.Privilege == ProcessPrivileges.Privilege.Restore) | + (p.Privilege == ProcessPrivileges.Privilege.Backup)) + .Count() == 0) + { + this.WriteError(new ErrorRecord(new AdjustPriviledgeException("Privileges are not enabled"), "Disable Privilege Error", ErrorCategory.SecurityError, null)); + return; + } + + this.DisableFileSystemPrivileges(); + this.WriteVerbose("The privileges 'TakeOwnership', 'Restore' and 'Backup' are now enabled."); + + if (passThru) + { + this.WriteObject(this.privControl.GetPrivileges()); + } + } + + protected override void EndProcessing() + { + //nothing as priviliges should already been cleaned up + } + } + #endregion Enable-Privileges + + #region Get-Privileges + [Cmdlet(VerbsCommon.Get, "Privileges")] + [OutputType(typeof(ProcessPrivileges.PrivilegeAndAttributes))] + public class GetPrivileges : BaseCmdlet + { + public string[] Path { get; set; } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + } + + protected override void ProcessRecord() + { + var privControl = new PrivilegeControl(); + + this.WriteObject(privControl.GetPrivileges(), true); + } + } + #endregion Get-Privileges +} \ No newline at end of file diff --git a/NTFSSecurity/OwnerCmdlets/GetOwner.cs b/NTFSSecurity/OwnerCmdlets/GetOwner.cs new file mode 100644 index 0000000..b19e259 --- /dev/null +++ b/NTFSSecurity/OwnerCmdlets/GetOwner.cs @@ -0,0 +1,99 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Management.Automation; + +namespace NTFSSecurity.OwnerCmdlets +{ + [Cmdlet(VerbsCommon.Get, "NTFSOwner", DefaultParameterSetName = "Path")] + [OutputType(typeof(FileSystemOwner))] + public class GetOwner : BaseCmdletWithPrivControl + { + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SecurityDescriptor")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + } + + protected override void ProcessRecord() + { + if (ParameterSetName == "Path") + { + FileSystemInfo item = null; + + foreach (var path in paths) + { + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + WriteObject(FileSystemOwner.GetOwner(item)); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + WriteObject(FileSystemOwner.GetOwner(item)); + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "ReadSecurityError", ErrorCategory.WriteError, path)); + continue; + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadSecurityError", ErrorCategory.OpenError, path)); + continue; + } + } + } + else + { + foreach (var sd in securityDescriptors) + { + WriteObject(FileSystemOwner.GetOwner(sd)); + } + } + } + } +} diff --git a/NTFSSecurity/OwnerCmdlets/SetOwner.cs b/NTFSSecurity/OwnerCmdlets/SetOwner.cs new file mode 100644 index 0000000..360b6c5 --- /dev/null +++ b/NTFSSecurity/OwnerCmdlets/SetOwner.cs @@ -0,0 +1,108 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Set, "NTFSOwner", DefaultParameterSetName = "Path")] + [OutputType(typeof(FileSystemOwner))] + public class SetOwner : BaseCmdletWithPrivControl + { + private SwitchParameter passThru; + private IdentityReference2 account; + + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SecurityDescriptor")] + [ValidateNotNullOrEmpty] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + [Parameter(Mandatory = true, Position = 2, ValueFromPipelineByPropertyName = true)] + public IdentityReference2 Account + { + get { return account; } + set { account = value; } + } + + [Parameter] + public SwitchParameter PassThru + { + get { return passThru; } + set { passThru = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + } + + protected override void ProcessRecord() + { + if (ParameterSetName == "Path") + { + foreach (var path in paths) + { + FileSystemInfo item = null; + + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + FileSystemOwner.SetOwner(item, account); + WriteDebug("Owner set on item {0}", item.FullName); + + if (passThru) + { + WriteObject(FileSystemOwner.GetOwner(item)); + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "SetOwnerError", ErrorCategory.WriteError, path)); + continue; + } + } + } + else + { + foreach (var sd in securityDescriptors) + { + FileSystemOwner.SetOwner(sd, account); + + if (passThru) + { + WriteObject(FileSystemOwner.GetOwner(sd)); + } + } + } + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/PathCmdlets/TestPath2.cs b/NTFSSecurity/PathCmdlets/TestPath2.cs new file mode 100644 index 0000000..220f7da --- /dev/null +++ b/NTFSSecurity/PathCmdlets/TestPath2.cs @@ -0,0 +1,85 @@ +using Alphaleonis.Win32.Filesystem; +using System.Collections.Generic; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsDiagnostic.Test, "Path2")] + [OutputType(typeof(FileInfo), typeof(DirectoryInfo))] + public class TestPath2 : BaseCmdlet + { + private TestPathType pathType = TestPathType.Any; + + [Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + [Parameter(ValueFromPipelineByPropertyName = true)] + public TestPathType PathType + { + get { return pathType; } + set { pathType = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + + if (paths.Count == 0) + { + paths = new List() { GetVariableValue("PWD").ToString() }; + } + } + + protected override void ProcessRecord() + { + foreach (var path in paths) + { + try + { + FileSystemInfo item; + TryGetFileSystemInfo2(path, out item); + + if (item == null) + WriteObject(false); + else + { + if (PathType == TestPathType.Any) + WriteObject(true); + else if (PathType == TestPathType.Container & item is DirectoryInfo) + WriteObject(true); + else if (PathType == TestPathType.Leaf & item is FileInfo) + WriteObject(true); + else + WriteObject(false); + } + } + catch (System.IO.FileNotFoundException ex) + { + WriteError(new ErrorRecord(ex, "PathNotFound", ErrorCategory.ObjectNotFound, path)); + } + } + } + + protected override void EndProcessing() + { + base.EndProcessing(); + } + } + + public enum TestPathType + { + Any, + Container, + Leaf + } +} \ No newline at end of file diff --git a/NTFSSecurity/Properties/AssemblyInfo.cs b/NTFSSecurity/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..104c43d --- /dev/null +++ b/NTFSSecurity/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("NTFSSecurity")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("NTFSSecurity")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("8f2c77c5-b143-4194-9e6f-840dfe19e5c4")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("4.2.1.0")] +[assembly: AssemblyFileVersion("4.2.1.0")] diff --git a/NTFSSecurity/Properties/Resources.Designer.cs b/NTFSSecurity/Properties/Resources.Designer.cs new file mode 100644 index 0000000..b2c9fb2 --- /dev/null +++ b/NTFSSecurity/Properties/Resources.Designer.cs @@ -0,0 +1,82 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18033 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace NTFSSecurity.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NTFSSecurity.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to . + /// + public static string ContainerIcon { + get { + return ResourceManager.GetString("ContainerIcon", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap IconContainer { + get { + object obj = ResourceManager.GetObject("IconContainer", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/NTFSSecurity/Properties/Resources.resx b/NTFSSecurity/Properties/Resources.resx new file mode 100644 index 0000000..75e4105 --- /dev/null +++ b/NTFSSecurity/Properties/Resources.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + + + ..\Resources\IconContainer.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/NTFSSecurity/Resources/IconContainer.bmp b/NTFSSecurity/Resources/IconContainer.bmp new file mode 100644 index 0000000..55516c7 Binary files /dev/null and b/NTFSSecurity/Resources/IconContainer.bmp differ diff --git a/NTFSSecurity/Resources/User.jpg b/NTFSSecurity/Resources/User.jpg new file mode 100644 index 0000000..3007e5b Binary files /dev/null and b/NTFSSecurity/Resources/User.jpg differ diff --git a/NTFSSecurity/Resources/container.jpg b/NTFSSecurity/Resources/container.jpg new file mode 100644 index 0000000..5af2b00 Binary files /dev/null and b/NTFSSecurity/Resources/container.jpg differ diff --git a/NTFSSecurity/SecurityDescriptorCmdlets/GetSecurityDescriptor.cs b/NTFSSecurity/SecurityDescriptorCmdlets/GetSecurityDescriptor.cs new file mode 100644 index 0000000..0b9dc93 --- /dev/null +++ b/NTFSSecurity/SecurityDescriptorCmdlets/GetSecurityDescriptor.cs @@ -0,0 +1,81 @@ +using Alphaleonis.Win32.Filesystem; +using Security2; +using System; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Get, "NTFSSecurityDescriptor")] + [OutputType(typeof(FileSystemSecurity2))] + public class GetSecurityDescriptor : BaseCmdletWithPrivControl + { + [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + [Alias("FullName")] + public string[] Path + { + get { return paths.ToArray(); } + set + { + paths.Clear(); + paths.AddRange(value); + } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + + if (paths.Count == 0) + { + paths.Add(GetVariableValue("PWD").ToString()); + } + } + + protected override void ProcessRecord() + { + FileSystemInfo item = null; + + foreach (var path in paths) + { + try + { + item = GetFileSystemInfo2(path); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path)); + continue; + } + + try + { + WriteObject(new FileSystemSecurity2(item)); + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + WriteObject(new FileSystemSecurity2(item)); + + FileSystemOwner.SetOwner(item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "ReadSecurityError", ErrorCategory.WriteError, path)); + continue; + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadSecurityError", ErrorCategory.OpenError, path)); + } + } + } + } +} diff --git a/NTFSSecurity/SecurityDescriptorCmdlets/SetSecurityDescriptor.cs b/NTFSSecurity/SecurityDescriptorCmdlets/SetSecurityDescriptor.cs new file mode 100644 index 0000000..8d14e60 --- /dev/null +++ b/NTFSSecurity/SecurityDescriptorCmdlets/SetSecurityDescriptor.cs @@ -0,0 +1,75 @@ +using Security2; +using System; +using System.Management.Automation; + +namespace NTFSSecurity +{ + [Cmdlet(VerbsCommon.Set, "NTFSSecurityDescriptor")] + [OutputType(typeof(FileSystemSecurity2))] + public class SetSecurityDescriptor : BaseCmdletWithPrivControl + { + private SwitchParameter passThru; + + [Parameter(Mandatory = true, Position = 2, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + public FileSystemSecurity2[] SecurityDescriptor + { + get { return securityDescriptors.ToArray(); } + set + { + securityDescriptors.Clear(); + securityDescriptors.AddRange(value); + } + } + + [Parameter()] + public SwitchParameter PassThru + { + get { return passThru; } + set { passThru = value; } + } + + protected override void BeginProcessing() + { + base.BeginProcessing(); + } + + protected override void ProcessRecord() + { + foreach (var sd in securityDescriptors) + { + try + { + sd.Write(); + + if (passThru) + { + WriteObject(new FileSystemSecurity2(sd.Item)); + } + } + catch (UnauthorizedAccessException) + { + try + { + var ownerInfo = FileSystemOwner.GetOwner(sd.Item); + var previousOwner = ownerInfo.Owner; + + FileSystemOwner.SetOwner(sd.Item, System.Security.Principal.WindowsIdentity.GetCurrent().User); + + sd.Write(); + + FileSystemOwner.SetOwner(sd.Item, previousOwner); + } + catch (Exception ex2) + { + WriteError(new ErrorRecord(ex2, "WriteSdError", ErrorCategory.WriteError, sd.Item)); + continue; + } + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "WriteSdError", ErrorCategory.WriteError, sd.Item)); + } + } + } + } +} diff --git a/NTFSSecurity/ShowSimpleAccess.Designer.cs b/NTFSSecurity/ShowSimpleAccess.Designer.cs new file mode 100644 index 0000000..b189990 --- /dev/null +++ b/NTFSSecurity/ShowSimpleAccess.Designer.cs @@ -0,0 +1,309 @@ +namespace NTFSSecurity +{ + partial class ShowSimpleAccessForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ShowSimpleAccessForm)); + this.trvDirectories = new System.Windows.Forms.TreeView(); + this.imlIcons = new System.Windows.Forms.ImageList(this.components); + this.lstPermissions = new System.Windows.Forms.ListView(); + this.chdIdentity = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chdRights = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chdAccessControlType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chkRemoveFoldersWithoutAccess = new System.Windows.Forms.CheckBox(); + this.grpFilter = new System.Windows.Forms.GroupBox(); + this.grpSearchForIdentity = new System.Windows.Forms.GroupBox(); + this.btnSearchForIdentityNext = new System.Windows.Forms.Button(); + this.btnSearchForIdentityPrev = new System.Windows.Forms.Button(); + this.txtSearchForIdentity = new System.Windows.Forms.TextBox(); + this.btnSearchForIdentity = new System.Windows.Forms.Button(); + this.grpSearchForFolder = new System.Windows.Forms.GroupBox(); + this.btnSearchForFolderPrev = new System.Windows.Forms.Button(); + this.btnSearchForFolderNext = new System.Windows.Forms.Button(); + this.btnSearchForFolder = new System.Windows.Forms.Button(); + this.txtSearchForFolder = new System.Windows.Forms.TextBox(); + this.labDirectoryTreeView = new System.Windows.Forms.Label(); + this.labAccessView = new System.Windows.Forms.Label(); + this.ttSearchForFolder = new System.Windows.Forms.ToolTip(this.components); + this.grpFilter.SuspendLayout(); + this.grpSearchForIdentity.SuspendLayout(); + this.grpSearchForFolder.SuspendLayout(); + this.SuspendLayout(); + // + // trvDirectories + // + this.trvDirectories.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.trvDirectories.ImageIndex = 0; + this.trvDirectories.ImageList = this.imlIcons; + this.trvDirectories.Location = new System.Drawing.Point(12, 29); + this.trvDirectories.Name = "trvDirectories"; + this.trvDirectories.SelectedImageIndex = 0; + this.trvDirectories.Size = new System.Drawing.Size(320, 574); + this.trvDirectories.TabIndex = 0; + this.trvDirectories.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.trvDirectories_AfterSelect); + // + // imlIcons + // + this.imlIcons.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imlIcons.ImageStream"))); + this.imlIcons.TransparentColor = System.Drawing.Color.Transparent; + this.imlIcons.Images.SetKeyName(0, "container.jpg"); + // + // lstPermissions + // + this.lstPermissions.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lstPermissions.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.chdIdentity, + this.chdRights, + this.chdAccessControlType}); + this.lstPermissions.Location = new System.Drawing.Point(338, 29); + this.lstPermissions.Name = "lstPermissions"; + this.lstPermissions.Size = new System.Drawing.Size(480, 342); + this.lstPermissions.SmallImageList = this.imlIcons; + this.lstPermissions.TabIndex = 1; + this.lstPermissions.UseCompatibleStateImageBehavior = false; + this.lstPermissions.View = System.Windows.Forms.View.Details; + // + // chdIdentity + // + this.chdIdentity.Text = "Identity"; + // + // chdRights + // + this.chdRights.Text = "Rights"; + // + // chdAccessControlType + // + this.chdAccessControlType.Text = "AccessControlType"; + // + // chkRemoveFoldersWithoutAccess + // + this.chkRemoveFoldersWithoutAccess.AutoSize = true; + this.chkRemoveFoldersWithoutAccess.Location = new System.Drawing.Point(6, 19); + this.chkRemoveFoldersWithoutAccess.Name = "chkRemoveFoldersWithoutAccess"; + this.chkRemoveFoldersWithoutAccess.Size = new System.Drawing.Size(347, 17); + this.chkRemoveFoldersWithoutAccess.TabIndex = 2; + this.chkRemoveFoldersWithoutAccess.Text = "Remove Folders that do not have different access than their parents"; + this.chkRemoveFoldersWithoutAccess.UseVisualStyleBackColor = true; + this.chkRemoveFoldersWithoutAccess.CheckedChanged += new System.EventHandler(this.chkRemoveFoldersWithoutAccess_CheckedChanged); + // + // grpFilter + // + this.grpFilter.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.grpFilter.Controls.Add(this.grpSearchForIdentity); + this.grpFilter.Controls.Add(this.grpSearchForFolder); + this.grpFilter.Controls.Add(this.chkRemoveFoldersWithoutAccess); + this.grpFilter.Location = new System.Drawing.Point(338, 377); + this.grpFilter.Name = "grpFilter"; + this.grpFilter.Size = new System.Drawing.Size(480, 226); + this.grpFilter.TabIndex = 3; + this.grpFilter.TabStop = false; + this.grpFilter.Text = "Filter"; + // + // grpSearchForIdentity + // + this.grpSearchForIdentity.Controls.Add(this.btnSearchForIdentityNext); + this.grpSearchForIdentity.Controls.Add(this.btnSearchForIdentityPrev); + this.grpSearchForIdentity.Controls.Add(this.txtSearchForIdentity); + this.grpSearchForIdentity.Controls.Add(this.btnSearchForIdentity); + this.grpSearchForIdentity.Location = new System.Drawing.Point(9, 125); + this.grpSearchForIdentity.Name = "grpSearchForIdentity"; + this.grpSearchForIdentity.Size = new System.Drawing.Size(384, 95); + this.grpSearchForIdentity.TabIndex = 4; + this.grpSearchForIdentity.TabStop = false; + this.grpSearchForIdentity.Text = "Search for Identity"; + // + // btnSearchForIdentityNext + // + this.btnSearchForIdentityNext.Enabled = false; + this.btnSearchForIdentityNext.Location = new System.Drawing.Point(222, 45); + this.btnSearchForIdentityNext.Name = "btnSearchForIdentityNext"; + this.btnSearchForIdentityNext.Size = new System.Drawing.Size(75, 23); + this.btnSearchForIdentityNext.TabIndex = 7; + this.btnSearchForIdentityNext.Text = "Prev"; + this.btnSearchForIdentityNext.UseVisualStyleBackColor = true; + this.btnSearchForIdentityNext.Click += new System.EventHandler(this.btnSearchForIdentityNext_Click); + // + // btnSearchForIdentityPrev + // + this.btnSearchForIdentityPrev.Enabled = false; + this.btnSearchForIdentityPrev.Location = new System.Drawing.Point(303, 45); + this.btnSearchForIdentityPrev.Name = "btnSearchForIdentityPrev"; + this.btnSearchForIdentityPrev.Size = new System.Drawing.Size(75, 23); + this.btnSearchForIdentityPrev.TabIndex = 6; + this.btnSearchForIdentityPrev.Text = "Next"; + this.btnSearchForIdentityPrev.UseVisualStyleBackColor = true; + this.btnSearchForIdentityPrev.Click += new System.EventHandler(this.btnSearchForIdentityPrev_Click); + // + // txtSearchForIdentity + // + this.txtSearchForIdentity.Location = new System.Drawing.Point(3, 19); + this.txtSearchForIdentity.Name = "txtSearchForIdentity"; + this.txtSearchForIdentity.Size = new System.Drawing.Size(341, 20); + this.txtSearchForIdentity.TabIndex = 4; + // + // btnSearchForIdentity + // + this.btnSearchForIdentity.Location = new System.Drawing.Point(350, 17); + this.btnSearchForIdentity.Name = "btnSearchForIdentity"; + this.btnSearchForIdentity.Size = new System.Drawing.Size(28, 23); + this.btnSearchForIdentity.TabIndex = 5; + this.btnSearchForIdentity.Text = "Go"; + this.btnSearchForIdentity.UseVisualStyleBackColor = true; + this.btnSearchForIdentity.Click += new System.EventHandler(this.btnSearchForIdentity_Click); + // + // grpSearchForFolder + // + this.grpSearchForFolder.Controls.Add(this.btnSearchForFolderPrev); + this.grpSearchForFolder.Controls.Add(this.btnSearchForFolderNext); + this.grpSearchForFolder.Controls.Add(this.btnSearchForFolder); + this.grpSearchForFolder.Controls.Add(this.txtSearchForFolder); + this.grpSearchForFolder.Location = new System.Drawing.Point(6, 42); + this.grpSearchForFolder.Name = "grpSearchForFolder"; + this.grpSearchForFolder.Size = new System.Drawing.Size(387, 77); + this.grpSearchForFolder.TabIndex = 3; + this.grpSearchForFolder.TabStop = false; + this.grpSearchForFolder.Text = "Search for Folder"; + this.ttSearchForFolder.SetToolTip(this.grpSearchForFolder, "\"Search for folder\" lets you search in the tree view for the"); + // + // btnSearchForFolderPrev + // + this.btnSearchForFolderPrev.Enabled = false; + this.btnSearchForFolderPrev.Location = new System.Drawing.Point(225, 45); + this.btnSearchForFolderPrev.Name = "btnSearchForFolderPrev"; + this.btnSearchForFolderPrev.Size = new System.Drawing.Size(75, 23); + this.btnSearchForFolderPrev.TabIndex = 3; + this.btnSearchForFolderPrev.Text = "Prev"; + this.btnSearchForFolderPrev.UseVisualStyleBackColor = true; + this.btnSearchForFolderPrev.Click += new System.EventHandler(this.btnSearchForFolderPrev_Click); + // + // btnSearchForFolderNext + // + this.btnSearchForFolderNext.Enabled = false; + this.btnSearchForFolderNext.Location = new System.Drawing.Point(306, 45); + this.btnSearchForFolderNext.Name = "btnSearchForFolderNext"; + this.btnSearchForFolderNext.Size = new System.Drawing.Size(75, 23); + this.btnSearchForFolderNext.TabIndex = 2; + this.btnSearchForFolderNext.Text = "Next"; + this.btnSearchForFolderNext.UseVisualStyleBackColor = true; + this.btnSearchForFolderNext.Click += new System.EventHandler(this.btnSearchForFolderNext_Click); + // + // btnSearchForFolder + // + this.btnSearchForFolder.Location = new System.Drawing.Point(353, 17); + this.btnSearchForFolder.Name = "btnSearchForFolder"; + this.btnSearchForFolder.Size = new System.Drawing.Size(28, 23); + this.btnSearchForFolder.TabIndex = 1; + this.btnSearchForFolder.Text = "Go"; + this.btnSearchForFolder.UseVisualStyleBackColor = true; + this.btnSearchForFolder.Click += new System.EventHandler(this.btnSearchForFolder_Click); + // + // txtSearchForFolder + // + this.txtSearchForFolder.Location = new System.Drawing.Point(6, 19); + this.txtSearchForFolder.Name = "txtSearchForFolder"; + this.txtSearchForFolder.Size = new System.Drawing.Size(341, 20); + this.txtSearchForFolder.TabIndex = 0; + this.ttSearchForFolder.SetToolTip(this.txtSearchForFolder, "\"Search for folder\" lets you search in the tree view for the"); + // + // labDirectoryTreeView + // + this.labDirectoryTreeView.AutoSize = true; + this.labDirectoryTreeView.Location = new System.Drawing.Point(13, 13); + this.labDirectoryTreeView.Name = "labDirectoryTreeView"; + this.labDirectoryTreeView.Size = new System.Drawing.Size(57, 13); + this.labDirectoryTreeView.TabIndex = 4; + this.labDirectoryTreeView.Text = "Directories"; + // + // labAccessView + // + this.labAccessView.AutoSize = true; + this.labAccessView.Location = new System.Drawing.Point(344, 12); + this.labAccessView.Name = "labAccessView"; + this.labAccessView.Size = new System.Drawing.Size(202, 13); + this.labAccessView.TabIndex = 5; + this.labAccessView.Text = "Permissions given on the seletcted object"; + // + // ttSearchForFolder + // + this.ttSearchForFolder.IsBalloon = true; + this.ttSearchForFolder.ToolTipIcon = System.Windows.Forms.ToolTipIcon.Info; + // + // ShowSimpleAccessForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(830, 615); + this.Controls.Add(this.labAccessView); + this.Controls.Add(this.labDirectoryTreeView); + this.Controls.Add(this.grpFilter); + this.Controls.Add(this.lstPermissions); + this.Controls.Add(this.trvDirectories); + this.Name = "ShowSimpleAccessForm"; + this.Text = "ShowAccess"; + this.grpFilter.ResumeLayout(false); + this.grpFilter.PerformLayout(); + this.grpSearchForIdentity.ResumeLayout(false); + this.grpSearchForIdentity.PerformLayout(); + this.grpSearchForFolder.ResumeLayout(false); + this.grpSearchForFolder.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TreeView trvDirectories; + private System.Windows.Forms.ListView lstPermissions; + private System.Windows.Forms.ColumnHeader chdIdentity; + private System.Windows.Forms.ColumnHeader chdRights; + private System.Windows.Forms.ColumnHeader chdAccessControlType; + private System.Windows.Forms.ImageList imlIcons; + private System.Windows.Forms.CheckBox chkRemoveFoldersWithoutAccess; + private System.Windows.Forms.GroupBox grpFilter; + private System.Windows.Forms.Label labDirectoryTreeView; + private System.Windows.Forms.Label labAccessView; + private System.Windows.Forms.GroupBox grpSearchForFolder; + private System.Windows.Forms.Button btnSearchForFolder; + private System.Windows.Forms.TextBox txtSearchForFolder; + private System.Windows.Forms.Button btnSearchForFolderNext; + private System.Windows.Forms.Button btnSearchForFolderPrev; + private System.Windows.Forms.GroupBox grpSearchForIdentity; + private System.Windows.Forms.Button btnSearchForIdentityNext; + private System.Windows.Forms.Button btnSearchForIdentityPrev; + private System.Windows.Forms.TextBox txtSearchForIdentity; + private System.Windows.Forms.Button btnSearchForIdentity; + private System.Windows.Forms.ToolTip ttSearchForFolder; + + } +} \ No newline at end of file diff --git a/NTFSSecurity/ShowSimpleAccess.cs b/NTFSSecurity/ShowSimpleAccess.cs new file mode 100644 index 0000000..5dcf43d --- /dev/null +++ b/NTFSSecurity/ShowSimpleAccess.cs @@ -0,0 +1,271 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Alphaleonis.Win32.Filesystem; +using Security2; + +namespace NTFSSecurity +{ + public partial class ShowSimpleAccessForm : Form + { + private IEnumerable directoryList; + private IQueryable aceList; + private IEnumerable searchResultByFolder; + private int searchResultByFolderIndex; + + public IEnumerable DirectoryList + { + get { return directoryList; } + } + + public IEnumerable AceList + { + get { return aceList; } + } + + public ShowSimpleAccessForm() + { + InitializeComponent(); + } + + public void BuildDirectoryTreeNodes() + { + string previousPath = string.Empty; + DirectoryTreeNode previousNode; + DirectoryTreeNode rootNode; + + var rootDirectory = directoryList.First(); + + rootNode = new DirectoryTreeNode(rootDirectory.FullName, rootDirectory.Name, aceList.Where(ace => ace.FullName == rootDirectory.Name)); + previousNode = rootNode; + trvDirectories.Nodes.Add(rootNode); + + foreach (var directory in directoryList.Skip(1)) + { + if (previousNode.Name == directory.GetParent().FullName) + { + var node = new DirectoryTreeNode(directory.FullName, directory.Name, aceList.Where(ace => ace.FullName == directory.FullName)); + previousNode.Nodes.Add(node); + } + else + { + previousNode = (DirectoryTreeNode)trvDirectories.Nodes.Find(directory.GetParent().FullName, true).FirstOrDefault(); + if (previousNode != null) + { + var node = new DirectoryTreeNode(directory.FullName, directory.Name, aceList.Where(ace => ace.FullName == directory.FullName)); + previousNode.Nodes.Add(node); + } + else + { + var node = new DirectoryTreeNode(directory.FullName, directory.Name, aceList.Where(ace => ace.FullName == directory.FullName)); + previousNode.Nodes.Add(node); + } + } + } + } + + public void BuildDirectoryTreeNodes(IEnumerable directoryList, IQueryable aceList) + { + this.directoryList = directoryList; + this.aceList = aceList; + + this.BuildDirectoryTreeNodes(); + } + + private void trvDirectories_AfterSelect(object sender, TreeViewEventArgs e) + { + lstPermissions.Items.Clear(); + + foreach (var ace in aceList.Where(ace => ace.FullName == e.Node.Name)) + { + ListViewItem listItem = new ListViewItem(); + listItem.Name = e.Node.Name; + listItem.Text = ace.Identity.AccountName; + listItem.SubItems.AddRange(new string[] { ace.AccessRights.ToString(), ace.AccessControlType.ToString(), e.Node.FullPath }); + listItem.ImageIndex = 1; + + lstPermissions.Items.Add(listItem); + } + + if (lstPermissions.Items.Count > 0) + { + foreach (ColumnHeader column in lstPermissions.Columns) + { + column.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent); + } + } + } + + private void chkRemoveFoldersWithoutAccess_CheckedChanged(object sender, EventArgs e) + { + if (chkRemoveFoldersWithoutAccess.Checked) + { + RemoveFoldersWithoutAccess((DirectoryTreeNode)trvDirectories.Nodes[0]); + } + else + { + trvDirectories.Nodes.Clear(); + BuildDirectoryTreeNodes(); + } + } + + public void RemoveFoldersWithoutAccess(DirectoryTreeNode node) + { + for (int i = 0; i < node.Nodes.Count; i++) + { + if (node.Nodes[i].GetNodeCount(false) > 0) + RemoveFoldersWithoutAccess((DirectoryTreeNode)node.Nodes[i]); + + if (node.Nodes[i].Nodes.Count == 0 & ((DirectoryTreeNode)node.Nodes[i]).Acl.Count() == 0) + { + node.Nodes.Remove(node.Nodes[i]); + i--; + } + } + } + + private void btnSearchForFolder_Click(object sender, EventArgs e) + { + searchResultByFolder = null; + searchResultByFolderIndex = 0; + trvDirectories.HideSelection = false; + + searchResultByFolder = FindNodeByFolder((DirectoryTreeNode)trvDirectories.Nodes[0], txtSearchForFolder.Text); + if (searchResultByFolder.Count() > 0) + { + btnSearchForFolderNext.Enabled = true; + btnSearchForFolderPrev.Enabled = true; + + trvDirectories.SelectedNode = searchResultByFolder.First(); + searchResultByFolderIndex = 0; + } + else + { + btnSearchForFolderNext.Enabled = false; + btnSearchForFolderPrev.Enabled = false; + } + } + + private IEnumerable FindNodeByFolder(DirectoryTreeNode node, string search) + { + if (node.Text.ToLower().Contains(search.ToLower())) + { + yield return node; + } + + foreach (DirectoryTreeNode childNode in node.Nodes) + { + foreach (DirectoryTreeNode match in this.FindNodeByFolder(childNode, search)) + { + yield return match; + } + } + } + + private IEnumerable FindNodeByIdentity(DirectoryTreeNode node, string search) + { + if (node.Acl.Where(ace => ace.Identity.AccountName.ToLower().Contains(search.ToLower())).Count() > 0) + { + yield return node; + } + + foreach (DirectoryTreeNode childNode in node.Nodes) + { + foreach (DirectoryTreeNode match in this.FindNodeByIdentity(childNode, search)) + { + yield return match; + } + } + } + + private void btnSearchForFolderNext_Click(object sender, EventArgs e) + { + if (searchResultByFolder.Count() > searchResultByFolderIndex + 1) + { + searchResultByFolderIndex++; + trvDirectories.SelectedNode = searchResultByFolder.ElementAt(searchResultByFolderIndex); + } + } + + private void btnSearchForFolderPrev_Click(object sender, EventArgs e) + { + if (searchResultByFolderIndex - 1 > -1) + { + searchResultByFolderIndex--; + trvDirectories.SelectedNode = searchResultByFolder.ElementAt(searchResultByFolderIndex); + } + } + + private void btnSearchForIdentity_Click(object sender, EventArgs e) + { + trvDirectories.HideSelection = false; + searchResultByFolder = null; + searchResultByFolderIndex = 0; + + searchResultByFolder = FindNodeByIdentity((DirectoryTreeNode)trvDirectories.Nodes[0], txtSearchForIdentity.Text); + if (searchResultByFolder.Count() > 0) + { + btnSearchForIdentityNext.Enabled = true; + btnSearchForIdentityPrev.Enabled = true; + + trvDirectories.SelectedNode = searchResultByFolder.First(); + searchResultByFolderIndex = 0; + } + else + { + btnSearchForIdentityNext.Enabled = false; + btnSearchForIdentityPrev.Enabled = false; + } + } + + private void btnSearchForIdentityPrev_Click(object sender, EventArgs e) + { + if (searchResultByFolder.Count() > searchResultByFolderIndex + 1) + { + searchResultByFolderIndex++; + trvDirectories.SelectedNode = searchResultByFolder.ElementAt(searchResultByFolderIndex); + } + } + + private void btnSearchForIdentityNext_Click(object sender, EventArgs e) + { + if (searchResultByFolderIndex - 1 > -1) + { + searchResultByFolderIndex--; + trvDirectories.SelectedNode = searchResultByFolder.ElementAt(searchResultByFolderIndex); + } + } + } + + public class DirectoryTreeNode : TreeNode + { + private IList acl; + + public IList Acl + { + get { return acl; } + } + + public DirectoryTreeNode(string key, string text) + : base(text) + { + this.Name = key; + } + + public DirectoryTreeNode(string key, string text, IQueryable acl) + : this(key, text) + { + this.acl = acl.ToList(); + + if (acl.Count() == 0) + { + this.ForeColor = Color.Gray; + } + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/ShowSimpleAccess.resx b/NTFSSecurity/ShowSimpleAccess.resx new file mode 100644 index 0000000..d30058d --- /dev/null +++ b/NTFSSecurity/ShowSimpleAccess.resx @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAs + CAAAAk1TRnQBSQFMAwEBAAGIAQABiAEAARABAAEQAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMA + AUADAAEQAwABAQEAAQgGAAEEGAABgAIAAYADAAKAAQABgAMAAYABAAGAAQACgAIAA8ABAAHAAdwBwAEA + AfABygGmAQABMwUAATMBAAEzAQABMwEAAjMCAAMWAQADHAEAAyIBAAMpAQADVQEAA00BAANCAQADOQEA + AYABfAH/AQACUAH/AQABkwEAAdYBAAH/AewBzAEAAcYB1gHvAQAB1gLnAQABkAGpAa0CAAH/ATMDAAFm + AwABmQMAAcwCAAEzAwACMwIAATMBZgIAATMBmQIAATMBzAIAATMB/wIAAWYDAAFmATMCAAJmAgABZgGZ + AgABZgHMAgABZgH/AgABmQMAAZkBMwIAAZkBZgIAApkCAAGZAcwCAAGZAf8CAAHMAwABzAEzAgABzAFm + AgABzAGZAgACzAIAAcwB/wIAAf8BZgIAAf8BmQIAAf8BzAEAATMB/wIAAf8BAAEzAQABMwEAAWYBAAEz + AQABmQEAATMBAAHMAQABMwEAAf8BAAH/ATMCAAMzAQACMwFmAQACMwGZAQACMwHMAQACMwH/AQABMwFm + AgABMwFmATMBAAEzAmYBAAEzAWYBmQEAATMBZgHMAQABMwFmAf8BAAEzAZkCAAEzAZkBMwEAATMBmQFm + AQABMwKZAQABMwGZAcwBAAEzAZkB/wEAATMBzAIAATMBzAEzAQABMwHMAWYBAAEzAcwBmQEAATMCzAEA + ATMBzAH/AQABMwH/ATMBAAEzAf8BZgEAATMB/wGZAQABMwH/AcwBAAEzAv8BAAFmAwABZgEAATMBAAFm + AQABZgEAAWYBAAGZAQABZgEAAcwBAAFmAQAB/wEAAWYBMwIAAWYCMwEAAWYBMwFmAQABZgEzAZkBAAFm + ATMBzAEAAWYBMwH/AQACZgIAAmYBMwEAA2YBAAJmAZkBAAJmAcwBAAFmAZkCAAFmAZkBMwEAAWYBmQFm + AQABZgKZAQABZgGZAcwBAAFmAZkB/wEAAWYBzAIAAWYBzAEzAQABZgHMAZkBAAFmAswBAAFmAcwB/wEA + AWYB/wIAAWYB/wEzAQABZgH/AZkBAAFmAf8BzAEAAcwBAAH/AQAB/wEAAcwBAAKZAgABmQEzAZkBAAGZ + AQABmQEAAZkBAAHMAQABmQMAAZkCMwEAAZkBAAFmAQABmQEzAcwBAAGZAQAB/wEAAZkBZgIAAZkBZgEz + AQABmQEzAWYBAAGZAWYBmQEAAZkBZgHMAQABmQEzAf8BAAKZATMBAAKZAWYBAAOZAQACmQHMAQACmQH/ + AQABmQHMAgABmQHMATMBAAFmAcwBZgEAAZkBzAGZAQABmQLMAQABmQHMAf8BAAGZAf8CAAGZAf8BMwEA + AZkBzAFmAQABmQH/AZkBAAGZAf8BzAEAAZkC/wEAAcwDAAGZAQABMwEAAcwBAAFmAQABzAEAAZkBAAHM + AQABzAEAAZkBMwIAAcwCMwEAAcwBMwFmAQABzAEzAZkBAAHMATMBzAEAAcwBMwH/AQABzAFmAgABzAFm + ATMBAAGZAmYBAAHMAWYBmQEAAcwBZgHMAQABmQFmAf8BAAHMAZkCAAHMAZkBMwEAAcwBmQFmAQABzAKZ + AQABzAGZAcwBAAHMAZkB/wEAAswCAALMATMBAALMAWYBAALMAZkBAAPMAQACzAH/AQABzAH/AgABzAH/ + ATMBAAGZAf8BZgEAAcwB/wGZAQABzAH/AcwBAAHMAv8BAAHMAQABMwEAAf8BAAFmAQAB/wEAAZkBAAHM + ATMCAAH/AjMBAAH/ATMBZgEAAf8BMwGZAQAB/wEzAcwBAAH/ATMB/wEAAf8BZgIAAf8BZgEzAQABzAJm + AQAB/wFmAZkBAAH/AWYBzAEAAcwBZgH/AQAB/wGZAgAB/wGZATMBAAH/AZkBZgEAAf8CmQEAAf8BmQHM + AQAB/wGZAf8BAAH/AcwCAAH/AcwBMwEAAf8BzAFmAQAB/wHMAZkBAAH/AswBAAH/AcwB/wEAAv8BMwEA + AcwB/wFmAQAC/wGZAQAC/wHMAQACZgH/AQABZgH/AWYBAAFmAv8BAAH/AmYBAAH/AWYB/wEAAv8BZgEA + ASEBAAGlAQADXwEAA3cBAAOGAQADlgEAA8sBAAOyAQAD1wEAA90BAAPjAQAD6gEAA/EBAAP4AQAB8AH7 + Af8BAAGkAqABAAOAAwAB/wIAAf8DAAL/AQAB/wMAAf8BAAH/AQAC/wIAA/8BABD/MAAQ/zAAAf8B9AGS + BPcDkgL3AZIB9wHyAf8wAAH/Ae8LFAEPAQcB/zAAAf8B7AGZAnkBHAF5ARwBWAEcAXkBHAFzAUMBBwH/ + MAAB/wHtAfQEeQFeAZkBXgJ5ARwBQwEHAf8wAAH/Ae0BwwN5AV4BmQFeAZkBXgF5AVgBQwEHAf8wAAH/ + Ae0B9AJ5AV0BmQFeAbwBXgGZAV4B9wFDAQcB/zAAAf8B7QHDAXoCeQFeAZkBXgGZAV4BeQFYAUMBBwH/ + MAAB/wHtAfQEeQFeAZkBXgJ5ARwBQwEHAf8wAAH/Ae0BwwOgAeUBGgHlARoB5QEaAXkBQwEHAf8wAAH/ + Ae0BGwGgAcMBGgGgARsEBwH3AewB8QH/MAAB/wG8ARwEeQH3AvABvALwAfMC/zAAAv8BvAHtAnMB7QHw + CP8wAAP/BPQJ/zAAEP8wAAFCAU0BPgcAAT4DAAEoAwABQAMAARADAAEBAQABAQUAAYAXAAP/gQAL + + + + 114, 17 + + \ No newline at end of file diff --git a/NTFSSecurity/ShowSimpleEffectiveAccess.Designer.cs b/NTFSSecurity/ShowSimpleEffectiveAccess.Designer.cs new file mode 100644 index 0000000..05076e9 --- /dev/null +++ b/NTFSSecurity/ShowSimpleEffectiveAccess.Designer.cs @@ -0,0 +1,234 @@ +namespace NTFSSecurity +{ + partial class ShowSimpleEffectiveAccessForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ShowSimpleEffectiveAccessForm)); + this.trvDirectories = new System.Windows.Forms.TreeView(); + this.imlIcons = new System.Windows.Forms.ImageList(this.components); + this.lstPermissions = new System.Windows.Forms.ListView(); + this.chdIdentity = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chdRights = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chdAccessControlType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chkRemoveFoldersWithoutAccess = new System.Windows.Forms.CheckBox(); + this.grpFilter = new System.Windows.Forms.GroupBox(); + this.grpSearchForFolder = new System.Windows.Forms.GroupBox(); + this.btnSearchForFolderPrev = new System.Windows.Forms.Button(); + this.btnSearchForFolderNext = new System.Windows.Forms.Button(); + this.btnSearchForFolder = new System.Windows.Forms.Button(); + this.txtSearchForFolder = new System.Windows.Forms.TextBox(); + this.labDirectoryTreeView = new System.Windows.Forms.Label(); + this.labAccessView = new System.Windows.Forms.Label(); + this.grpFilter.SuspendLayout(); + this.grpSearchForFolder.SuspendLayout(); + this.SuspendLayout(); + // + // trvDirectories + // + this.trvDirectories.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.trvDirectories.ImageIndex = 0; + this.trvDirectories.ImageList = this.imlIcons; + this.trvDirectories.Location = new System.Drawing.Point(12, 29); + this.trvDirectories.Name = "trvDirectories"; + this.trvDirectories.SelectedImageIndex = 0; + this.trvDirectories.Size = new System.Drawing.Size(320, 353); + this.trvDirectories.TabIndex = 0; + this.trvDirectories.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.trvDirectories_AfterSelect); + // + // imlIcons + // + this.imlIcons.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imlIcons.ImageStream"))); + this.imlIcons.TransparentColor = System.Drawing.Color.Transparent; + this.imlIcons.Images.SetKeyName(0, "container.jpg"); + // + // lstPermissions + // + this.lstPermissions.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lstPermissions.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.chdIdentity, + this.chdRights, + this.chdAccessControlType}); + this.lstPermissions.Location = new System.Drawing.Point(338, 29); + this.lstPermissions.Name = "lstPermissions"; + this.lstPermissions.Size = new System.Drawing.Size(480, 226); + this.lstPermissions.SmallImageList = this.imlIcons; + this.lstPermissions.TabIndex = 1; + this.lstPermissions.UseCompatibleStateImageBehavior = false; + this.lstPermissions.View = System.Windows.Forms.View.Details; + // + // chdIdentity + // + this.chdIdentity.Text = "Identity"; + // + // chdRights + // + this.chdRights.Text = "Rights"; + // + // chdAccessControlType + // + this.chdAccessControlType.Text = "AccessControlType"; + // + // chkRemoveFoldersWithoutAccess + // + this.chkRemoveFoldersWithoutAccess.AutoSize = true; + this.chkRemoveFoldersWithoutAccess.Location = new System.Drawing.Point(6, 19); + this.chkRemoveFoldersWithoutAccess.Name = "chkRemoveFoldersWithoutAccess"; + this.chkRemoveFoldersWithoutAccess.Size = new System.Drawing.Size(347, 17); + this.chkRemoveFoldersWithoutAccess.TabIndex = 2; + this.chkRemoveFoldersWithoutAccess.Text = "Remove Folders that do not have different access than their parents"; + this.chkRemoveFoldersWithoutAccess.UseVisualStyleBackColor = true; + this.chkRemoveFoldersWithoutAccess.CheckedChanged += new System.EventHandler(this.chkRemoveFoldersWithoutAccess_CheckedChanged); + // + // grpFilter + // + this.grpFilter.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.grpFilter.Controls.Add(this.grpSearchForFolder); + this.grpFilter.Controls.Add(this.chkRemoveFoldersWithoutAccess); + this.grpFilter.Location = new System.Drawing.Point(338, 258); + this.grpFilter.Name = "grpFilter"; + this.grpFilter.Size = new System.Drawing.Size(480, 124); + this.grpFilter.TabIndex = 3; + this.grpFilter.TabStop = false; + this.grpFilter.Text = "Filter"; + // + // grpSearchForFolder + // + this.grpSearchForFolder.Controls.Add(this.btnSearchForFolderPrev); + this.grpSearchForFolder.Controls.Add(this.btnSearchForFolderNext); + this.grpSearchForFolder.Controls.Add(this.btnSearchForFolder); + this.grpSearchForFolder.Controls.Add(this.txtSearchForFolder); + this.grpSearchForFolder.Location = new System.Drawing.Point(6, 42); + this.grpSearchForFolder.Name = "grpSearchForFolder"; + this.grpSearchForFolder.Size = new System.Drawing.Size(421, 77); + this.grpSearchForFolder.TabIndex = 3; + this.grpSearchForFolder.TabStop = false; + this.grpSearchForFolder.Text = "Search for Folder"; + // + // btnSearchForFolderPrev + // + this.btnSearchForFolderPrev.Enabled = false; + this.btnSearchForFolderPrev.Location = new System.Drawing.Point(240, 45); + this.btnSearchForFolderPrev.Name = "btnSearchForFolderPrev"; + this.btnSearchForFolderPrev.Size = new System.Drawing.Size(75, 23); + this.btnSearchForFolderPrev.TabIndex = 3; + this.btnSearchForFolderPrev.Text = "Prev"; + this.btnSearchForFolderPrev.UseVisualStyleBackColor = true; + this.btnSearchForFolderPrev.Click += new System.EventHandler(this.btnSearchForFolderPrev_Click); + // + // btnSearchForFolderNext + // + this.btnSearchForFolderNext.Enabled = false; + this.btnSearchForFolderNext.Location = new System.Drawing.Point(321, 45); + this.btnSearchForFolderNext.Name = "btnSearchForFolderNext"; + this.btnSearchForFolderNext.Size = new System.Drawing.Size(75, 23); + this.btnSearchForFolderNext.TabIndex = 2; + this.btnSearchForFolderNext.Text = "Next"; + this.btnSearchForFolderNext.UseVisualStyleBackColor = true; + this.btnSearchForFolderNext.Click += new System.EventHandler(this.btnSearchForFolderNext_Click); + // + // btnSearchForFolder + // + this.btnSearchForFolder.Location = new System.Drawing.Point(353, 17); + this.btnSearchForFolder.Name = "btnSearchForFolder"; + this.btnSearchForFolder.Size = new System.Drawing.Size(43, 23); + this.btnSearchForFolder.TabIndex = 1; + this.btnSearchForFolder.Text = "Go"; + this.btnSearchForFolder.UseVisualStyleBackColor = true; + this.btnSearchForFolder.Click += new System.EventHandler(this.btnSearchForFolder_Click); + // + // txtSearchForFolder + // + this.txtSearchForFolder.Location = new System.Drawing.Point(6, 19); + this.txtSearchForFolder.Name = "txtSearchForFolder"; + this.txtSearchForFolder.Size = new System.Drawing.Size(341, 20); + this.txtSearchForFolder.TabIndex = 0; + // + // labDirectoryTreeView + // + this.labDirectoryTreeView.AutoSize = true; + this.labDirectoryTreeView.Location = new System.Drawing.Point(13, 13); + this.labDirectoryTreeView.Name = "labDirectoryTreeView"; + this.labDirectoryTreeView.Size = new System.Drawing.Size(57, 13); + this.labDirectoryTreeView.TabIndex = 4; + this.labDirectoryTreeView.Text = "Directories"; + // + // labAccessView + // + this.labAccessView.AutoSize = true; + this.labAccessView.Location = new System.Drawing.Point(344, 12); + this.labAccessView.Name = "labAccessView"; + this.labAccessView.Size = new System.Drawing.Size(202, 13); + this.labAccessView.TabIndex = 5; + this.labAccessView.Text = "Permissions given on the seletcted object"; + // + // ShowSimpleEffectiveAccessForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(830, 389); + this.Controls.Add(this.labAccessView); + this.Controls.Add(this.labDirectoryTreeView); + this.Controls.Add(this.grpFilter); + this.Controls.Add(this.lstPermissions); + this.Controls.Add(this.trvDirectories); + this.Name = "ShowSimpleEffectiveAccessForm"; + this.Text = "ShowAccess"; + this.grpFilter.ResumeLayout(false); + this.grpFilter.PerformLayout(); + this.grpSearchForFolder.ResumeLayout(false); + this.grpSearchForFolder.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TreeView trvDirectories; + private System.Windows.Forms.ListView lstPermissions; + private System.Windows.Forms.ColumnHeader chdIdentity; + private System.Windows.Forms.ColumnHeader chdRights; + private System.Windows.Forms.ColumnHeader chdAccessControlType; + private System.Windows.Forms.ImageList imlIcons; + private System.Windows.Forms.CheckBox chkRemoveFoldersWithoutAccess; + private System.Windows.Forms.GroupBox grpFilter; + private System.Windows.Forms.Label labDirectoryTreeView; + private System.Windows.Forms.Label labAccessView; + private System.Windows.Forms.GroupBox grpSearchForFolder; + private System.Windows.Forms.Button btnSearchForFolder; + private System.Windows.Forms.TextBox txtSearchForFolder; + private System.Windows.Forms.Button btnSearchForFolderNext; + private System.Windows.Forms.Button btnSearchForFolderPrev; + + } +} \ No newline at end of file diff --git a/NTFSSecurity/ShowSimpleEffectiveAccess.cs b/NTFSSecurity/ShowSimpleEffectiveAccess.cs new file mode 100644 index 0000000..751b34d --- /dev/null +++ b/NTFSSecurity/ShowSimpleEffectiveAccess.cs @@ -0,0 +1,222 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.IO; +using Security2; + +namespace NTFSSecurity +{ + public partial class ShowSimpleEffectiveAccessForm : Form + { + private IEnumerable directoryList; + private IQueryable aceList; + private IEnumerable searchResultByFolder; + private int searchResultByFolderIndex; + + public IEnumerable DirectoryList + { + get { return directoryList; } + } + + public IEnumerable AceList + { + get { return aceList; } + } + + public ShowSimpleEffectiveAccessForm() + { + InitializeComponent(); + } + + public void BuildDirectoryTreeNodes() + { + string previousPath = string.Empty; + DirectoryTreeNode previousNode; + DirectoryTreeNode rootNode; + + var rootDirectory = directoryList.First(); + + rootNode = new DirectoryTreeNode(rootDirectory.FullName, rootDirectory.Name, aceList.Where(ace => ace.FullName == rootDirectory.Name)); + previousNode = rootNode; + trvDirectories.Nodes.Add(rootNode); + + foreach (var directory in directoryList.Skip(1)) + { + if (previousNode.Name == directory.GetParent().FullName) + { + var node = new DirectoryTreeNode(directory.FullName, directory.Name, aceList.Where(ace => ace.FullName == directory.FullName)); + previousNode.Nodes.Add(node); + } + else + { + previousNode = (DirectoryTreeNode)trvDirectories.Nodes.Find(directory.GetParent().FullName, true).FirstOrDefault(); + if (previousNode != null) + { + var node = new DirectoryTreeNode(directory.FullName, directory.Name, aceList.Where(ace => ace.FullName == directory.FullName)); + previousNode.Nodes.Add(node); + } + else + { + var node = new DirectoryTreeNode(directory.FullName, directory.Name, aceList.Where(ace => ace.FullName == directory.FullName)); + previousNode.Nodes.Add(node); + } + } + } + } + + public void BuildDirectoryTreeNodes(IEnumerable directoryList, IQueryable aceList) + { + this.directoryList = directoryList; + this.aceList = aceList; + + this.BuildDirectoryTreeNodes(); + } + + private void trvDirectories_AfterSelect(object sender, TreeViewEventArgs e) + { + lstPermissions.Items.Clear(); + + foreach (var ace in aceList.Where(ace => ace.FullName == e.Node.Name)) + { + ListViewItem listItem = new ListViewItem(); + listItem.Name = e.Node.Name; + listItem.Text = ace.Identity.AccountName; + listItem.SubItems.AddRange(new string[] { ace.AccessRights.ToString(), ace.AccessControlType.ToString(), e.Node.FullPath }); + listItem.ImageIndex = 1; + + lstPermissions.Items.Add(listItem); + } + + if (lstPermissions.Items.Count > 0) + { + foreach (ColumnHeader column in lstPermissions.Columns) + { + column.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent); + } + } + } + + private void chkRemoveFoldersWithoutAccess_CheckedChanged(object sender, EventArgs e) + { + if (chkRemoveFoldersWithoutAccess.Checked) + { + RemoveFoldersWithoutAccess((DirectoryTreeNode)trvDirectories.Nodes[0]); + } + else + { + trvDirectories.Nodes.Clear(); + BuildDirectoryTreeNodes(); + } + } + + public void RemoveFoldersWithoutAccess(DirectoryTreeNode node) + { + for (int i = 0; i < node.Nodes.Count; i++) + { + if (node.Nodes[i].GetNodeCount(false) > 0) + RemoveFoldersWithoutAccess((DirectoryTreeNode)node.Nodes[i]); + + if (node.Nodes[i].Nodes.Count == 0 & ((DirectoryTreeNode)node.Nodes[i]).Acl.Count() == 0) + { + node.Nodes.Remove(node.Nodes[i]); + i--; + } + } + } + + private void btnSearchForFolder_Click(object sender, EventArgs e) + { + searchResultByFolder = null; + searchResultByFolderIndex = 0; + trvDirectories.HideSelection = false; + + searchResultByFolder = FindNodeByFolder((DirectoryTreeNode)trvDirectories.Nodes[0], txtSearchForFolder.Text); + if (searchResultByFolder.Count() > 0) + { + btnSearchForFolderNext.Enabled = true; + btnSearchForFolderPrev.Enabled = true; + + trvDirectories.SelectedNode = searchResultByFolder.First(); + searchResultByFolderIndex = 0; + } + else + { + btnSearchForFolderNext.Enabled = false; + btnSearchForFolderPrev.Enabled = false; + } + } + + private IEnumerable FindNodeByFolder(DirectoryTreeNode node, string search) + { + if (node.Text.ToLower().Contains(search.ToLower())) + { + yield return node; + } + + foreach (DirectoryTreeNode childNode in node.Nodes) + { + foreach (DirectoryTreeNode match in this.FindNodeByFolder(childNode, search)) + { + yield return match; + } + } + } + + private IEnumerable FindNodeByIdentity(DirectoryTreeNode node, string search) + { + if (node.Acl.Where(ace => ace.Identity.AccountName.ToLower().Contains(search.ToLower())).Count() > 0) + { + yield return node; + } + + foreach (DirectoryTreeNode childNode in node.Nodes) + { + foreach (DirectoryTreeNode match in this.FindNodeByIdentity(childNode, search)) + { + yield return match; + } + } + } + + private void btnSearchForFolderNext_Click(object sender, EventArgs e) + { + if (searchResultByFolder.Count() > searchResultByFolderIndex + 1) + { + searchResultByFolderIndex++; + trvDirectories.SelectedNode = searchResultByFolder.ElementAt(searchResultByFolderIndex); + } + } + + private void btnSearchForFolderPrev_Click(object sender, EventArgs e) + { + if (searchResultByFolderIndex - 1 > -1) + { + searchResultByFolderIndex--; + trvDirectories.SelectedNode = searchResultByFolder.ElementAt(searchResultByFolderIndex); + } + } + + private void btnSearchForIdentityPrev_Click(object sender, EventArgs e) + { + if (searchResultByFolder.Count() > searchResultByFolderIndex + 1) + { + searchResultByFolderIndex++; + trvDirectories.SelectedNode = searchResultByFolder.ElementAt(searchResultByFolderIndex); + } + } + + private void btnSearchForIdentityNext_Click(object sender, EventArgs e) + { + if (searchResultByFolderIndex - 1 > -1) + { + searchResultByFolderIndex--; + trvDirectories.SelectedNode = searchResultByFolder.ElementAt(searchResultByFolderIndex); + } + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/ShowSimpleEffectiveAccess.resx b/NTFSSecurity/ShowSimpleEffectiveAccess.resx new file mode 100644 index 0000000..1c12697 --- /dev/null +++ b/NTFSSecurity/ShowSimpleEffectiveAccess.resx @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAs + CAAAAk1TRnQBSQFMAwEBAAGQAQABkAEAARABAAEQAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMA + AUADAAEQAwABAQEAAQgGAAEEGAABgAIAAYADAAKAAQABgAMAAYABAAGAAQACgAIAA8ABAAHAAdwBwAEA + AfABygGmAQABMwUAATMBAAEzAQABMwEAAjMCAAMWAQADHAEAAyIBAAMpAQADVQEAA00BAANCAQADOQEA + AYABfAH/AQACUAH/AQABkwEAAdYBAAH/AewBzAEAAcYB1gHvAQAB1gLnAQABkAGpAa0CAAH/ATMDAAFm + AwABmQMAAcwCAAEzAwACMwIAATMBZgIAATMBmQIAATMBzAIAATMB/wIAAWYDAAFmATMCAAJmAgABZgGZ + AgABZgHMAgABZgH/AgABmQMAAZkBMwIAAZkBZgIAApkCAAGZAcwCAAGZAf8CAAHMAwABzAEzAgABzAFm + AgABzAGZAgACzAIAAcwB/wIAAf8BZgIAAf8BmQIAAf8BzAEAATMB/wIAAf8BAAEzAQABMwEAAWYBAAEz + AQABmQEAATMBAAHMAQABMwEAAf8BAAH/ATMCAAMzAQACMwFmAQACMwGZAQACMwHMAQACMwH/AQABMwFm + AgABMwFmATMBAAEzAmYBAAEzAWYBmQEAATMBZgHMAQABMwFmAf8BAAEzAZkCAAEzAZkBMwEAATMBmQFm + AQABMwKZAQABMwGZAcwBAAEzAZkB/wEAATMBzAIAATMBzAEzAQABMwHMAWYBAAEzAcwBmQEAATMCzAEA + ATMBzAH/AQABMwH/ATMBAAEzAf8BZgEAATMB/wGZAQABMwH/AcwBAAEzAv8BAAFmAwABZgEAATMBAAFm + AQABZgEAAWYBAAGZAQABZgEAAcwBAAFmAQAB/wEAAWYBMwIAAWYCMwEAAWYBMwFmAQABZgEzAZkBAAFm + ATMBzAEAAWYBMwH/AQACZgIAAmYBMwEAA2YBAAJmAZkBAAJmAcwBAAFmAZkCAAFmAZkBMwEAAWYBmQFm + AQABZgKZAQABZgGZAcwBAAFmAZkB/wEAAWYBzAIAAWYBzAEzAQABZgHMAZkBAAFmAswBAAFmAcwB/wEA + AWYB/wIAAWYB/wEzAQABZgH/AZkBAAFmAf8BzAEAAcwBAAH/AQAB/wEAAcwBAAKZAgABmQEzAZkBAAGZ + AQABmQEAAZkBAAHMAQABmQMAAZkCMwEAAZkBAAFmAQABmQEzAcwBAAGZAQAB/wEAAZkBZgIAAZkBZgEz + AQABmQEzAWYBAAGZAWYBmQEAAZkBZgHMAQABmQEzAf8BAAKZATMBAAKZAWYBAAOZAQACmQHMAQACmQH/ + AQABmQHMAgABmQHMATMBAAFmAcwBZgEAAZkBzAGZAQABmQLMAQABmQHMAf8BAAGZAf8CAAGZAf8BMwEA + AZkBzAFmAQABmQH/AZkBAAGZAf8BzAEAAZkC/wEAAcwDAAGZAQABMwEAAcwBAAFmAQABzAEAAZkBAAHM + AQABzAEAAZkBMwIAAcwCMwEAAcwBMwFmAQABzAEzAZkBAAHMATMBzAEAAcwBMwH/AQABzAFmAgABzAFm + ATMBAAGZAmYBAAHMAWYBmQEAAcwBZgHMAQABmQFmAf8BAAHMAZkCAAHMAZkBMwEAAcwBmQFmAQABzAKZ + AQABzAGZAcwBAAHMAZkB/wEAAswCAALMATMBAALMAWYBAALMAZkBAAPMAQACzAH/AQABzAH/AgABzAH/ + ATMBAAGZAf8BZgEAAcwB/wGZAQABzAH/AcwBAAHMAv8BAAHMAQABMwEAAf8BAAFmAQAB/wEAAZkBAAHM + ATMCAAH/AjMBAAH/ATMBZgEAAf8BMwGZAQAB/wEzAcwBAAH/ATMB/wEAAf8BZgIAAf8BZgEzAQABzAJm + AQAB/wFmAZkBAAH/AWYBzAEAAcwBZgH/AQAB/wGZAgAB/wGZATMBAAH/AZkBZgEAAf8CmQEAAf8BmQHM + AQAB/wGZAf8BAAH/AcwCAAH/AcwBMwEAAf8BzAFmAQAB/wHMAZkBAAH/AswBAAH/AcwB/wEAAv8BMwEA + AcwB/wFmAQAC/wGZAQAC/wHMAQACZgH/AQABZgH/AWYBAAFmAv8BAAH/AmYBAAH/AWYB/wEAAv8BZgEA + ASEBAAGlAQADXwEAA3cBAAOGAQADlgEAA8sBAAOyAQAD1wEAA90BAAPjAQAD6gEAA/EBAAP4AQAB8AH7 + Af8BAAGkAqABAAOAAwAB/wIAAf8DAAL/AQAB/wMAAf8BAAH/AQAC/wIAA/8BABD/MAAQ/zAAAf8B9AGS + BPcDkgL3AZIB9wHyAf8wAAH/Ae8LFAEPAQcB/zAAAf8B7AGZAnkBHAF5ARwBWAEcAXkBHAFzAUMBBwH/ + MAAB/wHtAfQEeQFeAZkBXgJ5ARwBQwEHAf8wAAH/Ae0BwwN5AV4BmQFeAZkBXgF5AVgBQwEHAf8wAAH/ + Ae0B9AJ5AV0BmQFeAbwBXgGZAV4B9wFDAQcB/zAAAf8B7QHDAXoCeQFeAZkBXgGZAV4BeQFYAUMBBwH/ + MAAB/wHtAfQEeQFeAZkBXgJ5ARwBQwEHAf8wAAH/Ae0BwwOgAeUBGgHlARoB5QEaAXkBQwEHAf8wAAH/ + Ae0BGwGgAcMBGgGgARsEBwH3AewB8QH/MAAB/wG8ARwEeQH3AvABvALwAfMC/zAAAv8BvAHtAnMB7QHw + CP8wAAP/BPQJ/zAAEP8wAAFCAU0BPgcAAT4DAAEoAwABQAMAARADAAEBAQABAQUAAYAXAAP/gQAL + + + \ No newline at end of file diff --git a/NTFSSecurity/SimpleAccessCmdlets.cs b/NTFSSecurity/SimpleAccessCmdlets.cs new file mode 100644 index 0000000..aa8ac65 --- /dev/null +++ b/NTFSSecurity/SimpleAccessCmdlets.cs @@ -0,0 +1,298 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Diagnostics; +using System.Management.Automation; +using Security2; +using Alphaleonis.Win32.Filesystem; + +namespace NTFSSecurity +{ + #region Get-SimpleAccess + [Cmdlet(VerbsCommon.Get, "NTFSSimpleAccess")] + [OutputType(typeof(Security2.SimpleFileSystemAccessRule))] + public class GetSimpleAccess : GetAccess + { + private bool includeRootFolder = true; + protected List aceList = new List(); + protected List directoryList = new List(); + + [Parameter] + public SwitchParameter IncludeRootFolder + { + get { return includeRootFolder; } + set { includeRootFolder = value; } + } + + Dictionary> previousAcls = new Dictionary>(); + DirectoryInfo item; + FileSystemInfo previousItem; + bool isFirstFolder = true; + + protected override void ProcessRecord() + { + //as this cmdlet retreives also the current working folder to show the permissions. + if (includeRootFolder & isFirstFolder) + { + string rootPath = System.IO.Path.GetDirectoryName(paths[0]); + + if (!string.IsNullOrEmpty(rootPath)) + { + List l = new List(); + l.Add(rootPath); + l.AddRange(paths); + paths = l; + } + } + + foreach (var p in paths) + { + try + { + item = GetFileSystemInfo2(p) as DirectoryInfo; + + if (item != null) + { + WriteVerbose(string.Format("New folder: {0}", item.FullName)); + directoryList.Add(item); + + var acl = FileSystemAccessRule2.GetFileSystemAccessRules(item, true, true).Select(ace => ace.ToSimpleFileSystemAccessRule2()); + + try + { + previousItem = item.GetParent(); + } + catch { } + IEnumerable previousAcl = null; + + if (isFirstFolder) + { + previousAcls.Add(item.FullName, acl); + aceList.AddRange(acl); + acl.ForEach(ace => WriteObject(ace)); + + isFirstFolder = false; + } + else + { + if (previousAcls.ContainsKey(previousItem.FullName)) + { + previousAcl = previousAcls[previousItem.FullName]; + previousAcls.Add(item.FullName, acl); + + List diffAcl = new List(); + + foreach (var ace in acl) + { + var equalsUser = previousAcl.Where(prevAce => prevAce.Identity == ace.Identity); + var equalsUserAndAccessType = previousAcl.Where(prevAce => prevAce.Identity == ace.Identity & prevAce.AccessControlType == ace.AccessControlType); + var equalsRights = previousAcl.Where(prevAce => (prevAce.AccessRights & ace.AccessRights) == ace.AccessRights); + var totalEqual = previousAcl.Where(prevAce => prevAce.Identity == ace.Identity & prevAce.AccessControlType == ace.AccessControlType & (prevAce.AccessRights & ace.AccessRights) == ace.AccessRights); + + if (previousAcl.Where(prevAce => + prevAce.AccessControlType == ace.AccessControlType & + (prevAce.AccessRights & ace.AccessRights) == ace.AccessRights & + prevAce.Identity == ace.Identity).Count() == 0) + { + diffAcl.Add(ace); + } + } + + aceList.AddRange(diffAcl); + diffAcl.ForEach(ace => WriteObject(ace)); + } + } + } + + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, "ReadError", ErrorCategory.OpenError, p)); + } + } + } + } + #endregion + + //#region Get-SimpleEffectiveAccess + //[Cmdlet(VerbsCommon.Get, "SimpleEffectiveAccess")] + //public class GetSimpleEffectiveAccess : GetEffectiveAccess + //{ + // private bool includeRootFolder = true; + // protected List aceList = new List(); + // protected List directoryList = new List(); + + // [Parameter] + // public SwitchParameter IncludeRootFolder + // { + // get { return includeRootFolder; } + // set { includeRootFolder = value; } + // } + + // Dictionary> previousAcls = new Dictionary>(); + // DirectoryInfo item; + // FileSystemInfo previousItem; + // bool isFirstFolder = true; + + // protected override void ProcessRecord() + // { + // //as this cmdlet retreives also the current working folder to show the permissions. + // if (includeRootFolder & isFirstFolder) + // { + // string rootPath = System.IO.Path.GetDirectoryName(path[0]); + + // if (!string.IsNullOrEmpty(rootPath)) + // { + // List l = new List(); + // l.Add(rootPath); + // l.AddRange(path); + // path = l.ToArray(); + // } + // } + + // foreach (var p in path) + // { + // try + // { + // item = this.GetFileSystemInfo(p) as DirectoryInfo; + + // if (item != null) + // { + // WriteVerbose(string.Format("New folder: {0}", item.FullName)); + // directoryList.Add(item); + + // //var acl = FileSystemAccessRule2.GetFileSystemAccessRules(item, true, true).Select(ace => ace.ToSimpleFileSystemAccessRule2()); + // var acl = (new List() { EffectivePermissions.GetEffectiveAccess(item, Account).ToSimpleFileSystemAccessRule2() }).AsQueryable(); + + // try + // { + // previousItem = item.GetParent(); + // } + // catch { } + // IQueryable previousAcl = null; + + // if (isFirstFolder) + // { + // previousAcls.Add(item.FullName, acl); + // aceList.AddRange(acl); + // acl.ForEach(ace => WriteObject(ace)); + + // isFirstFolder = false; + // } + // else + // { + // if (previousAcls.ContainsKey(previousItem.FullName)) + // { + // previousAcl = previousAcls[previousItem.FullName]; + // previousAcls.Add(item.FullName, acl); + + // List diffAcl = new List(); + + // foreach (var ace in acl) + // { + // var equalsUser = previousAcl.Where(prevAce => prevAce.Identity == ace.Identity); + // var equalsUserAndAccessType = previousAcl.Where(prevAce => prevAce.Identity == ace.Identity & prevAce.AccessControlType == ace.AccessControlType); + // var equalsRights = previousAcl.Where(prevAce => (prevAce.AccessRights & ace.AccessRights) == ace.AccessRights); + // var totalEqual = previousAcl.Where(prevAce => prevAce.Identity == ace.Identity & prevAce.AccessControlType == ace.AccessControlType & (prevAce.AccessRights & ace.AccessRights) == ace.AccessRights); + + // if (previousAcl.Where(prevAce => + // prevAce.AccessControlType == ace.AccessControlType & + // (prevAce.AccessRights & ace.AccessRights) == ace.AccessRights & + // prevAce.Identity == ace.Identity).Count() == 0) + // { + // diffAcl.Add(ace); + // } + // } + + // aceList.AddRange(diffAcl); + // diffAcl.ForEach(ace => WriteObject(ace)); + // } + // } + // } + + // } + // catch (Exception ex) + // { + // this.WriteError(new ErrorRecord(ex, "ReadError", ErrorCategory.OpenError, p)); + // } + // } + // } + //} + //#endregion + + #region Show-SimpleAccess + [Cmdlet(VerbsCommon.Show, "SimpleAccess")] + public class ShowSimpleAccess : GetSimpleAccess + { + Stopwatch stopwatch; + + protected override void BeginProcessing() + { + stopwatch = new Stopwatch(); + stopwatch.Start(); + + WriteDebug("Running Get-SimpleAccess"); + } + + protected override void ProcessRecord() + { + base.ProcessRecord(); + } + + protected override void EndProcessing() + { + stopwatch.Stop(); + WriteDebug(string.Format("Runtime of Get-SimpleAccess: {0}.", stopwatch.Elapsed.ToString())); + + stopwatch.Reset(); stopwatch.Start(); + WriteDebug("Creating TreeView"); + + ShowSimpleAccessForm form = new ShowSimpleAccessForm(); + form.BuildDirectoryTreeNodes(directoryList, aceList.AsQueryable()); + stopwatch.Stop(); + + WriteDebug(string.Format("Creating the Treeview took: {0}.", stopwatch.Elapsed.ToString())); + + form.ShowDialog(); + } + } + #endregion + + //#region Show-SimpleEffectiveAccess + //[Cmdlet(VerbsCommon.Show, "SimpleEffectiveAccess")] + //public class ShowSimpleEffectiveAccess : GetSimpleEffectiveAccess + //{ + // Stopwatch stopwatch; + + // protected override void BeginProcessing() + // { + // stopwatch = new Stopwatch(); + // stopwatch.Start(); + + // this.WriteDebug("Running Get-SimpleAccess"); + // } + // protected override void ProcessRecord() + // { + // base.ProcessRecord(); + // } + + // protected override void EndProcessing() + // { + // stopwatch.Stop(); + // this.WriteDebug(string.Format("Runtime of Get-SimpleAccess: {0}.", stopwatch.Elapsed.ToString())); + + // stopwatch.Reset(); stopwatch.Start(); + // this.WriteDebug("Creating TreeView"); + + // ShowSimpleEffectiveAccessForm form = new ShowSimpleEffectiveAccessForm(); + // form.BuildDirectoryTreeNodes(directoryList, aceList.AsQueryable()); + // stopwatch.Stop(); + + // this.WriteDebug(string.Format("Creating the Treeview took: {0}.", stopwatch.Elapsed.ToString())); + + // form.ShowDialog(); + // } + //} + //#endregion +} \ No newline at end of file diff --git a/NTFSSecurityTest/IdentityReference2Tests.cs b/NTFSSecurityTest/IdentityReference2Tests.cs new file mode 100644 index 0000000..ea923fd --- /dev/null +++ b/NTFSSecurityTest/IdentityReference2Tests.cs @@ -0,0 +1,190 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Security.Principal; + +namespace Security2.Tests +{ + [TestClass()] + public class IdentityReference2Tests + { + IdentityReference2 currentUser; + IdentityReference2 currentUser2; + IdentityReference2 systemAccount; + string invalidSid; + + [TestInitialize] + public void Init() + { + currentUser = WindowsIdentity.GetCurrent().User; + currentUser2 = WindowsIdentity.GetCurrent().User; + systemAccount = new IdentityReference2(@"NT AUTHORITY\SYSTEM"); + invalidSid = "S-1-5-2-123456789-2021496291-1752113662-1002"; + } + + [TestMethod()] + public void EqualsToNameStringTest() + { + var name = WindowsIdentity.GetCurrent().User.Translate(typeof(NTAccount)).Value; + Assert.IsTrue(currentUser.Equals(name)); + } + + [TestMethod()] + public void NotEqualsToNameStringTest() + { + var name = systemAccount.AccountName; + Assert.IsFalse(currentUser.Equals(name)); + } + + [TestMethod()] + public void EqualsToSidStringTest() + { + var sid = WindowsIdentity.GetCurrent().User.Value; + Assert.IsTrue(currentUser.Equals(sid)); + } + + [TestMethod()] + public void NotEqualsToSidStringTest() + { + var sid = systemAccount.Sid; + Assert.IsFalse(currentUser.Equals(sid)); + } + + [TestMethod()] + public void NotEqualsToStringTest() + { + Assert.IsFalse(currentUser.Equals(systemAccount.AccountName)); + } + + [TestMethod()] + public void EqualsToNTAccount() + { + var ntAccount = WindowsIdentity.GetCurrent().User.Translate(typeof(NTAccount)); + Assert.IsTrue(currentUser.Equals(ntAccount)); + } + + [TestMethod()] + public void NotEqualsToNTAccount() + { + var ntAccount = new NTAccount(systemAccount.AccountName); + Assert.IsFalse(currentUser.Equals(ntAccount)); + } + + [TestMethod()] + public void EqualsToSecurityIdentifier() + { + var sid = WindowsIdentity.GetCurrent().User; + Assert.IsTrue(currentUser.Equals(sid)); + } + + [TestMethod()] + public void NotEqualsToSecurityIdentifier() + { + var sid = new SecurityIdentifier(systemAccount.Sid); + Assert.IsFalse(currentUser.Equals(sid)); + } + + [TestMethod()] + public void EqualsToIdentityReference2() + { + Assert.IsTrue(currentUser.Equals(currentUser2)); + } + + [TestMethod()] + public void NotEqualsToIdentityReference2() + { + Assert.IsFalse(currentUser.Equals(systemAccount)); + } + + [TestMethod()] + [ExpectedException(typeof(System.NullReferenceException))] + public void EqualsToNullThrowsException() + { + IdentityReference2 ir2 = null; + ir2.Equals(null); + } + + [TestMethod()] + public void NotEqualsToNull() + { + Assert.IsFalse(currentUser.Equals(null)); + } + + [TestMethod()] + public void GetHashCodeWithCurrentUserTest() + { + var sid = new SecurityIdentifier(currentUser.GetBinaryForm(), 0); + + Assert.AreEqual(sid.GetHashCode(), currentUser.GetHashCode()); + } + + [TestMethod()] + public void GetBinaryFormWithCurrentUserTest() + { + var sid = new SecurityIdentifier(currentUser.GetBinaryForm(), 0); + + Assert.AreEqual(sid.Value, currentUser.Sid); + } + + [TestMethod()] + public void ToStringWithCurrentUserTest() + { + var sid = WindowsIdentity.GetCurrent().User; + var ntAccount = sid.Translate(typeof(NTAccount)); + + Assert.AreEqual(currentUser.ToString(), ntAccount.Value); + } + + [TestMethod()] + public void ToStringWithInvalidSidEqualsNull() + { + var ir2 = (IdentityReference2)invalidSid; + Assert.AreEqual(ir2.ToString(), invalidSid); + } + + [TestMethod()] + public void op_ReferenceEquals() + { + var temp = currentUser; + Assert.IsTrue(currentUser == temp); + } + + [TestMethod()] + public void op_EqualsToIdentityReference2() + { + Assert.IsTrue(currentUser == currentUser2); + } + + [TestMethod()] + public void op_NotEqualsToIdentityReference2() + { + Assert.IsTrue(currentUser != systemAccount); + } + + [TestMethod()] + public void op_EqualsToNTAccout() + { + var ntAccount = new NTAccount(currentUser.AccountName); + Assert.IsTrue(currentUser == ntAccount); + } + + [TestMethod()] + public void op_NotEqualsToNTAccount() + { + var ntAccount = new NTAccount(systemAccount.AccountName); + Assert.IsTrue(currentUser != ntAccount); + } + + [TestMethod()] + public void op_EqualsToSecurityIdentifier() + { + var sid = new SecurityIdentifier(currentUser.Sid); + Assert.IsTrue(currentUser == sid); + } + + [TestMethod()] + public void op_NotEqualsToSecurityIdentifier() + { + var sid = new SecurityIdentifier(systemAccount.Sid); + Assert.IsTrue(currentUser != sid); + } + } +} \ No newline at end of file diff --git a/NTFSSecurityTest/NTFSSecurityTest.csproj b/NTFSSecurityTest/NTFSSecurityTest.csproj new file mode 100644 index 0000000..e772d03 --- /dev/null +++ b/NTFSSecurityTest/NTFSSecurityTest.csproj @@ -0,0 +1,105 @@ + + + + Debug + AnyCPU + {675D40FA-F56C-4ACC-B863-18B4A14F93E0} + Library + Properties + NTFSSecurityTest + NTFSSecurityTest + v4.5.2 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + SAK + SAK + SAK + SAK + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + True + True + Settings.settings + + + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + {B437C364-5BC7-42E4-93F7-0F459A5DF0D0} + Security2 + + + + + + + False + + + False + + + False + + + False + + + + + + + + \ No newline at end of file diff --git a/NTFSSecurityTest/Properties/AssemblyInfo.cs b/NTFSSecurityTest/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..efd29fb --- /dev/null +++ b/NTFSSecurityTest/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("NTFSSecurityTest")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("NTFSSecurityTest")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("675d40fa-f56c-4acc-b863-18b4a14f93e0")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/NTFSSecurityTest/Properties/Settings.Designer.cs b/NTFSSecurityTest/Properties/Settings.Designer.cs new file mode 100644 index 0000000..f15033b --- /dev/null +++ b/NTFSSecurityTest/Properties/Settings.Designer.cs @@ -0,0 +1,38 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace NTFSSecurityTest.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("d:\\UnitTest")] + public string path { + get { + return ((string)(this["path"])); + } + set { + this["path"] = value; + } + } + } +} diff --git a/NTFSSecurityTest/Properties/Settings.settings b/NTFSSecurityTest/Properties/Settings.settings new file mode 100644 index 0000000..21a3d4e --- /dev/null +++ b/NTFSSecurityTest/Properties/Settings.settings @@ -0,0 +1,9 @@ + + + + + + d:\UnitTest + + + \ No newline at end of file diff --git a/NTFSSecurityTest/UnitTest1.cs b/NTFSSecurityTest/UnitTest1.cs new file mode 100644 index 0000000..3a59fc1 --- /dev/null +++ b/NTFSSecurityTest/UnitTest1.cs @@ -0,0 +1,30 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.IO; +using NTFSSecurityTest.Properties; + +namespace NTFSSecurityTest +{ + [TestClass] + public class UnitTest1 + { + [TestMethod] + public void TestMethod1() + { + Assert.IsTrue(Directory.Exists(Settings.Default.path + "1")); + } + + [TestInitialize] + public void Init() + { + System.Threading.Thread.Sleep(3000); + Directory.CreateDirectory(Settings.Default.path); + } + + [TestCleanup] + public void Cleanup() + { + Directory.Delete(Settings.Default.path); + } + } +} diff --git a/NTFSSecurityTest/app.config b/NTFSSecurityTest/app.config new file mode 100644 index 0000000..7e50f8a --- /dev/null +++ b/NTFSSecurityTest/app.config @@ -0,0 +1,15 @@ + + + + +
+ + + + + + d:\UnitTest + + + + \ No newline at end of file diff --git a/PrivilegeControl/PrivilegeControl.cs b/PrivilegeControl/PrivilegeControl.cs new file mode 100644 index 0000000..58e376b --- /dev/null +++ b/PrivilegeControl/PrivilegeControl.cs @@ -0,0 +1,71 @@ +using System; +using System.Security.AccessControl; +using ProcessPrivileges; +using System.Diagnostics; + +namespace Security2 +{ + public class AdjustPriviledgeException : Exception + { + public AdjustPriviledgeException(string message) + : base(message) + { } + } + + public class PrivilegeControl + { + private Process p; + + public PrivilegeControl() + { + p = Process.GetCurrentProcess(); + } + + public PrivilegeAndAttributesCollection GetPrivileges() + { + return p.GetPrivileges(); + } + + public AdjustPrivilegeResult EnablePrivilege(Privilege privilege) + { + if (p.GetPrivilegeState(privilege) == PrivilegeState.Disabled) + { + AdjustPrivilegeResult result = p.EnablePrivilege(privilege); + return result; + } + else if (p.GetPrivilegeState(privilege) == PrivilegeState.Removed) + { + throw new PrivilegeNotHeldException(privilege.ToString()); + } + else if (p.GetPrivilegeState(privilege) == PrivilegeState.Enabled) + { + throw new AdjustPriviledgeException("Priviledge already enabled"); + } + else + { + throw new AdjustPriviledgeException("Unknown Error"); + } + } + + public AdjustPrivilegeResult DisablePrivilege(Privilege privilege) + { + if (p.GetPrivilegeState(privilege) == PrivilegeState.Enabled) + { + AdjustPrivilegeResult result = p.DisablePrivilege(privilege); + return result; + } + else if (p.GetPrivilegeState(privilege) == PrivilegeState.Removed) + { + throw new PrivilegeNotHeldException(privilege.ToString()); + } + else if (p.GetPrivilegeState(privilege) == PrivilegeState.Disabled) + { + throw new AdjustPriviledgeException("Priviledge already disabled"); + } + else + { + throw new AdjustPriviledgeException("Unknown Error"); + } + } + } +} diff --git a/PrivilegeControl/PrivilegeControl.csproj b/PrivilegeControl/PrivilegeControl.csproj new file mode 100644 index 0000000..43e7561 --- /dev/null +++ b/PrivilegeControl/PrivilegeControl.csproj @@ -0,0 +1,65 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {01EAB41B-B2CE-49FE-AB5A-0F0FF0A9A7EE} + Library + Properties + PrivilegeControl + PrivilegeControl + v3.5 + 512 + Client + SAK + SAK + SAK + SAK + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + {410CAEE5-D287-4A18-9B38-BB87397D218D} + ProcessPrivileges + + + + + \ No newline at end of file diff --git a/PrivilegeControl/Properties/AssemblyInfo.cs b/PrivilegeControl/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..d86c591 --- /dev/null +++ b/PrivilegeControl/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("PrivilegeControl")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("PrivilegeControl")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a8bb93b7-f0f5-47a1-b552-819b653bb3b8")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ProcessPrivileges/AccessTokenHandle.cs b/ProcessPrivileges/AccessTokenHandle.cs new file mode 100644 index 0000000..515ef20 --- /dev/null +++ b/ProcessPrivileges/AccessTokenHandle.cs @@ -0,0 +1,40 @@ +// +// Copyright © Nick Lowe 2009 +// +// Nick Lowe +// nick@int-r.net +// http://processprivileges.codeplex.com/ + +namespace ProcessPrivileges +{ + using System.ComponentModel; + using System.Runtime.ConstrainedExecution; + using System.Runtime.InteropServices; + using Microsoft.Win32.SafeHandles; + + /// Handle to an access token. + public sealed class AccessTokenHandle : SafeHandleZeroOrMinusOneIsInvalid + { + internal AccessTokenHandle(ProcessHandle processHandle, TokenAccessRights tokenAccessRights) + : base(true) + { + if (!NativeMethods.OpenProcessToken(processHandle, tokenAccessRights, ref handle)) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + } + + /// Releases the handle. + /// Value indicating if the handle released successfully. + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + protected override bool ReleaseHandle() + { + if (!NativeMethods.CloseHandle(handle)) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + return true; + } + } +} \ No newline at end of file diff --git a/ProcessPrivileges/AllocatedMemory.cs b/ProcessPrivileges/AllocatedMemory.cs new file mode 100644 index 0000000..e1915d0 --- /dev/null +++ b/ProcessPrivileges/AllocatedMemory.cs @@ -0,0 +1,54 @@ +// +// Copyright © Nick Lowe 2009 +// +// Nick Lowe +// nick@int-r.net +// http://processprivileges.codeplex.com/ + +namespace ProcessPrivileges +{ + using System; + using System.Diagnostics.CodeAnalysis; + using System.Runtime.InteropServices; + + internal sealed class AllocatedMemory : IDisposable + { + [SuppressMessage("Microsoft.Reliability", + "CA2006:UseSafeHandleToEncapsulateNativeResources", + Justification = "Not pointing to a native resource.")] + private IntPtr pointer; + + internal AllocatedMemory(int bytesRequired) + { + this.pointer = Marshal.AllocHGlobal(bytesRequired); + } + + ~AllocatedMemory() + { + this.InternalDispose(); + } + + internal IntPtr Pointer + { + get + { + return this.pointer; + } + } + + public void Dispose() + { + this.InternalDispose(); + GC.SuppressFinalize(this); + } + + private void InternalDispose() + { + if (this.pointer != IntPtr.Zero) + { + Marshal.FreeHGlobal(this.pointer); + this.pointer = IntPtr.Zero; + } + } + } +} \ No newline at end of file diff --git a/ProcessPrivileges/Enums.cs b/ProcessPrivileges/Enums.cs new file mode 100644 index 0000000..6a92038 --- /dev/null +++ b/ProcessPrivileges/Enums.cs @@ -0,0 +1,154 @@ +// +// Copyright © Nick Lowe 2009 +// +// Nick Lowe +// nick@int-r.net +// http://processprivileges.codeplex.com/ + +namespace ProcessPrivileges +{ + using System.Diagnostics.CodeAnalysis; + + /// Result from a privilege adjustment. + public enum AdjustPrivilegeResult + { + /// Privilege not modified. + None, + + /// Privilege modified. + PrivilegeModified + } + + /// Privilege determining the type of system operations that can be performed. + public enum Privilege + { + /// Privilege to replace a process-level token. + AssignPrimaryToken, + + /// Privilege to generate security audits. + Audit, + + /// Privilege to backup files and directories. + Backup, + + /// Privilege to bypass traverse checking. + ChangeNotify, + + /// Privilege to create global objects. + CreateGlobal, + + /// Privilege to create a pagefile. + CreatePageFile, + + /// Privilege to create permanent shared objects. + CreatePermanent, + + /// Privilege to create symbolic links. + CreateSymbolicLink, + + /// Privilege to create a token object. + CreateToken, + + /// Privilege to debug programs. + Debug, + + /// Privilege to enable computer and user accounts to be trusted for delegation. + EnableDelegation, + + /// Privilege to impersonate a client after authentication. + Impersonate, + + /// Privilege to increase scheduling priority. + IncreaseBasePriority, + + /// Privilege to adjust memory quotas for a process. + IncreaseQuota, + + /// Privilege to increase a process working set. + IncreaseWorkingSet, + + /// Privilege to load and unload device drivers. + LoadDriver, + + /// Privilege to lock pages in memory. + LockMemory, + + /// Privilege to add workstations to domain. + MachineAccount, + + /// Privilege to manage the files on a volume. + ManageVolume, + + /// Privilege to profile single process. + ProfileSingleProcess, + + /// Privilege to modify an object label. + [SuppressMessage( + "Microsoft.Naming", + "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "Spelling is correct.", + MessageId = "Relabel")] + Relabel, + + /// Privilege to force shutdown from a remote system. + RemoteShutdown, + + /// Privilege to restore files and directories. + Restore, + + /// Privilege to manage auditing and security log. + Security, + + /// Privilege to shut down the system. + Shutdown, + + /// Privilege to synchronize directory service data. + SyncAgent, + + /// Privilege to modify firmware environment values. + SystemEnvironment, + + /// Privilege to profile system performance. + SystemProfile, + + /// Privilege to change the system time. + SystemTime, + + /// Privilege to take ownership of files or other objects. + TakeOwnership, + + /// Privilege to act as part of the operating system. + TrustedComputerBase, + + /// Privilege to change the time zone. + TimeZone, + + /// Privilege to access Credential Manager as a trusted caller. + TrustedCredentialManagerAccess, + + /// Privilege to remove computer from docking station. + Undock, + + /// Privilege to read unsolicited input from a terminal device. + UnsolicitedInput + } + + /// State of a , derived from . + public enum PrivilegeState + { + /// + /// Privilege is disabled. + /// + Disabled, + + /// + /// Privilege is enabled. + /// + Enabled, + + /// + /// Privilege is removed. + /// + Removed + } +} \ No newline at end of file diff --git a/ProcessPrivileges/NativeEnums.cs b/ProcessPrivileges/NativeEnums.cs new file mode 100644 index 0000000..11edaa9 --- /dev/null +++ b/ProcessPrivileges/NativeEnums.cs @@ -0,0 +1,180 @@ +// +// Copyright © Nick Lowe 2009 +// +// Nick Lowe +// nick@int-r.net +// http://processprivileges.codeplex.com/ + +namespace ProcessPrivileges +{ + using System; + using System.Diagnostics.CodeAnalysis; + + /// + /// Privilege attributes that augment a with state information. + /// + /// + /// Use the following checks to interpret privilege attributes: + /// + /// // Privilege is disabled.
if (attributes == PrivilegeAttributes.Disabled) { /* ... */ }
+ ///
+ /// + /// // Privilege is enabled.
if ((attributes & PrivilegeAttributes.Enabled) == PrivilegeAttributes.Enabled) { /* ... */ }
+ ///
+ /// + /// // Privilege is removed.
if ((attributes & PrivilegeAttributes.Removed) == PrivilegeAttributes.Removed) { /* ... */ }
+ ///
+ /// To avoid having to work with a flags based enumerated type, use on attributes. + ///
+ [Flags, + SuppressMessage( + "Microsoft.Design", + "CA1008:EnumsShouldHaveZeroValue", + Justification = "Native enum."), + SuppressMessage( + "Microsoft.Usage", + "CA2217:DoNotMarkEnumsWithFlags", + Justification = "Native enum.")] + public enum PrivilegeAttributes + { + /// Privilege is disabled. + Disabled = 0, + + /// Privilege is enabled by default. + EnabledByDefault = 1, + + /// Privilege is enabled. + Enabled = 2, + + /// Privilege is removed. + Removed = 4, + + /// Privilege used to gain access to an object or service. + UsedForAccess = -2147483648 + } + + /// Access rights for access tokens. + [Flags, + SuppressMessage( + "Microsoft.Design", + "CA1008:EnumsShouldHaveZeroValue", + Justification = "Native enum."), + SuppressMessage("Microsoft.Usage", + "CA2217:DoNotMarkEnumsWithFlags", + Justification = "Native enum.")] + public enum TokenAccessRights + { + /// Right to attach a primary token to a process. + AssignPrimary = 0, + + /// Right to duplicate an access token. + Duplicate = 1, + + /// Right to attach an impersonation access token to a process. + Impersonate = 4, + + /// Right to query an access token. + Query = 8, + + /// Right to query the source of an access token. + QuerySource = 16, + + /// Right to enable or disable the privileges in an access token. + AdjustPrivileges = 32, + + /// Right to adjust the attributes of the groups in an access token. + AdjustGroups = 64, + + /// Right to change the default owner, primary group, or DACL of an access token. + AdjustDefault = 128, + + /// Right to adjust the session ID of an access token. + AdjustSessionId = 256, + + /// Combines all possible access rights for a token. + AllAccess = AccessTypeMasks.StandardRightsRequired | + AssignPrimary | + Duplicate | + Impersonate | + Query | + QuerySource | + AdjustPrivileges | + AdjustGroups | + AdjustDefault | + AdjustSessionId, + + /// Combines the standard rights required to read with . + Read = AccessTypeMasks.StandardRightsRead | + Query, + + /// Combines the standard rights required to write with , and . + Write = AccessTypeMasks.StandardRightsWrite | + AdjustPrivileges | + AdjustGroups | + AdjustDefault, + + /// Combines the standard rights required to execute with . + Execute = AccessTypeMasks.StandardRightsExecute | + Impersonate + } + + [Flags] + internal enum AccessTypeMasks + { + Delete = 65536, + + ReadControl = 131072, + + WriteDAC = 262144, + + WriteOwner = 524288, + + Synchronize = 1048576, + + StandardRightsRequired = 983040, + + StandardRightsRead = ReadControl, + + StandardRightsWrite = ReadControl, + + StandardRightsExecute = ReadControl, + + StandardRightsAll = 2031616, + + SpecificRightsAll = 65535 + } + + internal enum TokenInformationClass + { + None, + TokenUser, + TokenGroups, + TokenPrivileges, + TokenOwner, + TokenPrimaryGroup, + TokenDefaultDacl, + TokenSource, + TokenType, + TokenImpersonationLevel, + TokenStatistics, + TokenRestrictedSids, + TokenSessionId, + TokenGroupsAndPrivileges, + TokenSessionReference, + TokenSandBoxInert, + TokenAuditPolicy, + TokenOrigin, + TokenElevationType, + TokenLinkedToken, + TokenElevation, + TokenHasRestrictions, + TokenAccessInformation, + TokenVirtualizationAllowed, + TokenVirtualizationEnabled, + TokenIntegrityLevel, + TokenUIAccess, + TokenMandatoryPolicy, + TokenLogonSid, + MaxTokenInfoClass + } +} \ No newline at end of file diff --git a/ProcessPrivileges/NativeMethods.cs b/ProcessPrivileges/NativeMethods.cs new file mode 100644 index 0000000..71a9a56 --- /dev/null +++ b/ProcessPrivileges/NativeMethods.cs @@ -0,0 +1,78 @@ +// +// Copyright © Nick Lowe 2009 +// +// Nick Lowe +// nick@int-r.net +// http://processprivileges.codeplex.com/ + +namespace ProcessPrivileges +{ + using System; + using System.Runtime.ConstrainedExecution; + using System.Runtime.InteropServices; + using System.Security; + using System.Text; + + /// Static class containing Win32 native methods. + internal static class NativeMethods + { + internal const int ErrorInsufficientBuffer = 122; + + private const string AdvApi32 = "advapi32.dll"; + + private const string Kernel32 = "kernel32.dll"; + + [DllImport(AdvApi32, SetLastError = true), + SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool AdjustTokenPrivileges( + [In] AccessTokenHandle accessTokenHandle, + [In, MarshalAs(UnmanagedType.Bool)] bool disableAllPrivileges, + [In] ref TokenPrivilege newState, + [In] int bufferLength, + [In, Out] ref TokenPrivilege previousState, + [In, Out] ref int returnLength); + + [DllImport(Kernel32, SetLastError = true), + ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), + SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CloseHandle( + [In] IntPtr handle); + + [DllImport(AdvApi32, CharSet = CharSet.Unicode, SetLastError = true), + SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool LookupPrivilegeName( + [In] string systemName, + [In] ref Luid luid, + [In, Out] StringBuilder name, + [In, Out] ref int nameLength); + + [DllImport(AdvApi32, CharSet = CharSet.Unicode, SetLastError = true), + SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool LookupPrivilegeValue( + [In] string systemName, + [In] string name, + [In, Out] ref Luid luid); + + [DllImport(AdvApi32, SetLastError = true), + SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetTokenInformation( + [In] AccessTokenHandle accessTokenHandle, + [In] TokenInformationClass tokenInformationClass, + [Out] IntPtr tokenInformation, + [In] int tokenInformationLength, + [In, Out] ref int returnLength); + + [DllImport(AdvApi32, SetLastError = true), + SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool OpenProcessToken( + [In] ProcessHandle processHandle, + [In] TokenAccessRights desiredAccess, + [In, Out] ref IntPtr tokenHandle); + } +} \ No newline at end of file diff --git a/ProcessPrivileges/NativeStructs.cs b/ProcessPrivileges/NativeStructs.cs new file mode 100644 index 0000000..9e2446e --- /dev/null +++ b/ProcessPrivileges/NativeStructs.cs @@ -0,0 +1,35 @@ +// +// Copyright © Nick Lowe 2009 +// +// Nick Lowe +// nick@int-r.net +// http://processprivileges.codeplex.com/ + +namespace ProcessPrivileges +{ + using System.Runtime.InteropServices; + + [StructLayout(LayoutKind.Sequential)] + internal struct Luid + { + internal int LowPart; + + internal int HighPart; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct LuidAndAttributes + { + internal Luid Luid; + + internal PrivilegeAttributes Attributes; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct TokenPrivilege + { + internal int PrivilegeCount; + + internal LuidAndAttributes Privilege; + } +} \ No newline at end of file diff --git a/ProcessPrivileges/PrivilegeAndAttributes.cs b/ProcessPrivileges/PrivilegeAndAttributes.cs new file mode 100644 index 0000000..065ade9 --- /dev/null +++ b/ProcessPrivileges/PrivilegeAndAttributes.cs @@ -0,0 +1,102 @@ +// +// Copyright © Nick Lowe 2009 +// +// Nick Lowe +// nick@int-r.net +// http://processprivileges.codeplex.com/ + +namespace ProcessPrivileges +{ + using System; + + /// Structure that links and together. + public struct PrivilegeAndAttributes : IEquatable + { + private readonly Privilege privilege; + + private readonly PrivilegeAttributes privilegeAttributes; + + internal PrivilegeAndAttributes(Privilege privilege, PrivilegeAttributes privilegeAttributes) + { + this.privilege = privilege; + this.privilegeAttributes = privilegeAttributes; + } + + /// Gets the privilege. + /// The privilege. + public Privilege Privilege + { + get + { + return this.privilege; + } + } + + /// Gets the privilege attributes. + /// The privilege attributes. + public PrivilegeAttributes PrivilegeAttributes + { + get + { + return this.privilegeAttributes; + } + } + + /// Gets the privilege state. + /// The privilege state. + /// Derived from . + public PrivilegeState PrivilegeState + { + get + { + return ProcessExtensions.GetPrivilegeState(this.privilegeAttributes); + } + } + + /// Compares two instances for equality. + /// First instance. + /// Second instance. + /// Value indicating equality of instances. + public static bool operator ==(PrivilegeAndAttributes first, PrivilegeAndAttributes second) + { + return first.Equals(second); + } + + /// Compares two instances for inequality. + /// First instance. + /// Second instance. + /// Value indicating inequality of instances. + public static bool operator !=(PrivilegeAndAttributes first, PrivilegeAndAttributes second) + { + return !first.Equals(second); + } + + /// Returns the hash code for this instance. + /// The hash code for this instance. + public override int GetHashCode() + { + return this.privilege.GetHashCode() ^ this.privilegeAttributes.GetHashCode(); + } + + /// Indicates whether this instance and a specified object are equal. + /// Another object to compare to. + /// Value indicating whether this instance and a specified object are equal. + public override bool Equals(object obj) + { + return obj is PrivilegeAttributes ? this.Equals((PrivilegeAttributes)obj) : false; + } + + /// Indicates whether this instance and another instance are equal. + /// Another instance to compare to. + /// Value indicating whether this instance and another instance are equal. + public bool Equals(PrivilegeAndAttributes other) + { + return this.privilege == other.Privilege && this.privilegeAttributes == other.PrivilegeAttributes; + } + + public override string ToString() + { + return privilege.ToString(); + } + } +} \ No newline at end of file diff --git a/ProcessPrivileges/PrivilegeAndAttributesCollection.cs b/ProcessPrivileges/PrivilegeAndAttributesCollection.cs new file mode 100644 index 0000000..8b46bac --- /dev/null +++ b/ProcessPrivileges/PrivilegeAndAttributesCollection.cs @@ -0,0 +1,49 @@ +// +// Copyright © Nick Lowe 2009 +// +// Nick Lowe +// nick@int-r.net +// http://processprivileges.codeplex.com/ + +namespace ProcessPrivileges +{ + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Linq; + using System.Text; + + /// Read-only collection of privilege and attributes. + [Serializable] + public sealed class PrivilegeAndAttributesCollection : ReadOnlyCollection + { + internal PrivilegeAndAttributesCollection(IList list) + : base(list) + { + } + + /// Returns a representation of the collection. + /// representation of the collection. + public override string ToString() + { + StringBuilder stringBuilder = new StringBuilder(); + int maxPrivilegeLength = this.Max(privilegeAndAttributes => privilegeAndAttributes.Privilege.ToString().Length); + foreach (PrivilegeAndAttributes privilegeAndAttributes in this) + { + stringBuilder.Append(privilegeAndAttributes.Privilege); + int paddingLength = maxPrivilegeLength - privilegeAndAttributes.Privilege.ToString().Length; + char[] padding = new char[paddingLength]; + for (int i = 0; i < paddingLength; i++) + { + padding[i] = ' '; + } + + stringBuilder.Append(padding); + stringBuilder.Append(" => "); + stringBuilder.AppendLine(privilegeAndAttributes.PrivilegeAttributes.ToString()); + } + + return stringBuilder.ToString(); + } + } +} \ No newline at end of file diff --git a/ProcessPrivileges/PrivilegeEnabler.cs b/ProcessPrivileges/PrivilegeEnabler.cs new file mode 100644 index 0000000..d2e9cc5 --- /dev/null +++ b/ProcessPrivileges/PrivilegeEnabler.cs @@ -0,0 +1,220 @@ +// +// Copyright © Nick Lowe 2009 +// +// Nick Lowe +// nick@int-r.net +// http://processprivileges.codeplex.com/ + +namespace ProcessPrivileges +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Linq; + using System.Security.Permissions; + + /// Enables privileges on a process in a safe way, ensuring that they are returned to their original state when an operation that requires a privilege completes. + /// + /// + /// using System; + /// using System.Diagnostics; + /// using ProcessPrivileges; + /// + /// internal static class PrivilegeEnablerExample + /// { + /// public static void Main() + /// { + /// Process process = Process.GetCurrentProcess(); + /// + /// using (new PrivilegeEnabler(process, Privilege.TakeOwnership)) + /// { + /// // Privilege is enabled within the using block. + /// Console.WriteLine( + /// "{0} => {1}", + /// Privilege.TakeOwnership, + /// process.GetPrivilegeState(Privilege.TakeOwnership)); + /// } + /// + /// // Privilege is disabled outside the using block. + /// Console.WriteLine( + /// "{0} => {1}", + /// Privilege.TakeOwnership, + /// process.GetPrivilegeState(Privilege.TakeOwnership)); + /// } + /// } + /// + /// + /// + /// When disabled, privileges are enabled until the instance of the PrivilegeEnabler class is disposed. + /// If the privilege specified is already enabled, it is not modified and will not be disabled when the instance of the PrivilegeEnabler class is disposed. + /// If desired, multiple privileges can be specified in the constructor. + /// If using multiple instances on the same process, do not dispose of them out-of-order. Making use of a using statement, the recommended method, enforces this. + /// For more information on privileges, see: + /// Privileges + /// Privilege Constants + /// + public sealed class PrivilegeEnabler : IDisposable + { + private static readonly Dictionary sharedPrivileges = + new Dictionary(); + + private static readonly Dictionary accessTokenHandles = + new Dictionary(); + + private AccessTokenHandle accessTokenHandle; + + private bool disposed; + + private bool ownsHandle; + + private Process process; + + /// Initializes a new instance of the PrivilegeEnabler class. + /// The for a on which privileges should be enabled. + /// Thrown when another instance exists and has not been disposed. + /// Requires the immediate caller to have FullTrust. + [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public PrivilegeEnabler(AccessTokenHandle accessTokenHandle) + { + this.accessTokenHandle = accessTokenHandle; + } + + /// Initializes a new instance of the PrivilegeEnabler class. + /// The on which privileges should be enabled. + /// Thrown when another instance exists and has not been disposed. + /// Requires the immediate caller to have FullTrust. + [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public PrivilegeEnabler(Process process) + { + lock (accessTokenHandles) + { + if (accessTokenHandles.ContainsKey(process)) + { + this.accessTokenHandle = accessTokenHandles[process]; + } + else + { + this.accessTokenHandle = + process.GetAccessTokenHandle(TokenAccessRights.AdjustPrivileges | TokenAccessRights.Query); + accessTokenHandles.Add(process, this.accessTokenHandle); + this.ownsHandle = true; + } + } + + this.process = process; + } + + /// Initializes a new instance of the PrivilegeEnabler class with the specified privileges to be enabled. + /// The for a on which privileges should be enabled. + /// The privileges to be enabled. + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public PrivilegeEnabler(AccessTokenHandle accessTokenHandle, params Privilege[] privileges) + : this(accessTokenHandle) + { + foreach (Privilege privilege in privileges) + { + this.EnablePrivilege(privilege); + } + } + + /// Initializes a new instance of the PrivilegeEnabler class with the specified privileges to be enabled. + /// The on which privileges should be enabled. + /// The privileges to be enabled. + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public PrivilegeEnabler(Process process, params Privilege[] privileges) + : this(process) + { + foreach (Privilege privilege in privileges) + { + this.EnablePrivilege(privilege); + } + } + + /// Finalizes an instance of the PrivilegeEnabler class. + ~PrivilegeEnabler() + { + this.InternalDispose(); + } + + /// Disposes of an instance of the PrivilegeEnabler class. + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the call stack to have FullTrust. + [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] + public void Dispose() + { + this.InternalDispose(); + GC.SuppressFinalize(this); + } + + /// Enables the specified . + /// The to be enabled. + /// + /// Result from the privilege adjustment. + /// If the is already enabled, is returned. + /// If the is owned by another instance of the PrivilegeEnabler class, is returned. + /// If a is removed from a process, it cannot be enabled. + /// + /// + /// When disabled, privileges are enabled until the instance of the PrivilegeEnabler class is disposed. + /// If the privilege specified is already enabled, it is not modified and will not be disabled when the instance of the PrivilegeEnabler class is disposed. + /// + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public AdjustPrivilegeResult EnablePrivilege(Privilege privilege) + { + lock (sharedPrivileges) + { + if (!sharedPrivileges.ContainsKey(privilege) && + this.accessTokenHandle.GetPrivilegeState(privilege) == PrivilegeState.Disabled && + this.accessTokenHandle.EnablePrivilege(privilege) == AdjustPrivilegeResult.PrivilegeModified) + { + sharedPrivileges.Add(privilege, this); + return AdjustPrivilegeResult.PrivilegeModified; + } + + return AdjustPrivilegeResult.None; + } + } + + [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + private void InternalDispose() + { + if (!this.disposed) + { + lock (sharedPrivileges) + { + Privilege[] privileges = sharedPrivileges + .Where(keyValuePair => keyValuePair.Value == this) + .Select(keyValuePair => keyValuePair.Key) + .ToArray(); + + foreach (Privilege privilege in privileges) + { + this.accessTokenHandle.DisablePrivilege(privilege); + sharedPrivileges.Remove(privilege); + } + + if (this.ownsHandle) + { + this.accessTokenHandle.Dispose(); + lock (this.accessTokenHandle) + { + accessTokenHandles.Remove(this.process); + } + } + + this.accessTokenHandle = null; + this.ownsHandle = false; + this.process = null; + + this.disposed = true; + } + } + } + } +} \ No newline at end of file diff --git a/ProcessPrivileges/Privileges.cs b/ProcessPrivileges/Privileges.cs new file mode 100644 index 0000000..d225dc5 --- /dev/null +++ b/ProcessPrivileges/Privileges.cs @@ -0,0 +1,319 @@ +// +// Copyright © Nick Lowe 2009 +// +// Nick Lowe +// nick@int-r.net +// http://processprivileges.codeplex.com/ + +namespace ProcessPrivileges +{ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Runtime.InteropServices; + using System.Text; + + internal static class Privileges + { + private const int PrivilegesCount = 35; + + private const string SeAssignPrimaryTokenPrivilege = "SeAssignPrimaryTokenPrivilege"; + private const string SeAuditPrivilege = "SeAuditPrivilege"; + private const string SeBackupPrivilege = "SeBackupPrivilege"; + private const string SeChangeNotifyPrivilege = "SeChangeNotifyPrivilege"; + private const string SeCreateGlobalPrivilege = "SeCreateGlobalPrivilege"; + private const string SeCreatePagefilePrivilege = "SeCreatePagefilePrivilege"; + private const string SeCreatePermanentPrivilege = "SeCreatePermanentPrivilege"; + private const string SeCreateSymbolicLinkPrivilege = "SeCreateSymbolicLinkPrivilege"; + private const string SeCreateTokenPrivilege = "SeCreateTokenPrivilege"; + private const string SeDebugPrivilege = "SeDebugPrivilege"; + private const string SeEnableDelegationPrivilege = "SeEnableDelegationPrivilege"; + private const string SeImpersonatePrivilege = "SeImpersonatePrivilege"; + private const string SeIncreaseBasePriorityPrivilege = "SeIncreaseBasePriorityPrivilege"; + private const string SeIncreaseQuotaPrivilege = "SeIncreaseQuotaPrivilege"; + private const string SeIncreaseWorkingSetPrivilege = "SeIncreaseWorkingSetPrivilege"; + private const string SeLoadDriverPrivilege = "SeLoadDriverPrivilege"; + private const string SeLockMemoryPrivilege = "SeLockMemoryPrivilege"; + private const string SeMachineAccountPrivilege = "SeMachineAccountPrivilege"; + private const string SeManageVolumePrivilege = "SeManageVolumePrivilege"; + private const string SeProfileSingleProcessPrivilege = "SeProfileSingleProcessPrivilege"; + private const string SeRelabelPrivilege = "SeRelabelPrivilege"; + private const string SeRemoteShutdownPrivilege = "SeRemoteShutdownPrivilege"; + private const string SeRestorePrivilege = "SeRestorePrivilege"; + private const string SeSecurityPrivilege = "SeSecurityPrivilege"; + private const string SeShutdownPrivilege = "SeShutdownPrivilege"; + private const string SeSyncAgentPrivilege = "SeSyncAgentPrivilege"; + private const string SeSystemEnvironmentPrivilege = "SeSystemEnvironmentPrivilege"; + private const string SeSystemProfilePrivilege = "SeSystemProfilePrivilege"; + private const string SeSystemTimePrivilege = "SeSystemtimePrivilege"; + private const string SeTakeOwnershipPrivilege = "SeTakeOwnershipPrivilege"; + private const string SeTcbPrivilege = "SeTcbPrivilege"; + private const string SeTimeZonePrivilege = "SeTimeZonePrivilege"; + private const string SeTrustedCredManAccessPrivilege = "SeTrustedCredManAccessPrivilege"; + private const string SeUndockPrivilege = "SeUndockPrivilege"; + private const string SeUnsolicitedInputPrivilege = "SeUnsolicitedInputPrivilege"; + + private static readonly Dictionary luidDictionary = + new Dictionary(PrivilegesCount); + + private static readonly Dictionary privilegeConstantsDictionary = + new Dictionary(PrivilegesCount) + { + { Privilege.AssignPrimaryToken, SeAssignPrimaryTokenPrivilege }, + { Privilege.Audit, SeAuditPrivilege }, + { Privilege.Backup, SeBackupPrivilege }, + { Privilege.ChangeNotify, SeChangeNotifyPrivilege }, + { Privilege.CreateGlobal, SeCreateGlobalPrivilege }, + { Privilege.CreatePageFile, SeCreatePagefilePrivilege }, + { Privilege.CreatePermanent, SeCreatePermanentPrivilege }, + { Privilege.CreateSymbolicLink, SeCreateSymbolicLinkPrivilege }, + { Privilege.CreateToken, SeCreateTokenPrivilege }, + { Privilege.Debug, SeDebugPrivilege }, + { Privilege.EnableDelegation, SeEnableDelegationPrivilege }, + { Privilege.Impersonate, SeImpersonatePrivilege }, + { Privilege.IncreaseBasePriority, SeIncreaseBasePriorityPrivilege }, + { Privilege.IncreaseQuota, SeIncreaseQuotaPrivilege }, + { Privilege.IncreaseWorkingSet, SeIncreaseWorkingSetPrivilege }, + { Privilege.LoadDriver, SeLoadDriverPrivilege }, + { Privilege.LockMemory, SeLockMemoryPrivilege }, + { Privilege.MachineAccount, SeMachineAccountPrivilege }, + { Privilege.ManageVolume, SeManageVolumePrivilege }, + { Privilege.ProfileSingleProcess, SeProfileSingleProcessPrivilege }, + { Privilege.Relabel, SeRelabelPrivilege }, + { Privilege.RemoteShutdown, SeRemoteShutdownPrivilege }, + { Privilege.Restore, SeRestorePrivilege }, + { Privilege.Security, SeSecurityPrivilege }, + { Privilege.Shutdown, SeShutdownPrivilege }, + { Privilege.SyncAgent, SeSyncAgentPrivilege }, + { Privilege.SystemEnvironment, SeSystemEnvironmentPrivilege }, + { Privilege.SystemProfile, SeSystemProfilePrivilege }, + { Privilege.SystemTime, SeSystemTimePrivilege }, + { Privilege.TakeOwnership, SeTakeOwnershipPrivilege }, + { Privilege.TrustedComputerBase, SeTcbPrivilege }, + { Privilege.TimeZone, SeTimeZonePrivilege }, + { Privilege.TrustedCredentialManagerAccess, SeTrustedCredManAccessPrivilege }, + { Privilege.Undock, SeUndockPrivilege }, + { Privilege.UnsolicitedInput, SeUnsolicitedInputPrivilege } + }; + + private static readonly Dictionary privilegesDictionary = + new Dictionary(PrivilegesCount) + { + { SeAssignPrimaryTokenPrivilege, Privilege.AssignPrimaryToken }, + { SeAuditPrivilege, Privilege.Audit }, + { SeBackupPrivilege, Privilege.Backup }, + { SeChangeNotifyPrivilege, Privilege.ChangeNotify }, + { SeCreateGlobalPrivilege, Privilege.CreateGlobal }, + { SeCreatePagefilePrivilege, Privilege.CreatePageFile }, + { SeCreatePermanentPrivilege, Privilege.CreatePermanent }, + { SeCreateSymbolicLinkPrivilege, Privilege.CreateSymbolicLink }, + { SeCreateTokenPrivilege, Privilege.CreateToken }, + { SeDebugPrivilege, Privilege.Debug }, + { SeEnableDelegationPrivilege, Privilege.EnableDelegation }, + { SeImpersonatePrivilege, Privilege.Impersonate }, + { SeIncreaseBasePriorityPrivilege, Privilege.IncreaseBasePriority }, + { SeIncreaseQuotaPrivilege, Privilege.IncreaseQuota }, + { SeIncreaseWorkingSetPrivilege, Privilege.IncreaseWorkingSet }, + { SeLoadDriverPrivilege, Privilege.LoadDriver }, + { SeLockMemoryPrivilege, Privilege.LockMemory }, + { SeMachineAccountPrivilege, Privilege.MachineAccount }, + { SeManageVolumePrivilege, Privilege.ManageVolume }, + { SeProfileSingleProcessPrivilege, Privilege.ProfileSingleProcess }, + { SeRelabelPrivilege, Privilege.Relabel }, + { SeRemoteShutdownPrivilege, Privilege.RemoteShutdown }, + { SeRestorePrivilege, Privilege.Restore }, + { SeSecurityPrivilege, Privilege.Security }, + { SeShutdownPrivilege, Privilege.Shutdown }, + { SeSyncAgentPrivilege, Privilege.SyncAgent }, + { SeSystemEnvironmentPrivilege, Privilege.SystemEnvironment }, + { SeSystemProfilePrivilege, Privilege.SystemProfile }, + { SeSystemTimePrivilege, Privilege.SystemTime }, + { SeTakeOwnershipPrivilege, Privilege.TakeOwnership }, + { SeTcbPrivilege, Privilege.TrustedComputerBase }, + { SeTimeZonePrivilege, Privilege.TimeZone }, + { SeTrustedCredManAccessPrivilege, Privilege.TrustedCredentialManagerAccess }, + { SeUndockPrivilege, Privilege.Undock }, + { SeUnsolicitedInputPrivilege, Privilege.UnsolicitedInput } + }; + + internal static AdjustPrivilegeResult DisablePrivilege(AccessTokenHandle accessTokenHandle, Privilege privilege) + { + return AdjustPrivilege(accessTokenHandle, privilege, PrivilegeAttributes.Disabled); + } + + internal static AdjustPrivilegeResult EnablePrivilege(AccessTokenHandle accessTokenHandle, Privilege privilege) + { + return AdjustPrivilege(accessTokenHandle, privilege, PrivilegeAttributes.Enabled); + } + + internal static AdjustPrivilegeResult RemovePrivilege(AccessTokenHandle accessTokenHandle, Privilege privilege) + { + return AdjustPrivilege(accessTokenHandle, privilege, PrivilegeAttributes.Removed); + } + + internal static PrivilegeAttributes GetPrivilegeAttributes(Privilege privilege, PrivilegeAndAttributesCollection privileges) + { + foreach (PrivilegeAndAttributes privilegeAndAttributes in privileges) + { + if (privilegeAndAttributes.Privilege == privilege) + { + return privilegeAndAttributes.PrivilegeAttributes; + } + } + + GetLuid(privilege); + + return PrivilegeAttributes.Removed; + } + + internal static PrivilegeAndAttributesCollection GetPrivileges(AccessTokenHandle accessTokenHandle) + { + LuidAndAttributes[] luidAndAttributesArray = GetTokenPrivileges(accessTokenHandle); + int length = luidAndAttributesArray.Length; + List privilegeAndAttributes = new List(length); + for (int i = 0; i < length; i++) + { + LuidAndAttributes luidAndAttributes = luidAndAttributesArray[i]; + string name = GetPrivilegeName(luidAndAttributes.Luid); + if (privilegesDictionary.ContainsKey(name)) + { + privilegeAndAttributes.Add(new PrivilegeAndAttributes( + privilegesDictionary[name], + luidAndAttributes.Attributes)); + } + } + + return new PrivilegeAndAttributesCollection(privilegeAndAttributes); + } + + private static AdjustPrivilegeResult AdjustPrivilege( + AccessTokenHandle accessTokenHandle, + Luid luid, + PrivilegeAttributes privilegeAttributes) + { + TokenPrivilege newState = new TokenPrivilege + { + PrivilegeCount = 1, + Privilege = new LuidAndAttributes + { + Attributes = privilegeAttributes, + Luid = luid + } + }; + TokenPrivilege previousState = new TokenPrivilege(); + int returnLength = 0; + + if (!NativeMethods.AdjustTokenPrivileges( + accessTokenHandle, + false, + ref newState, + Marshal.SizeOf(previousState), + ref previousState, + ref returnLength)) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + return (AdjustPrivilegeResult)previousState.PrivilegeCount; + } + + private static AdjustPrivilegeResult AdjustPrivilege( + AccessTokenHandle accessTokenHandle, + Privilege privilege, + PrivilegeAttributes privilegeAttributes) + { + return AdjustPrivilege(accessTokenHandle, GetLuid(privilege), privilegeAttributes); + } + + private static Luid GetLuid(Privilege privilege) + { + if (luidDictionary.ContainsKey(privilege)) + { + return luidDictionary[privilege]; + } + + Luid luid = new Luid(); + if (!NativeMethods.LookupPrivilegeValue(String.Empty, privilegeConstantsDictionary[privilege], ref luid)) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + luidDictionary.Add(privilege, luid); + return luid; + } + + private static string GetPrivilegeName(Luid luid) + { + StringBuilder nameBuilder = new StringBuilder(); + int nameLength = 0; + if (NativeMethods.LookupPrivilegeName(String.Empty, ref luid, nameBuilder, ref nameLength)) + { + return String.Empty; + } + + int lastWin32Error = Marshal.GetLastWin32Error(); + if (lastWin32Error != NativeMethods.ErrorInsufficientBuffer) + { + throw new Win32Exception(lastWin32Error); + } + + nameBuilder.EnsureCapacity(nameLength); + if (!NativeMethods.LookupPrivilegeName(String.Empty, ref luid, nameBuilder, ref nameLength)) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + return nameBuilder.ToString(); + } + + private static LuidAndAttributes[] GetTokenPrivileges(AccessTokenHandle accessTokenHandle) + { + int tokenInformationLength = 0; + int returnLength = 0; + if (NativeMethods.GetTokenInformation( + accessTokenHandle, + TokenInformationClass.TokenPrivileges, + IntPtr.Zero, + tokenInformationLength, + ref returnLength)) + { + return new LuidAndAttributes[0]; + } + + int lastWin32Error = Marshal.GetLastWin32Error(); + if (lastWin32Error != NativeMethods.ErrorInsufficientBuffer) + { + throw new Win32Exception(lastWin32Error); + } + + tokenInformationLength = returnLength; + returnLength = 0; + + using (AllocatedMemory allocatedMemory = new AllocatedMemory(tokenInformationLength)) + { + if (!NativeMethods.GetTokenInformation( + accessTokenHandle, + TokenInformationClass.TokenPrivileges, + allocatedMemory.Pointer, + tokenInformationLength, + ref returnLength)) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + int privilegeCount = Marshal.ReadInt32(allocatedMemory.Pointer); + LuidAndAttributes[] luidAndAttributes = new LuidAndAttributes[privilegeCount]; + long pointer = allocatedMemory.Pointer.ToInt64() + Marshal.SizeOf(privilegeCount); + Type type = typeof(LuidAndAttributes); + long size = Marshal.SizeOf(type); + for (int i = 0; i < privilegeCount; i++) + { + luidAndAttributes[i] = (LuidAndAttributes)Marshal.PtrToStructure(new IntPtr(pointer), type); + pointer += size; + } + + return luidAndAttributes; + } + } + } +} \ No newline at end of file diff --git a/ProcessPrivileges/ProcessExtensions.cs b/ProcessPrivileges/ProcessExtensions.cs new file mode 100644 index 0000000..5210580 --- /dev/null +++ b/ProcessPrivileges/ProcessExtensions.cs @@ -0,0 +1,423 @@ +// +// Copyright © Nick Lowe 2009 +// +// Nick Lowe +// nick@int-r.net +// http://processprivileges.codeplex.com/ + +namespace ProcessPrivileges +{ + using System.Diagnostics; + using System.Runtime.CompilerServices; + using System.Security.Permissions; + + /// Provides extension methods to the class, implementing the functionality necessary to query, enable, disable or remove privileges on a process. + /// + /// + /// using System; + /// using System.Diagnostics; + /// using System.Linq; + /// using ProcessPrivileges; + /// + /// internal static class ProcessPrivilegesExample + /// { + /// public static void Main() + /// { + /// // Get the current process. + /// Process process = Process.GetCurrentProcess(); + /// + /// // Get the privileges and associated attributes. + /// PrivilegeAndAttributesCollection privileges = process.GetPrivileges(); + /// + /// int maxPrivilegeLength = privileges.Max(privilege => privilege.Privilege.ToString().Length); + /// + /// foreach (PrivilegeAndAttributes privilegeAndAttributes in privileges) + /// { + /// // The privilege. + /// Privilege privilege = privilegeAndAttributes.Privilege; + /// + /// // The privilege state. + /// PrivilegeState privilegeState = privilegeAndAttributes.PrivilegeState; + /// + /// // Write out the privilege and its state. + /// Console.WriteLine( + /// "{0}{1} => {2}", + /// privilege, + /// GetPadding(privilege.ToString().Length, maxPrivilegeLength), + /// privilegeState); + /// } + /// + /// Console.WriteLine(); + /// + /// // Privileges can only be enabled on a process if they are disabled. + /// if (process.GetPrivilegeState(Privilege.TakeOwnership) == PrivilegeState.Disabled) + /// { + /// // Enable the TakeOwnership privilege on it. + /// AdjustPrivilegeResult result = process.EnablePrivilege(Privilege.TakeOwnership); + /// + /// // Get the state of the TakeOwnership privilege. + /// PrivilegeState takeOwnershipState = process.GetPrivilegeState(Privilege.TakeOwnership); + /// + /// // Write out the TakeOwnership privilege, its state and the result. + /// Console.WriteLine( + /// "{0}{1} => {2} ({3})", + /// Privilege.TakeOwnership, + /// GetPadding(Privilege.TakeOwnership.ToString().Length, maxPrivilegeLength), + /// takeOwnershipState, + /// result); + /// } + /// } + /// + /// private static string GetPadding(int length, int maxLength) + /// { + /// int paddingLength = maxLength - length; + /// char[] padding = new char[paddingLength]; + /// for (int i = 0; i < paddingLength; i++) + /// { + /// padding[i] = ' '; + /// } + /// + /// return new string(padding); + /// } + /// } + /// + /// + /// using System; + /// using System.Diagnostics; + /// using ProcessPrivileges; + /// + /// internal static class ReusingAccessTokenHandleExample + /// { + /// public static void Main() + /// { + /// // Access token handle reused within the using block. + /// using (AccessTokenHandle accessTokenHandle = + /// Process.GetCurrentProcess().GetAccessTokenHandle( + /// TokenAccessRights.AdjustPrivileges | TokenAccessRights.Query)) + /// { + /// // Enable privileges using the same access token handle. + /// AdjustPrivilegeResult backupResult = accessTokenHandle.EnablePrivilege(Privilege.Backup); + /// AdjustPrivilegeResult restoreResult = accessTokenHandle.EnablePrivilege(Privilege.Restore); + /// + /// Console.WriteLine( + /// "{0} => {1} ({2})", + /// Privilege.Backup, + /// accessTokenHandle.GetPrivilegeState(Privilege.Backup), + /// backupResult); + /// + /// Console.WriteLine( + /// "{0} => {1} ({2})", + /// Privilege.Restore, + /// accessTokenHandle.GetPrivilegeState(Privilege.Restore), + /// restoreResult); + /// } + /// } + /// } + /// + /// + /// + /// For more information on privileges, see: + /// Privileges + /// Privilege Constants + /// + public static class ProcessExtensions + { + /// Disables the specified on a . + /// The for a on which the operation should be performed. + /// The to be disabled. + /// + /// Result from the privilege adjustment. + /// If the is already disabled, is returned. + /// + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + /// The caller must have permission to query and adjust token privileges on the target process. + [MethodImpl(MethodImplOptions.Synchronized), + PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public static AdjustPrivilegeResult DisablePrivilege(this AccessTokenHandle accessTokenHandle, Privilege privilege) + { + return Privileges.DisablePrivilege(accessTokenHandle, privilege); + } + + /// Disables the specified on a . + /// The on which the operation should be performed. + /// The to be disabled. + /// + /// Result from the privilege adjustment. + /// If the is already disabled, is returned. + /// + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + /// + /// If you are adjusting multiple privileges on a process, consider using with an access token handle for the process. + /// The caller must have permission to query and adjust token privileges on the target process. + /// + [MethodImpl(MethodImplOptions.Synchronized), + PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public static AdjustPrivilegeResult DisablePrivilege(this Process process, Privilege privilege) + { + using (AccessTokenHandle accessTokenHandle = new AccessTokenHandle( + new ProcessHandle(process.Handle, false), + TokenAccessRights.AdjustPrivileges | TokenAccessRights.Query)) + { + return DisablePrivilege(accessTokenHandle, privilege); + } + } + + /// Enables the specified on a . + /// The for a on which the operation should be performed. + /// The to be enabled. + /// + /// Result from the privilege adjustment. + /// If the is already enabled, is returned. + /// + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + /// + /// Enabling a privilege allows a process to perform system-level actions that it could not previously. + /// Before enabling a privilege, many potentially dangerous, thoroughly verify that functions or operations in your code actually require them. + /// It is not normally appropriate to hold privileges for the lifetime of a process. Use sparingly; enable when needed, disable when not. + /// Consider using that enables privileges on a process in a safe way, ensuring that they are returned to their original state when an operation that requires a privilege completes. + /// The caller must have permission to query and adjust token privileges on the target process. + /// + [MethodImpl(MethodImplOptions.Synchronized), + PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public static AdjustPrivilegeResult EnablePrivilege(this AccessTokenHandle accessTokenHandle, Privilege privilege) + { + return Privileges.EnablePrivilege(accessTokenHandle, privilege); + } + + /// Enables the specified on a . + /// The on which the operation should be performed. + /// The to be enabled. + /// + /// Result from the privilege adjustment. + /// If the is already enabled, is returned. + /// If a is removed from a process, it cannot be enabled. + /// + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + /// + /// Enabling a privilege allows a process to perform system-level actions that it could not previously. + /// Before enabling a privilege, many potentially dangerous, thoroughly verify that functions or operations in your code actually require them. + /// It is not normally appropriate to hold privileges for the lifetime of a process. Use sparingly; enable when needed, disable when not. + /// Consider using that enables privileges on a process in a safe way, ensuring that they are returned to their original state when an operation that requires a privilege completes. + /// If you are adjusting multiple privileges on a process, consider using with an access token handle for the process. + /// The caller must have permission to query and adjust token privileges on the target process. + /// + [MethodImpl(MethodImplOptions.Synchronized), + PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public static AdjustPrivilegeResult EnablePrivilege(this Process process, Privilege privilege) + { + using (AccessTokenHandle accessTokenHandle = new AccessTokenHandle( + new ProcessHandle(process.Handle, false), + TokenAccessRights.AdjustPrivileges | TokenAccessRights.Query)) + { + return EnablePrivilege(accessTokenHandle, privilege); + } + } + + /// Gets an access token handle for a . + /// The on which an access token handle should be retrieved. + /// An access token handle for a with access rights. + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + /// + /// The caller must have permission to acquire an access token handle with all access rights. + /// + [MethodImpl(MethodImplOptions.Synchronized), + PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public static AccessTokenHandle GetAccessTokenHandle(this Process process) + { + return GetAccessTokenHandle(process, TokenAccessRights.AllAccess); + } + + /// Gets an access token handle for a . + /// The on which an access token handle should be retrieved. + /// The desired access rights for the access token handle. + /// An access token handle for a . + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + /// + /// The caller must have permission to acquire an access token handle with the desired access rights. + /// To query permissions, the access token handle must have permission to query and adjust token privileges: + /// TokenAccessRights.Query + /// To enable, disable or remove a permission, the access token handle must have permission to query and adjust token privileges: + /// TokenAccessRights.AdjustPrivileges | TokenAccessRights.Query + /// + [MethodImpl(MethodImplOptions.Synchronized), + PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public static AccessTokenHandle GetAccessTokenHandle(this Process process, TokenAccessRights tokenAccessRights) + { + return new AccessTokenHandle(new ProcessHandle(process.Handle, false), tokenAccessRights); + } + + /// Gets the attributes for a on a . + /// The for a on which the operation should be performed. + /// The on which the attributes should be retrieved. + /// The for a on a . + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + /// + /// Consider using as it avoids the need to work with a flags based enumerated type. + /// The caller must have permission to query token privileges on the target process. + /// + [MethodImpl(MethodImplOptions.Synchronized), + PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public static PrivilegeAttributes GetPrivilegeAttributes(this AccessTokenHandle accessTokenHandle, Privilege privilege) + { + return Privileges.GetPrivilegeAttributes(privilege, GetPrivileges(accessTokenHandle)); + } + + /// Gets the attributes for a on a . + /// The on which the operation should be performed. + /// The on which the attributes should be retrieved. + /// The for a on a . + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + /// + /// Consider using as it avoids the need to work with a flags based enumerated type. + /// The caller must have permission to query token privileges on the target process. + /// + [MethodImpl(MethodImplOptions.Synchronized), + PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public static PrivilegeAttributes GetPrivilegeAttributes(this Process process, Privilege privilege) + { + return Privileges.GetPrivilegeAttributes(privilege, GetPrivileges(process)); + } + + /// Gets the privileges and associated attributes from a . + /// The for a on which the operation should be performed. + /// The privileges associated with a process. + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + /// + /// Consider using on attributes within the collection as it avoids the need to work with a flags based enumerated type. + /// The caller must have permission to query token privileges on the target process. + /// + [MethodImpl(MethodImplOptions.Synchronized), + PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public static PrivilegeAndAttributesCollection GetPrivileges(this AccessTokenHandle accessTokenHandle) + { + return Privileges.GetPrivileges(accessTokenHandle); + } + + /// Gets the privileges and associated attributes from a . + /// The on which the operation should be performed. + /// The privileges associated with a process. + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + /// + /// Consider using method on attributes within the collection as it avoids the need to work with a flags based enumerated type. + /// The caller must have permission to query token privileges on the target process. + /// + [MethodImpl(MethodImplOptions.Synchronized), + PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public static PrivilegeAndAttributesCollection GetPrivileges(this Process process) + { + using (AccessTokenHandle accessTokenHandle = new AccessTokenHandle( + new ProcessHandle(process.Handle, false), + TokenAccessRights.Query)) + { + return Privileges.GetPrivileges(accessTokenHandle); + } + } + + /// Gets the state of a . + /// The for a on which the operation should be performed. + /// The that should be checked. + /// The of the . + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + /// + /// Derives to establish the of a . + /// The caller must have permission to query token privileges on the target process. + /// + [MethodImpl(MethodImplOptions.Synchronized), + PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public static PrivilegeState GetPrivilegeState(this AccessTokenHandle accessTokenHandle, Privilege privilege) + { + return GetPrivilegeState(GetPrivilegeAttributes(accessTokenHandle, privilege)); + } + + /// Gets the state of a . + /// The on which the operation should be performed. + /// The that should be checked. + /// The of the . + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + /// + /// Derives to establish the of a . + /// The caller must have permission to query token privileges on the target process. + /// + [MethodImpl(MethodImplOptions.Synchronized), + PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public static PrivilegeState GetPrivilegeState(this Process process, Privilege privilege) + { + return GetPrivilegeState(GetPrivilegeAttributes(process, privilege)); + } + + /// Gets the state of a . + /// The privilege attributes. + /// The of the . + /// Thrown when an underlying Win32 function call does not succeed. + /// Derives to establish the of a . + [MethodImpl(MethodImplOptions.Synchronized)] + public static PrivilegeState GetPrivilegeState(PrivilegeAttributes privilegeAttributes) + { + if ((privilegeAttributes & PrivilegeAttributes.Enabled) == PrivilegeAttributes.Enabled) + { + return PrivilegeState.Enabled; + } + + if ((privilegeAttributes & PrivilegeAttributes.Removed) == PrivilegeAttributes.Removed) + { + return PrivilegeState.Removed; + } + + return PrivilegeState.Disabled; + } + + /// Removes the specified from a . + /// The for a on which the operation should be performed. + /// The to be removed. + /// + /// Result from the privilege adjustment. + /// Once a privilege has been removed from a process, it cannot be restored afterwards. + /// + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + /// The caller must have permission to query and adjust token privileges on the target process. + [MethodImpl(MethodImplOptions.Synchronized), + PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public static AdjustPrivilegeResult RemovePrivilege(this AccessTokenHandle accessTokenHandle, Privilege privilege) + { + return Privileges.RemovePrivilege(accessTokenHandle, privilege); + } + + /// Removes the specified from a . + /// The on which the operation should be performed. + /// The to be removed. + /// + /// Result from the privilege adjustment. + /// Once a privilege has been removed from a process, it cannot be restored afterwards. + /// + /// Thrown when an underlying Win32 function call does not succeed. + /// Requires the immediate caller to have FullTrust. + /// + /// If you are adjusting multiple privileges on a process, consider using with an access token handle for the process. + /// The caller must have permission to query and adjust token privileges on the target process. + /// + [MethodImpl(MethodImplOptions.Synchronized), + PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] + public static AdjustPrivilegeResult RemovePrivilege(this Process process, Privilege privilege) + { + using (AccessTokenHandle accessTokenHandle = new AccessTokenHandle( + new ProcessHandle(process.Handle, false), + TokenAccessRights.AdjustPrivileges | TokenAccessRights.Query)) + { + return RemovePrivilege(accessTokenHandle, privilege); + } + } + } +} \ No newline at end of file diff --git a/ProcessPrivileges/ProcessHandle.cs b/ProcessPrivileges/ProcessHandle.cs new file mode 100644 index 0000000..639ee35 --- /dev/null +++ b/ProcessPrivileges/ProcessHandle.cs @@ -0,0 +1,35 @@ +// +// Copyright © Nick Lowe 2009 +// +// Nick Lowe +// nick@int-r.net +// http://processprivileges.codeplex.com/ + +namespace ProcessPrivileges +{ + using System; + using System.ComponentModel; + using System.Runtime.ConstrainedExecution; + using System.Runtime.InteropServices; + using Microsoft.Win32.SafeHandles; + + internal sealed class ProcessHandle : SafeHandleZeroOrMinusOneIsInvalid + { + internal ProcessHandle(IntPtr processHandle, bool ownsHandle) + : base(ownsHandle) + { + handle = processHandle; + } + + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + protected override bool ReleaseHandle() + { + if (!NativeMethods.CloseHandle(handle)) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + return true; + } + } +} \ No newline at end of file diff --git a/ProcessPrivileges/ProcessPrivileges.csproj b/ProcessPrivileges/ProcessPrivileges.csproj new file mode 100644 index 0000000..945192e --- /dev/null +++ b/ProcessPrivileges/ProcessPrivileges.csproj @@ -0,0 +1,79 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {410CAEE5-D287-4A18-9B38-BB87397D218D} + Library + Properties + ProcessPrivileges + ProcessPrivileges + v3.5 + 512 + false + + + + + 3.5 + + SAK + SAK + SAK + SAK + Client + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + bin\Release\ProcessPrivileges.XML + true + AllRules.ruleset + + + + + 3.5 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ProcessPrivileges/Properties/AssemblyInfo.cs b/ProcessPrivileges/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..92f6777 --- /dev/null +++ b/ProcessPrivileges/Properties/AssemblyInfo.cs @@ -0,0 +1,45 @@ +// +// Copyright © Nick Lowe 2009 +// +// Nick Lowe +// nick@int-r.net +// http://processprivileges.codeplex.com/ + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Process Privileges")] +[assembly: AssemblyDescription("Implements the functionality necessary to query, enable, disable or remove privileges on a process.")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Process Privileges")] +[assembly: AssemblyCopyright("Copyright © Nick Lowe 2009")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("9ba57646-7a83-4f21-b555-92f1463c9f3e")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.5.7.0")] +[assembly: AssemblyFileVersion("1.5.7.0")] + +[assembly: System.CLSCompliant(true)] diff --git a/Security2/EffectiveAccess.cs b/Security2/EffectiveAccess.cs new file mode 100644 index 0000000..9527b2c --- /dev/null +++ b/Security2/EffectiveAccess.cs @@ -0,0 +1,66 @@ +using Alphaleonis.Win32.Filesystem; +using System; +using System.Security.AccessControl; +using System.Security.Principal; + +namespace Security2 +{ + public class EffectiveAccess + { + public static EffectiveAccessInfo GetEffectiveAccess(FileSystemInfo item, IdentityReference2 id, string serverName) + { + bool remoteServerAvailable = false; + Exception authzAccessCheckException = null; + + var win32 = new Win32(); + + var fss = new FileSystemSecurity2(item); + + var effectiveAccessMask = win32.GetEffectiveAccess(fss.SecurityDescriptor, id, serverName, out remoteServerAvailable, out authzAccessCheckException); + + var ace = new FileSystemAccessRule((SecurityIdentifier)id, (FileSystemRights)effectiveAccessMask, AccessControlType.Allow); + + return new EffectiveAccessInfo( + new FileSystemAccessRule2(ace, item), + remoteServerAvailable, + authzAccessCheckException); + } + } + + public class EffectiveAccessInfo + { + private FileSystemAccessRule2 ace; + private bool fromRemote; + private Exception authzException; + + public FileSystemAccessRule2 Ace + { + get { return ace; } + } + + public bool FromRemote + { + get { return fromRemote; } + } + + public Exception AuthzException + { + get { return authzException; } + } + + public bool OperationFailed + { + get + { + return authzException == null ? false : true; + } + } + + public EffectiveAccessInfo(FileSystemAccessRule2 ace, bool fromRemote, Exception authzException = null) + { + this.ace = ace; + this.fromRemote = fromRemote; + this.authzException = authzException; + } + } +} \ No newline at end of file diff --git a/Security2/Enums.cs b/Security2/Enums.cs new file mode 100644 index 0000000..a4f7e3a --- /dev/null +++ b/Security2/Enums.cs @@ -0,0 +1,82 @@ +using System; +using System.Security.AccessControl; + +namespace Security2 +{ + public enum ApplyTo + { + ThisFolderOnly, //InheritanceFlags None / PropagationFlags None + + ThisFolderSubfoldersAndFiles, //InheritanceFlags ContainerInherit, ObjectInherit / PropagationFlags None + ThisFolderAndSubfolders, //InheritanceFlags ContainerInherit / PropagationFlags None + ThisFolderAndFiles, //InheritanceFlags ObjectInherit / PropagationFlags None + SubfoldersAndFilesOnly, //InheritanceFlags ContainerInherit, ObjectInherit / PropagationFlags InheritOnly + SubfoldersOnly, //InheritanceFlags ContainerInherit / PropagationFlags InheritOnly + FilesOnly, //InheritanceFlags ObjectInherit / PropagationFlags InheritOnly + + ThisFolderSubfoldersAndFilesOneLevel, //InheritanceFlags ContainerInherit, ObjectInherit / PropagationFlags NoPropagateInherit + ThisFolderAndSubfoldersOneLevel, //InheritanceFlags ContainerInherit / PropagationFlags NoPropagateInherit + ThisFolderAndFilesOneLevel, //InheritanceFlags ObjectInherit / PropagationFlags NoPropagateInherit + SubfoldersAndFilesOnlyOneLevel, //InheritanceFlags ContainerInherit, ObjectInherit / PropagationFlags InheritOnly, NoPropagateInherit + SubfoldersOnlyOneLevel, //InheritanceFlags ContainerInherit / PropagationFlags InheritOnly, NoPropagateInherit + FilesOnlyOneLevel, //InheritanceFlags ObjectInherit / PropagationFlags InheritOnly, NoPropagateInherit + } + + [Flags] + public enum FileSystemRights2 : uint + { + None = 0, + ListDirectory = 1, + ReadData = 1, + WriteData = 2, + CreateFiles = 2, + CreateDirectories = 4, + AppendData = 4, + ReadExtendedAttributes = 8, + WriteExtendedAttributes = 16, + ExecuteFile = 32, + Traverse = 32, + DeleteSubdirectoriesAndFiles = 64, + ReadAttributes = 128, + WriteAttributes = 256, + Write = 278, + Delete = 65536, + ReadPermissions = 131072, + Read = 131209, + ReadAndExecute = 131241, + Modify = 197055, + ChangePermissions = 262144, + TakeOwnership = 524288, + Synchronize = 1048576, + FullControl = 2032127, + GenericRead = 0x80000000, + GenericWrite = 0x40000000, + GenericExecute = 0x20000000, + GenericAll = 0x10000000 + } + + [Flags] + public enum SimpleFileSystemAccessRights + { + None = 0, + Read = 1, + Write = 2, + Delete = 4 + } + + public enum GenericRights : uint + { + GENERIC_READ = 0x80000000, + GENERIC_WRITE = 0x40000000, + GENERIC_EXECUTE = 0x20000000, + GENERIC_ALL = 0x10000000 + } + + public enum MappedGenericRights : uint + { + FILE_GENERIC_EXECUTE = FileSystemRights.ExecuteFile | FileSystemRights.ReadPermissions | FileSystemRights.ReadAttributes | FileSystemRights.Synchronize, + FILE_GENERIC_READ = FileSystemRights.ReadAttributes | FileSystemRights.ReadData | FileSystemRights.ReadExtendedAttributes | FileSystemRights.ReadPermissions | FileSystemRights.Synchronize, + FILE_GENERIC_WRITE = FileSystemRights.AppendData | FileSystemRights.WriteAttributes | FileSystemRights.WriteData | FileSystemRights.WriteExtendedAttributes | FileSystemRights.ReadPermissions | FileSystemRights.Synchronize, + FILE_GENERIC_ALL = FileSystemRights.FullControl + } +} \ No newline at end of file diff --git a/Security2/Exceptions/Exceptions.cs b/Security2/Exceptions/Exceptions.cs new file mode 100644 index 0000000..ebd7fe8 --- /dev/null +++ b/Security2/Exceptions/Exceptions.cs @@ -0,0 +1,9 @@ +using System; + +namespace Security2 +{ + public class RightsConverionException : Exception + { + public RightsConverionException(string Message) : base(Message) { } + } +} diff --git a/Security2/Extensions.cs b/Security2/Extensions.cs new file mode 100644 index 0000000..cffc62d --- /dev/null +++ b/Security2/Extensions.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.InteropServices; + +namespace Security2 +{ + internal static class IntPtrExtensions + { + public static IntPtr Increment(this IntPtr ptr, int cbSize) + { + return new IntPtr(ptr.ToInt64() + cbSize); + } + + public static IntPtr Increment(this IntPtr ptr) + { + return ptr.Increment(Marshal.SizeOf(typeof(T))); + } + + public static T ElementAt(this IntPtr ptr, int index) + { + var offset = Marshal.SizeOf(typeof(T)) * index; + var offsetPtr = ptr.Increment(offset); + return (T)Marshal.PtrToStructure(offsetPtr, typeof(T)); + } + } +} diff --git a/Security2/FileSystem/FileInfo/Extensions.cs b/Security2/FileSystem/FileInfo/Extensions.cs new file mode 100644 index 0000000..5a3483d --- /dev/null +++ b/Security2/FileSystem/FileInfo/Extensions.cs @@ -0,0 +1,62 @@ +using System.Text; + +namespace Security2.FileSystem.FileInfo +{ + public enum HashAlgorithms + { + SHA1, + SHA256, + SHA384, + SHA512, + MACTripleDES, + MD5, + RIPEMD160 + } + + public static class Extensions + { + + public static string GetHash(this Alphaleonis.Win32.Filesystem.FileInfo file, HashAlgorithms algorithm) + { + byte[] hash = null; + + using (var fileStream = file.OpenRead()) + { + switch (algorithm) + { + case HashAlgorithms.MD5: + hash = System.Security.Cryptography.MD5.Create().ComputeHash(fileStream); + break; + case HashAlgorithms.SHA1: + hash = System.Security.Cryptography.SHA1.Create().ComputeHash(fileStream); + break; + case HashAlgorithms.SHA256: + hash = System.Security.Cryptography.SHA256.Create().ComputeHash(fileStream); + break; + case HashAlgorithms.SHA384: + hash = System.Security.Cryptography.SHA384.Create().ComputeHash(fileStream); + break; + case HashAlgorithms.SHA512: + hash = System.Security.Cryptography.SHA512.Create().ComputeHash(fileStream); + break; + case HashAlgorithms.MACTripleDES: + hash = System.Security.Cryptography.MACTripleDES.Create().ComputeHash(fileStream); + break; + case HashAlgorithms.RIPEMD160: + hash = System.Security.Cryptography.RIPEMD160.Create().ComputeHash(fileStream); + break; + } + + fileStream.Close(); + } + + var sb = new StringBuilder(hash.Length); + for (var i = 0; i < hash.Length; i++) + { + sb.Append(hash[i].ToString("X2")); + } + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Security2/FileSystem/FileSystemAccessRule2 Class/FileSystemAccessRule2.AddFileSystemAccessRules.cs b/Security2/FileSystem/FileSystemAccessRule2 Class/FileSystemAccessRule2.AddFileSystemAccessRules.cs new file mode 100644 index 0000000..7a39392 --- /dev/null +++ b/Security2/FileSystem/FileSystemAccessRule2 Class/FileSystemAccessRule2.AddFileSystemAccessRules.cs @@ -0,0 +1,122 @@ +using Alphaleonis.Win32.Filesystem; +using System.Collections.Generic; +using System.Security.AccessControl; + +namespace Security2 +{ + public partial class FileSystemAccessRule2 + { + public static FileSystemAccessRule2 AddFileSystemAccessRule(FileSystemSecurity2 sd, IdentityReference2 account, FileSystemRights2 rights, AccessControlType type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags) + { + if (type == AccessControlType.Allow) + rights = rights | FileSystemRights2.Synchronize; + + FileSystemAccessRule ace = null; + + if (sd.IsFile) + { + ace = (FileSystemAccessRule)sd.SecurityDescriptor.AccessRuleFactory(account, (int)rights, false, InheritanceFlags.None, PropagationFlags.None, type); + ((FileSecurity)sd.SecurityDescriptor).AddAccessRule(ace); + } + else + { + ace = (FileSystemAccessRule)sd.SecurityDescriptor.AccessRuleFactory(account, (int)rights, false, inheritanceFlags, propagationFlags, type); + ((DirectorySecurity)sd.SecurityDescriptor).AddAccessRule(ace); + } + + return ace; + } + + public static FileSystemAccessRule2 AddFileSystemAccessRule(FileSystemInfo item, IdentityReference2 account, FileSystemRights2 rights, AccessControlType type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags) + { + if (type == AccessControlType.Allow) + rights = rights | FileSystemRights2.Synchronize; + + var sd = new FileSystemSecurity2(item); + + var ace = AddFileSystemAccessRule(sd, account, rights, type, inheritanceFlags, propagationFlags); + + sd.Write(); + + return ace; + } + + public static IEnumerable AddFileSystemAccessRule(FileSystemInfo item, List accounts, FileSystemRights2 rights, AccessControlType type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags) + { + var aces = new List(); + + foreach (var account in accounts) + { + aces.Add(AddFileSystemAccessRule(item, account, rights, type, inheritanceFlags, propagationFlags)); + } + + return aces; + } + + public static IEnumerable AddFileSystemAccessRule(FileSystemSecurity2 sd, List accounts, FileSystemRights2 rights, AccessControlType type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags) + { + var aces = new List(); + + foreach (var account in accounts) + { + aces.Add(AddFileSystemAccessRule(sd, account, rights, type, inheritanceFlags, propagationFlags)); + } + + return aces; + } + + public static FileSystemAccessRule2 AddFileSystemAccessRule(string path, IdentityReference2 account, FileSystemRights2 rights, AccessControlType type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags) + { + if (type == AccessControlType.Allow) + rights = rights | FileSystemRights2.Synchronize; + + FileSystemAccessRule ace = null; + + if (File.Exists(path)) + { + var item = new FileInfo(path); + ace = AddFileSystemAccessRule(item, account, rights, type, inheritanceFlags, propagationFlags); + } + else + { + var item = new DirectoryInfo(path); + ace = AddFileSystemAccessRule(item, account, rights, type, inheritanceFlags, propagationFlags); + } + + return ace; + } + + public static IEnumerable AddFileSystemAccessRule(string path, List accounts, FileSystemRights2 rights, AccessControlType type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags) + { + if (type == AccessControlType.Allow) + rights = rights | FileSystemRights2.Synchronize; + + if (File.Exists(path)) + { + var item = new FileInfo(path); + foreach (var account in accounts) + { + yield return AddFileSystemAccessRule(item, account, rights, type, inheritanceFlags, propagationFlags); + } + } + else + { + var item = new DirectoryInfo(path); + foreach (var account in accounts) + { + yield return AddFileSystemAccessRule(item, account, rights, type, inheritanceFlags, propagationFlags); + } + } + } + + public static void AddFileSystemAccessRule(FileSystemAccessRule2 rule) + { + AddFileSystemAccessRule(rule.fullName, + rule.Account, + rule.AccessRights, + rule.AccessControlType, + rule.InheritanceFlags, + rule.PropagationFlags); + } + } +} \ No newline at end of file diff --git a/Security2/FileSystem/FileSystemAccessRule2 Class/FileSystemAccessRule2.GetFileSystemAccessRules.cs b/Security2/FileSystem/FileSystemAccessRule2 Class/FileSystemAccessRule2.GetFileSystemAccessRules.cs new file mode 100644 index 0000000..35f3bec --- /dev/null +++ b/Security2/FileSystem/FileSystemAccessRule2 Class/FileSystemAccessRule2.GetFileSystemAccessRules.cs @@ -0,0 +1,59 @@ +using Alphaleonis.Win32.Filesystem; +using System.Collections.Generic; +using System.Security.AccessControl; +using System.Security.Principal; + +namespace Security2 +{ + public partial class FileSystemAccessRule2 + { + public static IEnumerable GetFileSystemAccessRules(FileSystemInfo item, bool includeExplicit, bool includeInherited, bool getInheritedFrom = false) + { + var sd = new FileSystemSecurity2(item, AccessControlSections.Access); + + return GetFileSystemAccessRules(sd, includeExplicit, includeInherited, getInheritedFrom); + } + + public static IEnumerable GetFileSystemAccessRules(FileSystemSecurity2 sd, bool includeExplicit, bool includeInherited, bool getInheritedFrom = false) + { + List aceList = new List(); + List inheritedFrom = null; + + if (getInheritedFrom) + { + inheritedFrom = Win32.GetInheritedFrom(sd.Item, sd.SecurityDescriptor); + } + + var aceCounter = 0; + var acl = !sd.IsFile ? + ((DirectorySecurity)sd.SecurityDescriptor).GetAccessRules(includeExplicit, includeInherited, typeof(SecurityIdentifier)) : + ((FileSecurity)sd.SecurityDescriptor).GetAccessRules(includeExplicit, includeInherited, typeof(SecurityIdentifier)); + + foreach (FileSystemAccessRule ace in acl) + { + var ace2 = new FileSystemAccessRule2(ace) { FullName = sd.Item.FullName, InheritanceEnabled = !sd.SecurityDescriptor.AreAccessRulesProtected }; + if (getInheritedFrom && inheritedFrom.Count > 0) + { + ace2.inheritedFrom = string.IsNullOrEmpty(inheritedFrom[aceCounter]) ? "" : inheritedFrom[aceCounter].Substring(0, inheritedFrom[aceCounter].Length - 1); + aceCounter++; + } + + aceList.Add(ace2); + } + + return aceList; + } + + public static IEnumerable GetFileSystemAccessRules(string path, bool includeExplicit, bool includeInherited, bool getInheritedFrom = false) + { + if (File.Exists(path)) + { + return GetFileSystemAccessRules(new FileInfo(path), includeExplicit, includeInherited, getInheritedFrom); + } + else + { + return GetFileSystemAccessRules(new DirectoryInfo(path), includeExplicit, includeInherited, getInheritedFrom); + } + } + } +} \ No newline at end of file diff --git a/Security2/FileSystem/FileSystemAccessRule2 Class/FileSystemAccessRule2.RemoveFileSystemAccessRules.cs b/Security2/FileSystem/FileSystemAccessRule2 Class/FileSystemAccessRule2.RemoveFileSystemAccessRules.cs new file mode 100644 index 0000000..21d069f --- /dev/null +++ b/Security2/FileSystem/FileSystemAccessRule2 Class/FileSystemAccessRule2.RemoveFileSystemAccessRules.cs @@ -0,0 +1,146 @@ +using Alphaleonis.Win32.Filesystem; +using System.Collections.Generic; +using System.Security.AccessControl; + +namespace Security2 +{ + public partial class FileSystemAccessRule2 + { + public static void RemoveFileSystemAccessRule(FileSystemInfo item, IdentityReference2 account, FileSystemRights2 rights, AccessControlType type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, bool removeSpecific = false) + { + if (type == AccessControlType.Allow) + rights = rights | FileSystemRights2.Synchronize; + + FileSystemAccessRule ace = null; + + if (item as FileInfo != null) + { + var file = (FileInfo)item; + var sd = file.GetAccessControl(AccessControlSections.Access); + + ace = (FileSystemAccessRule)sd.AccessRuleFactory(account, (int)rights, false, inheritanceFlags, propagationFlags, type); + if (removeSpecific) + sd.RemoveAccessRuleSpecific(ace); + else + sd.RemoveAccessRule(ace); + + file.SetAccessControl(sd); + } + else + { + DirectoryInfo directory = (DirectoryInfo)item; + + var sd = directory.GetAccessControl(AccessControlSections.Access); + + ace = (FileSystemAccessRule)sd.AccessRuleFactory(account, (int)rights, false, inheritanceFlags, propagationFlags, type); + if (removeSpecific) + sd.RemoveAccessRuleSpecific(ace); + else + sd.RemoveAccessRule(ace); + + directory.SetAccessControl(sd); + } + } + + public static void RemoveFileSystemAccessRule(FileSystemInfo item, List accounts, FileSystemRights2 rights, AccessControlType type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, bool removeSpecific = false) + { + foreach (var account in accounts) + { + RemoveFileSystemAccessRule(item, account, rights, type, inheritanceFlags, propagationFlags, removeSpecific); + } + } + + public static void RemoveFileSystemAccessRule(string path, IdentityReference2 account, FileSystemRights2 rights, AccessControlType type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, bool removeSpecific = false) + { + if (File.Exists(path)) + { + var item = new FileInfo(path); + RemoveFileSystemAccessRule(item, account, rights, type, inheritanceFlags, propagationFlags, removeSpecific); + } + else + { + var item = new DirectoryInfo(path); + RemoveFileSystemAccessRule(item, account, rights, type, inheritanceFlags, propagationFlags, removeSpecific); + } + } + + public static void RemoveFileSystemAccessRule(string path, List account, FileSystemRights2 rights, AccessControlType type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, bool removeSpecific = false) + { + if (File.Exists(path)) + { + var item = new FileInfo(path); + RemoveFileSystemAccessRule(item, account, rights, type, inheritanceFlags, propagationFlags, removeSpecific); + } + else + { + var item = new DirectoryInfo(path); + RemoveFileSystemAccessRule(item, account, rights, type, inheritanceFlags, propagationFlags, removeSpecific); + } + } + + public static void RemoveFileSystemAccessRule(FileSystemInfo item, FileSystemAccessRule ace, bool removeSpecific = false) + { + if (item as FileInfo != null) + { + var file = (FileInfo)item; + var sd = file.GetAccessControl(AccessControlSections.Access); + + if (removeSpecific) + sd.RemoveAccessRuleSpecific(ace); + else + sd.RemoveAccessRule(ace); + + file.SetAccessControl(sd); + } + else + { + DirectoryInfo directory = (DirectoryInfo)item; + + var sd = directory.GetAccessControl(AccessControlSections.Access); + + if (removeSpecific) + sd.RemoveAccessRuleSpecific(ace); + else + sd.RemoveAccessRule(ace); + + directory.SetAccessControl(sd); + } + } + + public static FileSystemAccessRule2 RemoveFileSystemAccessRule(FileSystemSecurity2 sd, IdentityReference2 account, FileSystemRights2 rights, AccessControlType type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, bool removeSpecific = false) + { + if (type == AccessControlType.Allow) + rights = rights | FileSystemRights2.Synchronize; + + var ace = (FileSystemAccessRule)sd.SecurityDescriptor.AccessRuleFactory(account, (int)rights, false, inheritanceFlags, propagationFlags, type); + if (sd.IsFile) + { + if (removeSpecific) + ((FileSecurity)sd.SecurityDescriptor).RemoveAccessRuleSpecific(ace); + else + ((FileSecurity)sd.SecurityDescriptor).RemoveAccessRule(ace); + } + else + { + if (removeSpecific) + ((DirectorySecurity)sd.SecurityDescriptor).RemoveAccessRuleSpecific(ace); + else + ((DirectorySecurity)sd.SecurityDescriptor).RemoveAccessRule(ace); + } + + return ace; + } + + public static IEnumerable RemoveFileSystemAccessRule(FileSystemSecurity2 sd, List accounts, FileSystemRights2 rights, AccessControlType type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, bool removeSpecific = false) + { + var aces = new List(); + + foreach (var account in accounts) + { + aces.Add(RemoveFileSystemAccessRule(sd, account, rights, type, inheritanceFlags, propagationFlags)); + } + + return aces; + } + } +} \ No newline at end of file diff --git a/Security2/FileSystem/FileSystemAccessRule2 Class/FileSystemAccessRule2.RemoveFileSystemAccessRulesAll.cs b/Security2/FileSystem/FileSystemAccessRule2 Class/FileSystemAccessRule2.RemoveFileSystemAccessRulesAll.cs new file mode 100644 index 0000000..0cb8cd3 --- /dev/null +++ b/Security2/FileSystem/FileSystemAccessRule2 Class/FileSystemAccessRule2.RemoveFileSystemAccessRulesAll.cs @@ -0,0 +1,35 @@ +using Alphaleonis.Win32.Filesystem; +using System.Collections.Generic; +using System.Linq; +using System.Security.AccessControl; +using System.Security.Principal; + +namespace Security2 +{ + public partial class FileSystemAccessRule2 + { + public static void RemoveFileSystemAccessRuleAll(FileSystemSecurity2 sd, List accounts = null) + { + var acl = sd.SecurityDescriptor.GetAccessRules(true, false, typeof(SecurityIdentifier)); + + if (accounts != null) + { + acl.OfType().Where(ace => (accounts.Where(account => account == (IdentityReference2)ace.IdentityReference).Count() > 1)); + } + + foreach (FileSystemAccessRule ace in acl) + { + sd.SecurityDescriptor.RemoveAccessRuleSpecific(ace); + } + } + + public static void RemoveFileSystemAccessRuleAll(FileSystemInfo item, List accounts = null) + { + var sd = new FileSystemSecurity2(item); + + RemoveFileSystemAccessRuleAll(sd, accounts); + + sd.Write(); + } + } +} \ No newline at end of file diff --git a/Security2/FileSystem/FileSystemAccessRule2 Class/FileSystemAccessRule2.cs b/Security2/FileSystem/FileSystemAccessRule2 Class/FileSystemAccessRule2.cs new file mode 100644 index 0000000..4945596 --- /dev/null +++ b/Security2/FileSystem/FileSystemAccessRule2 Class/FileSystemAccessRule2.cs @@ -0,0 +1,74 @@ +using Alphaleonis.Win32.Filesystem; +using System.Security.AccessControl; + +namespace Security2 +{ + public partial class FileSystemAccessRule2 + { + #region Properties + private FileSystemAccessRule fileSystemAccessRule; + private string fullName; + private bool inheritanceEnabled; + private string inheritedFrom; + + public string Name { get { return System.IO.Path.GetFileName(fullName); } } + public string FullName { get { return fullName; } set { fullName = value; } } + public bool InheritanceEnabled { get { return inheritanceEnabled; } set { inheritanceEnabled = value; } } + public string InheritedFrom { get { return inheritedFrom; } set { inheritedFrom = value; } } + public AccessControlType AccessControlType { get { return fileSystemAccessRule.AccessControlType; } } + public FileSystemRights2 AccessRights { get { return (FileSystemRights2)fileSystemAccessRule.FileSystemRights; } } + public IdentityReference2 Account { get { return fileSystemAccessRule.IdentityReference; } } + public InheritanceFlags InheritanceFlags { get { return fileSystemAccessRule.InheritanceFlags; } } + public bool IsInherited { get { return fileSystemAccessRule.IsInherited; } } + public PropagationFlags PropagationFlags { get { return fileSystemAccessRule.PropagationFlags; } } + #endregion + + public FileSystemAccessRule2(FileSystemAccessRule fileSystemAccessRule) + { + this.fileSystemAccessRule = fileSystemAccessRule; + } + + public FileSystemAccessRule2(FileSystemAccessRule fileSystemAccessRule, FileSystemInfo item) + { + this.fileSystemAccessRule = fileSystemAccessRule; + this.fullName = item.FullName; + } + + public FileSystemAccessRule2(FileSystemAccessRule fileSystemAccessRule, string path) + { + this.fileSystemAccessRule = fileSystemAccessRule; + } + + public static implicit operator FileSystemAccessRule(FileSystemAccessRule2 ace2) + { + return ace2.fileSystemAccessRule; + } + public static implicit operator FileSystemAccessRule2(FileSystemAccessRule ace) + { + return new FileSystemAccessRule2(ace); + } + + //REQUIRED BECAUSE OF CONVERSION OPERATORS + public override bool Equals(object obj) + { + return fileSystemAccessRule == (FileSystemAccessRule)obj; + } + public override int GetHashCode() + { + return fileSystemAccessRule.GetHashCode(); + } + public override string ToString() + { + return string.Format("{0} '{1}' ({2})", + AccessControlType.ToString()[0], + Account.AccountName, + AccessRights.ToString() + ); + + } + public SimpleFileSystemAccessRule ToSimpleFileSystemAccessRule2() + { + return new SimpleFileSystemAccessRule(fullName, Account, AccessRights); + } + } +} \ No newline at end of file diff --git a/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.AddFileSystemAuditRules.cs b/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.AddFileSystemAuditRules.cs new file mode 100644 index 0000000..0bb350a --- /dev/null +++ b/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.AddFileSystemAuditRules.cs @@ -0,0 +1,110 @@ +using Alphaleonis.Win32.Filesystem; +using System.Collections.Generic; +using System.Security.AccessControl; + +namespace Security2 +{ + public partial class FileSystemAuditRule2 + { + public static FileSystemAuditRule2 AddFileSystemAuditRule(FileSystemSecurity2 sd, IdentityReference2 account, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags) + { + FileSystemAuditRule2 ace = null; + + if (sd.IsFile) + { + ace = (FileSystemAuditRule)sd.SecurityDescriptor.AuditRuleFactory(account, (int)rights, false, InheritanceFlags.None, PropagationFlags.None, type); + ((FileSecurity)sd.SecurityDescriptor).AddAuditRule(ace); + } + else + { + ace = (FileSystemAuditRule)sd.SecurityDescriptor.AuditRuleFactory(account, (int)rights, false, inheritanceFlags, propagationFlags, type); + ((DirectorySecurity)sd.SecurityDescriptor).AddAuditRule(ace); + } + + return ace; + } + + public static FileSystemAuditRule2 AddFileSystemAuditRule(FileSystemInfo item, IdentityReference2 account, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags) + { + var sd = new FileSystemSecurity2(item); + + var ace = AddFileSystemAuditRule(sd, account, rights, type, inheritanceFlags, propagationFlags); + + sd.Write(); + + return ace; + } + + public static FileSystemAuditRule2 AddFileSystemAuditRule(string path, IdentityReference2 account, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags) + { + FileSystemAuditRule ace = null; + + if (File.Exists(path)) + { + var item = new FileInfo(path); + ace = AddFileSystemAuditRule(item, account, rights, type, inheritanceFlags, propagationFlags); + } + else + { + var item = new DirectoryInfo(path); + ace = AddFileSystemAuditRule(item, account, rights, type, inheritanceFlags, propagationFlags); + } + + return ace; + } + + public static IEnumerable AddFileSystemAuditRule(FileSystemSecurity2 sd, List accounts, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags) + { + var aces = new List(); + + foreach (var account in accounts) + { + aces.Add(AddFileSystemAuditRule(sd, account, rights, type, inheritanceFlags, propagationFlags)); + } + + return aces; + } + + public static IEnumerable AddFileSystemAuditRule(FileSystemInfo item, List accounts, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags) + { + var aces = new List(); + + foreach (var account in accounts) + { + aces.Add(AddFileSystemAuditRule(item, account, rights, type, inheritanceFlags, propagationFlags)); + } + + return aces; + } + + public static IEnumerable AddFileSystemAuditRule(string path, List accounts, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags) + { + if (File.Exists(path)) + { + var item = new FileInfo(path); + foreach (var account in accounts) + { + yield return AddFileSystemAuditRule(item, account, rights, type, inheritanceFlags, propagationFlags); + } + } + else + { + var item = new DirectoryInfo(path); + foreach (var account in accounts) + { + yield return AddFileSystemAuditRule(item, account, rights, type, inheritanceFlags, propagationFlags); + } + } + } + + public static void AddFileSystemAuditRule(FileSystemAuditRule2 rule) + { + AddFileSystemAuditRule(rule.fullName, + rule.Account, + rule.AccessRights, + rule.AuditFlags, + rule.InheritanceFlags, + rule.PropagationFlags); + } + } +} diff --git a/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.GetFileSystemAuditRules.cs b/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.GetFileSystemAuditRules.cs new file mode 100644 index 0000000..9e797b6 --- /dev/null +++ b/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.GetFileSystemAuditRules.cs @@ -0,0 +1,61 @@ +using Alphaleonis.Win32.Filesystem; +using System.Collections.Generic; +using System.Security.AccessControl; +using System.Security.Principal; + +namespace Security2 +{ + public partial class FileSystemAuditRule2 + { + public static IEnumerable GetFileSystemAuditRules(FileSystemInfo item, bool includeExplicit, bool includeInherited, bool getInheritedFrom = false) + { + var sd = new FileSystemSecurity2(item); + + return GetFileSystemAuditRules(sd, includeExplicit, includeInherited, getInheritedFrom); + } + + public static IEnumerable GetFileSystemAuditRules(FileSystemSecurity2 sd, bool includeExplicit, bool includeInherited, bool getInheritedFrom = false) + { + List aceList = new List(); + List inheritedFrom = null; + + if (getInheritedFrom) + { + inheritedFrom = Win32.GetInheritedFrom(sd.Item, sd.SecurityDescriptor); + } + + var aceCounter = 0; + var acl = !sd.IsFile ? + ((DirectorySecurity)sd.SecurityDescriptor).GetAuditRules(includeExplicit, includeInherited, typeof(SecurityIdentifier)) : + ((FileSecurity)sd.SecurityDescriptor).GetAuditRules(includeExplicit, includeInherited, typeof(SecurityIdentifier)); + + foreach (FileSystemAuditRule ace in acl) + { + var ace2 = new FileSystemAuditRule2(ace) { FullName = sd.Item.FullName, InheritanceEnabled = !sd.SecurityDescriptor.AreAccessRulesProtected }; + if (getInheritedFrom) + { + ace2.inheritedFrom = string.IsNullOrEmpty(inheritedFrom[aceCounter]) ? "" : inheritedFrom[aceCounter].Substring(0, inheritedFrom[aceCounter].Length - 1); + aceCounter++; + } + + aceList.Add(ace2); + } + + return aceList; + } + + public static IEnumerable GetFileSystemAuditRules(string path, bool includeExplicit, bool includeInherited) + { + if (File.Exists(path)) + { + var item = new FileInfo(path); + return GetFileSystemAuditRules(item, includeExplicit, includeInherited); + } + else + { + var item = new DirectoryInfo(path); + return GetFileSystemAuditRules(item, includeExplicit, includeInherited); + } + } + } +} diff --git a/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.RemoveFileSystemAuditRule.cs b/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.RemoveFileSystemAuditRule.cs new file mode 100644 index 0000000..46a03e4 --- /dev/null +++ b/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.RemoveFileSystemAuditRule.cs @@ -0,0 +1,115 @@ +using Alphaleonis.Win32.Filesystem; +using System.Collections.Generic; +using System.Security.AccessControl; + +namespace Security2 +{ + public partial class FileSystemAuditRule2 + { + public static void RemoveFileSystemAuditRule(FileSystemInfo item, IdentityReference2 account, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags) + { + FileSystemAuditRule ace = null; + + if (item is FileInfo) + { + var file = (FileInfo)item; + var sd = file.GetAccessControl(AccessControlSections.Audit); + + ace = (FileSystemAuditRule)sd.AuditRuleFactory(account, (int)rights, false, inheritanceFlags, propagationFlags, type); + + sd.RemoveAuditRuleSpecific(ace); + + file.SetAccessControl(sd); + } + else + { + DirectoryInfo directory = (DirectoryInfo)item; + + var sd = directory.GetAccessControl(AccessControlSections.Audit); + + ace = (FileSystemAuditRule)sd.AuditRuleFactory(account, (int)rights, false, inheritanceFlags, propagationFlags, type); + sd.RemoveAuditRuleSpecific(ace); + + directory.SetAccessControl(sd); + } + } + + public static void RemoveFileSystemAuditRule(FileSystemInfo item, List accounts, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, bool removeSpecific = false) + { + foreach (var account in accounts) + { + RemoveFileSystemAuditRule(item, account, rights, type, inheritanceFlags, propagationFlags); + } + } + + public static void RemoveFileSystemAuditRule(FileSystemInfo item, FileSystemAuditRule ace) + { + if (item is FileInfo) + { + var file = (FileInfo)item; + var sd = file.GetAccessControl(AccessControlSections.Audit); + + sd.RemoveAuditRuleSpecific(ace); + + file.SetAccessControl(sd); + } + else + { + DirectoryInfo directory = (DirectoryInfo)item; + + var sd = directory.GetAccessControl(AccessControlSections.Audit); + + sd.RemoveAuditRuleSpecific(ace); + + directory.SetAccessControl(sd); + } + } + + public static void RemoveFileSystemAuditRule(string path, IdentityReference2 account, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags) + { + if (File.Exists(path)) + { + var item = new FileInfo(path); + RemoveFileSystemAuditRule(item, account, rights, type, inheritanceFlags, propagationFlags); + } + else + { + var item = new DirectoryInfo(path); + RemoveFileSystemAuditRule(item, account, rights, type, inheritanceFlags, propagationFlags); + } + } + + public static FileSystemAuditRule2 RemoveFileSystemAuditRule(FileSystemSecurity2 sd, IdentityReference2 account, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, bool removeSpecific = false) + { + var ace = (FileSystemAuditRule)sd.SecurityDescriptor.AuditRuleFactory(account, (int)rights, false, inheritanceFlags, propagationFlags, type); + if (sd.IsFile) + { + if (removeSpecific) + ((FileSecurity)sd.SecurityDescriptor).RemoveAuditRuleSpecific(ace); + else + ((FileSecurity)sd.SecurityDescriptor).RemoveAuditRule(ace); + } + else + { + if (removeSpecific) + ((DirectorySecurity)sd.SecurityDescriptor).RemoveAuditRuleSpecific(ace); + else + ((DirectorySecurity)sd.SecurityDescriptor).RemoveAuditRule(ace); + } + + return ace; + } + + public static IEnumerable RemoveFileSystemAuditRule(FileSystemSecurity2 sd, List accounts, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, bool removeSpecific = false) + { + var aces = new List(); + + foreach (var account in accounts) + { + aces.Add(RemoveFileSystemAuditRule(sd, account, rights, type, inheritanceFlags, propagationFlags)); + } + + return aces; + } + } +} diff --git a/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.RemoveFileSystemAuditRuleAll.cs b/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.RemoveFileSystemAuditRuleAll.cs new file mode 100644 index 0000000..97edeea --- /dev/null +++ b/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.RemoveFileSystemAuditRuleAll.cs @@ -0,0 +1,35 @@ +using Alphaleonis.Win32.Filesystem; +using System.Collections.Generic; +using System.Linq; +using System.Security.AccessControl; +using System.Security.Principal; + +namespace Security2 +{ + public partial class FileSystemAuditRule2 + { + public static void RemoveFileSystemAuditRuleAll(FileSystemSecurity2 sd, List accounts = null) + { + var acl = sd.SecurityDescriptor.GetAuditRules(true, false, typeof(SecurityIdentifier)); + + if (accounts != null) + { + acl.OfType().Where(ace => (accounts.Where(account => account == (IdentityReference2)ace.IdentityReference).Count() > 1)); + } + + foreach (FileSystemAuditRule ace in acl) + { + sd.SecurityDescriptor.RemoveAuditRuleSpecific(ace); + } + } + + public static void RemoveFileSystemAuditRuleAll(FileSystemInfo item, List accounts = null) + { + var sd = new FileSystemSecurity2(item); + + RemoveFileSystemAuditRuleAll(sd, accounts); + + sd.Write(); + } + } +} diff --git a/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.cs b/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.cs new file mode 100644 index 0000000..7f951e4 --- /dev/null +++ b/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.cs @@ -0,0 +1,70 @@ +using Alphaleonis.Win32.Filesystem; +using System.Security.AccessControl; + +namespace Security2 +{ + public partial class FileSystemAuditRule2 + { + #region Properties + private FileSystemAuditRule fileSystemAuditRule; + private string fullName; + private bool inheritanceEnabled; + private string inheritedFrom; + + public string Name { get { return System.IO.Path.GetFileName(fullName); } } + public string FullName { get { return fullName; } set { fullName = value; } } + public bool InheritanceEnabled { get { return inheritanceEnabled; } set { inheritanceEnabled = value; } } + public string InheritedFrom { get { return inheritedFrom; } set { inheritedFrom = value; } } + public AuditFlags AuditFlags { get { return fileSystemAuditRule.AuditFlags; } } + public FileSystemRights2 AccessRights { get { return (FileSystemRights2)fileSystemAuditRule.FileSystemRights; } } + public IdentityReference2 Account { get { return (IdentityReference2)fileSystemAuditRule.IdentityReference; } } + public InheritanceFlags InheritanceFlags { get { return fileSystemAuditRule.InheritanceFlags; } } + public bool IsInherited { get { return fileSystemAuditRule.IsInherited; } } + public PropagationFlags PropagationFlags { get { return fileSystemAuditRule.PropagationFlags; } } + #endregion + + public FileSystemAuditRule2(FileSystemAuditRule fileSystemAuditRule) + { + this.fileSystemAuditRule = fileSystemAuditRule; + } + + public FileSystemAuditRule2(FileSystemAuditRule fileSystemAuditRule, FileSystemInfo item) + { + this.fileSystemAuditRule = fileSystemAuditRule; + this.fullName = item.FullName; + } + + public FileSystemAuditRule2(FileSystemAuditRule fileSystemAuditRule, string path) + { + this.fileSystemAuditRule = fileSystemAuditRule; + } + + #region Conversion + public static implicit operator FileSystemAuditRule(FileSystemAuditRule2 ace2) + { + return ace2.fileSystemAuditRule; + } + public static implicit operator FileSystemAuditRule2(FileSystemAuditRule ace) + { + return new FileSystemAuditRule2(ace); + } + //REQUIRED BECAUSE OF CONVERSION OPERATORS + public override bool Equals(object obj) + { + return this.fileSystemAuditRule == (FileSystemAuditRule)obj; + } + public override int GetHashCode() + { + return this.fileSystemAuditRule.GetHashCode(); + } + public override string ToString() + { + return fileSystemAuditRule.ToString(); + } + public SimpleFileSystemAuditRule ToSimpleFileSystemAuditRule2() + { + return new SimpleFileSystemAuditRule(this.fullName, this.Account, this.AccessRights); + } + #endregion + } +} diff --git a/Security2/FileSystem/FileSystemEffectivePermissionEntry.cs b/Security2/FileSystem/FileSystemEffectivePermissionEntry.cs new file mode 100644 index 0000000..054a311 --- /dev/null +++ b/Security2/FileSystem/FileSystemEffectivePermissionEntry.cs @@ -0,0 +1,65 @@ +using System.Collections.Generic; +using System.Security.AccessControl; + +namespace Security2 +{ + public class FileSystemEffectivePermissionEntry + { + private IdentityReference2 account; + private uint accessMask; + private string objectPath; + + public IdentityReference2 Account { get { return account; } } + + public uint AccessMask { get { return accessMask; } } + + public string FullName { get { return objectPath; } } + + public string Name + { + get + { + if (!string.IsNullOrEmpty(FullName)) + { + return System.IO.Path.GetFileName(FullName); + } + else + { + return null; + } + } + } + + public FileSystemRights AccessRights + { + get + { + return (FileSystemRights)accessMask; + } + } + + private List accessAsString; + public List AccessAsString { get { return accessAsString; } } + + public FileSystemEffectivePermissionEntry(IdentityReference2 identity, uint AccessMask, string FullName) + { + this.account = identity; + this.accessMask = AccessMask; + this.objectPath = FullName; + this.accessAsString = new List(); + + if (accessMask == 0) + { + accessAsString.Add("None"); + } + else + { + string tempString = ((FileSystemRights)this.accessMask).ToString(); + foreach (var s in tempString.Split(',')) + { + this.accessAsString.Add(s); + } + } + } + } +} diff --git a/Security2/FileSystem/FileSystemFlags.cs b/Security2/FileSystem/FileSystemFlags.cs new file mode 100644 index 0000000..f976a4f --- /dev/null +++ b/Security2/FileSystem/FileSystemFlags.cs @@ -0,0 +1,10 @@ +using System.Security.AccessControl; + +namespace Security2 +{ + public class FileSystemFlags + { + public InheritanceFlags InheritanceFlags { get; set; } + public PropagationFlags PropagationFlags { get; set; } + } +} diff --git a/Security2/FileSystem/FileSystemInheritanceInfo.cs b/Security2/FileSystem/FileSystemInheritanceInfo.cs new file mode 100644 index 0000000..1b822c9 --- /dev/null +++ b/Security2/FileSystem/FileSystemInheritanceInfo.cs @@ -0,0 +1,289 @@ +using Alphaleonis.Win32.Filesystem; +using System.Security.AccessControl; +using System.Security.Principal; + +namespace Security2 +{ + + public class FileSystemInheritanceInfo + { + private enum InheritanceScope + { + Access, + Audit + } + + private FileSystemInfo item; + private bool? accessInheritanceEnabled; + private bool? auditInheritanceEnabled; + + public FileSystemInfo Item + { + get { return item; } + set { item = value; } + } + + public bool? AccessInheritanceEnabled + { + get { return accessInheritanceEnabled; } + set { accessInheritanceEnabled = value; } + } + + public bool? AuditInheritanceEnabled + { + get { return auditInheritanceEnabled; } + set { auditInheritanceEnabled = value; } + } + + public string FullName { get { return Item.FullName; } } + + public string Name { get { return Path.GetFileName(item.FullName); } } + + private FileSystemInheritanceInfo(FileSystemInfo item, bool? accessInheritanceEnabled, bool? auditInheritanceEnabled) + { + this.item = item; + this.accessInheritanceEnabled = accessInheritanceEnabled; + this.auditInheritanceEnabled = auditInheritanceEnabled; + } + + #region GetFileSystemInheritanceInfo + public static FileSystemInheritanceInfo GetFileSystemInheritanceInfo(string path) + { + var item = new FileInfo(path); + return GetFileSystemInheritanceInfo(item); + } + + public static FileSystemInheritanceInfo GetFileSystemInheritanceInfo(FileSystemInfo item) + { + if (item is FileInfo) + { + + bool? areAuditRulesProtected = null; + + var areAccessRulesProtected = ((FileInfo)item).GetAccessControl(AccessControlSections.Access).AreAccessRulesProtected; + + try + { + areAuditRulesProtected = ((FileInfo)item).GetAccessControl(AccessControlSections.Audit).AreAuditRulesProtected; + } + catch (System.IO.IOException) + { + //log that the security privilege is missing + } + + return new FileSystemInheritanceInfo(item, !areAccessRulesProtected, !areAuditRulesProtected); + } + else + { + bool? areAuditRulesProtected = null; + + var areAccessRulesProtected = ((DirectoryInfo)item).GetAccessControl(AccessControlSections.Access).AreAccessRulesProtected; + + try + { + areAuditRulesProtected = ((DirectoryInfo)item).GetAccessControl(AccessControlSections.Audit).AreAuditRulesProtected; + } + catch (System.IO.IOException) + { + //log that the security privilege is missing + } + + return new FileSystemInheritanceInfo(item, !areAccessRulesProtected, !areAuditRulesProtected); + } + } + + public static FileSystemInheritanceInfo GetFileSystemInheritanceInfo(FileSystemSecurity2 sd) + { + return new FileSystemInheritanceInfo(sd.Item, !sd.SecurityDescriptor.AreAccessRulesProtected, !sd.SecurityDescriptor.AreAuditRulesProtected); + } + #endregion GetFileSystemInheritanceInfo + + #region Enable / DisableInheritance internal + private static void EnableInheritance(FileSystemSecurity2 sd, bool removeExplicitAccessRules, InheritanceScope scope) + { + if (sd.IsFile) + { + if (scope == InheritanceScope.Access) + { + sd.SecurityDescriptor.SetAccessRuleProtection(false, false); + + //if RemoveExplicitAccessRules is set + if (removeExplicitAccessRules) + { + //remove all explicitly set ACEs from the item + foreach (FileSystemAccessRule ace in ((FileSecurity)sd.SecurityDescriptor).GetAccessRules(true, false, typeof(SecurityIdentifier))) + { + ((FileSecurity)sd.SecurityDescriptor).RemoveAccessRule(ace); + } + } + } + else + { + sd.SecurityDescriptor.SetAuditRuleProtection(false, false); + + //if RemoveExplicitAccessRules is set + if (removeExplicitAccessRules) + { + //remove all explicitly set ACEs from the item + foreach (FileSystemAuditRule ace in ((FileSecurity)sd.SecurityDescriptor).GetAuditRules(true, false, typeof(SecurityIdentifier))) + { + ((FileSecurity)sd.SecurityDescriptor).RemoveAuditRule(ace); + } + } + } + } + else + { + if (scope == InheritanceScope.Access) + { + ((DirectorySecurity)sd.SecurityDescriptor).SetAccessRuleProtection(false, false); + + //if RemoveExplicitAccessRules is set + if (removeExplicitAccessRules) + { + //remove all explicitly set ACEs from the item + foreach (FileSystemAccessRule ace in ((DirectorySecurity)sd.SecurityDescriptor).GetAccessRules(true, false, typeof(SecurityIdentifier))) + { + ((DirectorySecurity)sd.SecurityDescriptor).RemoveAccessRule(ace); + } + } + } + else + { + ((DirectorySecurity)sd.SecurityDescriptor).SetAuditRuleProtection(false, false); + + //if RemoveExplicitAccessRules is set + if (removeExplicitAccessRules) + { + //remove all explicitly set ACEs from the item + foreach (FileSystemAuditRule ace in ((DirectorySecurity)sd.SecurityDescriptor).GetAuditRules(true, false, typeof(SecurityIdentifier))) + { + ((DirectorySecurity)sd.SecurityDescriptor).RemoveAuditRule(ace); + } + } + } + } + } + + private static void DisableInheritance(FileSystemSecurity2 sd, bool removeInheritedAccessRules, InheritanceScope scope) + { + if (sd.IsFile) + { + if (scope == InheritanceScope.Access) + ((FileSecurity)sd.SecurityDescriptor).SetAccessRuleProtection(true, !removeInheritedAccessRules); + else + ((FileSecurity)sd.SecurityDescriptor).SetAuditRuleProtection(true, !removeInheritedAccessRules); + } + else + { + if (scope == InheritanceScope.Access) + ((DirectorySecurity)sd.SecurityDescriptor).SetAccessRuleProtection(true, !removeInheritedAccessRules); + else + ((DirectorySecurity)sd.SecurityDescriptor).SetAuditRuleProtection(true, !removeInheritedAccessRules); + } + } + #endregion Enable / DisableInheritance internal + + #region Public Methods using SecurityDescriptor + public static void EnableAccessInheritance(FileSystemSecurity2 sd, bool removeExplicitAccessRules) + { + EnableInheritance(sd, removeExplicitAccessRules, InheritanceScope.Access); + } + + public static void EnableAuditInheritance(FileSystemSecurity2 sd, bool removeExplicitAccessRules) + { + EnableInheritance(sd, removeExplicitAccessRules, InheritanceScope.Audit); + } + + public static void DisableAccessInheritance(FileSystemSecurity2 sd, bool removeExplicitAccessRules) + { + DisableInheritance(sd, removeExplicitAccessRules, InheritanceScope.Access); + } + + public static void DisableAuditInheritance(FileSystemSecurity2 sd, bool removeExplicitAccessRules) + { + DisableInheritance(sd, removeExplicitAccessRules, InheritanceScope.Audit); + } + #endregion Public Methods using SecurityDescriptor + + #region Public Methods using FileSystemInfo + public static void EnableAccessInheritance(FileSystemInfo item, bool removeExplicitAccessRules) + { + var sd = new FileSystemSecurity2(item, AccessControlSections.Access); + EnableAccessInheritance(sd, removeExplicitAccessRules); + sd.Write(); + } + + public static void DisableAccessInheritance(FileSystemInfo item, bool removeInheritedAccessRules) + { + var sd = new FileSystemSecurity2(item, AccessControlSections.Access); + DisableAccessInheritance(sd, removeInheritedAccessRules); + sd.Write(); + } + + public static void EnableAuditInheritance(FileSystemInfo item, bool removeExplicitAccessRules) + { + var sd = new FileSystemSecurity2(item, AccessControlSections.Audit); + EnableAuditInheritance(sd, removeExplicitAccessRules); + sd.Write(); + } + + public static void DisableAuditInheritance(FileSystemInfo item, bool removeInheritedAccessRules) + { + var sd = new FileSystemSecurity2(item, AccessControlSections.Audit); + DisableAuditInheritance(sd, removeInheritedAccessRules); + sd.Write(); + } + #endregion Public Methods using FileSystemInfo + + #region Public Methods using Path + public static void EnableAccessInheritance(string path, bool removeExplicitAccessRules) + { + if (File.Exists(path)) + { + EnableAccessInheritance(new FileInfo(path), removeExplicitAccessRules); + } + else if (Directory.Exists(path)) + { + EnableAccessInheritance(new DirectoryInfo(path), removeExplicitAccessRules); + } + } + + public static void DisableAccessInheritance(string path, bool removeInheritedAccessRules) + { + if (File.Exists(path)) + { + DisableAccessInheritance(new FileInfo(path), removeInheritedAccessRules); + } + else if (Directory.Exists(path)) + { + DisableAccessInheritance(new DirectoryInfo(path), removeInheritedAccessRules); + } + } + + public static void EnableAuditInheritance(string path, bool removeExplicitAccessRules) + { + if (File.Exists(path)) + { + EnableAuditInheritance(new FileInfo(path), removeExplicitAccessRules); + } + else if (Directory.Exists(path)) + { + EnableAuditInheritance(new DirectoryInfo(path), removeExplicitAccessRules); + } + } + + public static void DisableAuditInheritance(string path, bool removeInheritedAccessRules) + { + if (File.Exists(path)) + { + DisableAuditInheritance(new FileInfo(path), removeInheritedAccessRules); + } + else if (Directory.Exists(path)) + { + DisableAuditInheritance(new DirectoryInfo(path), removeInheritedAccessRules); + } + } + #endregion Public Methods using Path + } +} \ No newline at end of file diff --git a/Security2/FileSystem/FileSystemOwner.cs b/Security2/FileSystem/FileSystemOwner.cs new file mode 100644 index 0000000..275e565 --- /dev/null +++ b/Security2/FileSystem/FileSystemOwner.cs @@ -0,0 +1,58 @@ +using Alphaleonis.Win32.Filesystem; +using System.Security.AccessControl; +using System.Security.Principal; + +namespace Security2 +{ + public class FileSystemOwner + { + private FileSystemInfo item; + private IdentityReference2 owner; + private FileSystemSecurity sd; + + public FileSystemInfo Item + { + get { return item; } + } + + public IdentityReference2 Owner + { + get { return owner; } + } + + private FileSystemOwner(FileSystemInfo item, IdentityReference2 owner) + { + this.item = item; + this.owner = owner; + } + + public static FileSystemOwner GetOwner(FileSystemSecurity2 sd) + { + return new FileSystemOwner(sd.Item, sd.SecurityDescriptor.GetOwner(typeof(SecurityIdentifier))); + } + + public static void SetOwner(FileSystemSecurity2 sd, IdentityReference2 account) + { + sd.SecurityDescriptor.SetOwner(account); + } + + public static FileSystemOwner GetOwner(FileSystemInfo item) + { + return GetOwner(new FileSystemSecurity2(item, AccessControlSections.Owner)); + } + + public static void SetOwner(FileSystemInfo item, IdentityReference2 account) + { + var sd = new FileSystemSecurity2(item, AccessControlSections.Owner); + + SetOwner(sd, account); + + sd.Write(); + } + + public override string ToString() + { + return item.FullName; + } + } +} diff --git a/Security2/FileSystem/FileSystemSecurity2.cs b/Security2/FileSystem/FileSystemSecurity2.cs new file mode 100644 index 0000000..cd5eb08 --- /dev/null +++ b/Security2/FileSystem/FileSystemSecurity2.cs @@ -0,0 +1,314 @@ +using Alphaleonis.Win32.Filesystem; +using System; +using System.Security.AccessControl; + +namespace Security2 +{ + public class FileSystemSecurity2 + { + protected FileSecurity fileSecurityDescriptor; + protected DirectorySecurity directorySecurityDescriptor; + protected FileSystemInfo item; + protected FileSystemSecurity sd; + protected AccessControlSections sections; + protected bool isFile = false; + + public FileSystemInfo Item + { + get { return item; } + set { item = value; } + } + + public string FullName { get { return item.FullName; } } + + public string Name { get { return item.Name; } } + + public bool IsFile { get { return isFile; } } + + public FileSystemSecurity2(FileSystemInfo item, AccessControlSections sections) + { + this.sections = sections; + + if (item is FileInfo) + { + this.item = (FileInfo)item; + + sd = ((FileInfo)this.item).GetAccessControl(sections); + + isFile = true; + } + else + { + this.item = (DirectoryInfo)item; + + sd = ((DirectoryInfo)this.item).GetAccessControl(sections); + } + } + + public FileSystemSecurity2(FileSystemInfo item) + { + if (item is FileInfo) + { + this.item = (FileInfo)item; + try + { + sd = ((FileInfo)this.item).GetAccessControl(AccessControlSections.All); + } + catch + { + try + { + sd = ((FileInfo)this.item).GetAccessControl(AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group); + } + catch + { + sd = ((FileInfo)this.item).GetAccessControl(AccessControlSections.Access); + } + } + + isFile = true; + } + else + { + this.item = (DirectoryInfo)item; + try + { + sd = ((DirectoryInfo)this.item).GetAccessControl(AccessControlSections.All); + } + catch + { + try + { + sd = ((DirectoryInfo)this.item).GetAccessControl(AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group); + } + catch + { + sd = ((DirectoryInfo)this.item).GetAccessControl(AccessControlSections.Access); + } + } + } + } + + public FileSystemSecurity SecurityDescriptor + { + get + { + return sd; + } + } + + public void Write() + { + if (isFile) + { + ((FileInfo)item).SetAccessControl((FileSecurity)sd); + } + else + { + ((DirectoryInfo)item).SetAccessControl((DirectorySecurity)sd); + } + } + + public void Write(FileSystemInfo item) + { + if (item is FileInfo) + { + ((FileInfo)item).SetAccessControl((FileSecurity)sd); + } + else + { + ((DirectoryInfo)item).SetAccessControl((DirectorySecurity)sd); + } + } + + public void Write(string path) + { + FileSystemInfo item = null; + + if (File.Exists(path)) + { + item = new FileInfo(path); + } + else if (Directory.Exists(path)) + { + item = new DirectoryInfo(path); + } + else + { + throw new System.IO.FileNotFoundException("File not found", path); + } + + Write(item); + } + + #region Conversion + public static implicit operator FileSecurity(FileSystemSecurity2 fs2) + { + return fs2.fileSecurityDescriptor; + } + public static implicit operator FileSystemSecurity2(FileSecurity fs) + { + return new FileSystemSecurity2(new FileInfo("")); + } + + public static implicit operator DirectorySecurity(FileSystemSecurity2 fs2) + { + return fs2.directorySecurityDescriptor; + } + public static implicit operator FileSystemSecurity2(DirectorySecurity fs) + { + return new FileSystemSecurity2(new DirectoryInfo("")); + } + + //REQUIRED BECAUSE OF CONVERSION OPERATORS + public override bool Equals(object obj) + { + return this.fileSecurityDescriptor == (FileSecurity)obj; + } + public override int GetHashCode() + { + return fileSecurityDescriptor.GetHashCode(); + } + #endregion + + public static void ConvertToFileSystemFlags(ApplyTo ApplyTo, out InheritanceFlags inheritanceFlags, out PropagationFlags propagationFlags) + { + inheritanceFlags = InheritanceFlags.None; + propagationFlags = PropagationFlags.None; + + switch (ApplyTo) + { + case ApplyTo.FilesOnly: + inheritanceFlags = InheritanceFlags.ObjectInherit; + propagationFlags = PropagationFlags.InheritOnly; + break; + case ApplyTo.SubfoldersAndFilesOnly: + inheritanceFlags = InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit; + propagationFlags = PropagationFlags.InheritOnly; + break; + case ApplyTo.SubfoldersOnly: + inheritanceFlags = InheritanceFlags.ContainerInherit; + propagationFlags = PropagationFlags.InheritOnly; + break; + case ApplyTo.ThisFolderAndFiles: + inheritanceFlags = InheritanceFlags.ObjectInherit; + propagationFlags = PropagationFlags.None; + break; + case ApplyTo.ThisFolderAndSubfolders: + inheritanceFlags = InheritanceFlags.ContainerInherit; + propagationFlags = PropagationFlags.None; + break; + case ApplyTo.ThisFolderOnly: + inheritanceFlags = InheritanceFlags.None; + propagationFlags = PropagationFlags.None; + break; + case ApplyTo.ThisFolderSubfoldersAndFiles: + inheritanceFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit; + propagationFlags = PropagationFlags.None; + break; + case ApplyTo.FilesOnlyOneLevel: + inheritanceFlags = InheritanceFlags.ObjectInherit; + propagationFlags = PropagationFlags.InheritOnly | PropagationFlags.NoPropagateInherit; + break; + case ApplyTo.SubfoldersAndFilesOnlyOneLevel: + inheritanceFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit; + propagationFlags = PropagationFlags.InheritOnly | PropagationFlags.NoPropagateInherit; + break; + case ApplyTo.SubfoldersOnlyOneLevel: + inheritanceFlags = InheritanceFlags.ContainerInherit; + propagationFlags = PropagationFlags.InheritOnly | PropagationFlags.NoPropagateInherit; + break; + case ApplyTo.ThisFolderAndFilesOneLevel: + inheritanceFlags = InheritanceFlags.ObjectInherit; + propagationFlags = PropagationFlags.NoPropagateInherit; + break; + case ApplyTo.ThisFolderAndSubfoldersOneLevel: + inheritanceFlags = InheritanceFlags.ContainerInherit; + propagationFlags = PropagationFlags.NoPropagateInherit; + break; + case ApplyTo.ThisFolderSubfoldersAndFilesOneLevel: + inheritanceFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit; + propagationFlags = PropagationFlags.NoPropagateInherit; + break; + } + } + + public static ApplyTo ConvertToApplyTo(InheritanceFlags InheritanceFlags, PropagationFlags PropagationFlags) + { + if (InheritanceFlags == InheritanceFlags.ObjectInherit & PropagationFlags == PropagationFlags.InheritOnly) + return ApplyTo.FilesOnly; + else if (InheritanceFlags == (InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit) & PropagationFlags == PropagationFlags.InheritOnly) + return ApplyTo.SubfoldersAndFilesOnly; + else if (InheritanceFlags == InheritanceFlags.ContainerInherit & PropagationFlags == PropagationFlags.InheritOnly) + return ApplyTo.SubfoldersOnly; + else if (InheritanceFlags == InheritanceFlags.ObjectInherit & PropagationFlags == PropagationFlags.None) + return ApplyTo.ThisFolderAndFiles; + else if (InheritanceFlags == InheritanceFlags.ContainerInherit & PropagationFlags == PropagationFlags.None) + return ApplyTo.ThisFolderAndSubfolders; + else if (InheritanceFlags == InheritanceFlags.None & PropagationFlags == PropagationFlags.None) + return ApplyTo.ThisFolderOnly; + else if (InheritanceFlags == (InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit) & PropagationFlags == PropagationFlags.None) + return ApplyTo.ThisFolderSubfoldersAndFiles; + else if (InheritanceFlags == (InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit) & PropagationFlags == PropagationFlags.NoPropagateInherit) + return ApplyTo.ThisFolderSubfoldersAndFilesOneLevel; + else if (InheritanceFlags == InheritanceFlags.ContainerInherit & PropagationFlags == PropagationFlags.NoPropagateInherit) + return ApplyTo.ThisFolderAndSubfoldersOneLevel; + else if (InheritanceFlags == InheritanceFlags.ObjectInherit & PropagationFlags == PropagationFlags.NoPropagateInherit) + return ApplyTo.ThisFolderAndFilesOneLevel; + else if (InheritanceFlags == (InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit) & PropagationFlags == (PropagationFlags.InheritOnly | PropagationFlags.NoPropagateInherit)) + return ApplyTo.SubfoldersAndFilesOnlyOneLevel; + else if (InheritanceFlags == InheritanceFlags.ContainerInherit & PropagationFlags == (PropagationFlags.InheritOnly | PropagationFlags.NoPropagateInherit)) + return ApplyTo.SubfoldersOnlyOneLevel; + else if (InheritanceFlags == InheritanceFlags.ObjectInherit & PropagationFlags == (PropagationFlags.InheritOnly | PropagationFlags.NoPropagateInherit)) + return ApplyTo.FilesOnlyOneLevel; + + throw new RightsConverionException("The combination of InheritanceFlags and PropagationFlags could not be translated"); + } + + public static FileSystemRights MapGenericRightsToFileSystemRights(uint originalRights) + { + try + { + var r = Enum.Parse(typeof(FileSystemRights), (originalRights).ToString()); + if (r.ToString() == originalRights.ToString()) + { + throw new ArgumentOutOfRangeException(); + } + + var fileSystemRights = (FileSystemRights)originalRights; + return fileSystemRights; + } + catch (Exception) + { + FileSystemRights rights = 0; + if (Convert.ToBoolean(originalRights & (uint)GenericRights.GENERIC_EXECUTE)) + { + rights |= (FileSystemRights)MappedGenericRights.FILE_GENERIC_EXECUTE; + originalRights ^= (uint)GenericRights.GENERIC_EXECUTE; + } + if (Convert.ToBoolean(originalRights & (uint)GenericRights.GENERIC_READ)) + { + rights |= (FileSystemRights)MappedGenericRights.FILE_GENERIC_READ; + originalRights ^= (uint)GenericRights.GENERIC_READ; + } + if (Convert.ToBoolean(originalRights & (uint)GenericRights.GENERIC_WRITE)) + { + rights |= (FileSystemRights)MappedGenericRights.FILE_GENERIC_WRITE; + originalRights ^= (uint)GenericRights.GENERIC_WRITE; + } + if (Convert.ToBoolean(originalRights & (uint)GenericRights.GENERIC_ALL)) + { + rights |= (FileSystemRights)MappedGenericRights.FILE_GENERIC_ALL; + originalRights ^= (uint)GenericRights.GENERIC_ALL; + } + //throw new RightsConverionException("Cannot convert GenericRights into FileSystemRights"); + + var remainingRights = (FileSystemRights)Enum.Parse(typeof(FileSystemRights), (originalRights).ToString()); + + rights |= remainingRights; + + return rights; + } + } + } +} diff --git a/Security2/FileSystem/SimpleFileSystemAccessRule.cs b/Security2/FileSystem/SimpleFileSystemAccessRule.cs new file mode 100644 index 0000000..8bd09f1 --- /dev/null +++ b/Security2/FileSystem/SimpleFileSystemAccessRule.cs @@ -0,0 +1,134 @@ +using System.Security.AccessControl; + +namespace Security2 +{ + public class SimpleFileSystemAccessRule + { + private string fullName; + private IdentityReference2 identity; + private FileSystemRights2 accessRights; + private AccessControlType type; + + public AccessControlType AccessControlType + { + get { return type; } + set { type = value; } + } + + public string FullName + { + get { return fullName; } + } + + public string Name + { + get + { + return System.IO.Path.GetFileName(fullName); + } + } + + public IdentityReference2 Identity + { + get { return identity; } + } + + public SimpleFileSystemAccessRights AccessRights + { + get + { + SimpleFileSystemAccessRights result = SimpleFileSystemAccessRights.None; + + if ((accessRights & FileSystemRights2.Read) == FileSystemRights2.Read) + { result |= SimpleFileSystemAccessRights.Read; } + + if ((accessRights & FileSystemRights2.CreateFiles) == FileSystemRights2.CreateFiles) + { result |= SimpleFileSystemAccessRights.Write; } + + if ((accessRights & FileSystemRights2.AppendData) == FileSystemRights2.AppendData) + { result |= SimpleFileSystemAccessRights.Write; } + + if ((accessRights & FileSystemRights2.ReadExtendedAttributes) == FileSystemRights2.ReadExtendedAttributes) + { result |= SimpleFileSystemAccessRights.Read; } + + if ((accessRights & FileSystemRights2.WriteExtendedAttributes) == FileSystemRights2.WriteExtendedAttributes) + { result |= SimpleFileSystemAccessRights.Write; } + + if ((accessRights & FileSystemRights2.ExecuteFile) == FileSystemRights2.ExecuteFile) + { result |= SimpleFileSystemAccessRights.Read; } + + if ((accessRights & FileSystemRights2.DeleteSubdirectoriesAndFiles) == FileSystemRights2.DeleteSubdirectoriesAndFiles) + { result |= SimpleFileSystemAccessRights.Delete; } + + if ((accessRights & FileSystemRights2.ReadAttributes) == FileSystemRights2.ReadAttributes) + { result |= SimpleFileSystemAccessRights.Read; } + + if ((accessRights & FileSystemRights2.WriteAttributes) == FileSystemRights2.WriteAttributes) + { result |= SimpleFileSystemAccessRights.Write; } + + if ((accessRights & FileSystemRights2.Delete) == FileSystemRights2.Delete) + { result |= SimpleFileSystemAccessRights.Delete; } + + if ((accessRights & FileSystemRights2.ReadPermissions) == FileSystemRights2.ReadPermissions) + { result |= SimpleFileSystemAccessRights.Read; } + + if ((accessRights & FileSystemRights2.ChangePermissions) == FileSystemRights2.ChangePermissions) + { result |= SimpleFileSystemAccessRights.Write; } + + if ((accessRights & FileSystemRights2.TakeOwnership) == FileSystemRights2.TakeOwnership) + { result |= SimpleFileSystemAccessRights.Write; } + + if ((accessRights & FileSystemRights2.Synchronize) == FileSystemRights2.Synchronize) + { result |= SimpleFileSystemAccessRights.Read; } + + if ((accessRights & FileSystemRights2.FullControl) == FileSystemRights2.FullControl) + { result = (SimpleFileSystemAccessRights.Write | SimpleFileSystemAccessRights.Read | SimpleFileSystemAccessRights.Delete); } + + if ((accessRights & FileSystemRights2.GenericRead) == FileSystemRights2.GenericRead) + { result |= SimpleFileSystemAccessRights.Read; } + + if ((accessRights & FileSystemRights2.GenericWrite) == FileSystemRights2.GenericWrite) + { result |= SimpleFileSystemAccessRights.Write; } + + if ((accessRights & FileSystemRights2.GenericExecute) == FileSystemRights2.GenericExecute) + { result |= SimpleFileSystemAccessRights.Read; } + + if ((accessRights & FileSystemRights2.GenericAll) == FileSystemRights2.GenericAll) + { result = (SimpleFileSystemAccessRights.Write | SimpleFileSystemAccessRights.Read | SimpleFileSystemAccessRights.Delete); } + + return result; + } + } + + public SimpleFileSystemAccessRule(string Path, IdentityReference2 account, FileSystemRights2 access) + { + this.fullName = Path; + this.accessRights = access; + this.identity = account; + } + + public override bool Equals(object obj) + { + var compareObject = obj as SimpleFileSystemAccessRule; + + if (compareObject == null) + { + return false; + } + + if (this.AccessRights == compareObject.AccessRights && this.Identity == compareObject.Identity && this.AccessControlType == compareObject.AccessControlType) + { + return true; + } + else + { + return false; + } + } + + public override int GetHashCode() + { + return this.Identity.GetHashCode() | this.AccessRights.GetHashCode() | this.AccessControlType.GetHashCode(); + } + } +} diff --git a/Security2/FileSystem/SimpleFileSystemAuditRule.cs b/Security2/FileSystem/SimpleFileSystemAuditRule.cs new file mode 100644 index 0000000..fbf2a58 --- /dev/null +++ b/Security2/FileSystem/SimpleFileSystemAuditRule.cs @@ -0,0 +1,134 @@ +using System.Security.AccessControl; + +namespace Security2 +{ + public class SimpleFileSystemAuditRule + { + private string fullName; + private IdentityReference2 identity; + private FileSystemRights2 accessRights; + private AccessControlType type; + + public AccessControlType AccessControlType + { + get { return type; } + set { type = value; } + } + + public string FullName + { + get { return fullName; } + } + + public string Name + { + get + { + return System.IO.Path.GetFileName(fullName); + } + } + + public IdentityReference2 Identity + { + get { return identity; } + } + + public SimpleFileSystemAccessRights AccessRights + { + get + { + SimpleFileSystemAccessRights result = SimpleFileSystemAccessRights.None; + + if ((accessRights & FileSystemRights2.Read) == FileSystemRights2.Read) + { result |= SimpleFileSystemAccessRights.Read; } + + if ((accessRights & FileSystemRights2.CreateFiles) == FileSystemRights2.CreateFiles) + { result |= SimpleFileSystemAccessRights.Write; } + + if ((accessRights & FileSystemRights2.AppendData) == FileSystemRights2.AppendData) + { result |= SimpleFileSystemAccessRights.Write; } + + if ((accessRights & FileSystemRights2.ReadExtendedAttributes) == FileSystemRights2.ReadExtendedAttributes) + { result |= SimpleFileSystemAccessRights.Read; } + + if ((accessRights & FileSystemRights2.WriteExtendedAttributes) == FileSystemRights2.WriteExtendedAttributes) + { result |= SimpleFileSystemAccessRights.Write; } + + if ((accessRights & FileSystemRights2.ExecuteFile) == FileSystemRights2.ExecuteFile) + { result |= SimpleFileSystemAccessRights.Read; } + + if ((accessRights & FileSystemRights2.DeleteSubdirectoriesAndFiles) == FileSystemRights2.DeleteSubdirectoriesAndFiles) + { result |= SimpleFileSystemAccessRights.Delete; } + + if ((accessRights & FileSystemRights2.ReadAttributes) == FileSystemRights2.ReadAttributes) + { result |= SimpleFileSystemAccessRights.Read; } + + if ((accessRights & FileSystemRights2.WriteAttributes) == FileSystemRights2.WriteAttributes) + { result |= SimpleFileSystemAccessRights.Write; } + + if ((accessRights & FileSystemRights2.Delete) == FileSystemRights2.Delete) + { result |= SimpleFileSystemAccessRights.Delete; } + + if ((accessRights & FileSystemRights2.ReadPermissions) == FileSystemRights2.ReadPermissions) + { result |= SimpleFileSystemAccessRights.Read; } + + if ((accessRights & FileSystemRights2.ChangePermissions) == FileSystemRights2.ChangePermissions) + { result |= SimpleFileSystemAccessRights.Write; } + + if ((accessRights & FileSystemRights2.TakeOwnership) == FileSystemRights2.TakeOwnership) + { result |= SimpleFileSystemAccessRights.Write; } + + if ((accessRights & FileSystemRights2.Synchronize) == FileSystemRights2.Synchronize) + { result |= SimpleFileSystemAccessRights.Read; } + + if ((accessRights & FileSystemRights2.FullControl) == FileSystemRights2.FullControl) + { result = (SimpleFileSystemAccessRights.Write | SimpleFileSystemAccessRights.Read | SimpleFileSystemAccessRights.Delete); } + + if ((accessRights & FileSystemRights2.GenericRead) == FileSystemRights2.GenericRead) + { result |= SimpleFileSystemAccessRights.Read; } + + if ((accessRights & FileSystemRights2.GenericWrite) == FileSystemRights2.GenericWrite) + { result |= SimpleFileSystemAccessRights.Write; } + + if ((accessRights & FileSystemRights2.GenericExecute) == FileSystemRights2.GenericExecute) + { result |= SimpleFileSystemAccessRights.Read; } + + if ((accessRights & FileSystemRights2.GenericAll) == FileSystemRights2.GenericAll) + { result = (SimpleFileSystemAccessRights.Write | SimpleFileSystemAccessRights.Read | SimpleFileSystemAccessRights.Delete); } + + return result; + } + } + + public SimpleFileSystemAuditRule(string Path, IdentityReference2 account, FileSystemRights2 access) + { + this.fullName = Path; + this.accessRights = access; + this.identity = account; + } + + public override bool Equals(object obj) + { + var compareObject = obj as SimpleFileSystemAccessRule; + + if (compareObject == null) + { + return false; + } + + if (this.AccessRights == compareObject.AccessRights && this.Identity == compareObject.Identity && this.AccessControlType == compareObject.AccessControlType) + { + return true; + } + else + { + return false; + } + } + + public override int GetHashCode() + { + return this.Identity.GetHashCode() | this.AccessRights.GetHashCode() | this.AccessControlType.GetHashCode(); + } + } +} diff --git a/Security2/IdentityReference2.cs b/Security2/IdentityReference2.cs new file mode 100644 index 0000000..9f01a96 --- /dev/null +++ b/Security2/IdentityReference2.cs @@ -0,0 +1,264 @@ +using System; +using System.Security.Principal; +using System.Text.RegularExpressions; + +namespace Security2 +{ + public class IdentityReference2 + { + protected static Regex sidValidation = new Regex("(S-1-)[0-9-]+", RegexOptions.IgnoreCase); + protected SecurityIdentifier sid; + protected NTAccount ntAccount; + protected string lastError; + + #region Properties + + public string Sid + { + get { return sid.Value; } + } + + public string AccountName + { + get + { + return ntAccount != null ? ntAccount.Value : string.Empty; + } + } + + public string LastError + { + get { return lastError; } + } + + #endregion Properties + + #region Constructors + + public IdentityReference2(IdentityReference ir) + { + ntAccount = ir as NTAccount; + if (ntAccount != null) + { + //throws an IdentityNotMapped Exception if the account cannot be translated + sid = (SecurityIdentifier)ntAccount.Translate(typeof(SecurityIdentifier)); + } + else + { + sid = ir as SecurityIdentifier; + if (sid != null) + { + try + { + ntAccount = (NTAccount)sid.Translate(typeof(NTAccount)); + } + catch (Exception ex) + { + lastError = ex.Message; + } + } + } + } + + public IdentityReference2(string value) + { + if (string.IsNullOrEmpty(value)) + throw new ArgumentException("The value cannot be empty"); + + var sidMatch = sidValidation.Match(value); + + if (!string.IsNullOrEmpty(sidMatch.Value)) + { + //creating a SecurityIdentifier should always work if the string is in the right format + try + { + sid = new SecurityIdentifier(sidMatch.Value); + } + catch (Exception ex) + { + throw new InvalidCastException("Could not create an IdentityReference2 with the given SID", ex); + } + + //this is only going to work if the SID can be resolved + try + { + ntAccount = (NTAccount)sid.Translate(typeof(NTAccount)); + } + catch (Exception ex) + { + lastError = ex.Message; + } + } + else + { + try + { + //creating an NTAccount always works, the OS does not verify the name + ntAccount = new NTAccount(value); + //verification si done by translating the name into a SecurityIdentifier (SID) + sid = (SecurityIdentifier)ntAccount.Translate(typeof(SecurityIdentifier)); + } + catch (IdentityNotMappedException ex) + { + throw ex; + } + } + } + + #endregion Constructors + + #region Conversion + + //NTAccount + public static explicit operator NTAccount(IdentityReference2 ir2) + { + return ir2.ntAccount; + } + + public static explicit operator IdentityReference2(NTAccount ntAccount) + { + return new IdentityReference2(ntAccount); + } + + //SecurityIdentifier + public static explicit operator SecurityIdentifier(IdentityReference2 ir2) + { + return ir2.sid; + } + + public static explicit operator IdentityReference2(SecurityIdentifier sid) + { + return new IdentityReference2(sid); + } + + //IdentityReference + public static implicit operator IdentityReference(IdentityReference2 ir2) + { + return ir2.sid; + } + + public static implicit operator IdentityReference2(IdentityReference ir) + { + return new IdentityReference2(ir); + } + + //string + public static implicit operator IdentityReference2(string value) + { + return new IdentityReference2(value); + } + + public static implicit operator string(IdentityReference2 ir2) + { + return ir2.ToString(); + } + + #endregion Conversion + + #region comparison + + public override bool Equals(object obj) + { + //Instance cannot be null + if (ReferenceEquals(obj, null)) + return false; + + //Instances are equal + if (ReferenceEquals(this, obj)) + return true; + + SecurityIdentifier sid = obj as SecurityIdentifier; + if (sid != null) + { + return this.sid == sid; + } + + var ntAccount = obj as NTAccount; + if (ntAccount != null) + { + return this.ntAccount == ntAccount; + } + + IdentityReference2 ir2 = obj as IdentityReference2; + if (ir2 != null) + { + return this.sid == ir2.sid; + } + + string value = obj as string; + if (value != null) + { + if (this.sid.Value == value) + { + return true; + } + + if (this.ntAccount != null) + { + if (this.ntAccount.Value.ToLower() == value.ToLower()) + { + return true; + } + } + } + + return false; + } + + public override int GetHashCode() + { + return sid.GetHashCode(); + } + + public static bool operator ==(IdentityReference2 ir1, IdentityReference2 ir2) + { + //Instances are equal + if (ReferenceEquals(ir1, ir2)) + return true; + + //Instance cannot be null + if (ReferenceEquals(ir1, null) | ReferenceEquals(ir2, null)) + return false; + + return ir1.Equals(ir2); + } + + public static bool operator !=(IdentityReference2 ir1, IdentityReference2 ir2) + { + //Instances are equal + if (ReferenceEquals(ir1, ir2)) + return false; + + //Instance cannot be null + if (ReferenceEquals(ir1, null) | ReferenceEquals(ir2, null)) + return true; + + return !ir1.Equals(ir2); + } + + #endregion comparison + + #region Methods + + public byte[] GetBinaryForm() + { + byte[] rawSid = new byte[sid.BinaryLength]; + sid.GetBinaryForm(rawSid, 0); + return rawSid; + } + + public override string ToString() + { + if (ntAccount == null) + { + return sid.ToString(); + } + else + { + return ntAccount.ToString(); + } + } + + #endregion Methods + } +} \ No newline at end of file diff --git a/Security2/Properties/AssemblyInfo.cs b/Security2/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..6144a7c --- /dev/null +++ b/Security2/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Security2")] +[assembly: AssemblyDescription("Wrapper for security and identity classes")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("Security2")] +[assembly: AssemblyCopyright("Copyright © Raimund Andree 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("d89dc40a-9b43-4bce-972d-b995df8d2820")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("3.2.3.0")] +[assembly: AssemblyFileVersion("3.2.3.0")] diff --git a/Security2/Registry/RegistrySecurity.cs b/Security2/Registry/RegistrySecurity.cs new file mode 100644 index 0000000..c7085fa --- /dev/null +++ b/Security2/Registry/RegistrySecurity.cs @@ -0,0 +1,499 @@ +using System; +using System.Collections.Generic; +using System.Security.AccessControl; +using Microsoft.Win32; +using System.Runtime.InteropServices; +using System.Security.Principal; + +namespace Security2 +{ + //#region FileSecurity2 + //public class FileSecurity2 : ICast, IDisposable + //{ + // protected FileSecurity securityDescriptor; + + // public string FullName { get; set; } + + // public string Name { get { return System.IO.Path.GetFileName(FullName); } } + + // public FileSecurity2() { } + // public FileSecurity2(FileSecurity SecurityDescriptor) + // { + // this.securityDescriptor = SecurityDescriptor; + // } + + // #region conversion + // public static implicit operator FileSecurity(FileSecurity2 V) + // { + // return V.securityDescriptor; + // } + // public static implicit operator FileSecurity2(FileSecurity n) + // { + // return new FileSecurity2(n); + // } + // //REQUIRED BECAUSE OF CONVERSION OPERATORS + // public override bool Equals(object obj) + // { + // return this.securityDescriptor == (FileSecurity)obj; + // } + // public override int GetHashCode() + // { + // return this.securityDescriptor.GetHashCode(); + // } + // #endregion + + // #region ICast Members + // public FileSecurity Cast + // { + // get { return this.securityDescriptor; } + // } + // #endregion + + // #region IDisposable Members + // public void Dispose() + // { } + // #endregion + //} + //#endregion + + //#region DirectorySecurity2 + //public class DirectorySecurity2 : ICast, IDisposable + //{ + // protected DirectorySecurity securityDescriptor; + + // public string FullName { get; set; } + + // public string Name { get { return System.IO.Path.GetFileName(FullName); } } + + // public DirectorySecurity2() { } + // public DirectorySecurity2(DirectorySecurity SecurityDescriptor) + // { + // this.securityDescriptor = SecurityDescriptor; + // } + + // #region conversion + // public static implicit operator DirectorySecurity(DirectorySecurity2 V) + // { + // return V.securityDescriptor; + // } + // public static implicit operator DirectorySecurity2(DirectorySecurity n) + // { + // return new DirectorySecurity2(n); + // } + // //REQUIRED BECAUSE OF CONVERSION OPERATORS + // public override bool Equals(object obj) + // { + // return this.securityDescriptor == (DirectorySecurity)obj; + // } + // public override int GetHashCode() + // { + // return this.securityDescriptor.GetHashCode(); + // } + // #endregion + + // #region ICast Members + // public DirectorySecurity Cast + // { + // get { return this.securityDescriptor; } + // } + // #endregion + + // #region IDisposable Members + // public void Dispose() + // { } + // #endregion + //} + //#endregion + + #region RegistryAccessRule2 + public class RegistryAccessRule2 : IDisposable + { + protected RegistryAccessRule registryAccessRule; + + public string Name + { + get + { + if (!string.IsNullOrEmpty(FullName)) + { + if (FullName.Contains("\\")) + { + var elements = FullName.Split('\\'); + return elements[elements.Length - 1]; + } + else + { + return FullName; + } + } + else + { + return null; + } + } + } + + public string FullName { get; set; } + + public bool InheritanceEnabled { get; set; } + + public RegistryAccessRule2(RegistryAccessRule registryAccessRule) + { + this.registryAccessRule = registryAccessRule; + } + + #region Properties + public AccessControlType AccessControlType { get { return registryAccessRule.AccessControlType; } } + public RegistryRights RegistryRights { get { return registryAccessRule.RegistryRights; } } + public IdentityReference2 IdentityReference { get { return (IdentityReference2)registryAccessRule.IdentityReference; } } + public InheritanceFlags InheritanceFlags { get { return registryAccessRule.InheritanceFlags; } } + public bool IsInherited { get { return registryAccessRule.IsInherited; } } + public PropagationFlags PropagationFlags { get { return registryAccessRule.PropagationFlags; } } + #endregion + + #region conversion + public static implicit operator RegistryAccessRule(RegistryAccessRule2 V) + { + return V.registryAccessRule; + } + public static implicit operator RegistryAccessRule2(RegistryAccessRule n) + { + return new RegistryAccessRule2(n); + } + //REQUIRED BECAUSE OF CONVERSION OPERATORS + public override bool Equals(object obj) + { + return this.registryAccessRule == (RegistryAccessRule)obj; + } + public override int GetHashCode() + { + return this.registryAccessRule.GetHashCode(); + } + public override string ToString() + { + return registryAccessRule.ToString(); + } + #endregion + + #region IDisposable Members + public void Dispose() + { } + #endregion + } + #endregion + + #region RegistryInheritanceInfo + public class RegistryInheritanceInfo + { + public RegistryKey Item { get; set; } + public bool InheritanceEnabled { get; set; } + + public string FullName { get { return Item.Name; } } + public string Name + { + get + { + if (!string.IsNullOrEmpty(FullName)) + { + if (FullName.Contains("\\")) + { + var elements = FullName.Split('\\'); + return elements[elements.Length - 1]; + } + else + { + return FullName; + } + } + else + { + return null; + } + } + } + } + #endregion + + #region RegistryEffectivePermissionEntry + public class RegistryEffectivePermissionEntry + { + private IdentityReference2 account; + public IdentityReference2 Account { get { return account; } } + + private uint accessMask; + public uint AccessMask { get { return accessMask; } } + + private string objectPath; + public string FullName { get { return objectPath; } } + public string Name { get + { + if (!string.IsNullOrEmpty(FullName)) + { + if (FullName.Contains("\\")) + { + var elements = FullName.Split('\\'); + return elements[elements.Length - 1]; + } + else + { + return FullName; + } + } + else + { + return null; + } + } + } + + private List accessAsString; + public List AccessAsString { get { return accessAsString; } } + + public RegistryEffectivePermissionEntry(IdentityReference2 id, uint AccessMask, string FullName) + { + this.account = id; + this.accessMask = AccessMask; + this.objectPath = FullName; + this.accessAsString = new List(); + + if (accessMask == 0) + { + accessAsString.Add("None"); + } + else + { + string tempString = ((RegistryRights)this.accessMask).ToString(); + foreach (var s in tempString.Split(',')) + { + this.accessAsString.Add(s); + } + } + } + } + #endregion + + #region RegistryOwner + public class RegistryOwner + { + public RegistryKey Item { get; set; } + public Security2.IdentityReference2 Account { get; set; } + } + #endregion + + #region Win32 + #region Win32Enums + /// + /// enum used by RegOpenKeyEx + /// + public enum SAM_DESIRED : long + { + KEY_QUERY_VALUE = 0x1, + KEY_SET_VALUE = 0x2, + KEY_ALL_ACCESS = 0xf003f, + KEY_CREATE_SUB_KEY = 0x4, + KEY_ENUMERATE_SUB_KEYS = 0x8, + KEY_NOTIFY = 0x10, + KEY_CREATE_LINK = 0x20, + READ_CONTROL = 0x20000, + WRITE_DAC = 0x40000, + WRITE_OWNER = 0x80000, + SYNCHRONIZE = 0x100000, + + STANDARD_RIGHTS_REQUIRED = 0xf0000, + + STANDARD_RIGHTS_READ = READ_CONTROL, + STANDARD_RIGHTS_WRITE = READ_CONTROL, + STANDARD_RIGHTS_EXECUTE = READ_CONTROL, + + KEY_READ = STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY, + + KEY_WRITE = STANDARD_RIGHTS_WRITE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY, + + KEY_EXECUTE = KEY_READ + } + + /// + /// constant enum for registry roots + /// + public enum REGISTRY_ROOT : long + { + HKEY_CLASSES_ROOT = 0x80000000, + HKEY_CURRENT_USER = 0x80000001, + HKEY_LOCAL_MACHINE = 0x80000002, + HKEY_USERS = 0x80000003 + } + #endregion + + public class RegistryKeyOpenException : System.Exception + { + private long win32ErrorCode; + public long Win32ErrorCode { get { return win32ErrorCode; } } + + public RegistryKeyOpenException() + : base("Cannot open Registry Key") + { } + + public RegistryKeyOpenException(Exception innerException) + : base("Cannot open Registry Key", innerException) + { } + + public RegistryKeyOpenException(long Win32ErrorCode) + : base("Cannot open Registry Key") + { + this.win32ErrorCode = Win32ErrorCode; + } + + public RegistryKeyOpenException(Exception innerException, long Win32ErrorCode) + : base("Cannot open Registry Key", innerException) + { + this.win32ErrorCode = Win32ErrorCode; + } + } + + public class RegistryKeySetSecurityException : System.Exception + { + private long win32ErrorCode; + public long Win32ErrorCode { get { return win32ErrorCode; } } + + public RegistryKeySetSecurityException() + : base("Cannot set security descriptor on registry key") + { } + + public RegistryKeySetSecurityException(Exception innerException) + : base("Cannot set security descriptor on registry key", innerException) + { } + + public RegistryKeySetSecurityException(long Win32ErrorCode) + : base("Cannot set security descriptor on registry key") + { + this.win32ErrorCode = Win32ErrorCode; + } + + public RegistryKeySetSecurityException(Exception innerException, long Win32ErrorCode) + : base("Cannot set security descriptor on registry key", innerException) + { + this.win32ErrorCode = Win32ErrorCode; + } + } + + public class Win32RegistrySecurity + { + + #region DllImports + [DllImport("kernel32.dll")] + private static extern long CloseHandle(IntPtr hHandle); + + [DllImport("advapi32.dll")] + private static extern long InitializeSecurityDescriptor(ref SECURITY_DESCRIPTOR pSecurityDescriptor, long dwRevision); + + [DllImport("advapi32.dll")] + private static extern long SetSecurityDescriptorOwner(ref SECURITY_DESCRIPTOR pSecurityDescriptor, byte[] pOwner, long bOwnerDefaulted); + + [DllImport("advapi32.dll")] + private static extern long RegSetKeySecurity(IntPtr ptrKey, SECURITY_INFORMATION SecurityInformation, SECURITY_DESCRIPTOR pSecurityDescriptor); + + [DllImport("advapi32.dll", EntryPoint = "RegOpenKeyExA")] + private static extern long RegOpenKeyEx(REGISTRY_ROOT hKey, string lpSubKey, long ulOptions, SAM_DESIRED samDesired, ref IntPtr ptrKey); + + [DllImport("advapi32.dll")] + private static extern long RegCloseKey(IntPtr ptrKey); + + private struct SECURITY_DESCRIPTOR + { + public byte Revision; + public byte Sbz1; + public long Control; + public long Owner; + public long Group; + public ACL Sacl; + public ACL Dacl; + } + + private struct ACL + { + public byte AclRevision; + public byte Sbz1; + public int AclSize; + public int AceCount; + public int Sbz2; + } + #endregion + + private RegistryKey GetRegistryKey(REGISTRY_ROOT Root, string KeyPath, RegistryRights Desired) + { + try + { + switch (Root) + { + case REGISTRY_ROOT.HKEY_CLASSES_ROOT: + return Registry.ClassesRoot.OpenSubKey(KeyPath, RegistryKeyPermissionCheck.ReadWriteSubTree, Desired); + case REGISTRY_ROOT.HKEY_LOCAL_MACHINE: + return Registry.LocalMachine.OpenSubKey(KeyPath, RegistryKeyPermissionCheck.ReadWriteSubTree, Desired); + case REGISTRY_ROOT.HKEY_USERS: + return Registry.Users.OpenSubKey(KeyPath, RegistryKeyPermissionCheck.ReadWriteSubTree, Desired); + case REGISTRY_ROOT.HKEY_CURRENT_USER: + return Registry.CurrentUser.OpenSubKey(KeyPath, RegistryKeyPermissionCheck.ReadWriteSubTree, Desired); + default: + return null; + } + } + catch (Exception) + { + return null; + } + } + + public void SetRegistryOwner(REGISTRY_ROOT Root, string KeyPath, SecurityIdentifier sid) + { + long win32ErrorCode = 0; + + SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(); + byte[] byteSid = new byte[sid.BinaryLength]; + sid.GetBinaryForm(byteSid, 0); + + IntPtr pRegKey = IntPtr.Zero; + + try + { + win32ErrorCode = RegOpenKeyEx(Root, KeyPath, 0, SAM_DESIRED.WRITE_OWNER, ref pRegKey); + if (win32ErrorCode != 0) + { + throw new RegistryKeyOpenException(win32ErrorCode); + } + } + catch (RegistryKeyOpenException) + { + throw; + } + catch (Exception ex) + { + throw new RegistryKeyOpenException(ex); + } + + InitializeSecurityDescriptor(ref sd, 1); + SetSecurityDescriptorOwner(ref sd, byteSid, 0); + + try + { + win32ErrorCode = RegSetKeySecurity(pRegKey, SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION, sd); + if (win32ErrorCode != 0) + { + throw new RegistryKeySetSecurityException(win32ErrorCode); + } + } + catch (RegistryKeySetSecurityException) + { + throw; + } + catch (Exception ex) + { + throw new RegistryKeyOpenException(ex); + } + finally + { + RegCloseKey(pRegKey); + } + } + } +#endregion +} \ No newline at end of file diff --git a/Security2/Security2.csproj b/Security2/Security2.csproj new file mode 100644 index 0000000..4869af3 --- /dev/null +++ b/Security2/Security2.csproj @@ -0,0 +1,98 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {B437C364-5BC7-42E4-93F7-0F459A5DF0D0} + Library + Properties + Security2 + Security2 + v3.5 + 512 + Client + SAK + SAK + SAK + SAK + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {f0f9af1e-d5b5-4d72-804a-5380622fbdea} + AlphaFS + + + + + \ No newline at end of file diff --git a/Security2/Win32/Enums.cs b/Security2/Win32/Enums.cs new file mode 100644 index 0000000..8af9592 --- /dev/null +++ b/Security2/Win32/Enums.cs @@ -0,0 +1,116 @@ +using System; + +namespace Security2 +{ + enum SECURITY_INFORMATION + { + OWNER_SECURITY_INFORMATION = 1, + GROUP_SECURITY_INFORMATION = 2, + DACL_SECURITY_INFORMATION = 4, + SACL_SECURITY_INFORMATION = 8, + } + + internal enum AuthzRpcClientVersion : ushort // USHORT + { + V1 = 1 + } + + [Flags] + internal enum AuthzResourceManagerFlags : uint + { + NO_AUDIT = 0x1, + } + + [Flags] + internal enum StdAccess : uint + { + None = 0x0, + + SYNCHRONIZE = 0x100000, + STANDARD_RIGHTS_REQUIRED = 0xF0000, + + MAXIMUM_ALLOWED = 0x2000000, + } + + [Flags] + internal enum AuthzInitFlags : uint + { + Default = 0x0, + SkipTokenGroups = 0x2, + RequireS4ULogon = 0x4, + ComputePrivileges = 0x8, + } + + internal enum AuthzACFlags : uint // DWORD + { + None = 0, + NoDeepCopySD + } + + [Flags] + internal enum SecurityInformationClass : uint + { + Owner = 0x00001, + Group = 0x00002, + Dacl = 0x00004, + Sacl = 0x00008, + Label = 0x00010, + Attribute = 0x00020, + Scope = 0x00040 + } + + internal enum ObjectType : uint + { + File = 1, + } + + [Flags] + internal enum FileAccess : uint + { + None = 0x0, + ReadData = 0x1, + WriteData = 0x2, + AppendData = 0x4, + ReadExAttrib = 0x8, + WriteExAttrib = 0x10, + Execute = 0x20, + DeleteChild = 0x40, + ReadAttrib = 0x80, + WriteAttrib = 0x100, + + Delete = 0x10000, // DELETE, + ReadPermissions = 0x20000, // READ_CONTROL + ChangePermissions = 0x40000, // WRITE_DAC, + TakeOwnership = 0x80000, // WRITE_OWNER, + + GenericRead = ReadPermissions + | ReadData + | ReadAttrib + | ReadExAttrib + | StdAccess.SYNCHRONIZE, + + GenericAll = (StdAccess.STANDARD_RIGHTS_REQUIRED | 0x1FF), + + CategoricalAll = uint.MaxValue + } + + [Flags] + internal enum FileShare : uint + { + None = 0x0, + Read = 0x1, + Write = 0x2, + Delete = 0x4 + } + + internal enum FileMode : uint + { + OpenExisting = 3, + } + + [Flags] + internal enum FileFlagAttrib : uint + { + BackupSemantics = 0x02000000, + } +} diff --git a/Security2/Win32/Errors.cs b/Security2/Win32/Errors.cs new file mode 100644 index 0000000..cc2fe7d --- /dev/null +++ b/Security2/Win32/Errors.cs @@ -0,0 +1,96 @@ +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (c) Microsoft Corporation. All rights reserved + +using System; +using System.Runtime.InteropServices; + +namespace Security2 +{ + static internal class Win32Error + { + // Note - the error codes here should all match the definitions in winerror.h. + + /// + /// Equal to ERROR_SUCCESS (The operation completed successfully). + /// + public const int NO_ERROR = 0; + + /// + /// Error code indicating: The operation completed successfully. + /// + public const int ERROR_SUCCESS = 0; + + /// + /// The system cannot find the file specified. + /// + public const int ERROR_FILE_NOT_FOUND = 2; + + /// + /// Error code indicating: Access is denied. + /// + public const int ERROR_ACCESS_DENIED = 5; + + /// + /// Error code indicating: Not enough storage is available to process this command + /// + public const int ERROR_NOT_ENOUGH_MEMORY = 8; + /// + /// The data area passed to a system call is too small. + /// + public const int ERROR_INSUFFICIENT_BUFFER = 122; + + /// + /// The filename or extension is too long. + /// + public const int ERROR_FILENAME_EXCED_RANGE = 206; + + /// + /// More data is available. + /// + public const int ERROR_MORE_DATA = 234; + + /// + /// An attempt was made to reference a token that does not exist. + /// + public const int ERROR_NO_TOKEN = 1008; + + /// + /// The specified device name is invalid. + /// + public const int ERROR_BAD_DEVICE = 1200; + + /// + /// Not all privileges or groups referenced are assigned to the caller. + /// + public const int ERROR_NOT_ALL_ASSIGNED = 1300; + + /// + /// A specified privilege does not exist. + /// + public const int ERROR_NO_SUCH_PRIVILEGE = 1313; + + /// + /// Cannot open an anonymous level security token. + /// + public const int ERROR_CANT_OPEN_ANONYMOUS = 1347; + + /// + /// The RPC server is unavailable. + /// + public const int RPC_S_SERVER_UNAVAILABLE = 1722; + + /// + /// There are no more endpoints available from the endpoint mapper. + /// + public const int EPT_S_NOT_REGISTERED = 1753; + + /// + /// This network connection does not exist. + /// + public const int ERROR_NOT_CONNECTED = 2250; + } +} \ No newline at end of file diff --git a/Security2/Win32/Functions.cs b/Security2/Win32/Functions.cs new file mode 100644 index 0000000..43211e1 --- /dev/null +++ b/Security2/Win32/Functions.cs @@ -0,0 +1,103 @@ +using Microsoft.Win32.SafeHandles; +using System; +using System.Runtime.InteropServices; + +namespace Security2 +{ + internal partial class Win32 + { + const string ADVAPI32_DLL = "advapi32.dll"; + internal const string KERNEL32_DLL = "kernel32.dll"; + internal const string AUTHZ_DLL = "authz.dll"; + + [DllImport(ADVAPI32_DLL, EntryPoint = "GetInheritanceSourceW", CharSet = CharSet.Unicode)] + static extern UInt32 GetInheritanceSource( + [MarshalAs(UnmanagedType.LPTStr)] string pObjectName, + System.Security.AccessControl.ResourceType ObjectType, + SECURITY_INFORMATION SecurityInfo, + [MarshalAs(UnmanagedType.Bool)]bool Container, + IntPtr pObjectClassGuids, + UInt32 GuidCount, + byte[] pAcl, + IntPtr pfnArray, + ref GENERIC_MAPPING pGenericMapping, + IntPtr pInheritArray + ); + + [DllImport(ADVAPI32_DLL, EntryPoint = "FreeInheritedFromArray", CharSet = CharSet.Unicode)] + static extern UInt32 FreeInheritedFromArray( + IntPtr pInheritArray, + UInt16 AceCnt, + IntPtr pfnArray + ); + + [DllImport(AUTHZ_DLL, CharSet = CharSet.Unicode, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool AuthzInitializeRemoteResourceManager( + IntPtr rpcInitInfo, + out SafeAuthzRMHandle authRM); + + [DllImport(AUTHZ_DLL, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool AuthzInitializeResourceManager( + AuthzResourceManagerFlags flags, + IntPtr pfnAccessCheck, + IntPtr pfnComputeDynamicGroups, + IntPtr pfnFreeDynamicGroups, + string szResourceManagerName, + out SafeAuthzRMHandle phAuthzResourceManager); + + [DllImport(Win32.AUTHZ_DLL, CharSet = CharSet.Unicode, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool AuthzInitializeContextFromSid( + AuthzInitFlags flags, + byte[] rawUserSid, + SafeAuthzRMHandle authzRM, + IntPtr expirationTime, + Win32.LUID Identifier, + IntPtr DynamicGroupArgs, + out IntPtr authzClientContext); + + [DllImport(Win32.AUTHZ_DLL, CharSet = CharSet.Unicode, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool AuthzAccessCheck( + AuthzACFlags flags, + IntPtr hAuthzClientContext, + ref AUTHZ_ACCESS_REQUEST pRequest, + IntPtr AuditEvent, + byte[] rawSecurityDescriptor, + IntPtr[] OptionalSecurityDescriptorArray, + UInt32 OptionalSecurityDescriptorCount, + ref AUTHZ_ACCESS_REPLY pReply, + IntPtr cachedResults); + + [DllImport(Win32.AUTHZ_DLL, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool AuthzFreeContext(IntPtr authzClientContext); + + [DllImport(Win32.ADVAPI32_DLL, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode)] + public static extern UInt32 GetSecurityDescriptorLength(IntPtr pSecurityDescriptor); + + + [DllImport(Win32.ADVAPI32_DLL, CallingConvention = CallingConvention.Winapi, SetLastError = true, CharSet = CharSet.Unicode)] + internal static extern UInt32 GetSecurityInfo( + SafeFileHandle handle, + ObjectType objectType, + SecurityInformationClass infoClass, + IntPtr owner, + IntPtr group, + IntPtr dacl, + IntPtr sacl, + out IntPtr securityDescriptor); + + [DllImport(Win32.KERNEL32_DLL, SetLastError = true, CharSet = CharSet.Unicode)] + internal static extern SafeFileHandle CreateFile( + string lpFileName, + FileAccess desiredAccess, + FileShare shareMode, + IntPtr lpSecurityAttributes, + FileMode mode, + FileFlagAttrib flagsAndAttributes, + IntPtr hTemplateFile); + } +} \ No newline at end of file diff --git a/Security2/Win32/Lib.cs b/Security2/Win32/Lib.cs new file mode 100644 index 0000000..55be9a0 --- /dev/null +++ b/Security2/Win32/Lib.cs @@ -0,0 +1,322 @@ +using Alphaleonis.Win32.Filesystem; +using Microsoft.Win32.SafeHandles; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Security.AccessControl; + +namespace Security2 +{ + internal partial class Win32 + { + internal const string AUTHZ_OBJECTUUID_WITHCAP = "9a81c2bd-a525-471d-a4ed-49907c0b23da"; + internal const string RCP_OVER_TCP_PROTOCOL = "ncacn_ip_tcp"; + + IntPtr userClientCtxt = IntPtr.Zero; + SafeAuthzRMHandle authzRM; + IntPtr pGrantedAccess = IntPtr.Zero; + IntPtr pErrorSecObj = IntPtr.Zero; + + #region GetInheritedFrom + public static List GetInheritedFrom(FileSystemInfo item, ObjectSecurity sd) + { + var inheritedFrom = new List(); + + var sdBytes = sd.GetSecurityDescriptorBinaryForm(); + byte[] aclBytes = null; + var rawSd = new RawSecurityDescriptor(sdBytes, 0); + + var aceCount = 0; + + if (rawSd.SystemAcl != null) + { + aceCount = rawSd.SystemAcl.Count; + aclBytes = new byte[rawSd.SystemAcl.BinaryLength]; + rawSd.SystemAcl.GetBinaryForm(aclBytes, 0); + + try + { + inheritedFrom = GetInheritedFrom(item.FullName, + aclBytes, + aceCount, + item is DirectoryInfo ? true : false, + SECURITY_INFORMATION.SACL_SECURITY_INFORMATION); + } + catch + { + inheritedFrom = new List(); + for (int i = 0; i < aceCount; i++) + { + inheritedFrom.Add("unknown parent"); + } + } + } + else if (rawSd.DiscretionaryAcl != null) + { + aceCount = rawSd.DiscretionaryAcl.Count; + aclBytes = new byte[rawSd.DiscretionaryAcl.BinaryLength]; + rawSd.DiscretionaryAcl.GetBinaryForm(aclBytes, 0); + + try + { + inheritedFrom = GetInheritedFrom(item.FullName, + aclBytes, + aceCount, + item is DirectoryInfo ? true : false, + SECURITY_INFORMATION.DACL_SECURITY_INFORMATION); + } + catch + { + inheritedFrom = new List(); + for (int i = 0; i < aceCount; i++) + { + inheritedFrom.Add("unknown parent"); + } + } + } + + return inheritedFrom; + } + public static List GetInheritedFrom(string path, byte[] aclBytes, int aceCount, bool isContainer, SECURITY_INFORMATION aclType) + { + var inheritedFrom = new List(); + path = Path.GetLongPath(path); + + uint returnValue = 0; + GENERIC_MAPPING genericMap = new GENERIC_MAPPING(); + genericMap.GenericRead = (uint)MappedGenericRights.FILE_GENERIC_READ; + genericMap.GenericWrite = (uint)MappedGenericRights.FILE_GENERIC_WRITE; + genericMap.GenericExecute = (uint)MappedGenericRights.FILE_GENERIC_EXECUTE; + genericMap.GenericAll = (uint)MappedGenericRights.FILE_GENERIC_ALL; + + var pInheritInfo = Marshal.AllocHGlobal(aceCount * Marshal.SizeOf(typeof(PINHERITED_FROM))); + + returnValue = GetInheritanceSource( + path, + ResourceType.FileObject, + aclType, + isContainer, + IntPtr.Zero, + 0, + aclBytes, + IntPtr.Zero, + ref genericMap, + pInheritInfo + ); + + if (returnValue != 0) + { + throw new System.ComponentModel.Win32Exception((int)returnValue); + } + + for (int i = 0; i < aceCount; i++) + { + var inheritInfo = pInheritInfo.ElementAt(i); + + inheritedFrom.Add( + !string.IsNullOrEmpty(inheritInfo.AncestorName) && inheritInfo.AncestorName.StartsWith(@"\\?\") ? inheritInfo.AncestorName.Substring(4) : inheritInfo.AncestorName + ); + } + + FreeInheritedFromArray(pInheritInfo, (ushort)aceCount, IntPtr.Zero); + Marshal.FreeHGlobal(pInheritInfo); + + return inheritedFrom; + } + #endregion GetInheritedFrom + + public int GetEffectiveAccess(ObjectSecurity sd, IdentityReference2 identity, string serverName, out bool remoteServerAvailable, out Exception authzException) + { + int effectiveAccess = 0; + remoteServerAvailable = false; + authzException = null; + + try + { + GetEffectivePermissions_AuthzInitializeResourceManager(serverName, out remoteServerAvailable); + + try + { + GetEffectivePermissions_AuthzInitializeContextFromSid(identity); + effectiveAccess = GetEffectivePermissions_AuthzAccessCheck(sd); + } + catch (Exception ex) + { + authzException = ex; + } + } + catch + { } + finally + { + GetEffectivePermissions_FreeResouces(); + } + + return effectiveAccess; + } + + #region Win32 Wrapper + private void GetEffectivePermissions_AuthzInitializeResourceManager(string serverName, out bool remoteServerAvailable) + { + remoteServerAvailable = false; + + var rpcInitInfo = new AUTHZ_RPC_INIT_INFO_CLIENT(); + + rpcInitInfo.version = AuthzRpcClientVersion.V1; + rpcInitInfo.objectUuid = AUTHZ_OBJECTUUID_WITHCAP; + rpcInitInfo.protocol = RCP_OVER_TCP_PROTOCOL; + rpcInitInfo.server = serverName; + + SafeHGlobalHandle pRpcInitInfo = SafeHGlobalHandle.AllocHGlobalStruct(rpcInitInfo); + if (!AuthzInitializeRemoteResourceManager(pRpcInitInfo.ToIntPtr(), out authzRM)) + { + int error = Marshal.GetLastWin32Error(); + + if (error != Win32Error.EPT_S_NOT_REGISTERED) //if not RPC server unavailable + { + throw new Win32Exception(error); + } + + if (serverName == "localhost") + { + remoteServerAvailable = true; + } + + // + // As a fallback we do AuthzInitializeResourceManager. But the results can be inaccurate. + // + if (!AuthzInitializeResourceManager( + AuthzResourceManagerFlags.NO_AUDIT, + IntPtr.Zero, + IntPtr.Zero, + IntPtr.Zero, + "EffectiveAccessCheck", + out authzRM)) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + } + else + { + remoteServerAvailable = true; + } + } + + private void GetEffectivePermissions_AuthzInitializeContextFromSid(IdentityReference2 id) + { + var rawSid = id.GetBinaryForm(); + + // + // Create an AuthZ context based on the user account + // + if (!AuthzInitializeContextFromSid( + AuthzInitFlags.Default, + rawSid, + authzRM, + IntPtr.Zero, + Win32.LUID.NullLuid, + IntPtr.Zero, + out userClientCtxt)) + { + Win32Exception win32Expn = new Win32Exception(Marshal.GetLastWin32Error()); + + if (win32Expn.NativeErrorCode != Win32Error.RPC_S_SERVER_UNAVAILABLE) + { + throw win32Expn; + } + } + } + + private int GetEffectivePermissions_AuthzAccessCheck(ObjectSecurity sd) + { + var request = new AUTHZ_ACCESS_REQUEST(); + request.DesiredAccess = StdAccess.MAXIMUM_ALLOWED; + request.PrincipalSelfSid = null; + request.ObjectTypeList = IntPtr.Zero; + request.ObjectTypeListLength = 0; + request.OptionalArguments = IntPtr.Zero; + + var reply = new AUTHZ_ACCESS_REPLY(); + reply.ResultListLength = 1; + reply.SaclEvaluationResults = IntPtr.Zero; + reply.GrantedAccessMask = pGrantedAccess = Marshal.AllocHGlobal(sizeof(uint)); + reply.Error = pErrorSecObj = Marshal.AllocHGlobal(sizeof(uint)); + + byte[] rawSD = sd.GetSecurityDescriptorBinaryForm(); + + if (!AuthzAccessCheck( + AuthzACFlags.None, + userClientCtxt, + ref request, + IntPtr.Zero, + rawSD, + null, + 0, + ref reply, + IntPtr.Zero)) + { + var error = Marshal.GetLastWin32Error(); + if (error != 0) + { + throw new Win32Exception(); + } + } + + var grantedAccess = Marshal.ReadInt32(pGrantedAccess); + + return grantedAccess; + } + + private void GetEffectivePermissions_FreeResouces() + { + Marshal.FreeHGlobal(pGrantedAccess); + Marshal.FreeHGlobal(pErrorSecObj); + + if (userClientCtxt != IntPtr.Zero) + { + AuthzFreeContext(userClientCtxt); + userClientCtxt = IntPtr.Zero; + } + } + + static RawSecurityDescriptor GetRawSecurityDescriptor(SafeFileHandle handle, SecurityInformationClass infoClass) + { + return new RawSecurityDescriptor(GetByteSecurityDescriptor(handle, infoClass), 0); + } + + public static byte[] GetByteSecurityDescriptor(SafeFileHandle handle, SecurityInformationClass infoClass) + { + var tempSD = IntPtr.Zero; + var buffer = new byte[0]; + try + { + uint error = GetSecurityInfo(handle, + ObjectType.File, + infoClass, + IntPtr.Zero, + IntPtr.Zero, + IntPtr.Zero, + IntPtr.Zero, + out tempSD); + if (error != Win32Error.ERROR_SUCCESS) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + UInt32 sdLength = GetSecurityDescriptorLength(tempSD); + + buffer = new byte[sdLength]; + Marshal.Copy(tempSD, buffer, 0, (int)sdLength); + } + finally + { + Marshal.FreeHGlobal(tempSD); + tempSD = IntPtr.Zero; + } + + return buffer; + } + #endregion + } +} \ No newline at end of file diff --git a/Security2/Win32/SafeHandleEx.cs b/Security2/Win32/SafeHandleEx.cs new file mode 100644 index 0000000..08f35f3 --- /dev/null +++ b/Security2/Win32/SafeHandleEx.cs @@ -0,0 +1,334 @@ +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (c) Microsoft Corporation. All rights reserved + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using System.Runtime.ConstrainedExecution; +using System.Runtime.InteropServices; +using System.Security; + +using Microsoft.Win32.SafeHandles; + +namespace Security2 +{ + using HANDLE = System.IntPtr; + + internal sealed class SafeHGlobalHandle : IDisposable + { + #region Constructor and Destructor + SafeHGlobalHandle() + { + pointer = IntPtr.Zero; + } + + SafeHGlobalHandle(IntPtr handle) + { + pointer = handle; + } + + ~SafeHGlobalHandle() + { + Dispose(); + } + #endregion + + #region Public methods + public static SafeHGlobalHandle InvalidHandle + { + get { return new SafeHGlobalHandle(IntPtr.Zero); } + } + + /// + /// Adds reference to other SafeHGlobalHandle objects, the pointer to + /// which are refered to by this object. This is to ensure that such + /// objects being referred to wouldn't be unreferenced until this object + /// is active. + /// + /// For e.g. when this object is an array of pointers to other objects + /// + /// Collection of SafeHGlobalHandle objects + /// referred to by this object. + public void AddSubReference(IEnumerable children) + { + if (references == null) + { + references = new List(); + } + + references.AddRange(children); + } + + /// + /// Allocates from unmanaged memory to represent an array of pointers + /// and marshals the unmanaged pointers (IntPtr) to the native array + /// equivalent. + /// + /// Array of unmanaged pointers + /// SafeHGlobalHandle object to an native (unmanaged) array of pointers + public static SafeHGlobalHandle AllocHGlobal(IntPtr[] values) + { + SafeHGlobalHandle result = AllocHGlobal(IntPtr.Size * values.Length); + + Marshal.Copy(values, 0, result.pointer, values.Length); + + return result; + } + + public static SafeHGlobalHandle AllocHGlobalStruct(T obj) where T : struct + { + Debug.Assert(typeof(T).StructLayoutAttribute.Value == LayoutKind.Sequential); + + SafeHGlobalHandle result = AllocHGlobal(Marshal.SizeOf(typeof(T))); + + Marshal.StructureToPtr(obj, result.pointer, false); + + return result; + } + + /// + /// Allocates from unmanaged memory to represent an array of structures + /// and marshals the structure elements to the native array of + /// structures. ONLY structures with attribute StructLayout of + /// LayoutKind.Sequential are supported. + /// + /// Native structure type + /// Collection of structure objects + /// Number of elements in the collection + /// SafeHGlobalHandle object to an native (unmanaged) array of structures + public static SafeHGlobalHandle AllocHGlobal(ICollection values) where T : struct + { + Debug.Assert(typeof(T).StructLayoutAttribute.Value == LayoutKind.Sequential); + + return AllocHGlobal(0, values, values.Count); + } + + /// + /// Allocates from unmanaged memory to represent a structure with a + /// variable length array at the end and marshal these structure + /// elements. It is the callers responsibility to marshal what preceeds + /// the trailinh array into the unmanaged memory. ONLY structures with + /// attribute StructLayout of LayoutKind.Sequential are supported. + /// + /// Type of the trailing array of structures + /// Number of bytes preceeding the trailing array of structures + /// Collection of structure objects + /// + /// SafeHGlobalHandle object to an native (unmanaged) structure + /// with a trail array of structures + public static SafeHGlobalHandle AllocHGlobal(int prefixBytes, IEnumerable values, int count) where T + : struct + { + Debug.Assert(typeof(T).StructLayoutAttribute.Value == LayoutKind.Sequential); + + SafeHGlobalHandle result = AllocHGlobal(prefixBytes + Marshal.SizeOf(typeof(T)) * count); + + IntPtr ptr = new IntPtr(result.pointer.ToInt32() + prefixBytes); + foreach (var value in values) + { + Marshal.StructureToPtr(value, ptr, false); + ptr.Increment(); + } + + return result; + } + + /// + /// Allocates from unmanaged memory to represent a unicode string (WSTR) + /// and marshal this to a native PWSTR. + /// + /// String + /// SafeHGlobalHandle object to an native (unmanaged) unicode string + public static SafeHGlobalHandle AllocHGlobal(string s) + { + return new SafeHGlobalHandle(Marshal.StringToHGlobalUni(s)); + } + + /// + /// Operator to obtain the unmanaged pointer wrapped by the object. Note + /// that the returned pointer is only valid for the lifetime of this + /// object. + /// + /// SafeHGlobalHandle object + /// Unmanaged pointer wrapped by the object + public IntPtr ToIntPtr() + { + return pointer; + } + #endregion + + #region IDisposable implmentation + public void Dispose() + { + if (pointer != IntPtr.Zero) + { + Marshal.FreeHGlobal(pointer); + pointer = IntPtr.Zero; + } + + GC.SuppressFinalize(this); + } + #endregion + + #region Private implementation + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", + Justification = "Caller will dispose result")] + static SafeHGlobalHandle AllocHGlobal(int cb) + { + if (cb < 0) + { + throw new ArgumentOutOfRangeException("cb", "The value of this argument must be non-negative"); + } + + SafeHGlobalHandle result = new SafeHGlobalHandle(); + + // + // CER + // + RuntimeHelpers.PrepareConstrainedRegions(); + try { } + finally + { + result.pointer = Marshal.AllocHGlobal(cb); + } + + return result; + } + #endregion + + #region Private members + /// + /// Maintainsreference to other SafeHGlobalHandle objects, the pointer + /// to which are refered to by this object. This is to ensure that such + /// objects being referred to wouldn't be unreferenced until this object + /// is active. + /// + List references; + + // + // Using SafeHandle here doesn't buy much since the pointer is + // eventually stashed into a native structure. Using a SafeHandle would + // involve calling DangerousGetHandle in place of ToIntPtr which makes + // code analysis report CA2001: Avoid calling problematic methods. + // + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")] + /// + /// Unmanaged pointer wrapped by this object + /// + IntPtr pointer; + #endregion + } + + // + // Adopted from: http://msdn.microsoft.com/en-us/magazine/cc163823.aspx + // + /// + /// Safe wrapper for HANDLE to a token. + /// + internal class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid + { + #region Constructors + /// + /// This safehandle instance "owns" the handle, hence base(true) + /// is being called. When safehandle is no longer in use it will + /// call this class's ReleaseHandle method which will release + /// the resources + /// + private SafeTokenHandle() : base(true) { } + + // 0 is an Invalid Handle + internal SafeTokenHandle(HANDLE handle) + : base(true) + { + SetHandle(handle); + } + #endregion + + internal static SafeTokenHandle InvalidHandle + { + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Retain to illustrate semantics")] + get { return new SafeTokenHandle(HANDLE.Zero); } + } + + #region Private implementation + /// + /// Release the HANDLE held by this instance + /// + /// true if the release was successful. false otherwise. + override protected bool ReleaseHandle() + { + return NativeMethods.CloseHandle(handle); + } + #endregion + + #region Nested class for P/Invokes + static class NativeMethods + { + [DllImport(Win32.KERNEL32_DLL, SetLastError = true), + SuppressUnmanagedCodeSecurity, + ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool CloseHandle(HANDLE handle); + } + #endregion + } + + /// + /// Safe wrapper for AUTHZ_RESOURCE_MANAGER_HANDLE. + /// + internal class SafeAuthzRMHandle : SafeHandleZeroOrMinusOneIsInvalid + { + #region Constructors + /// + /// This safehandle instance "owns" the handle, hence base(true) + /// is being called. When safehandle is no longer in use it will + /// call this class's ReleaseHandle method which will release + /// the resources + /// + SafeAuthzRMHandle() : base(true) { } + + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", + Justification = "Retain to illustrate semantics and for reuse")] + SafeAuthzRMHandle(HANDLE handle) + : base(true) + { + SetHandle(handle); + } + #endregion + + public static SafeAuthzRMHandle InvalidHandle + { + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", + Justification = "Retain to illustrate semantics")] + get { return new SafeAuthzRMHandle(HANDLE.Zero); } + } + + #region Private implementation + /// + /// Release the resource manager handle held by this instance + /// + /// true if the release was successful. false otherwise. + override protected bool ReleaseHandle() + { + return NativeMethods.AuthzFreeResourceManager(handle); + } + #endregion + + #region Nested class for P/Invokes + static class NativeMethods + { + [DllImport(Win32.AUTHZ_DLL, SetLastError = true), + SuppressUnmanagedCodeSecurity, + ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool AuthzFreeResourceManager(HANDLE handle); + } + #endregion + } +} diff --git a/Security2/Win32/Structs.cs b/Security2/Win32/Structs.cs new file mode 100644 index 0000000..cfa4937 --- /dev/null +++ b/Security2/Win32/Structs.cs @@ -0,0 +1,83 @@ +using System; +using System.Runtime.InteropServices; + +namespace Security2 +{ + internal partial class Win32 + { + [StructLayout(LayoutKind.Sequential)] + struct PINHERITED_FROM + { + public Int32 GenerationGap; + [MarshalAs(UnmanagedType.LPTStr)] + public string AncestorName; + } + + [StructLayout(LayoutKind.Sequential)] + struct GENERIC_MAPPING + { + public uint GenericRead; + public uint GenericWrite; + public uint GenericExecute; + public uint GenericAll; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + struct AUTHZ_RPC_INIT_INFO_CLIENT + { + public AuthzRpcClientVersion version; + public string objectUuid; + public string protocol; + public string server; + public string endPoint; + public string options; + public string serverSpn; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct LUID + { + public uint LowPart; + public uint HighPart; + + public static LUID NullLuid + { + get + { + LUID Empty; + Empty.LowPart = 0; + Empty.HighPart = 0; + + return Empty; + } + } + } + + #region authz + [StructLayout(LayoutKind.Sequential)] + internal struct AUTHZ_ACCESS_REQUEST + { + public StdAccess DesiredAccess; + public byte[] PrincipalSelfSid; + public IntPtr ObjectTypeList; + public int ObjectTypeListLength; + public IntPtr OptionalArguments; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct AUTHZ_ACCESS_REPLY + { + public int ResultListLength; + public IntPtr GrantedAccessMask; + public IntPtr SaclEvaluationResults; + public IntPtr Error; + } + + internal enum AuthzACFlags : uint // DWORD + { + None = 0, + NoDeepCopySD + } + #endregion + } +} \ No newline at end of file diff --git a/Security2/Win32/Win32Functions.cs b/Security2/Win32/Win32Functions.cs new file mode 100644 index 0000000..a770a60 --- /dev/null +++ b/Security2/Win32/Win32Functions.cs @@ -0,0 +1,32 @@ +using System; +using System.Runtime.InteropServices; + +namespace Security2 +{ + internal partial class Win32 + { + const string ADVAPI32_DLL = "advapi32.dll"; + const string KERNEL32_DLL = "kernel32.dll"; + + [DllImport(Win32.ADVAPI32_DLL, EntryPoint = "GetInheritanceSourceW", CharSet = CharSet.Unicode)] + static extern UInt32 GetInheritanceSource( + [MarshalAs(UnmanagedType.LPTStr)] string pObjectName, + System.Security.AccessControl.ResourceType ObjectType, + SECURITY_INFORMATION SecurityInfo, + [MarshalAs(UnmanagedType.Bool)]bool Container, + IntPtr pObjectClassGuids, + UInt32 GuidCount, + byte[] pAcl, + IntPtr pfnArray, + ref GENERIC_MAPPING pGenericMapping, + IntPtr pInheritArray + ); + + [DllImport(Win32.ADVAPI32_DLL, EntryPoint = "FreeInheritedFromArray", CharSet = CharSet.Unicode)] + static extern UInt32 FreeInheritedFromArray( + IntPtr pInheritArray, + UInt16 AceCnt, + IntPtr pfnArray + ); + } +} \ No newline at end of file diff --git a/Security2/Win32/Win32Lib.cs b/Security2/Win32/Win32Lib.cs new file mode 100644 index 0000000..3fa97d4 --- /dev/null +++ b/Security2/Win32/Win32Lib.cs @@ -0,0 +1,66 @@ +using Alphaleonis.Win32.Filesystem; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Security.AccessControl; +using System.Text; + +namespace Security2 +{ + internal partial class Win32 + { + public static List GetInheritedFrom(string path, ObjectSecurity sd, bool isContainer) + { + var inheritedFrom = new List(); + path = Path.GetLongPath(path); + + uint returnValue = 0; + GENERIC_MAPPING genericMap = new GENERIC_MAPPING(); + genericMap.GenericRead = (uint)MappedGenericRights.FILE_GENERIC_READ; + genericMap.GenericWrite = (uint)MappedGenericRights.FILE_GENERIC_WRITE; + genericMap.GenericExecute = (uint)MappedGenericRights.FILE_GENERIC_EXECUTE; + genericMap.GenericAll = (uint)MappedGenericRights.FILE_GENERIC_ALL; + + var sdBytes = sd.GetSecurityDescriptorBinaryForm(); + var commonSd = new CommonSecurityDescriptor(isContainer, false, sdBytes, 0); + + var aclBytes = new byte[commonSd.DiscretionaryAcl.BinaryLength]; + commonSd.DiscretionaryAcl.GetBinaryForm(aclBytes, 0); + + var pInheritInfo = Marshal.AllocHGlobal(commonSd.DiscretionaryAcl.Count * Marshal.SizeOf(typeof(PINHERITED_FROM))); + + returnValue = GetInheritanceSource( + path, + ResourceType.FileObject, + SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, + isContainer, + IntPtr.Zero, + 0, + aclBytes, + IntPtr.Zero, + ref genericMap, + pInheritInfo + ); + + if (returnValue != 0) + { + throw new System.ComponentModel.Win32Exception((int)returnValue); + } + + for (int i = 0; i < commonSd.DiscretionaryAcl.Count; i++) + { + var inheritInfo = pInheritInfo.ElementAt(i); + + inheritedFrom.Add( + !string.IsNullOrEmpty(inheritInfo.AncestorName) && inheritInfo.AncestorName.StartsWith(@"\\?\") ? inheritInfo.AncestorName.Substring(4) : inheritInfo.AncestorName + ); + } + + FreeInheritedFromArray(pInheritInfo, (ushort)commonSd.DiscretionaryAcl.Count, IntPtr.Zero); + Marshal.FreeHGlobal(pInheritInfo); + + return inheritedFrom; + } + } +} diff --git a/TestClient/Program.cs b/TestClient/Program.cs new file mode 100644 index 0000000..a7b3bc6 --- /dev/null +++ b/TestClient/Program.cs @@ -0,0 +1,85 @@ +using Alphaleonis.Win32.Filesystem; +using NTFSSecurity; +using Security2; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Management.Automation; +using System.Management.Automation.Runspaces; +using System.Security.AccessControl; +using System.Security.Principal; + +namespace TestClient +{ + class Program + { + static void Main(string[] args) + { + var item1 = new FileInfo("D:\\file1.txt"); + var item2 = new DirectoryInfo("D:\\test3"); + var account1 = new List() { (IdentityReference2)@"raandree1\randr_000" }; + + FileSystemAccessRule2.AddFileSystemAccessRule(item1, account1, FileSystemRights2.FullControl, AccessControlType.Allow, InheritanceFlags.ContainerInherit, PropagationFlags.None); + + return; + var path = @"C:\Windows"; + var account = @"raandree1\randr_000"; + var server = "localhost"; + + var sd = Directory.GetAccessControl(path, AccessControlSections.Access); + var id = new IdentityReference2(account); + EffectiveAccess.GetEffectiveAccess(new FileInfo(path), id, "localhost"); + + var result1 = InvokeCommand("gi2 c:\\windows"); + + var result2 = InvokeCommand(@"gi -Path D:\SingleMachine\ | Get-EffectiveAccess") + .Select(ace => ace.ImmediateBaseObject) + .Cast().ToList(); + + foreach (var ace in result2) + { + Console.WriteLine(string.Format("{0};{1}", ace.Account, ace.IsInherited)); + } + + Console.ReadKey(); + } + + public static List InvokeCommand(string script) + { + var runspace = RunspaceFactory.CreateRunspace(); + runspace.Open(); + var powershell = PowerShell.Create(); + powershell.Runspace = runspace; + + powershell.Commands.AddScript(script); + var result = powershell.Invoke(); + + powershell.Dispose(); + runspace.Close(); + + return result.ToList(); + } + + public static List InvokeCommand(string command, Dictionary parameters) + { + var runspace = RunspaceFactory.CreateRunspace(); + runspace.Open(); + var powershell = PowerShell.Create(); + powershell.Runspace = runspace; + + var cmd = new Command(command); + foreach (var parameter in parameters) + { + cmd.Parameters.Add(parameter.Key, parameter.Value); + } + + powershell.Commands.AddCommand(cmd); + var result = powershell.Invoke(); + + powershell.Dispose(); + runspace.Close(); + + return result.ToList(); + } + } +} \ No newline at end of file diff --git a/TestClient/Properties/AssemblyInfo.cs b/TestClient/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..5d1cb04 --- /dev/null +++ b/TestClient/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("TestClient")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("TestClient")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("300b183b-855e-43f5-bc5c-4bcfb436cdf2")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/TestClient/TestClient.csproj b/TestClient/TestClient.csproj new file mode 100644 index 0000000..588cd91 --- /dev/null +++ b/TestClient/TestClient.csproj @@ -0,0 +1,86 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {DE60760F-53BD-4C54-9469-BD96DF0C2B20} + Exe + Properties + TestClient + TestClient + v4.5.1 + + + 512 + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + false + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + ..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll + + + + + + + + + + + + {f0f9af1e-d5b5-4d72-804a-5380622fbdea} + AlphaFS + + + {17768e1a-1422-4bd2-a9a5-42ba9feb82b8} + NTFSSecurity + + + {01EAB41B-B2CE-49FE-AB5A-0F0FF0A9A7EE} + PrivilegeControl + + + {410CAEE5-D287-4A18-9B38-BB87397D218D} + ProcessPrivileges + + + {B437C364-5BC7-42E4-93F7-0F459A5DF0D0} + Security2 + + + + + \ No newline at end of file