Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Windows platform file access to allow file sharing with external programs #51430

Merged
merged 2 commits into from
Aug 10, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions drivers/windows/file_access_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ 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
mhilbrunner marked this conversation as resolved.
Show resolved Hide resolved
backend supports utf8 encoding. */

struct _stat st;
if (_wstat((LPCWSTR)(path.utf16().get_data()), &st) == 0) {
Expand Down Expand Up @@ -113,10 +113,10 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
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;
Expand Down Expand Up @@ -157,10 +157,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) {
Expand Down Expand Up @@ -205,6 +205,7 @@ void FileAccessWindows::seek(uint64_t p_position) {

void FileAccessWindows::seek_end(int64_t p_position) {
ERR_FAIL_COND(!f);

if (_fseeki64(f, p_position, SEEK_END)) {
check_errors();
}
Expand Down Expand Up @@ -237,6 +238,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);
Expand Down Expand Up @@ -273,6 +275,7 @@ Error FileAccessWindows::get_error() const {

void FileAccessWindows::flush() {
ERR_FAIL_COND(!f);

fflush(f);
if (prev_op == WRITE) {
prev_op = 0;
Expand All @@ -281,6 +284,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) {
Expand All @@ -295,6 +299,7 @@ void FileAccessWindows::store_8(uint8_t p_dest) {
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) {
Expand All @@ -307,10 +312,8 @@ void FileAccessWindows::store_buffer(const uint8_t *p_src, uint64_t 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 {
Expand Down