예제 #1
0
        public void CreateDirectoryNested()
        {
            string Target = PathGeneratorUtilities.GetRelativePath("parentDir", "targetDir");

            FileUtilities.CreateDirectory(GetFullPath(Target));
            XAssert.IsTrue(Directory.Exists(GetFullPath(Target)));
        }
예제 #2
0
 private static FileSystemType GetFileSystemType(string path)
 {
     using (FileStream fileStream = FileUtilities.CreateFileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))
     {
         return(FileUtilities.GetVolumeFileSystemByHandle(fileStream.SafeFileHandle));
     }
 }
예제 #3
0
        public async Task WriteAllBytesCallback()
        {
            const string Target = "target";

            Usn closeUsn = default(Usn);
            await FileUtilities.WriteAllBytesAsync(
                GetFullPath(Target),
                Encoding.UTF8.GetBytes("Target"),
                onCompletion : stream =>
            {
                Usn?maybeCloseUsn = FileUtilities.TryWriteUsnCloseRecordByHandle(stream);
                XAssert.IsNotNull(maybeCloseUsn);
                closeUsn = maybeCloseUsn.Value;
            });

            XAssert.IsTrue(File.Exists(GetFullPath(Target)));
            XAssert.AreEqual("Target", File.ReadAllText(GetFullPath(Target)));
            XAssert.AreNotEqual(0, closeUsn, "Completion callback skipped");

            using (FileStream dest = File.OpenRead(GetFullPath(Target)))
            {
                Usn usn = FileUtilities.ReadFileUsnByHandle(dest.SafeFileHandle).Value.Usn;
                XAssert.AreEqual(closeUsn, usn, "CLOSE usn should have been written during the callback.");
            }
        }
예제 #4
0
        public void TestCopyOnWriteWithSymlink(bool followSymlink)
        {
            var file = GetFullPath(nameof(TestCopyOnWriteWithSymlink));

            File.WriteAllText(file, nameof(TestCopyOnWriteWithSymlink));

            if (!SupportCopyOnWrite(file))
            {
                return;
            }

            // Currently only APFS supports copy-on-write.
            XAssert.AreEqual(FileSystemType.APFS, GetFileSystemType(file));

            var symlink = GetFullPath(nameof(TestCopyOnWriteWithSymlink) + "_symlink");

            XAssert.PossiblySucceeded(FileUtilities.TryCreateSymbolicLink(symlink, file, isTargetFile: true));

            var clonedFile = GetFullPath(nameof(TestCopyOnWriteWithSymlink) + "_cloned");

            var possiblyCopyOnWrite = FileUtilities.TryCreateCopyOnWrite(symlink, clonedFile, followSymlink: followSymlink);

            XAssert.IsTrue(possiblyCopyOnWrite.Succeeded);

            var verifiedTimestamp = followSymlink
                ? FileUtilities.GetFileTimestamps(file)
                : FileUtilities.GetFileTimestamps(symlink);
            var clonedFileTimestamp = FileUtilities.GetFileTimestamps(clonedFile);

            // The access time and modified time must be equal, but not the last status change time.
            // The latter is hard to test when the underlying file system doesn't support high-precision file timestamp.
            XAssert.AreEqual(verifiedTimestamp.AccessTime, clonedFileTimestamp.AccessTime);
            XAssert.AreEqual(verifiedTimestamp.LastWriteTime, clonedFileTimestamp.LastWriteTime);
        }
