public string GetFullPath(string path, string basePath = null) { if (path == null) { throw new ArgumentNullException(nameof(path)); } switch (Paths.GetPathFormat(path)) { case PathFormat.UniformNamingConventionExtended: case PathFormat.VolumeAbsoluteExtended: // Don't mess with \\?\ return(path); case PathFormat.DriveRelative: // Get the directory for the specified drive, and remove the drive specifier string drive = Paths.AddTrailingSeparator(path.Substring(0, 2)); basePath = directory.GetCurrentDirectory(drive); path = path.Substring(2); break; } if (basePath == null || !Paths.IsRelative(path)) { // Fixed, or we don't have a base path return(NativeMethods.FileManagement.GetFullPathName(path)); } else { return(NativeMethods.FileManagement.GetFullPathName(Paths.Combine(basePath, path))); } }
public void FindFileWithTrailingSeparator() { using var cleaner = new TestFileCleaner(); string testFile = cleaner.CreateTestFile(nameof(FindFileWithTrailingSeparator)); string fullName = Storage.GetFullPathName(Paths.AddTrailingSeparator(testFile)); }
/// <summary> /// Gets volume information for the given volume root path. /// </summary> public static VolumeInformation GetVolumeInformation(string rootPath) { rootPath = Paths.AddTrailingSeparator(rootPath); using (var volumeName = new StringBuffer(initialCharCapacity: Paths.MaxPath + 1)) using (var fileSystemName = new StringBuffer(initialCharCapacity: Paths.MaxPath + 1)) { // Documentation claims that removable (floppy/optical) drives will prompt for media when calling this API and say to // set the error mode to prevent it. I can't replicate this behavior or find any documentation on when it might have // changed. I'm guessing this changed in Windows 7 when they added support for setting the thread's error mode (as // opposed to the entire process). uint serialNumber, maxComponentLength; FileSystemFeature flags; if (!Direct.GetVolumeInformationW(rootPath, volumeName, volumeName.CharCapacity, out serialNumber, out maxComponentLength, out flags, fileSystemName, fileSystemName.CharCapacity)) { throw ErrorHelper.GetIoExceptionForLastError(rootPath); } volumeName.SetLengthToFirstNull(); fileSystemName.SetLengthToFirstNull(); VolumeInformation info = new VolumeInformation { RootPathName = rootPath, VolumeName = volumeName.ToString(), VolumeSerialNumber = serialNumber, MaximumComponentLength = maxComponentLength, FileSystemFlags = flags, FileSystemName = fileSystemName.ToString() }; return(info); } }
internal static VolumeInformation GetVolumeInformation(string rootPath) { rootPath = Paths.AddTrailingSeparator(rootPath); using (var volumeName = new StringBuffer(initialMinCapacity: Paths.MaxPath + 1)) using (var fileSystemName = new StringBuffer(initialMinCapacity: Paths.MaxPath + 1)) { uint serialNumber, maxComponentLength; FileSystemFeature flags; if (!Private.GetVolumeInformationW(rootPath, volumeName, (uint)volumeName.CharCapacity, out serialNumber, out maxComponentLength, out flags, fileSystemName, (uint)fileSystemName.CharCapacity)) { int lastError = Marshal.GetLastWin32Error(); throw GetIoExceptionForError(lastError, rootPath); } volumeName.SetLengthToFirstNull(); fileSystemName.SetLengthToFirstNull(); VolumeInformation info = new VolumeInformation { RootPathName = rootPath, VolumeName = volumeName.ToString(), VolumeSerialNumber = serialNumber, MaximumComponentLength = maxComponentLength, FileSystemFlags = flags, FileSystemName = fileSystemName.ToString() }; return(info); } }
/// <summary> /// Get the drive type for the given root path. /// </summary> public static DriveType GetDriveType(string rootPath) { if (rootPath != null) { rootPath = Paths.AddTrailingSeparator(rootPath); } return(Imports.GetDriveTypeW(rootPath)); }
public void GetFileNameBasic() { string tempPath = Storage.GetTempPath(); using var directory = Storage.CreateDirectoryHandle(tempPath); // This will give back the local path (minus the device, eg \Users\... or \Server\Share\...) string name = Storage.GetFileName(directory); tempPath.Should().EndWith(Paths.AddTrailingSeparator(name)); }
public void GetFileNameBasic() { 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 local path (minus the device, eg \Users\... or \Server\Share\...) string name = FileDesktopMethods.GetFileName(directory); tempPath.Should().EndWith(Paths.AddTrailingSeparator(name)); } }
public void GetHandleNameBasic() { string tempPath = Storage.GetTempPath(); using (var directory = Storage.CreateDirectoryHandle(tempPath)) { // This will give back the NT path (\Device\HarddiskVolumen...) string name = Handles.GetObjectName(directory); // Skip past the C:\ Paths.AddTrailingSeparator(name).Should().EndWith(tempPath.Substring(3)); } }
public string GetFullPath(string path, string basePath = null) { if (path == null) { throw new ArgumentNullException(nameof(path)); } // Don't mess with \\?\ if (Paths.IsExtended(path)) { return(path); } if (basePath != null && Paths.IsPartiallyQualified(basePath)) { throw new ArgumentException(nameof(basePath)); } switch (Paths.GetPathFormat(path)) { case PathFormat.LocalDriveRooted: // Get the directory for the specified drive, and remove the drive specifier string drive = path.Substring(0, 2); if (basePath == null || !basePath.StartsWith(drive, StringComparison.OrdinalIgnoreCase)) { // No basepath or it doesn't match, find the current directory for the drive basePath = _directory.GetCurrentDirectory(Paths.AddTrailingSeparator(drive)); } path = path.Substring(2); break; case PathFormat.LocalCurrentDriveRooted: // Get the root directory of the basePath if possible basePath = basePath ?? _directory.GetCurrentDirectory(); basePath = Paths.GetRoot(basePath) ?? basePath; break; } if (basePath == null || !Paths.IsPartiallyQualified(path)) { // Fixed, or we don't have a base path return(Storage.GetFullPathName(path)); } else { return(Storage.GetFullPathName(Paths.Combine(basePath, path))); } }
public void GetHandleNameBasic() { 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 path (\Device\HarddiskVolumen...) string name = HandleDesktopMethods.GetObjectName(directory); // Skip past the C:\ Paths.AddTrailingSeparator(name).Should().EndWith(tempPath.Substring(3)); } }
public void OpenFileWithTrailingSeparator() { using (var cleaner = new TestFileCleaner()) { string testFile = cleaner.CreateTestFile(nameof(OpenFileWithTrailingSeparator)); string fullName = Storage.GetFullPathName(Paths.AddTrailingSeparator(testFile)); FindOperation <string> find = new FindOperation <string>(testFile); Action action = () => find.FirstOrDefault(); action.Should().Throw <ArgumentException>().And.HResult.Should().Be((int)WindowsError.ERROR_INVALID_PARAMETER.ToHResult()); action = () => Storage.CreateFile(Paths.AddTrailingSeparator(testFile), CreationDisposition.OpenExisting, DesiredAccess.ReadAttributes); action.Should().Throw <WInteropIOException>().And.HResult.Should().Be((int)WindowsError.ERROR_INVALID_NAME.ToHResult()); } }
internal static string GetVolumeNameForVolumeMountPoint(string volumeMountPoint) { volumeMountPoint = Paths.AddTrailingSeparator(volumeMountPoint); // MSDN claims 50 is "reasonable", let's go double. return(StringBufferCache.CachedBufferInvoke(100, (volumeName) => { if (!Private.GetVolumeNameForVolumeMountPointW(volumeMountPoint, volumeName, (uint)volumeName.CharCapacity)) { int lastError = Marshal.GetLastWin32Error(); throw GetIoExceptionForError(lastError, volumeMountPoint); } volumeName.SetLengthToFirstNull(); return volumeName.ToString(); })); }
/// <summary> /// Gets the GUID format (\\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\) of the given volume mount point path. /// </summary> public static string GetVolumeNameForVolumeMountPoint(string volumeMountPoint) { volumeMountPoint = Paths.AddTrailingSeparator(volumeMountPoint); return(BufferHelper.BufferInvoke((StringBuffer buffer) => { // MSDN claims 50 is "reasonable", let's go double. buffer.EnsureCharCapacity(100); if (!Imports.GetVolumeNameForVolumeMountPointW(volumeMountPoint, buffer, buffer.CharCapacity)) { throw Errors.GetIoExceptionForLastError(volumeMountPoint); } buffer.SetLengthToFirstNull(); return buffer.ToString(); })); }
public void AddTrailingSeparator(string value, string expected) { Paths.AddTrailingSeparator(value).Should().Be(expected); }