diff options
Diffstat (limited to 'drivers/windows/dir_access_windows.cpp')
-rw-r--r-- | drivers/windows/dir_access_windows.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp index 26b8881c39..8bf83823a0 100644 --- a/drivers/windows/dir_access_windows.cpp +++ b/drivers/windows/dir_access_windows.cpp @@ -32,6 +32,7 @@ #include "dir_access_windows.h" +#include "core/config/project_settings.h" #include "core/os/memory.h" #include "core/string/print_string.h" @@ -40,6 +41,26 @@ #define WIN32_LEAN_AND_MEAN #include <windows.h> +typedef struct _NT_IO_STATUS_BLOCK { + union { + LONG Status; + PVOID Pointer; + } DUMMY; + ULONG_PTR Information; +} NT_IO_STATUS_BLOCK; + +typedef struct _NT_FILE_CASE_SENSITIVE_INFO { + ULONG Flags; +} NT_FILE_CASE_SENSITIVE_INFO; + +typedef enum _NT_FILE_INFORMATION_CLASS { + FileCaseSensitiveInformation = 71, +} NT_FILE_INFORMATION_CLASS; + +#define NT_FILE_CS_FLAG_CASE_SENSITIVE_DIR 0x00000001 + +extern "C" NTSYSAPI LONG NTAPI NtQueryInformationFile(HANDLE FileHandle, NT_IO_STATUS_BLOCK *IoStatusBlock, PVOID FileInformation, ULONG Length, NT_FILE_INFORMATION_CLASS FileInformationClass); + struct DirAccessWindowsPrivate { HANDLE h; // handle for FindFirstFile. WIN32_FIND_DATA f; @@ -340,6 +361,33 @@ String DirAccessWindows::get_filesystem_type() const { ERR_FAIL_V(""); } +bool DirAccessWindows::is_case_sensitive(const String &p_path) const { + String f = p_path; + if (!f.is_absolute_path()) { + f = get_current_dir().path_join(f); + } + f = fix_path(f); + + HANDLE h_file = ::CreateFileW((LPCWSTR)(f.utf16().get_data()), 0, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); + + if (h_file == INVALID_HANDLE_VALUE) { + return false; + } + + NT_IO_STATUS_BLOCK io_status_block; + NT_FILE_CASE_SENSITIVE_INFO file_info; + LONG out = NtQueryInformationFile(h_file, &io_status_block, &file_info, sizeof(NT_FILE_CASE_SENSITIVE_INFO), FileCaseSensitiveInformation); + ::CloseHandle(h_file); + + if (out >= 0) { + return file_info.Flags & NT_FILE_CS_FLAG_CASE_SENSITIVE_DIR; + } else { + return false; + } +} + DirAccessWindows::DirAccessWindows() { p = memnew(DirAccessWindowsPrivate); p->h = INVALID_HANDLE_VALUE; |