예제 #5
0
        public void ReadEarliestUsnRecords()
        {
            WithVolumeHandle(
                volumeHandle =>
            {
                QueryUsnJournalData journalState = QueryJournal(volumeHandle);

                byte[] buffer = new byte[4096];
                ReadUsnJournalResult readJournalResult = FileUtilities.TryReadUsnJournal(volumeHandle, buffer, journalState.UsnJournalId, startUsn: new Usn(0));
                XAssert.AreEqual(ReadUsnJournalStatus.Success, readJournalResult.Status);

                XAssert.IsFalse(readJournalResult.NextUsn.IsZero);
                XAssert.IsTrue(readJournalResult.NextUsn >= journalState.FirstUsn);

                XAssert.AreNotEqual(0, readJournalResult.Records.Count, "It is unlikely that this journal should be empty, since this test's execution has written to the volume.");

                var firstRecord = readJournalResult.Records.First();

                XAssert.IsTrue(firstRecord.Usn == journalState.FirstUsn);
                XAssert.IsTrue(firstRecord.Usn < readJournalResult.NextUsn);

                var lastUsn = firstRecord.Usn;

                foreach (UsnRecord record in readJournalResult.Records.Skip(1))
                {
                    XAssert.IsTrue(record.Usn > lastUsn, "Expected USNs to be monotically increasing.");
                    lastUsn = record.Usn;

                    XAssert.IsTrue(record.Usn >= journalState.FirstUsn);
                    XAssert.IsTrue(record.Usn < readJournalResult.NextUsn);
                }
            });
        }
예제 #6
0
        public void ReOpenFileSuccess()
        {
            string path = Path.Combine(TemporaryDirectory, "file");

            using (var stream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                SafeFileHandle   writableHandle;
                ReOpenFileStatus status = FileUtilities.TryReOpenFile(
                    stream.SafeFileHandle,
                    FileDesiredAccess.GenericWrite,
                    FileShare.ReadWrite,
                    FileFlagsAndAttributes.None,
                    out writableHandle);

                using (writableHandle)
                {
                    XAssert.AreEqual(ReOpenFileStatus.Success, status);
                    XAssert.IsNotNull(writableHandle);
                    XAssert.IsFalse(writableHandle.IsInvalid);

                    using (var writableStream = new FileStream(writableHandle, FileAccess.Write, bufferSize: 128, isAsync: false))
                    {
                        writableStream.WriteByte(0xab);
                    }
                }

                int read = stream.ReadByte();
                XAssert.AreEqual(0xab, read);
            }
        }
예제 #7
0
        public void SetAndGetFileTimestampsOnlyAffectSymlink()
        {
            string originalFile = GetFullPath("somefile.txt");

            File.WriteAllText(originalFile, "Important Data");

            string intermediateLink = GetFullPath("someLinkThatWillChange.lnk");

            XAssert.IsTrue(FileUtilities.TryCreateSymbolicLink(intermediateLink, originalFile, isTargetFile: true));

            var test = new DateTime(2001, 12, 31, 1, 1, 1, DateTimeKind.Utc);

            FileUtilities.SetFileTimestamps(intermediateLink, new FileTimestamps(test));

            var originalTimestamps = FileUtilities.GetFileTimestamps(originalFile);
            var symlinkTimestamps  = FileUtilities.GetFileTimestamps(intermediateLink);

            // We dont look at last changed and access time as the test process touches the permissions of the output file and
            // the system indexes the files so the access time changes too!
            XAssert.AreEqual(test, symlinkTimestamps.CreationTime);
            XAssert.AreEqual(test, symlinkTimestamps.LastWriteTime);

            XAssert.AreNotEqual(originalTimestamps.CreationTime, symlinkTimestamps.CreationTime);
            XAssert.AreNotEqual(originalTimestamps.LastWriteTime, symlinkTimestamps.LastWriteTime);
        }
예제 #8
0
        /// <summary>
        /// Creates a volume root handle or retrieves an existing one.
        /// </summary>
        /// <remarks>
        /// This is the un-synchronized get-or-add operation resulting in <see cref="FileAccessor"/>
        /// not being thread-safe.
        /// </remarks>
        private SafeFileHandle TryGetVolumeRoot(ulong volumeSerial)
        {
            SafeFileHandle volumeRootHandle;

            if (!m_volumeRootHandles.TryGetValue(volumeSerial, out volumeRootHandle))
            {
                VolumeGuidPath volumeRootPath = m_map.TryGetVolumePathBySerial(volumeSerial);
                if (!volumeRootPath.IsValid)
                {
                    return(null);
                }

                if (
                    !FileUtilities.TryOpenDirectory(
                        volumeRootPath.Path,
                        FileShare.ReadWrite | FileShare.Delete,
                        out volumeRootHandle).Succeeded)
                {
                    Contract.Assert(volumeRootHandle == null);
                    return(null);
                }

                m_volumeRootHandles.Add(volumeSerial, volumeRootHandle);
            }

            return(volumeRootHandle);
        }
예제 #9
0
        public void GetChainOfJunctions()
        {
            string targetDirectory = GetFullPath("target");

            Directory.CreateDirectory(targetDirectory);

            string intermediateJunction = GetFullPath("intermediate.jct");

            Directory.CreateDirectory(intermediateJunction);
            FileUtilities.CreateJunction(intermediateJunction, targetDirectory);

            string sourceJunction = GetFullPath("source.jct");

            Directory.CreateDirectory(sourceJunction);
            FileUtilities.CreateJunction(sourceJunction, intermediateJunction);

            using (SafeFileHandle handle = OpenHandleForReparsePoint(sourceJunction))
            {
                var chain = new List <string>();
                FileUtilities.GetChainOfReparsePoints(handle, sourceJunction, chain);
                XAssert.AreEqual(3, chain.Count, "Chain of reparse points: " + string.Join(" -> ", chain));
                XAssert.AreEqual(sourceJunction.ToUpperInvariant(), TrimPathPrefix(chain[0].ToUpperInvariant()));
                XAssert.AreEqual(intermediateJunction.ToUpperInvariant(), TrimPathPrefix(chain[1].ToUpperInvariant()));
                XAssert.AreEqual(targetDirectory.ToUpperInvariant(), TrimPathPrefix(chain[2].ToUpperInvariant()));
            }
        }
예제 #10
0
        public void GetChainOfSymlinks()
        {
            string targetFile = GetFullPath("target");

            File.WriteAllText(targetFile, "Contents");

            string intermediateLink = GetFullPath("intermediate.lnk");

            XAssert.IsTrue(FileUtilities.TryCreateSymbolicLink(intermediateLink, targetFile, isTargetFile: true));
            XAssert.IsTrue(File.Exists(intermediateLink));

            string sourceLink = GetFullPath("source.lnk");

            XAssert.IsTrue(FileUtilities.TryCreateSymbolicLink(sourceLink, intermediateLink, isTargetFile: true));
            XAssert.IsTrue(File.Exists(sourceLink));

            using (SafeFileHandle handle = OpenHandleForReparsePoint(sourceLink))
            {
                var chain = new List <string>();
                FileUtilities.GetChainOfReparsePoints(handle, sourceLink, chain);
                XAssert.AreEqual(3, chain.Count, "Chain of reparse points: " + string.Join(" -> ", chain));
                XAssert.AreEqual(sourceLink.ToUpperInvariant(), TrimPathPrefix(chain[0].ToUpperInvariant()));
                XAssert.AreEqual(intermediateLink.ToUpperInvariant(), TrimPathPrefix(chain[1].ToUpperInvariant()));
                XAssert.AreEqual(targetFile.ToUpperInvariant(), TrimPathPrefix(chain[2].ToUpperInvariant()));
            }
        }
예제 #11
0
        public void FindOpenHandle()
        {
            string directory = Path.Combine(TemporaryDirectory, "directoryToDelete");

            Directory.CreateDirectory(directory);
            string     filePath = Path.Combine(directory, "openfileFindOpen.txt");
            List <int> pids;
            string     diagnosticInfo;

            using (Stream s = new FileStream(filePath, FileMode.Create))
            {
                s.Write(new byte[] { 1, 2, 3 }, 0, 3);

                XAssert.IsTrue(HandleSearcher.GetProcessIdsUsingHandle(filePath, out pids));
                int thisProcess = Process.GetCurrentProcess().Id;
                XAssert.IsTrue(pids.Contains(thisProcess));

                XAssert.IsTrue(FileUtilities.TryFindOpenHandlesToFile(filePath, out diagnosticInfo));
                XAssert.IsTrue(diagnosticInfo.Contains(filePath));
                XAssert.IsTrue(diagnosticInfo.Contains(Process.GetCurrentProcess().ProcessName));
            }

            // The handle is now closed. We shouldn't find any usage
            XAssert.IsTrue(HandleSearcher.GetProcessIdsUsingHandle(filePath, out pids));
            XAssert.AreEqual(0, pids.Count);

            // This should still succeed even if there aren't any open handles
            XAssert.IsTrue(FileUtilities.TryFindOpenHandlesToFile(filePath, out diagnosticInfo));
        }
