예제 #1
0
        /// <summary>
        /// Constructs a new USN helper instance
        /// </summary>
        /// <param name="volumeRoot">The root volume where the USN lookup is performed</param>
        internal USNJournal(string volumeRoot)
        {
            if (Utility.Utility.IsClientLinux)
            {
                throw new Interface.UserInformationException(Strings.USNHelper.LinuxNotSupportedError, "UsnOnLinuxNotSupported");
            }

            m_volume = Utility.Utility.AppendDirSeparator(volumeRoot);

            try
            {
                var device = GetDeviceNameFromPath(m_volume);

                m_volumeHandle = Win32USN.CreateFile(device, Win32USN.FileAccess.GenericRead,
                                                     Win32USN.FileShare.ReadWrite, IntPtr.Zero, Win32USN.CreationDisposition.OpenExisting,
                                                     Win32USN.FileAttributes.BackupSemantics, IntPtr.Zero);

                if (m_volumeHandle == null || m_volumeHandle.IsInvalid)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                Win32USN.ControlWithOutput(m_volumeHandle, Win32USN.FsCtl.QueryUSNJournal, ref m_journal);

                m_volumeRootRefNumber = GetFileRefNumber(volumeRoot);
            }
            catch
            {
                Dispose();
                throw;
            }
        }
예제 #2
0
        /// <summary>
        /// Constructs a new USN helper instance
        /// </summary>
        /// <param name="path">The path to the folder to perform USN services</param>
        /// <param name="volumeRoot">The root volume where the USN lookup is performed</param>
        internal USNHelper(string path, string volumeRoot)
        {
            if (Utility.Utility.IsClientLinux)
            {
                throw new Duplicati.Library.Interface.UserInformationException(Strings.USNHelper.LinuxNotSupportedError, "UsnOnLinuxNotSupported");
            }

            if (!System.IO.Path.IsPathRooted(path))
            {
                throw new Exception(string.Format("Path {0} is not rooted", path));
            }

            m_path = Utility.Utility.AppendDirSeparator(path);

            try
            {
                string devicename = @"\\.\" + System.IO.Path.GetPathRoot(path).TrimEnd('\\');
                if (volumeRoot != null)
                {
                    volumeRoot = volumeRoot.TrimEnd('\\');
                }

                m_volumeHandle = Win32USN.CreateFile(volumeRoot == null ? devicename : volumeRoot, Win32USN.EFileAccess.GenericRead, Win32USN.EFileShare.ReadWrite, IntPtr.Zero, Win32USN.ECreationDisposition.OpenExisting, Win32USN.EFileAttributes.BackupSemantics, IntPtr.Zero);
                if (m_volumeHandle == null || m_volumeHandle.IsInvalid)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                uint bytesReturned = 0;
                if (!Win32USN.DeviceIoControl(m_volumeHandle, Win32USN.EIOControlCode.FsctlQueryUsnJournal, null, 0, out m_journal, (uint)Marshal.SizeOf(typeof(Win32USN.USN_JOURNAL_DATA)), ref bytesReturned, IntPtr.Zero))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                Win32USN.BY_HANDLE_FILE_INFORMATION fileInfo;
                using (SafeFileHandle driveHandle = Win32USN.CreateFile(System.IO.Path.GetPathRoot(path), Win32USN.EFileAccess.GenericRead, Win32USN.EFileShare.ReadWrite, IntPtr.Zero, Win32USN.ECreationDisposition.OpenExisting, Win32USN.EFileAttributes.BackupSemantics, IntPtr.Zero))
                    if (!Win32USN.GetFileInformationByHandle(driveHandle, out fileInfo))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                m_volumeRootFileNameReferenceNumber = ((ulong)fileInfo.FileIndexHigh << 32) | ((ulong)fileInfo.FileIndexLow);
            }
            catch
            {
                if (m_volumeHandle != null)
                {
                    m_volumeHandle.Dispose();
                    m_volumeHandle = null;
                }

                throw;
            }

            if (this.FileSystemEntries.Count == 0)
            {
                throw new Exception(Strings.USNHelper.SafeGuardError);
            }
        }
예제 #3
0
        /// <summary>
        /// Get NTFS file reference number (FRN) from path
        /// </summary>
        /// <param name="filePath">Input path</param>
        /// <returns>NTFS file reference number</returns>
        private static ulong GetFileRefNumber(string filePath)
        {
            Win32USN.BY_HANDLE_FILE_INFORMATION fileInfo;
            using (var driveHandle = Win32USN.CreateFile(filePath, Win32USN.FileAccess.GenericRead,
                                                         Win32USN.FileShare.ReadWrite, IntPtr.Zero, Win32USN.CreationDisposition.OpenExisting,
                                                         Win32USN.FileAttributes.BackupSemantics, IntPtr.Zero))
            {
                if (!Win32USN.GetFileInformationByHandle(driveHandle, out fileInfo))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }

            return(((ulong)fileInfo.FileIndexHigh << 32) | fileInfo.FileIndexLow);
        }