Skip to content

Commit

Permalink
Fix network shared files saving regression
Browse files Browse the repository at this point in the history
  • Loading branch information
donho committed Nov 11, 2023
1 parent 4ff9d77 commit 2337a7b
Showing 1 changed file with 28 additions and 3 deletions.
31 changes: 28 additions & 3 deletions PowerEditor/src/MISC/Common/FileInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,40 @@ Win32_IO_File::Win32_IO_File(const wchar_t *fname)
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
_path = converter.to_bytes(fn);

DWORD dispParam = ::PathFileExistsW(fname) ? TRUNCATE_EXISTING : CREATE_ALWAYS;
WIN32_FILE_ATTRIBUTE_DATA attributes_original{};
DWORD dispParam = CREATE_ALWAYS;
BOOL doesFileExist = ::PathFileExistsW(fname);
if (doesFileExist)
{
// Store the file creation date & attributes for a possible use later...
::GetFileAttributesExW(fname, GetFileExInfoStandard, &attributes_original);

// Check the existence of Alternate Data Streams
WIN32_FIND_STREAM_DATA findData;
HANDLE hFind = FindFirstStreamW(fname, FindStreamInfoStandard, &findData, 0);
if (hFind != INVALID_HANDLE_VALUE) // Alternate Data Streams found
{
dispParam = TRUNCATE_EXISTING;
FindClose(hFind);
}
}

_hFile = ::CreateFileW(fname, _accessParam, _shareParam, NULL, dispParam, _attribParam, NULL);

// Race condition management:
// If file didn't exist while calling PathFileExistsW, but before calling CreateFileW, file is created: use CREATE_ALWAYS is OK
// If file did exist while calling PathFileExistsW, but before calling CreateFileW, file is deleted: use TRUNCATE_EXISTING will cause the error
if (_hFile == INVALID_HANDLE_VALUE && ::GetLastError() == ERROR_FILE_NOT_FOUND)
if (dispParam == TRUNCATE_EXISTING && _hFile == INVALID_HANDLE_VALUE && ::GetLastError() == ERROR_FILE_NOT_FOUND)
{
dispParam = CREATE_ALWAYS;
_hFile = ::CreateFileW(fname, _accessParam, _shareParam, NULL, dispParam, _attribParam, NULL);
}

if (doesFileExist && (dispParam == CREATE_ALWAYS) && (_hFile != INVALID_HANDLE_VALUE))
{
_hFile = ::CreateFileW(fname, _accessParam, _shareParam, NULL, CREATE_ALWAYS, _attribParam, NULL);
// restore back the original creation date & attributes
::SetFileTime(_hFile, &(attributes_original.ftCreationTime), NULL, NULL);
::SetFileAttributesW(fname, (_attribParam | attributes_original.dwFileAttributes));
}

NppParameters& nppParam = NppParameters::getInstance();
Expand Down

0 comments on commit 2337a7b

Please sign in to comment.