summaryrefslogtreecommitdiff
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.cpp85
1 files changed, 47 insertions, 38 deletions
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp
index 35f61c0623..1a66d19373 100644
--- a/drivers/windows/file_access_windows.cpp
+++ b/drivers/windows/file_access_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,7 +35,9 @@
#include "core/os/os.h"
#include "core/string/print_string.h"
+#include <share.h> // _SH_DENYNO
#include <shlwapi.h>
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <errno.h>
@@ -57,11 +59,10 @@ void FileAccessWindows::check_errors() const {
}
Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
+ _close();
+
path_src = p_path;
path = fix_path(p_path);
- if (f) {
- close();
- }
const WCHAR *mode_string;
@@ -77,15 +78,15 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
return ERR_INVALID_PARAMETER;
}
- /* pretty much every implementation that uses fopen as primary
- backend supports utf8 encoding */
+ /* Pretty much every implementation that uses fopen as primary
+ backend supports utf8 encoding. */
struct _stat st;
if (_wstat((LPCWSTR)(path.utf16().get_data()), &st) == 0) {
if (!S_ISREG(st.st_mode)) {
return ERR_FILE_CANT_OPEN;
}
- };
+ }
#ifdef TOOLS_ENABLED
// Windows is case insensitive, but all other platforms are sensitive to it
@@ -97,7 +98,7 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
HANDLE f = FindFirstFileW((LPCWSTR)(path.utf16().get_data()), &d);
if (f != INVALID_HANDLE_VALUE) {
String fname = String::utf16((const char16_t *)(d.cFileName));
- if (fname != String()) {
+ 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.");
@@ -108,15 +109,15 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
}
#endif
- if (is_backup_save_enabled() && p_mode_flags & WRITE && !(p_mode_flags & READ)) {
+ if (is_backup_save_enabled() && p_mode_flags == WRITE) {
save_path = path;
path = path + ".tmp";
}
- errno_t errcode = _wfopen_s(&f, (LPCWSTR)(path.utf16().get_data()), mode_string);
+ f = _wfsopen((LPCWSTR)(path.utf16().get_data()), mode_string, _SH_DENYNO);
if (f == nullptr) {
- switch (errcode) {
+ switch (errno) {
case ENOENT: {
last_error = ERR_FILE_NOT_FOUND;
} break;
@@ -132,7 +133,7 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
}
}
-void FileAccessWindows::close() {
+void FileAccessWindows::_close() {
if (!f) {
return;
}
@@ -140,7 +141,7 @@ void FileAccessWindows::close() {
fclose(f);
f = nullptr;
- if (save_path != "") {
+ if (!save_path.is_empty()) {
bool rename_error = true;
int attempts = 4;
while (rename_error && attempts) {
@@ -157,10 +158,10 @@ void FileAccessWindows::close() {
#else
if (!PathFileExistsW((LPCWSTR)(save_path.utf16().get_data()))) {
#endif
- //creating new file
+ // Creating new file
rename_error = _wrename((LPCWSTR)((save_path + ".tmp").utf16().get_data()), (LPCWSTR)(save_path.utf16().get_data())) != 0;
} else {
- //atomic replace for existing file
+ // Atomic replace for existing file
rename_error = !ReplaceFileW((LPCWSTR)(save_path.utf16().get_data()), (LPCWSTR)((save_path + ".tmp").utf16().get_data()), nullptr, 2 | 4, nullptr, nullptr);
}
if (rename_error) {
@@ -193,10 +194,11 @@ bool FileAccessWindows::is_open() const {
return (f != nullptr);
}
-void FileAccessWindows::seek(size_t p_position) {
+void FileAccessWindows::seek(uint64_t p_position) {
ERR_FAIL_COND(!f);
+
last_error = OK;
- if (fseek(f, p_position, SEEK_SET)) {
+ if (_fseeki64(f, p_position, SEEK_SET)) {
check_errors();
}
prev_op = 0;
@@ -204,28 +206,28 @@ void FileAccessWindows::seek(size_t p_position) {
void FileAccessWindows::seek_end(int64_t p_position) {
ERR_FAIL_COND(!f);
- if (fseek(f, p_position, SEEK_END)) {
+
+ if (_fseeki64(f, p_position, SEEK_END)) {
check_errors();
}
prev_op = 0;
}
-size_t FileAccessWindows::get_position() const {
- size_t aux_position = 0;
- aux_position = ftell(f);
- if (!aux_position) {
+uint64_t FileAccessWindows::get_position() const {
+ int64_t aux_position = _ftelli64(f);
+ if (aux_position < 0) {
check_errors();
}
return aux_position;
}
-size_t FileAccessWindows::get_len() const {
+uint64_t FileAccessWindows::get_length() const {
ERR_FAIL_COND_V(!f, 0);
- size_t pos = get_position();
- fseek(f, 0, SEEK_END);
- int size = get_position();
- fseek(f, pos, SEEK_SET);
+ uint64_t pos = get_position();
+ _fseeki64(f, 0, SEEK_END);
+ uint64_t size = get_position();
+ _fseeki64(f, pos, SEEK_SET);
return size;
}
@@ -237,6 +239,7 @@ bool FileAccessWindows::eof_reached() const {
uint8_t FileAccessWindows::get_8() const {
ERR_FAIL_COND_V(!f, 0);
+
if (flags == READ_WRITE || flags == WRITE_READ) {
if (prev_op == WRITE) {
fflush(f);
@@ -252,18 +255,20 @@ uint8_t FileAccessWindows::get_8() const {
return b;
}
-int FileAccessWindows::get_buffer(uint8_t *p_dst, int p_length) const {
+uint64_t FileAccessWindows::get_buffer(uint8_t *p_dst, uint64_t p_length) const {
+ ERR_FAIL_COND_V(!p_dst && p_length > 0, -1);
ERR_FAIL_COND_V(!f, -1);
+
if (flags == READ_WRITE || flags == WRITE_READ) {
if (prev_op == WRITE) {
fflush(f);
}
prev_op = READ;
}
- int read = fread(p_dst, 1, p_length, f);
+ uint64_t read = fread(p_dst, 1, p_length, f);
check_errors();
return read;
-};
+}
Error FileAccessWindows::get_error() const {
return last_error;
@@ -271,6 +276,7 @@ Error FileAccessWindows::get_error() const {
void FileAccessWindows::flush() {
ERR_FAIL_COND(!f);
+
fflush(f);
if (prev_op == WRITE) {
prev_op = 0;
@@ -279,6 +285,7 @@ void FileAccessWindows::flush() {
void FileAccessWindows::store_8(uint8_t p_dest) {
ERR_FAIL_COND(!f);
+
if (flags == READ_WRITE || flags == WRITE_READ) {
if (prev_op == READ) {
if (last_error != ERR_FILE_EOF) {
@@ -290,8 +297,10 @@ void FileAccessWindows::store_8(uint8_t p_dest) {
fwrite(&p_dest, 1, 1, f);
}
-void FileAccessWindows::store_buffer(const uint8_t *p_src, int p_length) {
+void FileAccessWindows::store_buffer(const uint8_t *p_src, uint64_t p_length) {
ERR_FAIL_COND(!f);
+ ERR_FAIL_COND(!p_src && p_length > 0);
+
if (flags == READ_WRITE || flags == WRITE_READ) {
if (prev_op == READ) {
if (last_error != ERR_FILE_EOF) {
@@ -304,10 +313,8 @@ void FileAccessWindows::store_buffer(const uint8_t *p_src, int p_length) {
}
bool FileAccessWindows::file_exists(const String &p_name) {
- FILE *g;
- //printf("opening file %s\n", p_fname.utf8().get_data());
String filename = fix_path(p_name);
- _wfopen_s(&g, (LPCWSTR)(filename.utf16().get_data()), L"rb");
+ FILE *g = _wfsopen((LPCWSTR)(filename.utf16().get_data()), L"rb", _SH_DENYNO);
if (g == nullptr) {
return false;
} else {
@@ -318,8 +325,9 @@ bool FileAccessWindows::file_exists(const String &p_name) {
uint64_t FileAccessWindows::_get_modified_time(const String &p_file) {
String file = fix_path(p_file);
- if (file.ends_with("/") && file != "/")
+ if (file.ends_with("/") && file != "/") {
file = file.substr(0, file.length() - 1);
+ }
struct _stat st;
int rv = _wstat((LPCWSTR)(file.utf16().get_data()), &st);
@@ -327,7 +335,8 @@ uint64_t FileAccessWindows::_get_modified_time(const String &p_file) {
if (rv == 0) {
return st.st_mtime;
} else {
- ERR_FAIL_V_MSG(0, "Failed to get modified time for: " + file + ".");
+ print_verbose("Failed to get modified time for: " + p_file + "");
+ return 0;
}
}
@@ -340,7 +349,7 @@ Error FileAccessWindows::_set_unix_permissions(const String &p_file, uint32_t p_
}
FileAccessWindows::~FileAccessWindows() {
- close();
+ _close();
}
#endif // WINDOWS_ENABLED