internal static void ToggleCompressionInternal(bool isFolder, KernelTransaction transaction, string path, bool compress, bool?isFullPath) { using (SafeFileHandle handle = File.CreateFileInternal(transaction, path, isFolder ? ExtendedFileAttributes.BackupSemantics : ExtendedFileAttributes.Normal, null, FileMode.Open, FileSystemRights.Modify, FileShare.None, true, isFullPath)) { // 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); } }
internal static void AddStreamInternal(bool isFolder, KernelTransaction transaction, string path, string name, IEnumerable <string> contents, bool?isFullPath) { if (Utils.IsNullOrWhiteSpace(path)) { throw new ArgumentNullException("path"); } if (Utils.IsNullOrWhiteSpace(name)) { throw new ArgumentNullException("name"); } if (name.Contains(Path.StreamSeparator)) { throw new ArgumentException(Resources.StreamNameWithColon); } using (SafeFileHandle handle = File.CreateFileInternal(transaction, path + Path.StreamSeparator + name, isFolder ? ExtendedFileAttributes.BackupSemantics : ExtendedFileAttributes.Normal, null, FileMode.Create, FileSystemRights.Write, FileShare.ReadWrite, false, isFullPath)) using (StreamWriter writer = new StreamWriter(new FileStream(handle, FileAccess.Write), NativeMethods.DefaultFileEncoding)) foreach (string line in contents) { writer.WriteLine(line); } }
internal static IEnumerable <AlternateDataStreamInfo> EnumerateStreamsInternal(bool?isFolder, KernelTransaction transaction, SafeFileHandle safeHandle, string path, string originalName, StreamType?streamType, bool?isFullPath) { string pathLp = null; bool callerHandle = safeHandle != null; if (!callerHandle) { pathLp = isFullPath == null ? path : (bool)isFullPath ? Path.GetLongPathInternal(path, false, false, false, false) : Path.GetFullPathInternal(transaction, path, true, false, false, true, false, true, false); if (isFolder == null) { FileAttributes attrs = File.GetAttributesExInternal <FileAttributes>(transaction, pathLp, null); isFolder = (attrs & FileAttributes.Directory) == FileAttributes.Directory; } safeHandle = File.CreateFileInternal(transaction, pathLp, (bool)isFolder ? ExtendedFileAttributes.BackupSemantics : ExtendedFileAttributes.Normal, null, FileMode.Open, FileSystemRights.Read, FileShare.ReadWrite, false, null); } else { NativeMethods.IsValidHandle(safeHandle); } try { using (new PrivilegeEnabler(Privilege.Backup)) using (SafeGlobalMemoryBufferHandle safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize)) { Type typeWin32Stream = typeof(NativeMethods.Win32StreamId); uint sizeOfType = (uint)Marshal.SizeOf(typeWin32Stream); uint numberOfBytesRead; IntPtr context; bool doLoop = true; while (doLoop) { if (!NativeMethods.BackupRead(safeHandle, safeBuffer, sizeOfType, out numberOfBytesRead, false, true, out context)) { // Throws IOException. NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp, true); } doLoop = numberOfBytesRead == sizeOfType; if (doLoop) { string streamName = null; string streamSearchName = null; // CA2001:AvoidCallingProblematicMethods IntPtr buffer = IntPtr.Zero; bool successRef = false; safeBuffer.DangerousAddRef(ref successRef); // MSDN: The DangerousGetHandle method poses a security risk because it can return a handle that is not valid. if (successRef) { buffer = safeBuffer.DangerousGetHandle(); } safeBuffer.DangerousRelease(); if (buffer == IntPtr.Zero) { NativeError.ThrowException(Resources.HandleDangerousRef); } // CA2001:AvoidCallingProblematicMethods NativeMethods.Win32StreamId stream = Utils.MarshalPtrToStructure <NativeMethods.Win32StreamId>(0, buffer); if (streamType == null || stream.StreamType == streamType) { if (stream.StreamNameSize > 0) { if (!NativeMethods.BackupRead(safeHandle, safeBuffer, stream.StreamNameSize, out numberOfBytesRead, false, true, out context)) { // Throws IOException. NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp, true); } // CA2001:AvoidCallingProblematicMethods buffer = IntPtr.Zero; successRef = false; safeBuffer.DangerousAddRef(ref successRef); // MSDN: The DangerousGetHandle method poses a security risk because it can return a handle that is not valid. if (successRef) { buffer = safeBuffer.DangerousGetHandle(); } safeBuffer.DangerousRelease(); if (buffer == IntPtr.Zero) { NativeError.ThrowException(Resources.HandleDangerousRef); } // CA2001:AvoidCallingProblematicMethods streamName = Marshal.PtrToStringUni(buffer, (int)numberOfBytesRead / 2); // Returned stream name format: ":streamName:$DATA" streamSearchName = streamName.TrimStart(Path.StreamSeparatorChar).Replace(Path.StreamSeparator + "$DATA", string.Empty); } if (originalName == null || (streamSearchName != null && streamSearchName.Equals(originalName, StringComparison.OrdinalIgnoreCase))) { yield return(new AlternateDataStreamInfo(stream, transaction, pathLp ?? path, streamName, originalName ?? streamSearchName, isFolder, isFullPath)); } } uint lo, hi; doLoop = !NativeMethods.BackupSeek(safeHandle, uint.MinValue, uint.MaxValue, out lo, out hi, out context); } } // 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(safeHandle, safeBuffer, 0, out numberOfBytesRead, true, false, out context)) { // Throws IOException. NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp, true); } } } finally { // Handle is ours, dispose. if (!callerHandle && safeHandle != null) { safeHandle.Close(); } } }
public BackupFileStream(string path, FileMode mode, FileSystemRights access, FileShare share, ExtendedFileAttributes attributes) : this(File.CreateFileInternal(null, path, attributes, null, mode, access, share, true, PathFormat.RelativePath), access) { }
public BackupFileStream(string path, FileMode mode) : this(File.CreateFileInternal(null, path, ExtendedFileAttributes.Normal, null, mode, FileSystemRights.Read | FileSystemRights.Write, FileShare.None, true, PathFormat.RelativePath), FileSystemRights.Read | FileSystemRights.Write) { }
public BackupFileStream(KernelTransaction transaction, string path, FileMode mode, FileSystemRights access, FileShare share, ExtendedFileAttributes attributes, FileSecurity security) : this(File.CreateFileInternal(transaction, path, attributes, security, mode, access, share, true, PathFormat.RelativePath), access) { }
public BackupFileStream(KernelTransaction transaction, string path, FileMode mode, FileSystemRights access) : this(File.CreateFileInternal(transaction, path, ExtendedFileAttributes.Normal, null, mode, access, FileShare.None, true, PathFormat.RelativePath), access) { }
internal static IEnumerable <FileIdBothDirectoryInfo> EnumerateFileIdBothDirectoryInfoInternal(KernelTransaction transaction, SafeFileHandle safeHandle, string path, FileShare shareMode, bool continueOnException, PathFormat pathFormat) { if (!NativeMethods.IsAtLeastWindowsVista) { throw new PlatformNotSupportedException(Resources.RequiresWindowsVistaOrHigher); } bool callerHandle = safeHandle != null; if (!callerHandle) { if (Utils.IsNullOrWhiteSpace(path)) { throw new ArgumentNullException("path"); } string pathLp = Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); safeHandle = File.CreateFileInternal(transaction, pathLp, ExtendedFileAttributes.BackupSemantics, null, FileMode.Open, FileSystemRights.ReadData, shareMode, true, PathFormat.LongFullPath); } try { if (!NativeMethods.IsValidHandle(safeHandle, Marshal.GetLastWin32Error(), !continueOnException)) { yield break; } // 2014-10-16: Number of returned items depends on the size of the buffer. // That does not seem right, investigate. using (var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize)) { NativeMethods.IsValidHandle(safeBuffer, Marshal.GetLastWin32Error()); long fileNameOffset = Marshal.OffsetOf(typeof(NativeMethods.FileIdBothDirInfo), "FileName").ToInt64(); while (NativeMethods.GetFileInformationByHandleEx(safeHandle, NativeMethods.FileInfoByHandleClass.FileIdBothDirectoryInfo, safeBuffer.DangerousGetHandle(), NativeMethods.DefaultFileBufferSize)) { // CA2001:AvoidCallingProblematicMethods IntPtr buffer = IntPtr.Zero; bool successRef = false; safeBuffer.DangerousAddRef(ref successRef); // MSDN: The DangerousGetHandle method poses a security risk because it can return a handle that is not valid. if (successRef) { buffer = safeBuffer.DangerousGetHandle(); } safeBuffer.DangerousRelease(); if (buffer == IntPtr.Zero) { NativeError.ThrowException(Resources.HandleDangerousRef); } // CA2001:AvoidCallingProblematicMethods while (buffer != IntPtr.Zero) { NativeMethods.FileIdBothDirInfo fibdi = Utils.MarshalPtrToStructure <NativeMethods.FileIdBothDirInfo>(0, buffer); string fileName = Marshal.PtrToStringUni(new IntPtr(fileNameOffset + buffer.ToInt64()), (int)(fibdi.FileNameLength / 2)); if (!Utils.IsNullOrWhiteSpace(fileName) && !fileName.Equals(Path.CurrentDirectoryPrefix, StringComparison.OrdinalIgnoreCase) && !fileName.Equals(Path.ParentDirectoryPrefix, StringComparison.OrdinalIgnoreCase)) { yield return(new FileIdBothDirectoryInfo(fibdi, fileName)); } buffer = fibdi.NextEntryOffset == 0 ? IntPtr.Zero : new IntPtr(buffer.ToInt64() + fibdi.NextEntryOffset); } } int lastError = Marshal.GetLastWin32Error(); switch ((uint)lastError) { case Win32Errors.ERROR_SUCCESS: case Win32Errors.ERROR_NO_MORE_FILES: case Win32Errors.ERROR_HANDLE_EOF: yield break; default: NativeError.ThrowException(lastError, path); break; } } } finally { // Handle is ours, dispose. if (!callerHandle && safeHandle != null) { safeHandle.Close(); } } }
public BackupFileStream(string path, FileMode mode, FileSystemRights access, FileShare share) : this(File.CreateFileInternal(null, path, ExtendedFileAttributes.Normal, null, mode, access, share, true, false), access) { }
public BackupFileStream(KernelTransaction transaction, string path, FileMode mode, FileSystemRights access, FileShare share, ExtendedFileAttributes attributes) : this(File.CreateFileInternal(transaction, path, attributes, null, mode, access, share, true, false), access) { }
public BackupFileStream(KernelTransaction transaction, string path, FileMode mode) : this(File.CreateFileInternal(transaction, path, ExtendedFileAttributes.Normal, null, mode, FileSystemRights.Read | FileSystemRights.Write, FileShare.None, true, false), FileSystemRights.Read | FileSystemRights.Write) { }
public BackupFileStream(string path, FileMode mode, FileSystemRights access, FileShare share, ExtendedFileAttributes attributes, FileSecurity security) : this(File.CreateFileInternal(null, path, attributes, security, mode, access, share, true, false), access) { }