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
This commit is contained in:
Pavel Nedev 2020-10-05 14:40:13 +03:00 committed by Don HO
parent 8426c9ccd9
commit a103151774
No known key found for this signature in database
GPG Key ID: 6C429F1D8D84F46E
5 changed files with 20 additions and 9 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
}