Fix detection of backup file restored back problem
Fix #10839, close #10843
This commit is contained in:
parent
e7bf582ffd
commit
bab3573be7
|
@ -22,10 +22,7 @@ Win32_IO_File::Win32_IO_File(const char *fname, Mode fmode) : _hMode(fmode)
|
|||
{
|
||||
if (fname)
|
||||
{
|
||||
DWORD access, share, disp, attrib;
|
||||
fillCreateParams(access, share, disp, attrib);
|
||||
|
||||
_hFile = ::CreateFileA(fname, access, share, NULL, disp, attrib, NULL);
|
||||
_hFile = ::CreateFileA(fname, _accessParam, _shareParam, NULL, _dispParam, _attribParam, NULL);
|
||||
}
|
||||
|
||||
if ((_hFile != INVALID_HANDLE_VALUE) && (_hMode == Mode::APPEND))
|
||||
|
@ -42,10 +39,7 @@ Win32_IO_File::Win32_IO_File(const wchar_t *fname, Mode fmode) : _hMode(fmode)
|
|||
{
|
||||
if (fname)
|
||||
{
|
||||
DWORD access, share, disp, attrib;
|
||||
fillCreateParams(access, share, disp, attrib);
|
||||
|
||||
_hFile = ::CreateFileW(fname, access, share, NULL, disp, attrib, NULL);
|
||||
_hFile = ::CreateFileW(fname, _accessParam, _shareParam, NULL, _dispParam, _attribParam, NULL);
|
||||
}
|
||||
|
||||
if ((_hFile != INVALID_HANDLE_VALUE) && (_hMode == Mode::APPEND))
|
||||
|
@ -74,7 +68,7 @@ void Win32_IO_File::close()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
int_fast64_t Win32_IO_File::getSize()
|
||||
{
|
||||
LARGE_INTEGER r;
|
||||
|
@ -85,7 +79,7 @@ int_fast64_t Win32_IO_File::getSize()
|
|||
|
||||
return static_cast<int_fast64_t>(r.QuadPart);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
unsigned long Win32_IO_File::read(void *rbuf, unsigned long buf_size)
|
||||
{
|
||||
|
@ -102,7 +96,7 @@ unsigned long Win32_IO_File::read(void *rbuf, unsigned long buf_size)
|
|||
|
||||
bool Win32_IO_File::write(const void *wbuf, unsigned long buf_size)
|
||||
{
|
||||
if (!isOpened() || (wbuf == nullptr) || ((_hMode != Mode::WRITE) && (_hMode != Mode::APPEND)))
|
||||
if (!isOpened() || (wbuf == nullptr))
|
||||
return false;
|
||||
|
||||
DWORD bytes_written = 0;
|
||||
|
@ -116,25 +110,3 @@ bool Win32_IO_File::write(const void *wbuf, unsigned long buf_size)
|
|||
return (bytes_written == buf_size);
|
||||
}
|
||||
|
||||
|
||||
// Helper function to auto-fill CreateFile params optimized for Notepad++ usage.
|
||||
void Win32_IO_File::fillCreateParams(DWORD &access, DWORD &share, DWORD &disp, DWORD &attrib)
|
||||
{
|
||||
access = GENERIC_READ;
|
||||
share = FILE_SHARE_READ;
|
||||
attrib = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_POSIX_SEMANTICS; // Distinguish between upper/lower case in name
|
||||
|
||||
if (_hMode == Mode::READ)
|
||||
{
|
||||
disp = OPEN_EXISTING; // Open only if file exists and is not locked by other process
|
||||
|
||||
attrib |= FILE_FLAG_SEQUENTIAL_SCAN; // Optimize caching for sequential read
|
||||
}
|
||||
else
|
||||
{
|
||||
disp = OPEN_ALWAYS; // Open existing file for writing without destroying it or create new
|
||||
share |= FILE_SHARE_WRITE;
|
||||
access |= GENERIC_WRITE;
|
||||
attrib |= FILE_FLAG_WRITE_THROUGH; // Write cached data directly to disk (no lazy writer)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,13 +27,12 @@ class Win32_IO_File final
|
|||
{
|
||||
public:
|
||||
enum class Mode {
|
||||
READ,
|
||||
WRITE,
|
||||
APPEND
|
||||
};
|
||||
|
||||
Win32_IO_File(const char *fname, Mode fmode = Mode::READ);
|
||||
Win32_IO_File(const wchar_t *fname, Mode fmode = Mode::READ);
|
||||
Win32_IO_File(const char *fname, Mode fmode);
|
||||
Win32_IO_File(const wchar_t *fname, Mode fmode);
|
||||
|
||||
Win32_IO_File() = delete;
|
||||
Win32_IO_File(const Win32_IO_File&) = delete;
|
||||
|
@ -48,7 +47,7 @@ public:
|
|||
};
|
||||
|
||||
void close();
|
||||
int_fast64_t getSize();
|
||||
//int_fast64_t getSize();
|
||||
unsigned long read(void *rbuf, unsigned long buf_size);
|
||||
bool write(const void *wbuf, unsigned long buf_size);
|
||||
|
||||
|
@ -58,8 +57,11 @@ public:
|
|||
|
||||
private:
|
||||
HANDLE _hFile {INVALID_HANDLE_VALUE};
|
||||
Mode _hMode {Mode::READ};
|
||||
Mode _hMode {Mode::WRITE};
|
||||
bool _written {false};
|
||||
|
||||
void fillCreateParams(DWORD& access, DWORD& share, DWORD& disp, DWORD& attrib);
|
||||
const DWORD _accessParam { GENERIC_READ | GENERIC_WRITE };
|
||||
const DWORD _shareParam { FILE_SHARE_READ | FILE_SHARE_WRITE };
|
||||
const DWORD _dispParam { OPEN_ALWAYS }; // Open existing file for writing without destroying it or create new
|
||||
const DWORD _attribParam { FILE_ATTRIBUTE_NORMAL | FILE_FLAG_POSIX_SEMANTICS | FILE_FLAG_WRITE_THROUGH }; // FILE_FLAG_POSIX_SEMANTICS: distinguish between upper/lower case in name
|
||||
};
|
||||
|
|
|
@ -140,16 +140,17 @@ void Buffer::updateTimeStamp()
|
|||
}
|
||||
|
||||
LONG res = CompareFileTime(&_timeStamp, &timeStampLive);
|
||||
if (res == -1) // timeStampLive is later, it means the file has been modified outside of Notepad++
|
||||
if (res == -1 || res == 1)
|
||||
// (res == -1) => timeStampLive is later, it means the file has been modified outside of Notepad++ - usual case
|
||||
//
|
||||
// (res == 1) => timeStampLive (get directly from the file on disk) is earlier than buffer's timestamp - unusual case
|
||||
// It can happen when user copies a backup of editing file somewhere-else firstly, then modifies the editing file in Notepad++ and saves it.
|
||||
// Now user copies the backup back to erase the modified editing file outside Notepad++ (via Explorer).
|
||||
{
|
||||
_timeStamp = timeStampLive;
|
||||
doNotify(BufferChangeTimestamp);
|
||||
}
|
||||
else if (res == 1) // timeStampLive (get directly from the file on disk) is earlier than buffer's timestamp - abnormal case
|
||||
{
|
||||
// This absurd case can be ignored
|
||||
}
|
||||
// else res == 0 => nothing to change
|
||||
// else (res == 0) => nothing to change
|
||||
}
|
||||
|
||||
|
||||
|
@ -271,17 +272,19 @@ bool Buffer::checkFileState() // returns true if the status has been changed (it
|
|||
}
|
||||
|
||||
LONG res = CompareFileTime(&_timeStamp, &attributes.ftLastWriteTime);
|
||||
if (res == -1) // // attributes.ftLastWriteTime is later, it means the file has been modified outside of Notepad++
|
||||
|
||||
if (res == -1 || res == 1)
|
||||
// (res == -1) => attributes.ftLastWriteTime is later, it means the file has been modified outside of Notepad++ - usual case
|
||||
//
|
||||
// (res == 1) => The timestamp get directly from the file on disk is earlier than buffer's timestamp - unusual case
|
||||
// It can happen when user copies a backup of editing file somewhere-else firstly, then modifies the editing file in Notepad++ and saves it.
|
||||
// Now user copies the backup back to erase the modified editing file outside Notepad++ (via Explorer).
|
||||
{
|
||||
_timeStamp = attributes.ftLastWriteTime;
|
||||
mask |= BufferChangeTimestamp;
|
||||
_currentStatus = DOC_MODIFIED;
|
||||
mask |= BufferChangeStatus; //status always 'changes', even if from modified to modified
|
||||
}
|
||||
else if (res == 1) // The timestamp get directly from the file on disk is earlier than buffer's timestamp - abnormal case
|
||||
{
|
||||
// This absurd case can be ignored
|
||||
}
|
||||
// else res == 0 => nothing to change
|
||||
|
||||
if (mask != 0)
|
||||
|
|
Loading…
Reference in New Issue