public static bool IsDirectoryCaseSensitive(string directory, bool throwOnError = true) { IntPtr hFile = CreateFile(directory, 0, 0, IntPtr.Zero, FileMode.Open, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero); if (hFile == INVALID_HANDLE) { throw new Win32Exception(); } try { IO_STATUS_BLOCK iosb = new IO_STATUS_BLOCK(); FILE_CASE_SENSITIVE_INFORMATION caseSensitive = new FILE_CASE_SENSITIVE_INFORMATION(); uint status = NtQueryInformationFile(hFile, ref iosb, ref caseSensitive, Marshal.SizeOf <FILE_CASE_SENSITIVE_INFORMATION>(), FILE_INFORMATION_CLASS.FileCaseSensitiveInformation); if (status == STATUS_NOT_SUPPORTED) { // Not supported, must be older version of windows. // Directory case sensitivity is impossible. // Not tested, but this is most likely what // should be returned in this situation. return(false); } else if (status != STATUS_SUCCESS) { throw new Exception($"Unknown NTSTATUS: {status:X8}!"); } return(caseSensitive.Flags.HasFlag(CASE_SENSITIVITY_FLAGS.CaseSensitiveDirectory)); } finally { CloseHandle(hFile); } }
public static bool IsDirectoryCaseSensitivitySupported() { if (isSupported.HasValue) { return(isSupported.Value); } // Make sure the directory exists if (!Directory.Exists(TempDirectory)) { Directory.CreateDirectory(TempDirectory); } IntPtr hFile = CreateFile(TempDirectory, 0, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero); if (hFile == INVALID_HANDLE) { throw new Exception("Failed to open file while checking case sensitivity support!"); } try { IO_STATUS_BLOCK iosb = new IO_STATUS_BLOCK(); FILE_CASE_SENSITIVE_INFORMATION caseSensitive = new FILE_CASE_SENSITIVE_INFORMATION(); // Strangely enough, this doesn't fail on files NTSTATUS result = NtQueryInformationFile(hFile, ref iosb, ref caseSensitive, Marshal.SizeOf <FILE_CASE_SENSITIVE_INFORMATION>(), FILE_INFORMATION_CLASS.FileCaseSensitiveInformation); switch (result) { case NTSTATUS.SUCCESS: return((isSupported = true).Value); case NTSTATUS.NOT_IMPLEMENTED: case NTSTATUS.INVALID_INFO_CLASS: case NTSTATUS.INVALID_PARAMETER: case NTSTATUS.NOT_SUPPORTED: // Not supported, must be older version of windows. // Directory case sensitivity is impossible. return((isSupported = false).Value); default: throw new Exception($"Unknown NTSTATUS {result:X8} while checking case sensitivity support!"); } } finally { CloseHandle(hFile); try { // CHOOSE: If you delete the folder, future calls to this will not be any faster // Directory.Delete(TempDirectory); } catch { } } }
// Require's elevated priviledges public static void SetDirectoryCaseSensitive(string directory, bool enable) { // FILE_WRITE_ATTRIBUTES access is the only requirement IntPtr hFile = CreateFile(directory, FILE_WRITE_ATTRIBUTES, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero); if (hFile == INVALID_HANDLE) { throw new Win32Exception(); } try { IO_STATUS_BLOCK iosb = new IO_STATUS_BLOCK(); FILE_CASE_SENSITIVE_INFORMATION caseSensitive = new FILE_CASE_SENSITIVE_INFORMATION(); if (enable) { caseSensitive.Flags |= CASE_SENSITIVITY_FLAGS.CaseSensitiveDirectory; } NTSTATUS status = NtSetInformationFile(hFile, ref iosb, ref caseSensitive, Marshal.SizeOf <FILE_CASE_SENSITIVE_INFORMATION>(), FILE_INFORMATION_CLASS.FileCaseSensitiveInformation); switch (status) { case NTSTATUS.SUCCESS: return; case NTSTATUS.DIRECTORY_NOT_EMPTY: throw new IOException($"Directory \"{directory}\" is not empty! " + $"Cannot set case sensitivity!"); case NTSTATUS.NOT_IMPLEMENTED: case NTSTATUS.NOT_SUPPORTED: case NTSTATUS.INVALID_INFO_CLASS: case NTSTATUS.INVALID_PARAMETER: // Not supported, must be older version of windows. // Directory case sensitivity is impossible. throw new NotSupportedException("This version of Windows does not support directory case sensitivity!"); default: throw new Exception($"Unknown NTSTATUS: {(uint)status:X8}!"); } } finally { CloseHandle(hFile); } }
public static bool IsDirectoryCaseSensitive(string directory, bool throwOnError = true) { // Read access is NOT required IntPtr hFile = CreateFile(directory, 0, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero); if (hFile == INVALID_HANDLE) { throw new Win32Exception(); } try { IO_STATUS_BLOCK iosb = new IO_STATUS_BLOCK(); FILE_CASE_SENSITIVE_INFORMATION caseSensitive = new FILE_CASE_SENSITIVE_INFORMATION(); NTSTATUS status = NtQueryInformationFile(hFile, ref iosb, ref caseSensitive, Marshal.SizeOf <FILE_CASE_SENSITIVE_INFORMATION>(), FILE_INFORMATION_CLASS.FileCaseSensitiveInformation); switch (status) { case NTSTATUS.SUCCESS: return(caseSensitive.Flags.HasFlag(CASE_SENSITIVITY_FLAGS.CaseSensitiveDirectory)); case NTSTATUS.NOT_IMPLEMENTED: case NTSTATUS.NOT_SUPPORTED: case NTSTATUS.INVALID_INFO_CLASS: case NTSTATUS.INVALID_PARAMETER: // Not supported, must be older version of windows. // Directory case sensitivity is impossible. return(false); case NTSTATUS.ACCESS_DENIED: throw new UnauthorizedAccessException(); default: throw new Exception($"Unknown NTSTATUS: {status:X8}!"); } } finally { CloseHandle(hFile); } }
public static extern NTSTATUS NtSetInformationFile( IntPtr FileHandle, ref IO_STATUS_BLOCK IoStatusBlock, ref FILE_CASE_SENSITIVE_INFORMATION FileInformation, int Length, FILE_INFORMATION_CLASS FileInformationClass);