1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-05 12:10:55 +00:00

Add method to check if filesystem is case sensitive.

This commit is contained in:
bruvzg
2023-10-07 14:36:41 +03:00
parent 6916349697
commit 97bcd8a631
9 changed files with 91 additions and 6 deletions

View File

@@ -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;