internal static DateTime GetChangeTimeCore(KernelTransaction transaction, SafeFileHandle safeFileHandle, bool isFolder, string path, bool getUtc, PathFormat pathFormat) { if (!NativeMethods.IsAtLeastWindowsVista) { throw new PlatformNotSupportedException(new Win32Exception((int)Win32Errors.ERROR_OLD_WIN_VERSION).Message); } var callerHandle = null != safeFileHandle; if (!callerHandle) { if (pathFormat != PathFormat.LongFullPath && Utils.IsNullOrWhiteSpace(path)) { throw new ArgumentNullException("path"); } var pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars); safeFileHandle = CreateFileCore(transaction, isFolder, pathLp, ExtendedFileAttributes.BackupSemantics, null, FileMode.Open, FileSystemRights.ReadData, FileShare.ReadWrite, true, false, PathFormat.LongFullPath); } try { NativeMethods.IsValidHandle(safeFileHandle); using (var safeBuffer = new SafeGlobalMemoryBufferHandle(IntPtr.Size + Marshal.SizeOf(typeof(NativeMethods.FILE_BASIC_INFO)))) { NativeMethods.FILE_BASIC_INFO fbi; var success = NativeMethods.GetFileInformationByHandleEx_FileBasicInfo(safeFileHandle, NativeMethods.FILE_INFO_BY_HANDLE_CLASS.FILE_BASIC_INFO, out fbi, (uint)safeBuffer.Capacity); var lastError = Marshal.GetLastWin32Error(); if (!success) { NativeError.ThrowException(lastError, !Utils.IsNullOrWhiteSpace(path) ? path : null); } safeBuffer.StructureToPtr(fbi, true); var changeTime = safeBuffer.PtrToStructure <NativeMethods.FILE_BASIC_INFO>(0).ChangeTime; return(getUtc ? DateTime.FromFileTimeUtc(changeTime) : DateTime.FromFileTime(changeTime)); } } finally { // Handle is ours, dispose. if (!callerHandle && null != safeFileHandle) { safeFileHandle.Close(); } } }
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 <NativeMethods.FILE_BASIC_INFO>(0).ChangeTime; return(getUtc ? DateTime.FromFileTimeUtc(changeTime) : DateTime.FromFileTime(changeTime)); } } finally { // Handle is ours, dispose. if (!callerHandle && safeHandle != null) { safeHandle.Close(); } } }
/// <summary>[AlphaFS] Creates an NTFS directory junction (similar to CMD command: "MKLINK /J").</summary> internal static void CreateDirectoryJunction(SafeFileHandle safeHandle, string directoryPath) { var targetDirBytes = Encoding.Unicode.GetBytes(Path.NonInterpretedPathPrefix + Path.GetRegularPathCore(directoryPath, GetFullPathOptions.AddTrailingDirectorySeparator, false)); var header = new NativeMethods.ReparseDataBufferHeader { ReparseTag = ReparsePointTag.MountPoint, ReparseDataLength = (ushort)(targetDirBytes.Length + 12) }; var mountPoint = new NativeMethods.MountPointReparseBuffer { SubstituteNameOffset = 0, SubstituteNameLength = (ushort)targetDirBytes.Length, PrintNameOffset = (ushort)(targetDirBytes.Length + UnicodeEncoding.CharSize), PrintNameLength = 0 }; var reparseDataBuffer = new NativeMethods.REPARSE_DATA_BUFFER { ReparseTag = header.ReparseTag, ReparseDataLength = header.ReparseDataLength, SubstituteNameOffset = mountPoint.SubstituteNameOffset, SubstituteNameLength = mountPoint.SubstituteNameLength, PrintNameOffset = mountPoint.PrintNameOffset, PrintNameLength = mountPoint.PrintNameLength, PathBuffer = new byte[NativeMethods.MAXIMUM_REPARSE_DATA_BUFFER_SIZE - 16] // 16368 }; targetDirBytes.CopyTo(reparseDataBuffer.PathBuffer, 0); using (var safeBuffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(reparseDataBuffer))) { safeBuffer.StructureToPtr(reparseDataBuffer, false); uint bytesReturned; var succes = NativeMethods.DeviceIoControl2(safeHandle, NativeMethods.FSCTL_SET_REPARSE_POINT, safeBuffer, (uint)(targetDirBytes.Length + 20), IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero); var lastError = Marshal.GetLastWin32Error(); if (!succes) { NativeError.ThrowException(lastError, directoryPath); } } }
/// <summary>[AlphaFS] Deletes an NTFS directory junction.</summary> internal static void DeleteDirectoryJunction(SafeFileHandle safeHandle) { var reparseDataBuffer = new NativeMethods.REPARSE_DATA_BUFFER { ReparseTag = ReparsePointTag.MountPoint, ReparseDataLength = 0, PathBuffer = new byte[NativeMethods.MAXIMUM_REPARSE_DATA_BUFFER_SIZE - 16] // 16368 }; using (var safeBuffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(reparseDataBuffer))) { safeBuffer.StructureToPtr(reparseDataBuffer, false); uint bytesReturned; var success = NativeMethods.DeviceIoControl2(safeHandle, NativeMethods.FSCTL_DELETE_REPARSE_POINT, safeBuffer, NativeMethods.REPARSE_DATA_BUFFER_HEADER_SIZE, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero); var lastError = Marshal.GetLastWin32Error(); if (!success) { NativeError.ThrowException(lastError); } } }
internal static DateTime GetChangeTimeInternal(bool isFolder, KernelTransaction transaction, SafeFileHandle safeHandle, string path, bool getUtc, PathFormat pathFormat) { if (!NativeMethods.IsAtLeastWindowsVista) throw new PlatformNotSupportedException(Resources.RequiresWindowsVistaOrHigher); bool callerHandle = safeHandle != null; if (!callerHandle) { if (pathFormat != PathFormat.LongFullPath && Utils.IsNullOrWhiteSpace(path)) throw new ArgumentNullException("path"); string pathLp = Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars); safeHandle = CreateFileInternal(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.FileBasicInfo)))) { NativeMethods.FileBasicInfo 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<NativeMethods.FileBasicInfo>().ChangeTime; return getUtc ? DateTime.FromFileTimeUtc(changeTime) : DateTime.FromFileTime(changeTime); } } finally { // Handle is ours, dispose. if (!callerHandle && safeHandle != null) safeHandle.Close(); } }