예제 #1
0
파일: Device.cs 프로젝트: CDEApp/CDE
        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);
            }
        }
예제 #2
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);
                    }
        }
예제 #3
0
        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();
                }
            }
        }
예제 #4
0
 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)
 {
 }
예제 #5
0
 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)
 {
 }
예제 #6
0
 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)
 {
 }
예제 #7
0
 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();
                }
            }
        }
예제 #9
0
 public BackupFileStream(string path, FileMode mode, FileSystemRights access, FileShare share)
     : this(File.CreateFileInternal(null, path, ExtendedFileAttributes.Normal, null, mode, access, share, true, false), access)
 {
 }
예제 #10
0
 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)
 {
 }
예제 #11
0
 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)
 {
 }
예제 #12
0
 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)
 {
 }