예제 #1
0
        /// <summary>
        /// Updates the <paramref name="path"/> timestamps with the values given.
        /// </summary>
        /// <param name="path">Symbolic link to be updated.</param>
        /// <param name="creationTime">Creation time.</param>
        /// <param name="lastAccessTime">Last access time.</param>
        /// <param name="lastWriteTime">Last write time.</param>
        /// <exception cref="UnauthorizedAccessException">The caller does not have the required permission.</exception>
        /// <exception cref="ArgumentException">
        /// <paramref name="path"/> is a zero-length string, contains only white space, or contains one or more invalid characters as defined by <see cref="Path.GetInvalidPathChars"/>.
        ///     <para>-or-</para>
        /// <paramref name="path"/> is prefixed with, or contains only a colon character (<c>:</c>).
        /// </exception>
        /// <exception cref="ArgumentNullException"><paramref name="path"/> is <see langword="null"/>.</exception>
        /// <exception cref="PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length.</exception>
        /// <exception cref="DirectoryNotFoundException">The specified path is invalid (for example, it is on an unmapped drive).</exception>
        /// <exception cref="NotSupportedException"><paramref name="path"/> contains a colon character (<c>:</c>) that is not part of a drive label (<c>"C:\"</c>).</exception>
        /// <remarks>
        /// The major difference between this method and the <see cref="File.SetAttributes"/> is that this method supports
        /// setting attributes for symbolic links (both files and directories), while the <see cref="File.SetAttributes"/>
        /// will set them for a target file, not the link itself.
        /// </remarks>
        public static void SetTimestamps(string path, DateTime creationTime, DateTime lastAccessTime, DateTime lastWriteTime)
        {
            string normalizedPath = LongPathCommon.NormalizePath(path);

            using (SafeFileHandle handle = NativeMethods.CreateFile(
                       normalizedPath,
                       EFileAccess.FileWriteAttributes,
                       FileShare.ReadWrite,
                       IntPtr.Zero,
                       FileMode.Open,
                       EFileAttributes.OpenReparsePoint | EFileAttributes.BackupSemantics,
                       IntPtr.Zero))
            {
                if (handle.IsInvalid)
                {
                    throw LongPathCommon.GetExceptionForHr(Marshal.GetHRForLastWin32Error(), path);
                }

                long creationFileTime   = creationTime.ToLocalTime().ToFileTime();
                long lastAccessFileTime = lastAccessTime.ToLocalTime().ToFileTime();
                long lastWriteFileTime  = lastWriteTime.ToLocalTime().ToFileTime();

                if (!NativeMethods.SetFileTime(handle, ref creationFileTime, ref lastAccessFileTime, ref lastWriteFileTime))
                {
                    throw LongPathCommon.GetExceptionForHr(Marshal.GetHRForLastWin32Error(), path);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Normalizes path (can be longer than <c>MAX_PATH</c>) and adds <c>\\?\</c> long path prefix, if needed.
        /// UNC paths are also supported.
        /// </summary>
        /// <param name="path">Path to be normalized.</param>
        /// <returns>Normalized path.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="path"/> is <see langword="null"/>.</exception>
        public static string NormalizePath(string path)
        {
            // This will also validate the path.
            path = LongPathCommon.AddLongPathPrefix(path);

            // Don't forget about the null terminator.
            StringBuilder buffer = new StringBuilder(path.Length + 1);

            uint normalizedPathLength = NativeMethods.GetFullPathName(path, (uint)buffer.Capacity, buffer, IntPtr.Zero);

            // Length returned does not include null terminator.
            if (normalizedPathLength > buffer.Capacity - 1)
            {
                // Resulting path longer than our buffer, so increase it.
                buffer.Capacity      = unchecked ((int)normalizedPathLength) + 1;
                normalizedPathLength = NativeMethods.GetFullPathName(path, normalizedPathLength, buffer, IntPtr.Zero);
            }

            if (normalizedPathLength == 0)
            {
                throw LongPathCommon.GetExceptionForHr(Marshal.GetHRForLastWin32Error(), path);
            }

            if (normalizedPathLength > NativeMethods.MaxLongPath - 1)
            {
                throw LongPathCommon.GetExceptionForHr(NativeMethods.ErrorFilenameExcedRange, path);
            }

            return(buffer.ToString());
        }
예제 #3
0
        /// <summary>
        /// Sets the attributes for a file or directory.
        /// </summary>
        /// <param name="path">The name of the file whose attributes are to be set.</param>
        /// <param name="attributes">The file attributes to set for the file.</param>
        /// <exception cref="UnauthorizedAccessException">The caller does not have the required permission.</exception>
        /// <exception cref="ArgumentException">
        /// <paramref name="path"/> is a zero-length string, contains only white space, or contains one or more invalid characters as defined by <see cref="Path.GetInvalidPathChars"/>.
        ///     <para>-or-</para>
        /// <paramref name="path"/> is prefixed with, or contains only a colon character (<c>:</c>).
        /// </exception>
        /// <exception cref="ArgumentNullException"><paramref name="path"/> is <see langword="null"/>.</exception>
        /// <exception cref="PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length.</exception>
        /// <exception cref="DirectoryNotFoundException">The specified path is invalid (for example, it is on an unmapped drive).</exception>
        /// <exception cref="NotSupportedException"><paramref name="path"/> contains a colon character (<c>:</c>) that is not part of a drive label (<c>"C:\"</c>).</exception>
        public static void SetAttributes(string path, FileAttributes attributes)
        {
            string normalizedPath = LongPathCommon.NormalizePath(path);

            if (!NativeMethods.SetFileAttributes(normalizedPath, (EFileAttributes)attributes))
            {
                throw LongPathCommon.GetExceptionForHr(Marshal.GetHRForLastWin32Error(), path);
            }
        }