+ chg: silent ignore write permissions missing on Inifile

This commit is contained in:
Rainer Kottenhoff 2020-06-28 18:42:28 +02:00
parent b18ffedda8
commit a5ef3bb3f3
9 changed files with 137 additions and 98 deletions

View File

@ -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<PSECURITY_DESCRIPTOR>(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);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -293,6 +293,7 @@ typedef struct _globals_t
HINSTANCE hInstance;
HINSTANCE hPrevInst;
HINSTANCE hLngResContainer;
bool bCanSaveIniFile;
int iAvailLngCount;
bool bPrefLngNotAvail;
HWND hwndMain;