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 static IEnumerable <BackupStreamInformation> GetAlternateStreamInformation(string path) { List <BackupStreamInformation> streams = new List <BackupStreamInformation>(); using (var fileHandle = FileMethods.CreateFile( path: path, // To look at metadata we don't need read or write access desiredAccess: 0, shareMode: ShareMode.FILE_SHARE_READWRITE, creationDisposition: CreationDisposition.OPEN_EXISTING, fileAttributes: FileAttributes.NONE, fileFlags: FileFlags.FILE_FLAG_BACKUP_SEMANTICS)) { using (BackupReader reader = new BackupReader(fileHandle)) { BackupStreamInformation?info; while ((info = reader.GetNextInfo()).HasValue) { if (info.Value.StreamType == BackupStreamType.BACKUP_ALTERNATE_DATA) { streams.Add(new BackupStreamInformation { Name = info.Value.Name, Size = info.Value.Size }); } } } } return(streams); }
public void DeleteDirectoryBasic() { using (var temp = new TestFileCleaner()) { string directoryPath = temp.GetTestPath(); DirectoryMethods.CreateDirectory(directoryPath); using (var directory = FileMethods.CreateFile(directoryPath, 0, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.OPEN_EXISTING, FileAttributes.FILE_ATTRIBUTE_DIRECTORY, FileFlags.FILE_FLAG_BACKUP_SEMANTICS)) { directory.IsInvalid.Should().BeFalse(); } DirectoryMethods.RemoveDirectory(directoryPath); Action action = () => { using (var directory = FileMethods.CreateFile(directoryPath, 0, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.OPEN_EXISTING, FileAttributes.FILE_ATTRIBUTE_DIRECTORY, FileFlags.FILE_FLAG_BACKUP_SEMANTICS)) { } }; action.ShouldThrow <System.IO.FileNotFoundException>(); } }
public void GetBasicInfoByHandleBasic() { string tempPath = FileMethods.GetTempPath(); string tempFileName = System.IO.Path.Combine(tempPath, System.IO.Path.GetRandomFileName()); try { using (var directory = FileMethods.CreateFile(tempPath, DesiredAccess.GENERIC_READ, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.OPEN_EXISTING, FileAttributes.NONE, FileFlags.FILE_FLAG_BACKUP_SEMANTICS)) { var directoryInfo = FileMethods.GetFileBasicInfoByHandle(directory); directoryInfo.Attributes.Should().HaveFlag(FileAttributes.FILE_ATTRIBUTE_DIRECTORY); using (var file = FileMethods.CreateFile(tempFileName, DesiredAccess.GENERIC_READ | DesiredAccess.GENERIC_WRITE, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.CREATE_NEW)) { var fileInfo = FileMethods.GetFileBasicInfoByHandle(file); fileInfo.Attributes.Should().NotHaveFlag(FileAttributes.FILE_ATTRIBUTE_DIRECTORY); fileInfo.CreationTime.Should().BeAfter(directoryInfo.CreationTime); } } } finally { FileMethods.DeleteFile(tempFileName); } }
public void GetStreamInfoByHandleBasic() { string tempPath = FileMethods.GetTempPath(); string tempFileName = System.IO.Path.Combine(tempPath, System.IO.Path.GetRandomFileName()); try { using (var directory = FileMethods.CreateFile(tempPath, DesiredAccess.GENERIC_READ, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.OPEN_EXISTING, FileAttributes.NONE, FileFlags.FILE_FLAG_BACKUP_SEMANTICS)) { var directoryInfo = FileMethods.GetStreamInformationByHandle(directory); directoryInfo.Should().BeEmpty(); using (var file = FileMethods.CreateFile(tempFileName, DesiredAccess.GENERIC_READ | DesiredAccess.GENERIC_WRITE, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.CREATE_NEW)) { var fileInfo = FileMethods.GetStreamInformationByHandle(file); fileInfo.Should().HaveCount(1); var info = fileInfo.First(); info.Name.Should().Be(@"::$DATA"); info.Size.Should().Be(0); info.AllocationSize.Should().Be(0); } } } finally { FileMethods.DeleteFile(tempFileName); } }
public void FinalPathNameVolumeNameBehavior() { // This test is asserting that the original volume name has nothing to do with the volume GetFinalPathNameByHandle returns using (var cleaner = new TestFileCleaner()) { string filePath = cleaner.CreateTestFile("FinalPathNameVolumeNameBehavior"); using (var handle = FileMethods.CreateFile(filePath.ToLower(), DesiredAccess.GENERIC_READ, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.OPEN_EXISTING)) { handle.IsInvalid.Should().BeFalse(); string extendedPath = @"\\?\" + filePath; FileDesktopMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.FILE_NAME_NORMALIZED) .Should().Be(extendedPath); FileDesktopMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.FILE_NAME_OPENED) .Should().Be(extendedPath); FileDesktopMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.VOLUME_NAME_DOS) .Should().Be(extendedPath); FileDesktopMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.VOLUME_NAME_GUID) .Should().StartWith(@"\\?\Volume"); FileDesktopMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.VOLUME_NAME_NT) .Should().StartWith(@"\Device\"); FileDesktopMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.VOLUME_NAME_NONE) .Should().Be(filePath.Substring(2)); } } }
public void GetFileAttributesBehavior_DeletedFile() { using (var cleaner = new TestFileCleaner()) { string path = cleaner.CreateTestFile(nameof(GetFileAttributesBehavior_DeletedFile)); using (var handle = FileMethods.CreateFile(path, CreationDisposition.OpenExisting, shareMode: ShareModes.All)) { handle.IsInvalid.Should().BeFalse(); FileMethods.FileExists(path).Should().BeTrue(); FileMethods.DeleteFile(path); // With the file deleted and the handle still open the file will still physically exist. // Trying to access the file via a handle at this point will fail with access denied. Action action = () => FileMethods.FileExists(path); action.ShouldThrow <UnauthorizedAccessException>(); action = () => FileMethods.CreateFile(path, CreationDisposition.OpenExisting, shareMode: ShareModes.All, desiredAccess: DesiredAccess.ReadAttributes); action.ShouldThrow <UnauthorizedAccessException>(); // Find file will work at this point. IntPtr findHandle = FileMethods.Imports.FindFirstFileW(path, out WIN32_FIND_DATA findData); findHandle.Should().NotBe(IntPtr.Zero); try { findData.cFileName.CreateString().Should().Be(Paths.GetLastSegment(path)); } finally { FileMethods.Imports.FindClose(findHandle); } } } }
public void GetMultipleStreamInfoByHandle() { using (var temp = new TestFileCleaner()) { string source = temp.GetTestPath(); using (var file = FileMethods.CreateFile(source, DesiredAccess.GENERIC_READ, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.CREATE_NEW)) { file.IsInvalid.Should().BeFalse(); } string destination = temp.GetTestPath(); FileMethods.CopyFile(source, destination); string alternateStream = destination + @":Foo:$DATA"; FileMethods.CopyFile(source, alternateStream); using (var file = FileMethods.CreateFile(destination, DesiredAccess.GENERIC_READ | DesiredAccess.GENERIC_WRITE, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.OPEN_EXISTING)) { var fileInfo = FileMethods.GetStreamInformationByHandle(file); fileInfo.Should().BeEquivalentTo(new StreamInformation[] { new StreamInformation { Name = @"::$DATA" }, new StreamInformation { Name = @":Foo:$DATA" } }); } } }
public void FinalPathNameLongPath() { using (var cleaner = new TestFileCleaner()) { string longPath = @"\\?\" + PathGenerator.CreatePathOfLength(cleaner.TempFolder, 500); string filePath = Paths.Combine(longPath, System.IO.Path.GetRandomFileName()); FileHelper.CreateDirectoryRecursive(longPath); FileHelper.WriteAllText(filePath, "FinalPathNameLongPathPrefixRoundTripBehavior"); using (var handle = FileMethods.CreateFile(filePath, DesiredAccess.GENERIC_READ, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.OPEN_EXISTING)) { handle.IsInvalid.Should().BeFalse(); FileDesktopMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.FILE_NAME_NORMALIZED) .Should().Be(filePath); FileDesktopMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.FILE_NAME_OPENED) .Should().Be(filePath); FileDesktopMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.VOLUME_NAME_DOS) .Should().Be(filePath); FileDesktopMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.VOLUME_NAME_GUID) .Should().StartWith(@"\\?\Volume"); FileDesktopMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.VOLUME_NAME_NT) .Should().StartWith(@"\Device\"); FileDesktopMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.VOLUME_NAME_NONE) .Should().Be(filePath.Substring(6)); } } }
public void FinalPathNameBasic() { using (var cleaner = new TestFileCleaner()) { string filePath = cleaner.CreateTestFile("FinalPathNameBehavior"); using (var handle = FileMethods.CreateFile(filePath.ToLower(), CreationDisposition.OpenExisting, DesiredAccess.GenericRead)) { handle.IsInvalid.Should().BeFalse(); string extendedPath = @"\\?\" + filePath; FileMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.FILE_NAME_NORMALIZED) .Should().Be(extendedPath); FileMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.FILE_NAME_OPENED) .Should().Be(extendedPath); FileMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.VOLUME_NAME_DOS) .Should().Be(extendedPath); FileMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.VOLUME_NAME_GUID) .Should().StartWith(@"\\?\Volume"); FileMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.VOLUME_NAME_NT) .Should().StartWith(@"\Device\"); FileMethods.GetFinalPathNameByHandle(handle, GetFinalPathNameByHandleFlags.VOLUME_NAME_NONE) .Should().Be(filePath.Substring(2)); } } }
public void GetMultipleStreamInfoByHandle() { using (var temp = new TestFileCleaner()) { string source = temp.GetTestPath(); using (var file = FileMethods.CreateFile(source, CreationDisposition.CreateNew)) { file.IsInvalid.Should().BeFalse(); } string destination = temp.GetTestPath(); FileMethods.CopyFile(source, destination); string alternateStream = destination + @":Foo:$DATA"; FileMethods.CopyFile(source, alternateStream); using (var file = FileMethods.CreateFile(destination, CreationDisposition.OpenExisting)) { var fileInfo = FileMethods.GetStreamInformation(file); fileInfo.Should().BeEquivalentTo(new StreamInformation[] { new StreamInformation { Name = @"::$DATA" }, new StreamInformation { Name = @":Foo:$DATA" } }); } } }
public void GetShortNameBasic() { string tempPath = FileMethods.GetTempPath(); using (var directory = DirectoryMethods.CreateDirectoryHandle(tempPath)) { // This will give back the NT volume path (\Device\HarddiskVolumen\) string directoryName = FileMethods.GetShortName(directory); directoryName.Should().Be("Temp"); string tempFileName = "ExtraLongName" + System.IO.Path.GetRandomFileName(); string tempFilePath = System.IO.Path.Combine(tempPath, tempFileName); try { using (var file = FileMethods.CreateFile(tempFilePath, CreationDisposition.CreateNew, DesiredAccess.GenericRead)) { string fileName = FileMethods.GetShortName(file); fileName.Length.Should().BeLessOrEqualTo(12); } } finally { FileMethods.DeleteFile(tempFilePath); } } }
public void GetStandardInfoByHandleBasic() { string tempPath = FileMethods.GetTempPath(); string tempFileName = System.IO.Path.Combine(tempPath, System.IO.Path.GetRandomFileName()); try { using (var directory = FileMethods.CreateFile(tempPath, DesiredAccess.GENERIC_READWRITE, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.OPEN_EXISTING, FileAttributes.NONE, FileFlags.FILE_FLAG_BACKUP_SEMANTICS)) { var info = FileMethods.GetFileStandardInfoByHandle(directory); info.Directory.Should().BeTrue(); } using (var file = FileMethods.CreateFile(tempFileName, DesiredAccess.GENERIC_READWRITE, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.CREATE_NEW)) { var info = FileMethods.GetFileStandardInfoByHandle(file); info.Directory.Should().BeFalse(); info.NumberOfLinks.Should().Be(1); info.DeletePending.Should().BeFalse(); info.AllocationSize.Should().Be(0); info.EndOfFile.Should().Be(0); } } finally { FileMethods.DeleteFile(tempFileName); } }
public void GetShortNameBasic() { string tempPath = FileMethods.GetTempPath(); using (var directory = FileMethods.CreateFile(tempPath, DesiredAccess.GENERIC_READ, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.OPEN_EXISTING, FileAttributes.NONE, FileFlags.FILE_FLAG_BACKUP_SEMANTICS)) { // This will give back the NT volume path (\Device\HarddiskVolumen\) string directoryName = FileDesktopMethods.GetShortName(directory); directoryName.Should().Be("Temp"); string tempFileName = "ExtraLongName" + System.IO.Path.GetRandomFileName(); string tempFilePath = System.IO.Path.Combine(tempPath, tempFileName); try { using (var file = FileMethods.CreateFile(tempFilePath, DesiredAccess.GENERIC_READ, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.CREATE_NEW)) { string fileName = FileDesktopMethods.GetShortName(file); fileName.Length.Should().BeLessOrEqualTo(12); } } finally { FileMethods.DeleteFile(tempFilePath); } } }
public void QueryDeviceName() { // Need to open the handle with no rights (desiredAccess: 0) to avoid needing to run as admin using (var handle = FileMethods.CreateFile(@"\\.\C:", CreationDisposition.OpenExisting, desiredAccess: 0)) { DeviceMethods.QueryDeviceName(handle).Should().StartWith(@"\Device\HarddiskVolume"); } }
public void QueryStableGuid() { // Need to open the handle with no rights (desiredAccess: 0) to avoid needing to run as admin using (var handle = FileMethods.CreateFile(@"\\.\C:", CreationDisposition.OpenExisting, desiredAccess: 0)) { DeviceMethods.QueryStableGuid(handle).Should().NotBe(Guid.Empty); } }
public void CreateFileComPort() { using (var file = FileMethods.CreateFile(@"COM4", CreationDisposition.OpenExisting, DesiredAccess.GenericRead)) { file.IsInvalid.Should().BeFalse(); FileMethods.GetFileType(file).Should().Be(FileType.Character); } }
public void CreateFileHarddiskVolume() { using (var file = FileMethods.CreateFile(@"\\?\GLOBALROOT\Device\HarddiskVolume1", CreationDisposition.OpenExisting, DesiredAccess.GenericRead)) { file.IsInvalid.Should().BeFalse(); FileMethods.GetFileType(file).Should().Be(FileType.Disk); } }
public void CreateFileRawParition() { // You can't open with read/write access unless running elevated using (var file = FileMethods.CreateFile(@"\\?\GLOBALROOT\Device\Harddisk0\Partition0", CreationDisposition.OpenExisting, 0)) { file.IsInvalid.Should().BeFalse(); FileMethods.GetFileType(file).Should().Be(FileType.Disk); } }
public void CreateFileHarddiskVolume() { using (var file = FileMethods.CreateFile(@"\\?\GLOBALROOT\Device\HarddiskVolume1", DesiredAccess.GENERIC_READ, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.OPEN_EXISTING)) { file.IsInvalid.Should().BeFalse(); FileMethods.GetFileType(file).Should().Be(FileType.FILE_TYPE_DISK); } }
/// <summary> /// Simple wrapper to allow creating a file handle for an existing directory. /// </summary> public static SafeFileHandle CreateDirectoryHandle(string directoryPath, DesiredAccess desiredAccess = DesiredAccess.ListDirectory) { return(FileMethods.CreateFile( directoryPath, CreationDisposition.OpenExisting, desiredAccess, ShareModes.ReadWrite | ShareModes.Delete, FileAttributes.None, FileFlags.BackupSemantics)); }
public void GetFilePositionForEmptyFile() { using (var temp = new TestFileCleaner()) { using (var fileHandle = FileMethods.CreateFile(temp.GetTestPath(), CreationDisposition.CreateNew, DesiredAccess.GenericReadWrite, 0)) { FileMethods.SetFilePointer(fileHandle, 0, MoveMethod.Current).Should().Be(0); } } }
public void QueryInterfaceName() { // TODO: Need to conditionalize this on RS1 // Need to open the handle with no rights (desiredAccess: 0) to avoid needing to run as admin using (var handle = FileMethods.CreateFile(@"\\.\C:", CreationDisposition.OpenExisting, desiredAccess: 0)) { DeviceMethods.QueryInterfacename(handle).Should().StartWith(@"\\?\STORAGE#Volume#{"); } }
public void GetEmptyFileSize() { using (var temp = new TestFileCleaner()) { using (var fileHandle = FileMethods.CreateFile(temp.GetTestPath(), CreationDisposition.CreateNew, DesiredAccess.GenericReadWrite, 0)) { FileMethods.GetFileSize(fileHandle).Should().Be(0); } } }
public void QuerySuggestedLinkName() { // Need to open the handle with no rights (desiredAccess: 0) to avoid needing to run as admin using (var handle = FileMethods.CreateFile(@"\\.\C:", CreationDisposition.OpenExisting, desiredAccess: 0)) { Action action = () => DeviceMethods.QuerySuggestedLinkName(handle); action.ShouldThrow <WInteropIOException>("this is an optional query, not aware of which drivers support this"). And.HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_NOT_FOUND)); } }
public void FileTypeOfFile() { using (var cleaner = new TestFileCleaner()) { using (var testFile = FileMethods.CreateFile(cleaner.GetTestPath(), CreationDisposition.CreateNew)) { FileMethods.GetFileType(testFile).Should().Be(FileType.Disk); } } }
public void CreateFileRawParition() { // You can't open with read/write access unless running elevated using (var file = FileMethods.CreateFile(@"\\?\GLOBALROOT\Device\Harddisk0\Partition0", DesiredAccess.NONE, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.OPEN_EXISTING)) { file.IsInvalid.Should().BeFalse(); FileMethods.GetFileType(file).Should().Be(FileType.FILE_TYPE_DISK); } }
public void CreateFileOpenDriveRoot() { StoreHelper.ValidateStoreGetsUnauthorizedAccess(() => { using (var file = FileMethods.CreateFile(@"C:\.", 0, ShareMode.FILE_SHARE_READWRITE, CreationDisposition.OPEN_EXISTING, FileAttributes.NONE, FileFlags.FILE_FLAG_BACKUP_SEMANTICS)) { file.IsInvalid.Should().BeFalse(); } }); }
/// <summary> /// Gets the DOS drive letter for the given volume if it has one. /// </summary> public unsafe static string QueryDosVolumePath(string volume) { var mountManager = FileMethods.CreateFile( @"\\?\MountPointManager", CreationDisposition.OpenExisting, 0); ControlCode controlCode = ControlCodes.MountManager.QueryDosVolumePath; // Read ulong then get string string dosVolumePath = null; BufferHelper.BufferInvoke((StringBuffer inBuffer) => { // The input is MOUNTMGR_TARGET_NAME which is a short length in bytes followed by the unicode string // https://msdn.microsoft.com/en-us/library/windows/hardware/ff562289.aspx inBuffer.Append((char)(volume.Length * sizeof(char))); inBuffer.Append(volume); BufferHelper.BufferInvoke((StringBuffer outBuffer) => { // Give enough for roughly 50 characters for a start outBuffer.EnsureCharCapacity(50); while (!Imports.DeviceIoControl( hDevice: mountManager, dwIoControlCode: controlCode, lpInBuffer: inBuffer.VoidPointer, nInBufferSize: checked ((uint)inBuffer.ByteCapacity), lpOutBuffer: outBuffer.VoidPointer, nOutBufferSize: checked ((uint)outBuffer.ByteCapacity), lpBytesReturned: out _, lpOverlapped: null)) { WindowsError error = Errors.GetLastError(); switch (error) { case WindowsError.ERROR_MORE_DATA: outBuffer.EnsureByteCapacity(checked (outBuffer.ByteCapacity * 2)); break; default: throw Errors.GetIoExceptionForError(error, volume); } } // MOUNTMGR_VOLUME_PATHS is a uint length followed by a multi string (double null terminated) // we only care about the first string in this case (should only be one?) so we can skip beyond // the 4 bytes and read to null. dosVolumePath = new string(outBuffer.CharPointer + 2); }); }); return(dosVolumePath); }
public void CanCreateHandleToMountPointManager() { StoreHelper.ValidateStoreGetsUnauthorizedAccess(() => { using (var mountPointManager = FileMethods.CreateFile( @"\\.\MountPointManager", CreationDisposition.OpenExisting, 0, ShareModes.ReadWrite, FileAttributes.Normal)) { mountPointManager.IsInvalid.Should().BeFalse(); } }); }