Пример #1
0
    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);
        }
    }
Пример #2
0
    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);