summaryrefslogtreecommitdiffstats
path: root/drivers/windows/file_access_windows.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/windows/file_access_windows.cpp')
-rw-r--r--drivers/windows/file_access_windows.cpp84
1 files changed, 74 insertions, 10 deletions
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp
index dd8bceb573..9885d9d7ee 100644
--- a/drivers/windows/file_access_windows.cpp
+++ b/drivers/windows/file_access_windows.cpp
@@ -32,6 +32,7 @@
#include "file_access_windows.h"
+#include "core/config/project_settings.h"
#include "core/os/os.h"
#include "core/string/print_string.h"
@@ -41,6 +42,7 @@
#include <windows.h>
#include <errno.h>
+#include <io.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <tchar.h>
@@ -120,19 +122,63 @@ Error FileAccessWindows::open_internal(const String &p_path, int p_mode_flags) {
// Windows is case insensitive, but all other platforms are sensitive to it
// To ease cross-platform development, we issue a warning if users try to access
// a file using the wrong case (which *works* on Windows, but won't on other
- // platforms).
- if (p_mode_flags == READ) {
- WIN32_FIND_DATAW d;
- HANDLE fnd = FindFirstFileW((LPCWSTR)(path.utf16().get_data()), &d);
- if (fnd != INVALID_HANDLE_VALUE) {
- String fname = String::utf16((const char16_t *)(d.cFileName));
- if (!fname.is_empty()) {
- String base_file = path.get_file();
- if (base_file != fname && base_file.findn(fname) == 0) {
- WARN_PRINT("Case mismatch opening requested file '" + base_file + "', stored as '" + fname + "' in the filesystem. This file will not open when exported to other case-sensitive platforms.");
+ // platforms), we only check for relative paths, or paths in res:// or user://,
+ // other paths aren't likely to be portable anyway.
+ if (p_mode_flags == READ && (p_path.is_relative_path() || get_access_type() != ACCESS_FILESYSTEM)) {
+ String base_path = path;
+ String working_path;
+ String proper_path;
+
+ if (get_access_type() == ACCESS_RESOURCES) {
+ if (ProjectSettings::get_singleton()) {
+ working_path = ProjectSettings::get_singleton()->get_resource_path();
+ if (!working_path.is_empty()) {
+ base_path = working_path.path_to_file(base_path);
}
}
+ proper_path = "res://";
+ } else if (get_access_type() == ACCESS_USERDATA) {
+ working_path = OS::get_singleton()->get_user_data_dir();
+ if (!working_path.is_empty()) {
+ base_path = working_path.path_to_file(base_path);
+ }
+ proper_path = "user://";
+ }
+
+ WIN32_FIND_DATAW d;
+ Vector<String> parts = base_path.split("/");
+
+ bool mismatch = false;
+
+ for (const String &part : parts) {
+ working_path = working_path.path_join(part);
+
+ // Skip if relative.
+ if (part == "." || part == "..") {
+ proper_path = proper_path.path_join(part);
+ continue;
+ }
+
+ HANDLE fnd = FindFirstFileW((LPCWSTR)(working_path.utf16().get_data()), &d);
+
+ if (fnd == INVALID_HANDLE_VALUE) {
+ mismatch = false;
+ break;
+ }
+
+ const String fname = String::utf16((const char16_t *)(d.cFileName));
+
FindClose(fnd);
+
+ if (!mismatch) {
+ mismatch = (part != fname && part.findn(fname) == 0);
+ }
+
+ proper_path = proper_path.path_join(fname);
+ }
+
+ if (mismatch) {
+ WARN_PRINT("Case mismatch opening requested file '" + p_path + "', stored as '" + proper_path + "' in the filesystem. This file will not open when exported to other case-sensitive platforms.");
}
}
#endif
@@ -369,6 +415,24 @@ Error FileAccessWindows::get_error() const {
return last_error;
}
+Error FileAccessWindows::resize(int64_t p_length) {
+ ERR_FAIL_NULL_V_MSG(f, FAILED, "File must be opened before use.");
+ errno_t res = _chsize_s(_fileno(f), p_length);
+ switch (res) {
+ case 0:
+ return OK;
+ case EACCES:
+ case EBADF:
+ return ERR_FILE_CANT_OPEN;
+ case ENOSPC:
+ return ERR_OUT_OF_MEMORY;
+ case EINVAL:
+ return ERR_INVALID_PARAMETER;
+ default:
+ return FAILED;
+ }
+}
+
void FileAccessWindows::flush() {
ERR_FAIL_NULL(f);