Fix session file saving problem if it's read-only

Refactoring and fix a typo.

Fix #14024, fix #13894, fix #13859, close #14035
pull/14039/head
Don Ho 2023-08-20 20:11:06 +02:00
parent fc736d8afb
commit 3aa9e9280f
8 changed files with 25 additions and 17 deletions

View File

@ -1517,6 +1517,16 @@ HFONT createFont(const TCHAR* fontName, int fontSize, bool isBold, HWND hDestPar
return newFont;
}
bool removeReadOnlyFlagFromFileAttributes(const wchar_t* fileFullPath)
{
if (!PathFileExists(fileFullPath))
return false;
DWORD dwFileAttribs = ::GetFileAttributes(fileFullPath);
dwFileAttribs &= ~FILE_ATTRIBUTE_READONLY;
return (::SetFileAttributes(fileFullPath, dwFileAttribs) != FALSE);
}
// "For file I/O, the "\\?\" prefix to a path string tells the Windows APIs to disable all string parsing
// and to send the string that follows it straight to the file system..."
// Ref: https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#win32-file-namespaces

View File

@ -220,6 +220,7 @@ int nbDigitsFromNbLines(size_t nbLines);
generic_string getDateTimeStrFrom(const generic_string& dateTimeFormat, const SYSTEMTIME& st);
HFONT createFont(const TCHAR* fontName, int fontSize, bool isBold, HWND hDestParent);
bool removeReadOnlyFlagFromFileAttributes(const wchar_t* fileFullPath);
bool isWin32NamespacePrefixedFileName(const generic_string& fileName);
bool isWin32NamespacePrefixedFileName(const TCHAR* szFileName);

View File

@ -1994,12 +1994,7 @@ void Notepad_plus::command(int id)
case IDM_EDIT_CLEARREADONLY:
{
Buffer * buf = _pEditView->getCurrentBuffer();
DWORD dwFileAttribs = ::GetFileAttributes(buf->getFullPathName());
dwFileAttribs &= ~FILE_ATTRIBUTE_READONLY;
::SetFileAttributes(buf->getFullPathName(), dwFileAttribs);
buf->setFileReadOnly(false);
removeReadOnlyFlagFromFileAttributes(buf->getFullPathName());
}
break;

View File

@ -3476,6 +3476,9 @@ void NppParameters::writeSession(const Session & session, const TCHAR *fileName)
{
const TCHAR *sessionPathName = fileName ? fileName : _sessionPath.c_str();
// Make sure session file is not read-only
removeReadOnlyFlagFromFileAttributes(sessionPathName);
// Backup session file before overriting it
TCHAR backupPathName[MAX_PATH]{};
BOOL doesBackupCopyExist = FALSE;
@ -3483,6 +3486,9 @@ void NppParameters::writeSession(const Session & session, const TCHAR *fileName)
{
_tcscpy(backupPathName, sessionPathName);
_tcscat(backupPathName, TEXT(".inCaseOfCorruption.bak"));
// Make sure backup file is not read-only, if it exists
removeReadOnlyFlagFromFileAttributes(backupPathName);
doesBackupCopyExist = CopyFile(sessionPathName, backupPathName, FALSE);
if (!doesBackupCopyExist)
{

View File

@ -1023,12 +1023,8 @@ bool FileManager::backupCurrentBuffer()
}
// Make sure the backup file is not read only
DWORD dwFileAttribs = ::GetFileAttributes(fullpath);
if (dwFileAttribs & FILE_ATTRIBUTE_READONLY) // if file is read only, remove read only attribute
{
dwFileAttribs ^= FILE_ATTRIBUTE_READONLY;
::SetFileAttributes(fullpath, dwFileAttribs);
}
removeReadOnlyFlagFromFileAttributes(fullpath);
if (UnicodeConvertor.openFile(fullpath))
{

View File

@ -223,7 +223,7 @@ BEGIN
CONTROL "",IDC_OPENSAVEDIR_ALWAYSON_RADIO,"Button",BS_AUTORADIOBUTTON,118,89,11,10
EDITTEXT IDC_OPENSAVEDIR_ALWAYSON_EDIT,134,88,179,14,ES_AUTOHSCROLL
PUSHBUTTON "...",IDD_OPENSAVEDIR_ALWAYSON_BROWSE_BUTTON,320,87,16,14
CONTROL "Open all files of folder instead of launching Folder as Workspace on folder dropping",IDC_OPENSAVEDIR_CHECK_DRROPFOLDEROPENFILES, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,110, 145,342,10
CONTROL "Open all files of folder instead of launching Folder as Workspace on folder dropping",IDC_OPENSAVEDIR_CHECK_DROPFOLDEROPENFILES, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,110, 145,342,10
END

View File

@ -2501,7 +2501,7 @@ intptr_t CALLBACK DefaultDirectorySubDlg::run_dlgProc(UINT message, WPARAM wPara
::EnableWindow(::GetDlgItem(_hSelf, IDC_OPENSAVEDIR_ALWAYSON_EDIT), shouldActivated);
::EnableWindow(::GetDlgItem(_hSelf, IDD_OPENSAVEDIR_ALWAYSON_BROWSE_BUTTON), shouldActivated);
::SendDlgItemMessage(_hSelf, IDC_OPENSAVEDIR_CHECK_DRROPFOLDEROPENFILES, BM_SETCHECK, nppGUI._isFolderDroppedOpenFiles ? BST_CHECKED : BST_UNCHECKED, 0);
::SendDlgItemMessage(_hSelf, IDC_OPENSAVEDIR_CHECK_DROPFOLDEROPENFILES, BM_SETCHECK, nppGUI._isFolderDroppedOpenFiles ? BST_CHECKED : BST_UNCHECKED, 0);
return TRUE;
}
@ -2572,8 +2572,8 @@ intptr_t CALLBACK DefaultDirectorySubDlg::run_dlgProc(UINT message, WPARAM wPara
}
return TRUE;
case IDC_OPENSAVEDIR_CHECK_DRROPFOLDEROPENFILES:
nppGUI._isFolderDroppedOpenFiles = isCheckedOrNot(IDC_OPENSAVEDIR_CHECK_DRROPFOLDEROPENFILES);
case IDC_OPENSAVEDIR_CHECK_DROPFOLDEROPENFILES:
nppGUI._isFolderDroppedOpenFiles = isCheckedOrNot(IDC_OPENSAVEDIR_CHECK_DROPFOLDEROPENFILES);
return TRUE;
default:

View File

@ -292,7 +292,7 @@
#define IDC_RADIO_CUSTOMIZELENTH (IDD_PREFERENCE_SUB_NEWDOCUMENT + 27)
//#define IDC_CUSTOMIZELENGTHVAL_STATIC (IDD_PREFERENCE_SUB_NEWDOCUMENT + 28)
#define IDC_DISPLAY_STATIC (IDD_PREFERENCE_SUB_NEWDOCUMENT + 29)
#define IDC_OPENSAVEDIR_CHECK_DRROPFOLDEROPENFILES (IDD_PREFERENCE_SUB_NEWDOCUMENT + 31)
#define IDC_OPENSAVEDIR_CHECK_DROPFOLDEROPENFILES (IDD_PREFERENCE_SUB_NEWDOCUMENT + 31)
#define IDC_CHECK_ADDNEWDOCONSTARTUP (IDD_PREFERENCE_SUB_NEWDOCUMENT + 32)
#define IDD_PREFERENCE_SUB_DEFAULTDIRECTORY 6450 //(IDD_PREFERENCE_BOX + 400)