示例#1
0
        public void WindowsErrorToHresultMappings(WindowsError error, HRESULT expected)
        {
            HRESULT result = ErrorMacros.HRESULT_FROM_WIN32(error);

            result.Should().Be(expected);
        }
示例#2
0
        public void CreateSymbolicLinkToFile()
        {
            using (var cleaner = new TestFileCleaner())
            {
                string filePath     = cleaner.CreateTestFile("CreateSymbolicLinkToFile");
                string symbolicLink = cleaner.GetTestPath();
                Action action       = () => FileMethods.CreateSymbolicLink(symbolicLink, filePath);

                if (CanCreateSymbolicLinks())
                {
                    action();
                    var attributes = FileMethods.GetFileAttributes(symbolicLink);
                    attributes.Should().HaveFlag(FileAttributes.ReparsePoint);

                    using (var handle = FileMethods.CreateFile(symbolicLink, CreationDisposition.OpenExisting, DesiredAccess.ReadExtendedAttributes,
                                                               ShareModes.All, fileFlags: FileFlags.OpenReparsePoint))
                    {
                        handle.IsInvalid.Should().BeFalse();
                        var(printName, substituteName, tag) = DeviceMethods.GetReparsePointNames(handle);
                        tag.Should().Be(ReparseTag.SymbolicLink);
                        printName.Should().Be(filePath);
                        substituteName.Should().Be(@"\??\" + filePath);
                    }
                }
                else
                {
                    // Can't create links unless you have admin rights SE_CREATE_SYMBOLIC_LINK_NAME SeCreateSymbolicLinkPrivilege
                    action.ShouldThrow <System.IO.IOException>().And.HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_PRIVILEGE_NOT_HELD));
                }
            }
        }
        public void OpenFileWithTrailingSeparator()
        {
            using (var cleaner = new TestFileCleaner())
            {
                string testFile = cleaner.CreateTestFile(nameof(OpenFileWithTrailingSeparator));

                string fullName = FileMethods.GetFullPathName(Paths.AddTrailingSeparator(testFile));

                FindOperation <string> find = new FindOperation <string>(testFile);
                Action action = () => find.FirstOrDefault();
                action.ShouldThrow <ArgumentException>().And.HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_INVALID_PARAMETER));

                action = () => FileMethods.CreateFile(Paths.AddTrailingSeparator(testFile), CreationDisposition.OpenExisting, DesiredAccess.ReadAttributes);
                action.ShouldThrow <WInteropIOException>().And.HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_INVALID_NAME));
            }
        }
示例#4
0
        public void CreateSymbolicLinkToLongPathFile()
        {
            using (var cleaner = new TestFileCleaner())
            {
                string longPath = @"\\?\" + PathGenerator.CreatePathOfLength(cleaner.TempFolder, 500);
                FileHelper.CreateDirectoryRecursive(longPath);
                string filePath = cleaner.CreateTestFile("CreateSymbolicLinkToLongPathFile", longPath);

                string symbolicLink = cleaner.GetTestPath();
                Action action       = () => FileMethods.CreateSymbolicLink(symbolicLink, filePath);

                if (CanCreateSymbolicLinks())
                {
                    action();
                    var attributes = FileMethods.GetFileAttributes(symbolicLink);
                    attributes.Should().HaveFlag(FileAttributes.ReparsePoint);
                }
                else
                {
                    action.ShouldThrow <System.IO.IOException>().And.HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_PRIVILEGE_NOT_HELD));
                }
            }
        }
        public void LockedFileDirectoryDeletion()
        {
            using (var cleaner = new TestFileCleaner())
            {
                string directory = cleaner.GetTestPath();
                DirectoryMethods.CreateDirectory(directory);
                FileMethods.DirectoryExists(directory).Should().BeTrue();
                string file = cleaner.CreateTestFile(nameof(LockedFileDirectoryDeletion), directory);
                using (var handle = FileMethods.CreateFile(file, CreationDisposition.OpenExisting, DesiredAccess.GenericRead, ShareModes.ReadWrite | ShareModes.Delete))
                {
                    handle.IsInvalid.Should().BeFalse();

                    // Mark the file for deletion
                    FileMethods.DeleteFile(file);

                    // RemoveDirectory API call will throw
                    Action action = () => DirectoryMethods.RemoveDirectory(directory);
                    action.ShouldThrow <WInteropIOException>().And.HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_DIR_NOT_EMPTY));

                    // Opening the directory for deletion will succeed, but have no impact
                    using (var directoryHandle = FileMethods.CreateFile(
                               directory,
                               CreationDisposition.OpenExisting,
                               DesiredAccess.ListDirectory | DesiredAccess.Delete,
                               ShareModes.ReadWrite | ShareModes.Delete,
                               FileAttributes.None,
                               FileFlags.BackupSemantics | FileFlags.DeleteOnClose))
                    {
                        directoryHandle.IsInvalid.Should().BeFalse();
                    }
                }

                // File will be gone now that the handle is closed
                FileMethods.FileExists(file).Should().BeFalse();

                // But the directory will still exist as it doesn't respect DeleteOnClose with an open handle when it is closed
                FileMethods.DirectoryExists(directory).Should().BeTrue();

                // Create a handle to the directory again with DeleteOnClose and it will actually delete the directory
                using (var directoryHandle = FileMethods.CreateFile(
                           directory,
                           CreationDisposition.OpenExisting,
                           DesiredAccess.ListDirectory | DesiredAccess.Delete,
                           ShareModes.ReadWrite | ShareModes.Delete,
                           FileAttributes.None,
                           FileFlags.BackupSemantics | FileFlags.DeleteOnClose))
                {
                    directoryHandle.IsInvalid.Should().BeFalse();
                }
                FileMethods.DirectoryExists(directory).Should().BeFalse();
            }
        }