From a1031517742c7ef600b825bf9f193b3f2740dff6 Mon Sep 17 00:00:00 2001 From: Pavel Nedev Date: Mon, 5 Oct 2020 14:40:13 +0300 Subject: [PATCH] Fix NUL file-corruption bug after Windows shutdown brutally Bypass Windows caching when flushing files after write. According Microsoft documentation this fixes the issues with saved file corruption (all NULs) on sudden power loss or restart. Microsoft documentation for reference: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-wfopen?view=vs-2019 https://docs.microsoft.com/en-us/cpp/c-runtime-library/stream-i-o?view=vs-2019 Fix #6133, close #8952 --- PowerEditor/src/MISC/Common/Common.cpp | 4 ++-- PowerEditor/src/ScitillaComponent/Buffer.cpp | 7 ++++--- PowerEditor/src/TinyXml/tinyXmlA/tinyxmlA.cpp | 6 ++++-- PowerEditor/src/TinyXml/tinyxml.cpp | 3 ++- PowerEditor/src/Utf8_16.cpp | 9 ++++++++- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/PowerEditor/src/MISC/Common/Common.cpp b/PowerEditor/src/MISC/Common/Common.cpp index 6c682fe40..5e72ad040 100644 --- a/PowerEditor/src/MISC/Common/Common.cpp +++ b/PowerEditor/src/MISC/Common/Common.cpp @@ -125,7 +125,7 @@ generic_string relativeFilePathToFullFilePath(const TCHAR *relativeFilePath) void writeFileContent(const TCHAR *file2write, const char *content2write) { - FILE *f = generic_fopen(file2write, TEXT("w+")); + FILE *f = generic_fopen(file2write, TEXT("w+c")); fwrite(content2write, sizeof(content2write[0]), strlen(content2write), f); fflush(f); fclose(f); @@ -134,7 +134,7 @@ void writeFileContent(const TCHAR *file2write, const char *content2write) void writeLog(const TCHAR *logFileName, const char *log2write) { - FILE *f = generic_fopen(logFileName, TEXT("a+")); + FILE *f = generic_fopen(logFileName, TEXT("a+c")); fwrite(log2write, sizeof(log2write[0]), strlen(log2write), f); fputc('\n', f); fflush(f); diff --git a/PowerEditor/src/ScitillaComponent/Buffer.cpp b/PowerEditor/src/ScitillaComponent/Buffer.cpp index f257a7008..daf2c9f53 100644 --- a/PowerEditor/src/ScitillaComponent/Buffer.cpp +++ b/PowerEditor/src/ScitillaComponent/Buffer.cpp @@ -879,7 +879,7 @@ bool FileManager::backupCurrentBuffer() ::SetFileAttributes(fullpath, dwFileAttribs); } - FILE *fp = UnicodeConvertor.fopen(fullpath, TEXT("wb")); + FILE *fp = UnicodeConvertor.fopen(fullpath, TEXT("wbc")); if (fp) { int lengthDoc = _pNotepadPlus->_pEditView->getCurrentDocLen(); @@ -1004,7 +1004,7 @@ bool FileManager::saveBuffer(BufferID id, const TCHAR * filename, bool isCopy, g int encoding = buffer->getEncoding(); - FILE *fp = UnicodeConvertor.fopen(fullpath, TEXT("wb")); + FILE *fp = UnicodeConvertor.fopen(fullpath, TEXT("wbc")); if (fp) { _pscratchTilla->execute(SCI_SETDOCPOINTER, 0, buffer->_doc); //generate new document @@ -1495,9 +1495,10 @@ BufferID FileManager::getBufferFromDocument(Document doc) bool FileManager::createEmptyFile(const TCHAR * path) { - FILE * file = generic_fopen(path, TEXT("wb")); + FILE * file = generic_fopen(path, TEXT("wbc")); if (!file) return false; + fflush(file); fclose(file); return true; } diff --git a/PowerEditor/src/TinyXml/tinyXmlA/tinyxmlA.cpp b/PowerEditor/src/TinyXml/tinyXmlA/tinyxmlA.cpp index ce5e72a4d..a5637dd4e 100644 --- a/PowerEditor/src/TinyXml/tinyXmlA/tinyxmlA.cpp +++ b/PowerEditor/src/TinyXml/tinyXmlA/tinyxmlA.cpp @@ -816,10 +816,11 @@ bool TiXmlDocumentA::LoadUnicodeFilePath( const TCHAR* filename ) bool TiXmlDocumentA::SaveFile( const char * filename ) const { // The old c stuff lives on... - FILE* fp = fopen( filename, "w" ); + FILE* fp = fopen( filename, "wc" ); if ( fp ) { Print( fp, 0 ); + fflush( fp ); fclose( fp ); return true; } @@ -828,10 +829,11 @@ bool TiXmlDocumentA::SaveFile( const char * filename ) const bool TiXmlDocumentA::SaveUnicodeFilePath( const TCHAR* filename ) const { // The old c stuff lives on... - FILE* fp = generic_fopen( filename, TEXT("w") ); + FILE* fp = generic_fopen( filename, TEXT("wc") ); if ( fp ) { Print( fp, 0 ); + fflush( fp ); fclose( fp ); return true; } diff --git a/PowerEditor/src/TinyXml/tinyxml.cpp b/PowerEditor/src/TinyXml/tinyxml.cpp index d3582c255..83286fcca 100644 --- a/PowerEditor/src/TinyXml/tinyxml.cpp +++ b/PowerEditor/src/TinyXml/tinyxml.cpp @@ -755,10 +755,11 @@ bool TiXmlDocument::LoadFile( const TCHAR* filename ) bool TiXmlDocument::SaveFile( const TCHAR * filename ) const { // The old c stuff lives on... - FILE* fp = generic_fopen( filename, TEXT("w") ); + FILE* fp = generic_fopen( filename, TEXT("wc") ); if ( fp ) { Print( fp, 0 ); + fflush( fp ); fclose( fp ); return true; } diff --git a/PowerEditor/src/Utf8_16.cpp b/PowerEditor/src/Utf8_16.cpp index fcc61ddc9..bf952fb43 100644 --- a/PowerEditor/src/Utf8_16.cpp +++ b/PowerEditor/src/Utf8_16.cpp @@ -360,7 +360,7 @@ size_t Utf8_16_Write::fwrite(const void* p, size_t _size) default: break; } - + return ret; } @@ -435,10 +435,17 @@ void Utf8_16_Write::setEncoding(UniMode eType) void Utf8_16_Write::fclose() { if (m_pNewBuf) + { delete [] m_pNewBuf; + m_pNewBuf = NULL; + } if (m_pFile) + { + ::fflush(m_pFile); ::fclose(m_pFile); + m_pFile = NULL; + } }