Backup session file in case of its corruption
It could be, in certain unknown circumstances, the session file (session.xml) is saved with the incorrect characters (for example NUL characters) which leads session file corrupted and empty session loaded on the next launch. This commit makes a backup of session file before rewritting it, then check the session file after it having been writting - if written session file is corrupted, the backup session file will be restored, otherwise the backup file will be removed. Ref: 1. https://github.com/notepad-plus-plus/notepad-plus-plus/issues/6133#issuecomment-1121781830 2. https://github.com/notepad-plus-plus/notepad-plus-plus/issues/6133#issuecomment-1544703701 Fix #13514, close #13648
This commit is contained in:
parent
34186d2e85
commit
50b81eadef
|
@ -47,7 +47,15 @@ Win32_IO_File::Win32_IO_File(const wchar_t *fname)
|
|||
pathAppend(nppIssueLog, issueFn);
|
||||
|
||||
std::string msg = _path;
|
||||
msg += " is opened.";
|
||||
if (_hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
msg += " is opened.";
|
||||
}
|
||||
else
|
||||
{
|
||||
msg += " failed to open, CreateFileW ErrorCode: ";
|
||||
msg += std::to_string(::GetLastError());
|
||||
}
|
||||
writeLog(nppIssueLog.c_str(), msg.c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3434,9 +3434,18 @@ void NppParameters::insertScintKey(TiXmlNodeA *scintKeyRoot, const ScintillaKeyM
|
|||
|
||||
void NppParameters::writeSession(const Session & session, const TCHAR *fileName)
|
||||
{
|
||||
const TCHAR *pathName = fileName?fileName:_sessionPath.c_str();
|
||||
const TCHAR *sessionPathName = fileName ? fileName : _sessionPath.c_str();
|
||||
|
||||
TiXmlDocument* pXmlSessionDoc = new TiXmlDocument(pathName);
|
||||
// Backup session file before overriting it
|
||||
TCHAR backupPathName[MAX_PATH]{};
|
||||
if (PathFileExists(sessionPathName))
|
||||
{
|
||||
_tcscpy(backupPathName, sessionPathName);
|
||||
_tcscat(backupPathName, TEXT(".inCaseOfCorruption.bak"));
|
||||
CopyFile(sessionPathName, backupPathName, FALSE);
|
||||
}
|
||||
|
||||
TiXmlDocument* pXmlSessionDoc = new TiXmlDocument(sessionPathName);
|
||||
|
||||
TiXmlDeclaration* decl = new TiXmlDeclaration(TEXT("1.0"), TEXT("UTF-8"), TEXT(""));
|
||||
pXmlSessionDoc->LinkEndChild(decl);
|
||||
|
@ -3530,7 +3539,36 @@ void NppParameters::writeSession(const Session & session, const TCHAR *fileName)
|
|||
}
|
||||
}
|
||||
}
|
||||
pXmlSessionDoc->SaveFile();
|
||||
|
||||
bool sessionSaveOK = pXmlSessionDoc->SaveFile();
|
||||
|
||||
if (sessionSaveOK)
|
||||
{
|
||||
// Double checking: prevent written session file corrupted while writting
|
||||
TiXmlDocument* pXmlSessionCheck = new TiXmlDocument(sessionPathName);
|
||||
sessionSaveOK = pXmlSessionCheck->LoadFile();
|
||||
delete pXmlSessionCheck;
|
||||
}
|
||||
|
||||
if (!sessionSaveOK)
|
||||
{
|
||||
if (backupPathName[0]) // session backup file exists, restore it
|
||||
{
|
||||
_pNativeLangSpeaker->messageBox("ErrorOfSavingSessionFile",
|
||||
nullptr,
|
||||
TEXT("The old session file will be restored."),
|
||||
TEXT("Error of saving session file"),
|
||||
MB_OK | MB_APPLMODAL | MB_ICONWARNING);
|
||||
CopyFile(backupPathName, sessionPathName, FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (backupPathName[0]) // session backup file not useful, delete it
|
||||
{
|
||||
::DeleteFile(backupPathName);
|
||||
}
|
||||
}
|
||||
|
||||
delete pXmlSessionDoc;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue