From a5ef3bb3f3e5b8f72c51f4591ba3328375839b0f Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Sun, 28 Jun 2020 18:42:28 +0200 Subject: [PATCH] + chg: silent ignore write permissions missing on Inifile --- src/Config/Config.cpp | 66 +++++++++++++++++++++++++---- src/Config/Config.h | 1 + src/Dialogs.c | 9 ++-- src/Helpers.c | 30 ++++--------- src/MuiLanguage.c | 13 +++--- src/Notepad3.c | 98 ++++++++++++++++++++++++------------------- src/Styles.c | 16 +------ src/Styles.h | 1 - src/TypeDefs.h | 1 + 9 files changed, 137 insertions(+), 98 deletions(-) diff --git a/src/Config/Config.cpp b/src/Config/Config.cpp index 686d6633e..fcd2577e6 100644 --- a/src/Config/Config.cpp +++ b/src/Config/Config.cpp @@ -93,6 +93,49 @@ constexpr bool SI_Success(const SI_Error rc) noexcept { // ============================================================================ + +bool CanAccessPath(LPCWSTR lpIniFilePath, DWORD genericAccessRights) +{ + bool bRet = false; + if (StrIsEmpty(lpIniFilePath)) { + return bRet; + } + DWORD length = 0; + SECURITY_INFORMATION const secInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; + + if (!::GetFileSecurity(lpIniFilePath, secInfo, NULL, 0, &length) && (ERROR_INSUFFICIENT_BUFFER == GetLastError())) { + PSECURITY_DESCRIPTOR security = static_cast(AllocMem(length, HEAP_ZERO_MEMORY)); + if (security && ::GetFileSecurity(lpIniFilePath, secInfo, security, length, &length)) { + HANDLE hToken = NULL; + if (::OpenProcessToken(::GetCurrentProcess(), TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ, &hToken)) { + HANDLE hImpersonatedToken = NULL; + if (::DuplicateToken(hToken, SecurityImpersonation, &hImpersonatedToken)) { + GENERIC_MAPPING mapping = {0xFFFFFFFF}; + PRIVILEGE_SET privileges = {0}; + DWORD grantedAccess = 0, privilegesLength = sizeof(privileges); + BOOL result = FALSE; + + mapping.GenericRead = FILE_GENERIC_READ; + mapping.GenericWrite = FILE_GENERIC_WRITE; + mapping.GenericExecute = FILE_GENERIC_EXECUTE; + mapping.GenericAll = FILE_ALL_ACCESS; + + ::MapGenericMask(&genericAccessRights, &mapping); + if (::AccessCheck(security, hImpersonatedToken, genericAccessRights, + &mapping, &privileges, &privilegesLength, &grantedAccess, &result)) { + bRet = (result == TRUE); + } + ::CloseHandle(hImpersonatedToken); + } + ::CloseHandle(hToken); + } + FreeMem(security); + } + } + return bRet; +} + + // ---------------------------------------------------------------------------- // No mechanism for EXCLUSIVE WRITE / SHARD READ: // cause we need completely synchronized exclusive access for READ _and_ WRITE @@ -119,12 +162,14 @@ HANDLE AcquireWriteFileLock(LPCWSTR lpIniFilePath, OVERLAPPED& rOvrLpd) MsgBoxLastError(msg, 0); } } +#ifdef DEBUG else { wchar_t msg[MAX_PATH + 128] = { 0 }; StringCchPrintf(msg, ARRAYSIZE(msg), L"AcquireWriteFileLock(%s): INVALID FILE HANDLE!", lpIniFilePath); MsgBoxLastError(msg, 0); } +#endif return (bLocked ? hFile : INVALID_HANDLE_VALUE); } @@ -152,12 +197,14 @@ HANDLE AcquireReadFileLock(LPCWSTR lpIniFilePath, OVERLAPPED& rOvrLpd) MsgBoxLastError(msg, 0); } } +#ifdef DEBUG else { wchar_t msg[MAX_PATH + 128] = { 0 }; StringCchPrintf(msg, ARRAYSIZE(msg), L"AcquireReadFileLock(%s): INVALID FILE HANDLE!", lpIniFilePath); MsgBoxLastError(msg, 0); } +#endif return (bLocked ? hFile : INVALID_HANDLE_VALUE); } @@ -265,13 +312,13 @@ extern "C" bool OpenSettingsFile(bool* keepCached) // extern "C" bool CloseSettingsFile(bool bSaveChanges, bool keepCached) { - if (StrIsEmpty(Globals.IniFile) || !IsIniFileCached()) { return false; } + if (!Globals.bCanSaveIniFile || !IsIniFileCached()) { return false; } - bool const ok = bSaveChanges ? SaveIniFileCache(Globals.IniFile) : true; + bool const bSaved = bSaveChanges ? SaveIniFileCache(Globals.IniFile) : false; if (!keepCached) { ResetIniFileCache(); } - return ok; + return bSaved; } @@ -961,7 +1008,9 @@ extern "C" bool CreateIniFile(LPCWSTR pszIniFilePath, DWORD* pdwFileSize_out) } if (pdwFileSize_out) { *pdwFileSize_out = dwFileSize; } - if (dwFileSize == 0UL) { + Globals.bCanSaveIniFile = CanAccessPath(pszIniFilePath, GENERIC_WRITE); + + if ((dwFileSize == 0UL) && Globals.bCanSaveIniFile) { // Set at least Application Name Section result = IniFileSetString(pszIniFilePath, _W(SAPPNAME), NULL, NULL); } @@ -999,7 +1048,7 @@ void LoadSettings() Globals.iCfgVersionRead = IniSectionGetInt(IniSecSettings, L"SettingsVersion", _ver); Defaults.SaveSettings = StrIsNotEmpty(Globals.IniFile); - Settings.SaveSettings = IniSectionGetBool(IniSecSettings, L"SaveSettings", Defaults.SaveSettings); + Settings.SaveSettings = Defaults.SaveSettings && IniSectionGetBool(IniSecSettings, L"SaveSettings", Defaults.SaveSettings); // --- first set "hard coded" .ini-Settings --- @@ -1979,7 +2028,7 @@ bool SaveAllSettings(bool bForceSaveSettings) { if (Flags.bDoRelaunchElevated) { return true; } // already saved before relaunch if (Flags.bSettingsFileSoftLocked) { return false; } - + WCHAR tchMsg[80]; GetLngString(IDS_MUI_SAVINGSETTINGS, tchMsg, COUNTOF(tchMsg)); @@ -1996,7 +2045,7 @@ __try { _SaveSettings(bForceSaveSettings); - if (StrIsNotEmpty(Globals.IniFile)) + if (Globals.bCanSaveIniFile) { if (!Settings.SaveRecentFiles) { // Cleanup unwanted MRUs @@ -2032,7 +2081,8 @@ __try { } // separate INI files for Style-Themes - if (Globals.idxSelectedTheme >= 2) { + if (Globals.idxSelectedTheme >= 2) + { Style_SaveSettings(bForceSaveSettings); } diff --git a/src/Config/Config.h b/src/Config/Config.h index bd0ebc5ed..77a0b85fc 100644 --- a/src/Config/Config.h +++ b/src/Config/Config.h @@ -28,6 +28,7 @@ extern "C" { bool FindIniFile(); bool TestIniFile(); +bool CanAccessPath(LPCWSTR lpIniFilePath, DWORD genericAccessRights); bool CreateIniFile(LPCWSTR pszIniFilePath, DWORD* pdwFileSize_out); void LoadSettings(); bool SaveWindowPositionSettings(bool bClearSettings); diff --git a/src/Dialogs.c b/src/Dialogs.c index 77ed14671..ce47ca702 100644 --- a/src/Dialogs.c +++ b/src/Dialogs.c @@ -287,7 +287,7 @@ static INT_PTR CALLBACK _InfoBoxLngDlgProc(HWND hwnd, UINT umsg, WPARAM wParam, case IDIGNORE: case IDTRYAGAIN: case IDCONTINUE: - if (IsButtonChecked(hwnd, IDC_INFOBOXCHECK) && StrIsNotEmpty(lpMsgBox->lpstrSetting)) { + if (IsButtonChecked(hwnd, IDC_INFOBOXCHECK) && StrIsNotEmpty(lpMsgBox->lpstrSetting) ) { IniFileSetInt(Globals.IniFile, Constants.SectionSuppressedMessages, lpMsgBox->lpstrSetting, LOWORD(wParam)); } case IDNO: @@ -336,7 +336,9 @@ INT_PTR InfoBoxLng(UINT uType, LPCWSTR lpstrSetting, UINT uidMsg, ...) break; default: - IniFileDelete(Globals.IniFile, Constants.SectionSuppressedMessages, lpstrSetting, false); + if (Globals.bCanSaveIniFile) { + IniFileDelete(Globals.IniFile, Constants.SectionSuppressedMessages, lpstrSetting, false); + } break; } @@ -385,8 +387,7 @@ INT_PTR InfoBoxLng(UINT uType, LPCWSTR lpstrSetting, UINT uidMsg, ...) } msgBox.lpstrSetting = (LPWSTR)lpstrSetting; - msgBox.bDisableCheckBox = (StrIsEmpty(Globals.IniFile) || StrIsEmpty(lpstrSetting) || (iMode < 0)) ? true : false; - + msgBox.bDisableCheckBox = (!Globals.bCanSaveIniFile || StrIsEmpty(lpstrSetting) || (iMode < 0)) ? true : false; int idDlg; switch (uType & MB_TYPEMASK) { diff --git a/src/Helpers.c b/src/Helpers.c index dca8b3f89..6b72c6541 100644 --- a/src/Helpers.c +++ b/src/Helpers.c @@ -688,24 +688,22 @@ bool VerifyContrast(COLORREF cr1,COLORREF cr2) // IsFontAvailable() // Test if a certain font is installed on the system // -int CALLBACK EnumFontsProc(CONST LOGFONT *plf,CONST TEXTMETRIC *ptm,DWORD FontType,LPARAM lParam) +static int CALLBACK EnumFontsProc(CONST LOGFONT *plf,CONST TEXTMETRIC *ptm,DWORD FontType,LPARAM lParam) { - *((PBOOL)lParam) = true; UNUSED(plf); UNUSED(ptm); UNUSED(FontType); + *((PBOOL)lParam) = true; return 0; } bool IsFontAvailable(LPCWSTR lpszFontName) { BOOL fFound = FALSE; - - HDC hDC = GetDC(NULL); + HDC const hDC = GetDC(NULL); EnumFonts(hDC,lpszFontName,EnumFontsProc,(LPARAM)&fFound); ReleaseDC(NULL,hDC); - - return (bool)(fFound); + return fFound; } @@ -713,22 +711,12 @@ bool IsFontAvailable(LPCWSTR lpszFontName) // // IsCmdEnabled() // -bool IsCmdEnabled(HWND hwnd,UINT uId) +bool IsCmdEnabled(HWND hwnd, UINT uId) { - - HMENU hmenu; - UINT ustate; - - hmenu = GetMenu(hwnd); - - SendMessage(hwnd,WM_INITMENU,(WPARAM)hmenu,0); - - ustate = GetMenuState(hmenu,uId,MF_BYCOMMAND); - - if (ustate == 0xFFFFFFFF) { - return true; - } - return (!(ustate & (MF_GRAYED|MF_DISABLED))); + HMENU const hmenu = GetMenu(hwnd); + SendMessage(hwnd, WM_INITMENU,(WPARAM)hmenu, 0); + UINT const ustate = GetMenuState(hmenu, uId, MF_BYCOMMAND); + return ((ustate == 0xFFFFFFFF) ? true : (!(ustate & (MF_GRAYED | MF_DISABLED)))); } diff --git a/src/MuiLanguage.c b/src/MuiLanguage.c index d9d1504df..cccb9279d 100644 --- a/src/MuiLanguage.c +++ b/src/MuiLanguage.c @@ -293,12 +293,13 @@ void SetPreferredLanguage(LANGID iPreferredLanguageID) { StringCchCopyW(Settings2.PreferredLanguageLocaleName, COUNTOF(Settings2.PreferredLanguageLocaleName), szLocaleName); - if (StringCchCompareXIW(Settings2.PreferredLanguageLocaleName, Defaults2.PreferredLanguageLocaleName) != 0) - { - IniFileSetString(Globals.IniFile, Constants.Settings2_Section, L"PreferredLanguageLocaleName", Settings2.PreferredLanguageLocaleName); - } - else { - IniFileDelete(Globals.IniFile, Constants.Settings2_Section, L"PreferredLanguageLocaleName", false); + if (Globals.bCanSaveIniFile) { + if (StringCchCompareXIW(Settings2.PreferredLanguageLocaleName, Defaults2.PreferredLanguageLocaleName) != 0) { + IniFileSetString(Globals.IniFile, Constants.Settings2_Section, L"PreferredLanguageLocaleName", Settings2.PreferredLanguageLocaleName); + } + else { + IniFileDelete(Globals.IniFile, Constants.Settings2_Section, L"PreferredLanguageLocaleName", false); + } } } } diff --git a/src/Notepad3.c b/src/Notepad3.c index 881a0efaf..1323ba300 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -2139,25 +2139,29 @@ bool SelectExternalToolBar(HWND hwnd) StringCchCopy(szFile, COUNTOF(szFile), s_tchToolbarBitmap); PathRemoveExtension(szFile); StringCchCat(szFile, COUNTOF(szFile), L"Hot.bmp"); - if (PathIsExistingFile(szFile)) { - PathRelativeToApp(szFile, s_tchToolbarBitmapHot, COUNTOF(s_tchToolbarBitmapHot), true, true, true); - IniFileSetString(Globals.IniFile, L"Toolbar Images", L"BitmapHot", s_tchToolbarBitmapHot); - } - else { - StringCchCopy(s_tchToolbarBitmapHot, COUNTOF(s_tchToolbarBitmapHot), L""); - IniFileDelete(Globals.IniFile, L"Toolbar Images", L"BitmapHot", false); + if (Globals.bCanSaveIniFile) { + if (PathIsExistingFile(szFile)) { + PathRelativeToApp(szFile, s_tchToolbarBitmapHot, COUNTOF(s_tchToolbarBitmapHot), true, true, true); + IniFileSetString(Globals.IniFile, L"Toolbar Images", L"BitmapHot", s_tchToolbarBitmapHot); + } + else { + StringCchCopy(s_tchToolbarBitmapHot, COUNTOF(s_tchToolbarBitmapHot), L""); + IniFileDelete(Globals.IniFile, L"Toolbar Images", L"BitmapHot", false); + } } StringCchCopy(szFile, COUNTOF(szFile), s_tchToolbarBitmap); PathRemoveExtension(szFile); StringCchCat(szFile, COUNTOF(szFile), L"Disabled.bmp"); - if (PathIsExistingFile(szFile)) { - PathRelativeToApp(szFile, s_tchToolbarBitmapDisabled, COUNTOF(s_tchToolbarBitmapDisabled), true, true, true); - IniFileSetString(Globals.IniFile, L"Toolbar Images", L"BitmapDisabled", s_tchToolbarBitmapDisabled); - } - else { - StringCchCopy(s_tchToolbarBitmapHot, COUNTOF(s_tchToolbarBitmapHot), L""); - IniFileDelete(Globals.IniFile, L"Toolbar Images", L"BitmapDisabled", false); + if (Globals.bCanSaveIniFile) { + if (PathIsExistingFile(szFile)) { + PathRelativeToApp(szFile, s_tchToolbarBitmapDisabled, COUNTOF(s_tchToolbarBitmapDisabled), true, true, true); + IniFileSetString(Globals.IniFile, L"Toolbar Images", L"BitmapDisabled", s_tchToolbarBitmapDisabled); + } + else { + StringCchCopy(s_tchToolbarBitmapHot, COUNTOF(s_tchToolbarBitmapHot), L""); + IniFileDelete(Globals.IniFile, L"Toolbar Images", L"BitmapDisabled", false); + } } Settings.ToolBarTheme = 2; return true; @@ -3139,6 +3143,7 @@ LRESULT MsgInitMenu(HWND hwnd, WPARAM wParam, LPARAM lParam) HMENU const hmenu = wParam ? (HMENU)wParam : GetMenu(hwnd); if (!hmenu) { return 0; } + bool const sav = Globals.bCanSaveIniFile; bool const ro = SciCall_GetReadOnly(); DocPos const iCurPos = SciCall_GetCurrentPos(); DocLn const iCurLine = SciCall_LineFromPosition(iCurPos); @@ -3429,12 +3434,12 @@ LRESULT MsgInitMenu(HWND hwnd, WPARAM wParam, LPARAM lParam) CheckCmd(hmenu, IDM_VIEW_SCROLLPASTEOF, Settings.ScrollPastEOF); CheckCmd(hmenu, IDM_VIEW_SHOW_HYPLNK_CALLTIP, Settings.ShowHypLnkToolTip); - bool b = Flags.bReuseWindow; - CheckCmd(hmenu, IDM_VIEW_REUSEWINDOW, b); - b = Flags.bSingleFileInstance; - CheckCmd(hmenu, IDM_VIEW_SINGLEFILEINSTANCE, b); - b = Flags.bStickyWindowPosition; - CheckCmd(hmenu, IDM_VIEW_STICKYWINPOS, b); + CheckCmd(hmenu, IDM_VIEW_REUSEWINDOW, Flags.bReuseWindow); + EnableCmd(hmenu, IDM_VIEW_REUSEWINDOW, sav); + CheckCmd(hmenu, IDM_VIEW_SINGLEFILEINSTANCE, Flags.bSingleFileInstance); + EnableCmd(hmenu, IDM_VIEW_SINGLEFILEINSTANCE, sav); + CheckCmd(hmenu, IDM_VIEW_STICKYWINPOS, Flags.bStickyWindowPosition); + EnableCmd(hmenu, IDM_VIEW_STICKYWINPOS, sav); CheckCmd(hmenu, IDM_VIEW_ALWAYSONTOP, ((Settings.AlwaysOnTop || s_flagAlwaysOnTop == 2) && s_flagAlwaysOnTop != 1)); CheckCmd(hmenu, IDM_VIEW_MINTOTRAY, Settings.MinimizeToTray); @@ -3459,10 +3464,13 @@ LRESULT MsgInitMenu(HWND hwnd, WPARAM wParam, LPARAM lParam) CheckCmd(hmenu, IDM_VIEW_SPLIT_UNDOTYPSEQ_LNBRK, Settings.SplitUndoTypingSeqOnLnBreak); CheckCmd(hmenu, IDM_VIEW_NOSAVERECENT, Settings.SaveRecentFiles); + EnableCmd(hmenu, IDM_VIEW_NOSAVERECENT, sav); CheckCmd(hmenu, IDM_VIEW_NOPRESERVECARET, Settings.PreserveCaretPos); - EnableCmd(hmenu, IDM_VIEW_NOPRESERVECARET, Settings.SaveRecentFiles); + EnableCmd(hmenu, IDM_VIEW_NOPRESERVECARET, Settings.SaveRecentFiles && sav); CheckCmd(hmenu, IDM_VIEW_NOSAVEFINDREPL, Settings.SaveFindReplace); + EnableCmd(hmenu, IDM_VIEW_NOSAVEFINDREPL, sav); CheckCmd(hmenu, IDM_VIEW_SAVEBEFORERUNNINGTOOLS, Settings.SaveBeforeRunningTools); + EnableCmd(hmenu, IDM_VIEW_SAVEBEFORERUNNINGTOOLS, sav); CheckCmd(hmenu, IDM_VIEW_CHANGENOTIFY, Settings.FileWatchingMode); @@ -3672,8 +3680,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) InfoBoxLng(MB_ICONWARNING, NULL, IDS_MUI_READONLY_MODIFY, PathFindFileName(Globals.CurrentFile)); } dwFileAttributes = GetFileAttributes(Globals.CurrentFile); - if (dwFileAttributes != INVALID_FILE_ATTRIBUTES) - s_bFileReadOnly = (dwFileAttributes & FILE_ATTRIBUTE_READONLY); + s_bFileReadOnly = (dwFileAttributes == INVALID_FILE_ATTRIBUTES) || (dwFileAttributes & FILE_ATTRIBUTE_READONLY); UpdateToolbar(); } @@ -5348,7 +5355,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) case IDM_VIEW_STICKYWINPOS: - { + if (IsCmdEnabled(hwnd, IDM_VIEW_STICKYWINPOS)) { Flags.bStickyWindowPosition = !Flags.bStickyWindowPosition; // toggle if (Flags.bStickyWindowPosition) { InfoBoxLng(MB_OK, L"MsgStickyWinPos", IDS_MUI_STICKYWINPOS); } @@ -5372,23 +5379,27 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) case IDM_VIEW_REUSEWINDOW: - Flags.bReuseWindow = !Flags.bReuseWindow; // reverse - if (Flags.bReuseWindow != DefaultFlags.bReuseWindow) { - IniFileSetBool(Globals.IniFile, Constants.Settings2_Section, L"ReuseWindow", Flags.bReuseWindow); - } - else { - IniFileDelete(Globals.IniFile, Constants.Settings2_Section, L"ReuseWindow", false); + if (IsCmdEnabled(hwnd, IDM_VIEW_REUSEWINDOW)) { + Flags.bReuseWindow = !Flags.bReuseWindow; // reverse + if (Flags.bReuseWindow != DefaultFlags.bReuseWindow) { + IniFileSetBool(Globals.IniFile, Constants.Settings2_Section, L"ReuseWindow", Flags.bReuseWindow); + } + else { + IniFileDelete(Globals.IniFile, Constants.Settings2_Section, L"ReuseWindow", false); + } } break; case IDM_VIEW_SINGLEFILEINSTANCE: - Flags.bSingleFileInstance = !Flags.bSingleFileInstance; // reverse - if (Flags.bSingleFileInstance != DefaultFlags.bSingleFileInstance) { - IniFileSetInt(Globals.IniFile, Constants.Settings2_Section, L"SingleFileInstance", Flags.bSingleFileInstance); - } - else { - IniFileDelete(Globals.IniFile, Constants.Settings2_Section, L"SingleFileInstance", false); + if (IsCmdEnabled(hwnd, IDM_VIEW_SINGLEFILEINSTANCE)) { + Flags.bSingleFileInstance = !Flags.bSingleFileInstance; // reverse + if (Flags.bSingleFileInstance != DefaultFlags.bSingleFileInstance) { + IniFileSetInt(Globals.IniFile, Constants.Settings2_Section, L"SingleFileInstance", Flags.bSingleFileInstance); + } + else { + IniFileDelete(Globals.IniFile, Constants.Settings2_Section, L"SingleFileInstance", false); + } } break; @@ -5516,9 +5527,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) if (IsCmdEnabled(hwnd, IDM_VIEW_SAVESETTINGSNOW)) { bool bCreateFailure = false; - if (StrIsEmpty(Globals.IniFile)) { - if (StrIsNotEmpty(Globals.IniFileDefault)) { StringCchCopy(Globals.IniFile, COUNTOF(Globals.IniFile), Globals.IniFileDefault); if (CreateIniFile(Globals.IniFile, NULL)) { @@ -6096,7 +6105,9 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) WININFO const wi = GetMyWindowPlacement(Globals.hwndMain, NULL); WCHAR tchDefWinPos[80]; StringCchPrintf(tchDefWinPos, COUNTOF(tchDefWinPos), L"%i,%i,%i,%i,%i", wi.x, wi.y, wi.cx, wi.cy, wi.max); - IniFileSetString(Globals.IniFile, Constants.Settings2_Section, L"DefaultWindowPosition", tchDefWinPos); + if (Globals.bCanSaveIniFile) { + IniFileSetString(Globals.IniFile, Constants.Settings2_Section, L"DefaultWindowPosition", tchDefWinPos); + } g_DefWinInfo = GetWinInfoByFlag(-1); // use current win pos as new default } break; @@ -8835,7 +8846,7 @@ void UpdateMarginWidth() void UpdateSaveSettingsCmds() { CheckCmd(Globals.hMainMenu, IDM_VIEW_SAVESETTINGS, Settings.SaveSettings && !Flags.bSettingsFileSoftLocked); - EnableCmd(Globals.hMainMenu, IDM_VIEW_SAVESETTINGS, StrIsNotEmpty(Globals.IniFile) && !Flags.bSettingsFileSoftLocked); + EnableCmd(Globals.hMainMenu, IDM_VIEW_SAVESETTINGS, Globals.bCanSaveIniFile && !Flags.bSettingsFileSoftLocked); EnableCmd(Globals.hMainMenu, IDM_VIEW_SAVESETTINGSNOW, (StrIsNotEmpty(Globals.IniFile) || StrIsNotEmpty(Globals.IniFileDefault)) && !Flags.bSettingsFileSoftLocked); EnableCmd(Globals.hMainMenu, CMD_OPENINIFILE, StrIsNotEmpty(Globals.IniFile) && !Flags.bSettingsFileSoftLocked); } @@ -9307,7 +9318,7 @@ bool FileIO(bool fLoad,LPWSTR pszFileName, } DWORD const dwFileAttributes = GetFileAttributes(pszFileName); - s_bFileReadOnly = ((dwFileAttributes != INVALID_FILE_ATTRIBUTES) && (dwFileAttributes & FILE_ATTRIBUTE_READONLY)); + s_bFileReadOnly = ((dwFileAttributes == INVALID_FILE_ATTRIBUTES) || (dwFileAttributes & FILE_ATTRIBUTE_READONLY)); EndWaitCursor(); @@ -9912,9 +9923,8 @@ bool FileSave(bool bSaveAlways, bool bAsk, bool bSaveAs, bool bSaveCopy, bool bP // Read only... if (!bSaveAs && !bSaveCopy && StrIsNotEmpty(Globals.CurrentFile)) { - DWORD dwFileAttributes = GetFileAttributes(Globals.CurrentFile); - if (dwFileAttributes != INVALID_FILE_ATTRIBUTES) - s_bFileReadOnly = (dwFileAttributes & FILE_ATTRIBUTE_READONLY); + DWORD const dwFileAttributes = GetFileAttributes(Globals.CurrentFile); + s_bFileReadOnly = (dwFileAttributes == INVALID_FILE_ATTRIBUTES) || (dwFileAttributes & FILE_ATTRIBUTE_READONLY); if (s_bFileReadOnly) { INT_PTR const answer = InfoBoxLng(MB_YESNO | MB_ICONWARNING, NULL, IDS_MUI_READONLY_SAVE, PathFindFileName(Globals.CurrentFile)); if ((IDOK == answer) || (IDYES == answer)) { diff --git a/src/Styles.c b/src/Styles.c index 899e81d3d..eb7fe8479 100644 --- a/src/Styles.c +++ b/src/Styles.c @@ -174,8 +174,6 @@ static void _FillThemesMenuTable() { Theme_Files[0].rid = IDM_THEMES_DEFAULT; // factory default Theme_Files[1].rid = IDM_THEMES_FILE_ITEM; // NP3.ini settings - // names are filled by Style_InsertThemesMenu() - StringCchCopy(Theme_Files[1].szFilePath, COUNTOF(Theme_Files[1].szFilePath), Globals.IniFile); unsigned iTheme = 1; // Standard @@ -183,6 +181,8 @@ static void _FillThemesMenuTable() // find "themes" sub-dir (side-by-side to Notepad3.ini) if (StrIsNotEmpty(Globals.IniFile)) { StringCchCopy(tchThemeDir, COUNTOF(tchThemeDir), Globals.IniFile); + // names are filled by Style_InsertThemesMenu() + StringCchCopy(Theme_Files[iTheme].szFilePath, COUNTOF(Theme_Files[iTheme].szFilePath), Globals.IniFile); } else if (StrIsNotEmpty(Globals.IniFileDefault)) { StringCchCopy(tchThemeDir, COUNTOF(tchThemeDir), Globals.IniFileDefault); @@ -232,16 +232,6 @@ static void _FillThemesMenuTable() -//============================================================================= -// -// Style_SetIniFile() -// -void Style_SetIniFile(LPCWSTR szIniFile) -{ - StringCchCopy(Theme_Files[1].szFilePath, COUNTOF(Theme_Files[1].szFilePath), szIniFile); - _FillThemesMenuTable(); -} - //============================================================================= // @@ -484,8 +474,6 @@ void Style_Load() _FillThemesMenuTable(); - // get theme name from settings - unsigned iTheme = 1; if (StrIsNotEmpty(Globals.SelectedThemeName)) { for (; iTheme < ThemeItems_CountOf(); ++iTheme) diff --git a/src/Styles.h b/src/Styles.h index 9195de16e..e61a4b5ac 100644 --- a/src/Styles.h +++ b/src/Styles.h @@ -39,7 +39,6 @@ void Style_ToIniSection(bool bForceAll, bool bIsStdIniFile); bool Style_ExportToFile(const WCHAR* szFile, bool bForceAll); unsigned ThemeItems_CountOf(); -void Style_SetIniFile(LPCWSTR szIniFile); bool Style_InsertThemesMenu(HMENU hMenuBar); void Style_DynamicThemesMenuCmd(int cmd); diff --git a/src/TypeDefs.h b/src/TypeDefs.h index 0acb9cfdb..a3a6f647d 100644 --- a/src/TypeDefs.h +++ b/src/TypeDefs.h @@ -293,6 +293,7 @@ typedef struct _globals_t HINSTANCE hInstance; HINSTANCE hPrevInst; HINSTANCE hLngResContainer; + bool bCanSaveIniFile; int iAvailLngCount; bool bPrefLngNotAvail; HWND hwndMain;