예제 #12
0
        /// <summary>
        /// Creates a volume root handle or retrieves an existing one.
        /// </summary>
        /// <remarks>
        /// This is the un-synchronized get-or-add operation resulting in <see cref="VolumeAccessor"/>
        /// not being thread-safe.
        /// The returned handle should not be disposed.
        /// </remarks>
        private SafeFileHandle TryGetVolumeHandle(ulong volumeSerial)
        {
            SafeFileHandle volumeHandle;

            if (!m_volumeHandles.TryGetValue(volumeSerial, out volumeHandle))
            {
                VolumeGuidPath volumeRootPath = m_map.TryGetVolumePathBySerial(volumeSerial);
                if (!volumeRootPath.IsValid)
                {
                    return(null);
                }

                OpenFileResult openResult = FileUtilities.TryCreateOrOpenFile(
                    volumeRootPath.GetDevicePath(),
                    FileDesiredAccess.GenericRead,
                    FileShare.ReadWrite | FileShare.Delete,
                    FileMode.Open,
                    FileFlagsAndAttributes.None,
                    out volumeHandle);

                if (!openResult.Succeeded)
                {
                    Contract.Assert(volumeHandle == null);
                    return(null);
                }

                m_volumeHandles.Add(volumeSerial, volumeHandle);
            }

            return(volumeHandle);
        }
예제 #13
0
        public void DirectoryAndFileSerialsAgree()
        {
            XAssert.IsTrue(Directory.Exists(TemporaryDirectory));

            SafeFileHandle directoryHandle = OpenTemporaryDirectory();

            using (directoryHandle)
            {
                using (FileStream fileStream = File.Create(GetFullPath("Junk")))
                {
                    uint directoryShortSerial = FileUtilities.GetShortVolumeSerialNumberByHandle(directoryHandle);
                    XAssert.AreNotEqual(0, directoryShortSerial, "A volume serial of zero (volume handle) is very unlikely");

                    uint fileShortSerial = FileUtilities.GetShortVolumeSerialNumberByHandle(fileStream.SafeFileHandle);
                    XAssert.AreNotEqual(0, fileShortSerial, "File reports a volume short serial of zero (unlikely), and this disagrees with the volume serial");
                    XAssert.AreEqual(directoryShortSerial, fileShortSerial, "File and volume short serials disagree");

                    ulong directorySerial = FileUtilities.GetVolumeSerialNumberByHandle(directoryHandle);
                    XAssert.AreEqual(directoryShortSerial, unchecked ((uint)directorySerial), "Directory long and short serials disagree");

                    ulong fileSerial = FileUtilities.GetVolumeSerialNumberByHandle(fileStream.SafeFileHandle);
                    XAssert.AreEqual(fileShortSerial, unchecked ((uint)fileSerial), "File long and short serials disagree");
                }
            }
        }
예제 #14
0
 private static bool SupportCopyOnWrite(string path)
 {
     using (FileStream fileStream = FileUtilities.CreateFileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))
     {
         return(FileUtilities.CheckIfVolumeSupportsCopyOnWriteByHandle(fileStream.SafeFileHandle));
     }
 }
예제 #15
0
        public void CanDeleteWithOtherOpenHardlinks()
        {
            string hardlink1 = Path.Combine(TemporaryDirectory, "hardlink1");

            File.WriteAllText(hardlink1, "asdf");

            string hardlink2 = Path.Combine(TemporaryDirectory, "hardlink2");

            XAssert.IsTrue(CreateHardLinkIfSupported(hardlink2, hardlink1));

            // Open a handle to hardlink2 without FileShare Delete mode
            using (new FileStream(hardlink2, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                BuildXLException exception = null;
                try
                {
                    FileUtilities.DeleteFile(hardlink1);
                }
                catch (BuildXLException ex)
                {
                    exception = ex;
                }
                // Successfully delete file
                XAssert.IsTrue(exception == null);
                XAssert.IsFalse(File.Exists(hardlink1));
            }
        }
예제 #16
0
        public void DeleteDispositionResultsInDeletion()
        {
            string path = Path.Combine(TemporaryDirectory, "toDelete");

            File.WriteAllText(path, "Important data");

            SafeFileHandle handle;
            var            openResult = FileUtilities.TryCreateOrOpenFile(
                path,
                FileDesiredAccess.Delete,
                FileShare.None,
                FileMode.Open,
                FileFlagsAndAttributes.None,
                out handle);

            using (handle)
            {
                XAssert.IsNotNull(handle);
                XAssert.IsTrue(openResult.Succeeded);
                XAssert.IsTrue(openResult.OpenedOrTruncatedExistingFile);

                // WindowsOSOnly - need to investigate equivalent on Unix
                if (!OperatingSystemHelper.IsUnixOS)
                {
                    XAssert.IsTrue(FileUtilities.TrySetDeletionDisposition(handle), "Failed to set deletion disposition");
                }
            }

            // WindowsOSOnly - need to investigate equivalent on Unix
            if (!OperatingSystemHelper.IsUnixOS)
            {
                XAssert.IsFalse(File.Exists(path), "File not unlinked after handle close.");
            }
        }
예제 #17
0
        public void DeleteDirectoryContents()
        {
            string rootDir = GetFullPath("Directory");

            Directory.CreateDirectory(rootDir);
            Directory.CreateDirectory(Path.Combine(rootDir, "subdir1"));
            Directory.CreateDirectory(Path.Combine(rootDir, "subdir2"));

            // Create a readonly file
            string nestedFile = Path.Combine(rootDir, "subdir1", "File.txt");

            File.WriteAllText(nestedFile, "asdf");
            File.SetAttributes(nestedFile, FileAttributes.ReadOnly);

            // And a normal file
            File.WriteAllText(Path.Combine(rootDir, "File.txt"), "asdf");

            string exeLink = Path.Combine(rootDir, "hardlink");

            XAssert.IsTrue(CreateHardLinkIfSupported(link: exeLink, linkTarget: DummyWaiter.GetDummyWaiterExeLocation()));

            // Add a hardlink
            using (var waiter = DummyWaiter.RunAndWait())
            {
                FileUtilities.DeleteDirectoryContents(rootDir);
            }

            XAssert.AreEqual(0, Directory.GetFileSystemEntries(rootDir).Length);
        }
예제 #18
0
        [Trait("Category", "WindowsOSOnly")] // need to investigate if equivalent on Unix
        public void DeleteDirectoryContentsHandleOpen()
        {
            string directory = Path.Combine(TemporaryDirectory, "directoryToDelete");

            Directory.CreateDirectory(directory);
            string openFile = Path.Combine(directory, "openfileDelDirContents.txt");

            using (Stream s = new FileStream(openFile, FileMode.Create))
            {
                Exception exception = null;
                s.Write(new byte[] { 1, 2, 3 }, 0, 3);
                try
                {
                    FileUtilities.DeleteDirectoryContents(directory);
                }
                catch (BuildXLException ex)
                {
                    exception = ex;
                }

                XAssert.IsNotNull(exception, "Expected failure since a handle to a contained file was still open");
                XAssert.IsTrue(exception.Message.Contains(FileUtilitiesMessages.FileDeleteFailed + NormalizeDirectoryPath(openFile)), exception.Message);
                XAssert.IsTrue(exception.Message.Contains("Handle was used by"), exception.Message);
            }

            // Try again with the handle closed. There should be no crash.
            FileUtilities.DeleteDirectoryContents(directory);

            // Clean up files so we don't leave undeletable files on disk
            FileUtilities.DeleteDirectoryContents(directory, deleteRootDirectory: true);
        }
예제 #19
0
        public void CanDeleteFileWithDenyACL()
        {
            string file      = GetFullPath("File with space");
            string directory = Path.GetDirectoryName(file);

            File.WriteAllText(file, string.Empty);
            try
            {
                FileInfo     fi            = new FileInfo(file);
                FileSecurity accessControl = fi.GetAccessControl(AccessControlSections.All);
                accessControl.PurgeAccessRules(WindowsIdentity.GetCurrent().User);
                accessControl.AddAccessRule(new FileSystemAccessRule(WindowsIdentity.GetCurrent().User, FileSystemRights.FullControl, AccessControlType.Deny));
                fi.SetAccessControl(accessControl);
                DirectoryInfo     di = new DirectoryInfo(directory);
                DirectorySecurity ds = di.GetAccessControl(AccessControlSections.All);
                ds.PurgeAccessRules(WindowsIdentity.GetCurrent().User);
                ds.AddAccessRule(new FileSystemAccessRule(WindowsIdentity.GetCurrent().User, FileSystemRights.CreateFiles, AccessControlType.Deny));
                di.SetAccessControl(ds);

                XAssert.IsTrue(File.Exists(file));
                FileUtilities.DeleteFile(file);
                XAssert.IsFalse(File.Exists(file));
            }
            finally
            {
                DirectoryInfo     di = new DirectoryInfo(directory);
                DirectorySecurity ds = di.GetAccessControl(AccessControlSections.All);
                ds.PurgeAccessRules(WindowsIdentity.GetCurrent().User);
                ds.AddAccessRule(new FileSystemAccessRule(WindowsIdentity.GetCurrent().User, FileSystemRights.FullControl, AccessControlType.Allow));
                di.SetAccessControl(ds);
                di.Delete(true);
            }
        }
예제 #20
0
        public void CanGetVolumePath()
        {
            VolumeMap map = CreateMapOfAllLocalVolumes();

            ulong          thisVolumeSerial;
            SafeFileHandle directoryHandle;

            FileUtilities.TryOpenDirectory(TemporaryDirectory, FileShare.ReadWrite | FileShare.Delete, out directoryHandle);
            using (directoryHandle)
            {
                XAssert.IsNotNull(directoryHandle, "Failed to open the TemporaryDirectory, which we just created");
                thisVolumeSerial = FileUtilities.GetVolumeSerialNumberByHandle(directoryHandle);
            }

            VolumeGuidPath volumePath = map.TryGetVolumePathBySerial(thisVolumeSerial);

            XAssert.IsTrue(volumePath.IsValid);

            var openResult = FileUtilities.TryOpenDirectory(volumePath.Path, FileShare.ReadWrite | FileShare.Delete, out directoryHandle);

            using (directoryHandle)
            {
                XAssert.IsTrue(openResult.Succeeded, "Failed to open the volume root (but we didn't ask for any access)");
                XAssert.IsTrue(openResult.OpenedOrTruncatedExistingFile);
                XAssert.IsNotNull(directoryHandle);
                XAssert.AreEqual(thisVolumeSerial, FileUtilities.GetVolumeSerialNumberByHandle(directoryHandle), "The volume root path has the wrong volume serial");
            }
        }
예제 #21
0
        public void RetryEmptyDirectoryDelete()
        {
            // Create an empty directory
            string dir = Path.Combine(TemporaryDirectory, "dir");

            Directory.CreateDirectory(dir);

            SafeFileHandle childHandle = null;

            FileUtilities.TryCreateOrOpenFile(
                dir,
                FileDesiredAccess.GenericRead,
                FileShare.Read,
                FileMode.Open,
                FileFlagsAndAttributes.FileFlagBackupSemantics,
                out childHandle);

            using (childHandle)
            {
                Exception exception = null;
                try
                {
                    // Fails because of handle open to /dir
                    FileUtilities.DeleteDirectoryContents(dir, deleteRootDirectory: true);
                }
                catch (Exception e)
                {
                    exception = e;
                }
                XAssert.IsTrue(exception != null);
                XAssert.IsTrue(FileUtilities.Exists(dir));
            }
        }
예제 #22
0
        public void CreateHardlinkSupportsLongPath()
        {
            var longPath = Enumerable.Range(0, NativeIOConstants.MaxDirectoryPath).Aggregate(TemporaryDirectory, (path, _) => Path.Combine(path, "dir"));

            FileUtilities.CreateDirectory(longPath);

            var file = Path.Combine(longPath, "out.txt");
            var link = Path.Combine(longPath, "hardlink");

            SafeFileHandle fileHandle;
            var            result = FileUtilities.TryCreateOrOpenFile(
                file,
                FileDesiredAccess.GenericWrite,
                FileShare.Delete,
                FileMode.Create,
                FileFlagsAndAttributes.FileAttributeNormal,
                out fileHandle);

            XAssert.IsTrue(result.Succeeded);
            using (FileStream stream = new FileStream(fileHandle, FileAccess.Write))
            {
                stream.WriteByte(255);
            }

            XAssert.IsTrue(CreateHardLinkIfSupported(link: link, linkTarget: file));
        }
예제 #23
0
        public void CannotAccessDeletedFile()
        {
            ulong  volumeSerial;
            FileId fileId;
            string path = GetFullPath("F");

            using (FileStream fs = File.Create(path))
            {
                volumeSerial = FileUtilities.GetVolumeSerialNumberByHandle(fs.SafeFileHandle);
                fileId       = FileUtilities.ReadFileUsnByHandle(fs.SafeFileHandle).Value.FileId;
            }

            File.Delete(path);

            VolumeMap map = CreateMapOfAllLocalVolumes();

            using (FileAccessor accessor = map.CreateFileAccessor())
            {
                SafeFileHandle handle;
                FileAccessor.OpenFileByIdResult openResult = accessor.TryOpenFileById(
                    volumeSerial,
                    fileId,
                    FileDesiredAccess.GenericRead,
                    FileShare.ReadWrite,
                    FileFlagsAndAttributes.None,
                    out handle);
                using (handle)
                {
                    XAssert.AreEqual(FileAccessor.OpenFileByIdResult.FailedToFindFile, openResult);
                    XAssert.IsNull(handle);
                }
            }
        }
예제 #24
0
        public void ReadToEnd()
        {
            WithVolumeHandle(
                volumeHandle =>
            {
                byte[] buffer = new byte[4096];

                while (true)
                {
                    QueryUsnJournalData journalState = QueryJournal(volumeHandle);

                    ReadUsnJournalResult readJournalResult = FileUtilities.TryReadUsnJournal(
                        volumeHandle,
                        buffer,
                        journalState.UsnJournalId,
                        startUsn: journalState.NextUsn);
                    XAssert.AreEqual(ReadUsnJournalStatus.Success, readJournalResult.Status);

                    XAssert.IsFalse(readJournalResult.NextUsn.IsZero);
                    XAssert.IsTrue(readJournalResult.NextUsn >= journalState.NextUsn);

                    if (readJournalResult.Records.Count == 0)
                    {
                        break;
                    }
                }
            });
        }
예제 #25
0
        public void TestEnumerateFilesWithPattern()
        {
            const string Target          = "targetDir";
            string       nestedDirectory = GetFullPath(Path.Combine(Target, "sub1", "sub2", "sub3"));

            FileUtilities.CreateDirectory(nestedDirectory);

            const string Content = "my text";

            File.WriteAllText(Path.Combine(nestedDirectory, "sub_file.txt"), Content);

            var entries = FileUtilities.FileSystem.EnumerateFiles(GetFullPath(Target), pattern: "sub*", recursive: true);

            XAssert.SetEqual(new [] { "sub_file.txt" }, entries.Select(e => e.FileName).ToHashSet());

            // Checking the size of the file.
            XAssert.AreEqual(Content.Length, entries.First(e => e.FileName == "sub_file.txt").Size);

            XAssert.AreEqual(0, FileUtilities.FileSystem.EnumerateFiles(GetFullPath(Target), pattern: "sub1", recursive: true).Count);
            XAssert.AreEqual(1, FileUtilities.FileSystem.EnumerateFiles(GetFullPath(Target), pattern: "sub_file*", recursive: true).Count);
            XAssert.AreEqual(1, FileUtilities.FileSystem.EnumerateFiles(GetFullPath(Target), pattern: "*.txt", recursive: true).Count);

            // Non recursive case
            XAssert.AreEqual(0, FileUtilities.FileSystem.EnumerateFiles(GetFullPath(Target), pattern: "*.txt", recursive: false).Count);

            // Pattern with 0 matches
            XAssert.AreEqual(0, FileUtilities.FileSystem.EnumerateFiles(GetFullPath(Target), pattern: "foo", recursive: true).Count);
        }
예제 #26
0
        public void RemoveDirectoryWithException()
        {
            string rootDir = GetFullPath("Directory");

            Directory.CreateDirectory(rootDir);
            Directory.CreateDirectory(Path.Combine(rootDir, "subdir1"));
            Assert.Throws <NativeWin32Exception>(() => FileUtilities.RemoveDirectory(rootDir));
        }
예제 #27
0
        private SafeFileHandle OpenTemporaryDirectory()
        {
            SafeFileHandle directoryHandle;
            var            directoryOpenResult = FileUtilities.TryOpenDirectory(TemporaryDirectory, FileShare.Read | FileShare.Write | FileShare.Delete, out directoryHandle);

            XAssert.IsTrue(directoryOpenResult.Succeeded);
            return(directoryHandle);
        }
예제 #28
0
        public void CreateAsyncFileStreamToCreateNewFile()
        {
            const string Target = @"newFile";

            using (FileUtilities.CreateAsyncFileStream(GetFullPath(Target), FileMode.CreateNew, FileAccess.Write, FileShare.Read | FileShare.Delete))
            {
                XAssert.IsTrue(File.Exists(GetFullPath(Target)));
            }
        }
예제 #29
0
 public void CreateReplacementFileInitiallyAbsent()
 {
     using (FileStream fs = FileUtilities.CreateReplacementFile(GetFullPath("Ghost"), FileShare.Read | FileShare.Delete))
     {
         XAssert.IsNotNull(fs);
         XAssert.AreEqual(0, fs.Length);
         fs.WriteByte(1);
     }
 }
예제 #30
0
        private void ExpectChangesSinceUsn(
            UsnChangeReasons expectedChangeReasons,
            SafeFileHandle volumeHandle,
            Usn startUsn,
            FileId fileId,
            out Usn nextUsn,
            TimeSpan?timeLimit = default(TimeSpan?))
        {
            const int DefaultTimeLimitForScanningInSecond = 30; // 30 sec for scanning.

            QueryUsnJournalData journalState = QueryJournal(volumeHandle);

            byte[] buffer = new byte[64 * 1024]; // 655 records per read.
            timeLimit = timeLimit.HasValue ? timeLimit : TimeSpan.FromSeconds(DefaultTimeLimitForScanningInSecond);
            var stopWatch = System.Diagnostics.Stopwatch.StartNew();
            UsnChangeReasons foundChangeReasons = 0;

            nextUsn = startUsn;

            while (true)
            {
                if (stopWatch.ElapsedTicks > timeLimit.Value.Ticks)
                {
                    break;
                }

                ReadUsnJournalResult result = FileUtilities.TryReadUsnJournal(
                    volumeHandle,
                    buffer,
                    journalState.UsnJournalId,
                    startUsn);

                nextUsn = result.NextUsn;

                if (!result.Succeeded)
                {
                    break;
                }

                if (result.Records.Count == 0)
                {
                    break;
                }

                foundChangeReasons |= UsnJournalUtilities.GetAggregateChangeReasons(fileId, result.Records);

                if (expectedChangeReasons == (foundChangeReasons & expectedChangeReasons))
                {
                    // Found all expected change reasons.
                    return;
                }

                startUsn = result.NextUsn;
            }

            XAssert.AreEqual(expectedChangeReasons, foundChangeReasons & expectedChangeReasons);
        }