diff --git a/Versions/build.txt b/Versions/build.txt
index b8626c4cf..d00491fd7 100644
--- a/Versions/build.txt
+++ b/Versions/build.txt
@@ -1 +1 @@
-4
+1
diff --git a/Versions/day.txt b/Versions/day.txt
index b661fff6c..a1e0432c9 100644
--- a/Versions/day.txt
+++ b/Versions/day.txt
@@ -1 +1 @@
-311
+312
diff --git a/minipath/minipath.vcxproj b/minipath/minipath.vcxproj
index 5c9515863..593b5ac24 100644
--- a/minipath/minipath.vcxproj
+++ b/minipath/minipath.vcxproj
@@ -290,6 +290,7 @@
+
@@ -298,7 +299,6 @@
-
diff --git a/minipath/minipath.vcxproj.filters b/minipath/minipath.vcxproj.filters
index c4d415eb9..81ec44a07 100644
--- a/minipath/minipath.vcxproj.filters
+++ b/minipath/minipath.vcxproj.filters
@@ -66,7 +66,7 @@
H Source Files
-
+
H Source Files
diff --git a/minipath/src/Config.cpp b/minipath/src/Config.cpp
index 2e0e2ee20..f193bf423 100644
--- a/minipath/src/Config.cpp
+++ b/minipath/src/Config.cpp
@@ -49,7 +49,7 @@ extern "C" int flagPosParam;
// ----------------------------------------------------------------------------
-#include "SimpleIni.h"
+#include "..\..\src\Config\SimpleIni.h"
#include "Config.h"
// ============================================================================
@@ -68,6 +68,45 @@ constexpr bool SI_Success(const SI_Error rc) noexcept {
// ============================================================================
+
+// ----------------------------------------------------------------------------
+// No mechanism for EXCLUSIVE WRITE / SHARD READ:
+// cause we need completely synchronized exclusive access for READ _and_ WRITE
+// of complete file to preserve integrety of any transaction
+// ----------------------------------------------------------------------------
+
+HANDLE AcquireFileLock(LPCWSTR lpIniFilePath, OVERLAPPED& rOvrLpd)
+{
+ HANDLE hFile = CreateFile(lpIniFilePath,
+ GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
+
+ DWORD const flags = LOCKFILE_EXCLUSIVE_LOCK;
+ bool const bLocked = LockFileEx(hFile, flags, 0, MAXDWORD, 0, &rOvrLpd);
+
+ return (bLocked ? hFile : INVALID_HANDLE_VALUE);
+}
+
+// ----------------------------------------------------------------------------
+
+bool ReleaseFileLock(HANDLE hFile, OVERLAPPED& rOvrLpd)
+{
+ bool bUnLocked = true;
+ if (hFile != INVALID_HANDLE_VALUE) {
+ FlushFileBuffers(hFile);
+ bUnLocked = !UnlockFileEx(hFile, 0, MAXDWORD, 0, &rOvrLpd);
+ CloseHandle(hFile);
+ }
+ return bUnLocked;
+}
+
+// ============================================================================
+
+
+// ============================================================================
+
+static OVERLAPPED s_OvrLpd = { 0 };
+static HANDLE s_INI_Hndl = INVALID_HANDLE_VALUE;
static CSimpleIni s_INI(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine);
@@ -76,20 +115,36 @@ extern "C" BOOL LoadIniFile(LPCWSTR lpIniFilePath)
s_INI.Reset();
s_INI.SetSpaces(s_bSetSpaces);
s_INI.SetMultiLine(s_bUseMultiLine);
- SI_Error const rc = s_INI.LoadFile(lpIniFilePath);
- return SI_Success(rc);
+
+ s_INI_Hndl = AcquireFileLock(lpIniFilePath, s_OvrLpd);
+ if (s_INI_Hndl == INVALID_HANDLE_VALUE) {
+ return false;
+ }
+
+ return SI_Success(s_INI.LoadFile(s_INI_Hndl));
}
+
+extern "C" bool IsIniFileLoaded()
+{
+ return (s_INI_Hndl != INVALID_HANDLE_VALUE);
+}
+
+
extern "C" void ReleaseIniFile()
{
s_INI.Reset();
+ ReleaseFileLock(s_INI_Hndl, s_OvrLpd);
+ s_INI_Hndl = INVALID_HANDLE_VALUE;
+ ZeroMemory(&s_OvrLpd, sizeof(OVERLAPPED));
}
-extern "C" BOOL SaveIniFile(LPCWSTR lpIniFilePath)
+
+extern "C" BOOL SaveIniFile()
{
s_INI.SetSpaces(s_bSetSpaces);
s_INI.SetMultiLine(s_bUseMultiLine);
- SI_Error const rc = s_INI.SaveFile(lpIniFilePath, s_bWriteSIG);
+ SI_Error const rc = s_INI.SaveFile(s_INI_Hndl, s_bWriteSIG);
ReleaseIniFile();
return SI_Success(rc);
}
@@ -97,7 +152,7 @@ extern "C" BOOL SaveIniFile(LPCWSTR lpIniFilePath)
//=============================================================================
//
-// Manipulation of (cached) INI file
+// Manipulation of (cached) ini file
//
//=============================================================================
@@ -243,7 +298,7 @@ extern "C" BOOL IniClearAllSections(LPCWSTR lpPrefix, BOOL bRemoveEmpty)
{
if (lstrcmpi(section.pItem, lpPrefix) == 0)
{
- s_INI.Delete(section.pItem, nullptr, bRemoveEmpty);
+ IniSectionClear(section.pItem, bRemoveEmpty);
}
}
return TRUE;
@@ -259,7 +314,17 @@ extern "C" size_t IniFileGetString(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LP
LPWSTR lpReturnedString, size_t cchReturnedString)
{
CSimpleIni Ini(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine);
- SI_Error const rc = Ini.LoadFile(lpFilePath);
+
+ OVERLAPPED ovrLpd = { 0 };
+ HANDLE hFile = AcquireFileLock(lpFilePath, ovrLpd);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ StringCchCopyW(lpReturnedString, cchReturnedString, lpDefault);
+ return (size_t)lstrlen(lpReturnedString);
+ }
+
+ SI_Error const rc = Ini.LoadFile(hFile);
+ ReleaseFileLock(hFile, ovrLpd);
+
if (SI_Success(rc)) {
bool bHasMultiple = false;
StringCchCopyW(lpReturnedString, cchReturnedString, Ini.GetValue(lpSectionName, lpKeyName, lpDefault, &bHasMultiple));
@@ -277,16 +342,24 @@ extern "C" BOOL IniFileSetString(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCW
{
CSimpleIni Ini(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine);
Ini.SetSpaces(s_bSetSpaces);
- Ini.SetMultiLine(s_bUseMultiLine);
- SI_Error rc = Ini.LoadFile(lpFilePath);
+
+ OVERLAPPED ovrLpd = { 0 };
+ HANDLE hFile = AcquireFileLock(lpFilePath, ovrLpd);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ return false;
+ }
+
+ SI_Error rc = Ini.LoadFile(hFile);
if (SI_Success(rc))
{
SI_Error const res = Ini.SetValue(lpSectionName, lpKeyName, lpString, nullptr, !s_bUseMultiKey);
rc = SI_Success(res) ? SI_Error::SI_OK : SI_Error::SI_FAIL;
if (SI_Success(rc)) {
- rc = Ini.SaveFile(lpFilePath, s_bWriteSIG);
+ rc = Ini.SaveFile(hFile, s_bWriteSIG);
}
}
+ ReleaseFileLock(hFile, ovrLpd);
+
return SI_Success(rc);
}
// ============================================================================
@@ -295,8 +368,18 @@ extern "C" BOOL IniFileSetString(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCW
extern "C" int IniFileGetInt(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWSTR lpKeyName, int iDefault)
{
CSimpleIni Ini(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine);
- SI_Error const rc = Ini.LoadFile(lpFilePath);
- if (SI_Success(rc)) {
+
+ OVERLAPPED ovrLpd = { 0 };
+ HANDLE hFile = AcquireFileLock(lpFilePath, ovrLpd);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ return iDefault;
+ }
+
+ SI_Error rc = Ini.LoadFile(hFile);
+ ReleaseFileLock(hFile, ovrLpd);
+
+ if (SI_Success(rc))
+ {
bool bHasMultiple = false;
int const iValue = Ini.GetLongValue(lpSectionName, lpKeyName, (long)iDefault, &bHasMultiple);
//assert(!bHasMultiple);
@@ -311,13 +394,21 @@ extern "C" BOOL IniFileSetInt(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWSTR
{
CSimpleIni Ini(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine);
Ini.SetSpaces(s_bSetSpaces);
- Ini.SetMultiLine(s_bUseMultiLine);
- SI_Error rc = Ini.LoadFile(lpFilePath);
- if (SI_Success(rc)) {
- Ini.SetLongValue(lpSectionName, lpKeyName, (long)iValue, nullptr, false, !s_bUseMultiKey);
- rc = Ini.SaveFile(lpFilePath, s_bWriteSIG);
+
+ OVERLAPPED ovrLpd = { 0 };
+ HANDLE hFile = AcquireFileLock(lpFilePath, ovrLpd);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ return false;
}
- Ini.Reset();
+
+ SI_Error rc = Ini.LoadFile(hFile);
+ if (SI_Success(rc))
+ {
+ Ini.SetLongValue(lpSectionName, lpKeyName, (long)iValue, nullptr, false, !s_bUseMultiKey);
+ rc = Ini.SaveFile(hFile, s_bWriteSIG);
+ }
+ ReleaseFileLock(hFile, ovrLpd);
+
return SI_Success(rc);
}
// ============================================================================
@@ -326,10 +417,20 @@ extern "C" BOOL IniFileSetInt(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWSTR
extern "C" BOOL IniFileGetBool(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWSTR lpKeyName, BOOL bDefault)
{
CSimpleIni Ini(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine);
- SI_Error const rc = Ini.LoadFile(lpFilePath);
- if (SI_Success(rc)) {
+
+ OVERLAPPED ovrLpd = { 0 };
+ HANDLE hFile = AcquireFileLock(lpFilePath, ovrLpd);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ return bDefault;
+ }
+
+ SI_Error rc = Ini.LoadFile(hFile);
+ ReleaseFileLock(hFile, ovrLpd);
+
+ if (SI_Success(rc))
+ {
bool bHasMultiple = false;
- BOOL const bValue = Ini.GetBoolValue(lpSectionName, lpKeyName, bDefault, &bHasMultiple);
+ bool const bValue = Ini.GetBoolValue(lpSectionName, lpKeyName, bDefault, &bHasMultiple);
//assert(!bHasMultiple);
return bValue;
}
@@ -342,13 +443,21 @@ extern "C" BOOL IniFileSetBool(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWST
{
CSimpleIni Ini(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine);
Ini.SetSpaces(s_bSetSpaces);
- Ini.SetMultiLine(s_bUseMultiLine);
- SI_Error rc = Ini.LoadFile(lpFilePath);
- if (SI_Success(rc)) {
- Ini.SetBoolValue(lpSectionName, lpKeyName, bValue, nullptr, !s_bUseMultiKey);
- rc = Ini.SaveFile(lpFilePath, s_bWriteSIG);
+
+ OVERLAPPED ovrLpd = { 0 };
+ HANDLE hFile = AcquireFileLock(lpFilePath, ovrLpd);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ return false;
}
- Ini.Reset();
+
+ SI_Error rc = Ini.LoadFile(hFile);
+ if (SI_Success(rc))
+ {
+ Ini.SetBoolValue(lpSectionName, lpKeyName, bValue, nullptr, !s_bUseMultiKey);
+ rc = Ini.SaveFile(hFile, s_bWriteSIG);
+ }
+ ReleaseFileLock(hFile, ovrLpd);
+
return SI_Success(rc);
}
// ============================================================================
@@ -357,26 +466,40 @@ extern "C" BOOL IniFileSetBool(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWST
extern "C" BOOL IniFileDelete(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWSTR lpKeyName, BOOL bRemoveEmpty)
{
CSimpleIni Ini(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine);
- Ini.SetMultiLine(s_bUseMultiLine);
Ini.SetSpaces(s_bSetSpaces);
- SI_Error rc = Ini.LoadFile(lpFilePath);
+
+ OVERLAPPED ovrLpd = { 0 };
+ HANDLE hFile = AcquireFileLock(lpFilePath, ovrLpd);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ return false;
+ }
+
+ SI_Error rc = Ini.LoadFile(hFile);
if (SI_Success(rc))
{
Ini.Delete(lpSectionName, lpKeyName, bRemoveEmpty);
- Ini.SetSpaces(s_bSetSpaces);
- rc = Ini.SaveFile(lpFilePath, s_bWriteSIG);
+ rc = Ini.SaveFile(hFile, s_bWriteSIG);
}
- Ini.Reset();
+ ReleaseFileLock(hFile, ovrLpd);
+
return SI_Success(rc);
}
// ============================================================================
-
extern "C" BOOL IniFileIterateSection(LPCWSTR lpFilePath, LPCWSTR lpSectionName, IterSectionFunc_t callBack)
{
CSimpleIni Ini(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine);
- SI_Error rc = Ini.LoadFile(lpFilePath);
+
+ OVERLAPPED ovrLpd = { 0 };
+ HANDLE hFile = AcquireFileLock(lpFilePath, ovrLpd);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ return false;
+ }
+
+ SI_Error rc = Ini.LoadFile(hFile);
+ ReleaseFileLock(hFile, ovrLpd);
+
if (SI_Success(rc))
{
bool bHasMultiple = false;
@@ -397,7 +520,6 @@ extern "C" BOOL IniFileIterateSection(LPCWSTR lpFilePath, LPCWSTR lpSectionName,
-
//=============================================================================
//
// InitDefaultSettings()
@@ -441,39 +563,52 @@ void InitDefaultSettings()
//
int CreateIniFile()
{
- return(CreateIniFileEx(g_wchIniFile));
-}
-
-int CreateIniFileEx(LPCWSTR lpszIniFile) {
-
- if (lpszIniFile && *lpszIniFile)
+ int result = 0;
+ if (g_wchIniFile[0] != L'\0')
{
- WCHAR* pwchTail = StrRChrW(lpszIniFile, nullptr, L'\\');
+ WCHAR* pwchTail = StrRChrW(g_wchIniFile, NULL, L'\\');
+
if (pwchTail) {
*pwchTail = 0;
- SHCreateDirectoryEx(nullptr, lpszIniFile, nullptr);
+ SHCreateDirectoryEx(NULL, g_wchIniFile, NULL);
*pwchTail = L'\\';
}
- HANDLE hFile = CreateFile(lpszIniFile,
- GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
- nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
- if (hFile != INVALID_HANDLE_VALUE) {
- if (GetFileSize(hFile, nullptr) == 0) {
- DWORD dw;
- WriteFile(hFile, (LPCVOID)L"\xFEFF[minipath]\r\n", 26, &dw, nullptr);
+ DWORD dwFileSize = 0UL;
+
+ if (!PathFileExists(g_wchIniFile)) {
+ HANDLE hFile = CreateFile(g_wchIniFile,
+ GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
+ if (hFile != INVALID_HANDLE_VALUE) {
+ CloseHandle(hFile);
}
- CloseHandle(hFile);
- return(1);
}
else {
- return(0);
+ OVERLAPPED ovrLpd = { 0 };
+ HANDLE hFile = AcquireFileLock(g_wchIniFile, ovrLpd);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ return result;
+ }
+ DWORD dwFSHigh = 0UL;
+ dwFileSize = GetFileSize(hFile, &dwFSHigh);
+ ReleaseFileLock(hFile, ovrLpd);
}
+
+ if ((dwFileSize == 0) && (dwFileSize != INVALID_FILE_SIZE)) {
+ result = IniFileSetString(g_wchIniFile, L"minipath", NULL, NULL);
+ }
+ else {
+ result = true;
+ }
+
+ return result;
}
- else {
- return(0);
- }
+ return result;
}
+//=============================================================================
+
+
//=============================================================================
//
@@ -682,34 +817,39 @@ int TestIniFile() {
//
void LoadFlags()
{
- LoadIniFile(g_wchIniFile);
+ __try {
- const WCHAR* const Settings_Section2 = L"Settings2";
+ LoadIniFile(g_wchIniFile);
+
+ const WCHAR* const Settings_Section2 = L"Settings2";
+
+ if (!IniSectionGetString(Settings_Section2, L"PreferredLanguageLocaleName", L"",
+ g_tchPrefLngLocName, COUNTOF(g_tchPrefLngLocName)))
+ {
+ // try to fetch Locale Name from Notepad3.ini
+ IniFileGetString(g_wchNP3IniFile, L"Settings2", L"PreferredLanguageLocaleName", L"",
+ g_tchPrefLngLocName, COUNTOF(g_tchPrefLngLocName));
+ }
+
+ if (!flagNoReuseWindow) {
+
+ if (!IniSectionGetInt(Settings_Section2, L"ReuseWindow", 1))
+ flagNoReuseWindow = 1;
+ }
+
+ if (IniSectionGetInt(Settings_Section2, L"PortableMyDocs", 1))
+ flagPortableMyDocs = 1;
+
+ if (IniSectionGetInt(Settings_Section2, L"NoFadeHidden", 0))
+ flagNoFadeHidden = 1;
+
+ flagToolbarLook = IniSectionGetInt(Settings_Section2, L"ToolbarLook", 0);
+ flagToolbarLook = max(min(flagToolbarLook, 2), 0);
- if (!IniSectionGetString(Settings_Section2, L"PreferredLanguageLocaleName", L"",
- g_tchPrefLngLocName, COUNTOF(g_tchPrefLngLocName)))
- {
- // try to fetch Locale Name from Notepad3.ini
- IniFileGetString(g_wchNP3IniFile, L"Settings2", L"PreferredLanguageLocaleName", L"",
- g_tchPrefLngLocName, COUNTOF(g_tchPrefLngLocName));
}
-
- if (!flagNoReuseWindow) {
-
- if (!IniSectionGetInt(Settings_Section2, L"ReuseWindow", 1))
- flagNoReuseWindow = 1;
+ __finally {
+ ReleaseIniFile();
}
-
- if (IniSectionGetInt(Settings_Section2, L"PortableMyDocs", 1))
- flagPortableMyDocs = 1;
-
- if (IniSectionGetInt(Settings_Section2, L"NoFadeHidden", 0))
- flagNoFadeHidden = 1;
-
- flagToolbarLook = IniSectionGetInt(Settings_Section2, L"ToolbarLook", 0);
- flagToolbarLook = max(min(flagToolbarLook, 2), 0);
-
- ReleaseIniFile();
}
@@ -733,6 +873,8 @@ extern "C" LPWSTR lpFilterArg;
void LoadSettings()
{
+ __try {
+
LoadIniFile(g_wchIniFile);
const WCHAR* const Settings_Section = L"Settings";
@@ -865,7 +1007,10 @@ void LoadSettings()
Settings.crCustom[i] = Defaults.crCustom[i];
}
- ReleaseIniFile();
+ }
+ __finally {
+ ReleaseIniFile();
+ }
}
@@ -909,99 +1054,104 @@ void SaveSettings(BOOL bSaveSettingsNow)
return;
}
- LoadIniFile(g_wchIniFile);
+ __try {
- const WCHAR* const Settings_Section = L"Settings";
+ LoadIniFile(g_wchIniFile);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"SaveSettings", bSaveSettings);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"SingleClick", bSingleClick);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"TrackSelect", bTrackSelect);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"FullRowSelect", bFullRowSelect);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"UseRecycleBin", fUseRecycleBin);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"NoConfirmDelete", fNoConfirmDelete);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"ClearReadOnly", bClearReadOnly);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"RenameOnCollision", bRenameOnCollision);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"FocusEdit", bFocusEdit);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"AlwaysOnTop", bAlwaysOnTop);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"MinimizeToTray", bMinimizeToTray);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"TransparentMode", g_bTransparentMode);
+ const WCHAR* const Settings_Section = L"Settings";
+
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"SaveSettings", bSaveSettings);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"SingleClick", bSingleClick);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"TrackSelect", bTrackSelect);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"FullRowSelect", bFullRowSelect);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"UseRecycleBin", fUseRecycleBin);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"NoConfirmDelete", fNoConfirmDelete);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"ClearReadOnly", bClearReadOnly);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"RenameOnCollision", bRenameOnCollision);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"FocusEdit", bFocusEdit);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"AlwaysOnTop", bAlwaysOnTop);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"MinimizeToTray", bMinimizeToTray);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"TransparentMode", g_bTransparentMode);
+
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"EscFunction", iEscFunction);
+
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"StartupDirectory", iStartupDir);
+ if (Settings.iStartupDir == 1) {
+ IniSectionSetString(Settings_Section, L"MRUDirectory", Settings.szCurDir);
+ }
+ if (!Settings.bNP3sFavoritesSettings) {
+ PathRelativeToApp(Settings.g_tchFavoritesDir, wchTmp, COUNTOF(wchTmp), FALSE, TRUE, flagPortableMyDocs);
+ IniSectionSetString(Settings_Section, L"Favorites", wchTmp);
+ }
+
+ PathRelativeToApp(Settings.szQuickview, wchTmp, COUNTOF(wchTmp), FALSE, TRUE, flagPortableMyDocs);
+ IniSectionSetString(Settings_Section, L"Quikview.exe", wchTmp);
+ SAVE_STRING_IF_NOT_EQ_DEFAULT(L"Quikview.exe", szQuickviewParams);
+
+ PathRelativeToApp(Settings.tchOpenWithDir, wchTmp, COUNTOF(wchTmp), FALSE, TRUE, flagPortableMyDocs);
+ if (lstrcmp(wchTmp, Defaults.tchOpenWithDir) != 0) {
+ IniSectionSetString(Settings_Section, L"OpenWithDir", wchTmp);
+ }
+
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"FillMask", dwFillMask);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"SortOptions", nSortFlags);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"SortReverse", fSortRev);
+ SAVE_STRING_IF_NOT_EQ_DEFAULT(L"FileFilter", tchFilter);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"NegativeFilter", bNegFilter);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"DefColorNoFilter", bDefCrNoFilt);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"DefColorFilter", bDefCrFilter);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"ColorNoFilter", crNoFilt);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"ColorFilter", crFilter);
+ SAVE_STRING_IF_NOT_EQ_DEFAULT(L"ToolbarButtons", tchToolbarButtons);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"ShowToolbar", bShowToolbar);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"ShowStatusbar", bShowStatusbar);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"ShowDriveBox", bShowDriveBox);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"GotoDlgSizeX", cxGotoDlg);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"OpenWithDlgSizeX", cxOpenWithDlg);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"OpenWithDlgSizeY", cyOpenWithDlg);
+ SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"CopyMoveDlgSizeX", cxCopyMoveDlg);
+
+ // cleanup
+ IniSectionDelete(Settings_Section, L"WriteTest", FALSE);
+
+ /*
+ SaveSettingsNow(): query Window Dimensions
+ */
+
+ if (bSaveSettingsNow)
+ {
+ WINDOWPLACEMENT wndpl;
+ ZeroMemory(&wndpl, sizeof(WINDOWPLACEMENT));
+ // GetWindowPlacement
+ wndpl.length = sizeof(WINDOWPLACEMENT);
+ GetWindowPlacement(hwndMain, &wndpl);
+
+ Settings.wi.x = wndpl.rcNormalPosition.left;
+ Settings.wi.y = wndpl.rcNormalPosition.top;
+ Settings.wi.cx = wndpl.rcNormalPosition.right - wndpl.rcNormalPosition.left;
+ Settings.wi.cy = wndpl.rcNormalPosition.bottom - wndpl.rcNormalPosition.top;
+ }
+
+ WCHAR tchPosX[32], tchPosY[32], tchSizeX[32], tchSizeY[32], tchMaximized[32];
+ int ResX = GetSystemMetrics(SM_CXSCREEN);
+ int ResY = GetSystemMetrics(SM_CYSCREEN);
+ wsprintf(tchPosX, L"%ix%i PosX", ResX, ResY);
+ wsprintf(tchPosY, L"%ix%i PosY", ResX, ResY);
+ wsprintf(tchSizeX, L"%ix%i SizeX", ResX, ResY);
+ wsprintf(tchSizeY, L"%ix%i SizeY", ResX, ResY);
+ wsprintf(tchMaximized, L"%ix%i Maximized", ResX, ResY);
+
+ const WCHAR* const Windows_Section = L"Window";
+
+ IniSectionSetInt(Windows_Section, tchPosX, Settings.wi.x);
+ IniSectionSetInt(Windows_Section, tchPosY, Settings.wi.y);
+ IniSectionSetInt(Windows_Section, tchSizeX, Settings.wi.cx);
+ IniSectionSetInt(Windows_Section, tchSizeY, Settings.wi.cy);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"EscFunction", iEscFunction);
-
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"StartupDirectory", iStartupDir);
- if (Settings.iStartupDir == 1) {
- IniSectionSetString(Settings_Section, L"MRUDirectory", Settings.szCurDir);
}
- if (!Settings.bNP3sFavoritesSettings) {
- PathRelativeToApp(Settings.g_tchFavoritesDir, wchTmp, COUNTOF(wchTmp), FALSE, TRUE, flagPortableMyDocs);
- IniSectionSetString(Settings_Section, L"Favorites", wchTmp);
+ __finally {
+ SaveIniFile();
}
-
- PathRelativeToApp(Settings.szQuickview, wchTmp, COUNTOF(wchTmp), FALSE, TRUE, flagPortableMyDocs);
- IniSectionSetString(Settings_Section, L"Quikview.exe", wchTmp);
- SAVE_STRING_IF_NOT_EQ_DEFAULT(L"Quikview.exe", szQuickviewParams);
-
- PathRelativeToApp(Settings.tchOpenWithDir, wchTmp, COUNTOF(wchTmp), FALSE, TRUE, flagPortableMyDocs);
- if (lstrcmp(wchTmp, Defaults.tchOpenWithDir) != 0) {
- IniSectionSetString(Settings_Section, L"OpenWithDir", wchTmp);
- }
-
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"FillMask", dwFillMask);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"SortOptions", nSortFlags);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"SortReverse", fSortRev);
- SAVE_STRING_IF_NOT_EQ_DEFAULT(L"FileFilter", tchFilter);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"NegativeFilter", bNegFilter);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"DefColorNoFilter", bDefCrNoFilt);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"DefColorFilter", bDefCrFilter);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"ColorNoFilter", crNoFilt);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"ColorFilter", crFilter);
- SAVE_STRING_IF_NOT_EQ_DEFAULT(L"ToolbarButtons", tchToolbarButtons);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"ShowToolbar", bShowToolbar);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"ShowStatusbar", bShowStatusbar);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Bool, L"ShowDriveBox", bShowDriveBox);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"GotoDlgSizeX", cxGotoDlg);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"OpenWithDlgSizeX", cxOpenWithDlg);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"OpenWithDlgSizeY", cyOpenWithDlg);
- SAVE_VALUE_IF_NOT_EQ_DEFAULT(Int, L"CopyMoveDlgSizeX", cxCopyMoveDlg);
-
- // cleanup
- IniSectionDelete(Settings_Section, L"WriteTest", FALSE);
-
- /*
- SaveSettingsNow(): query Window Dimensions
- */
-
- if (bSaveSettingsNow)
- {
- WINDOWPLACEMENT wndpl;
- ZeroMemory(&wndpl, sizeof(WINDOWPLACEMENT));
- // GetWindowPlacement
- wndpl.length = sizeof(WINDOWPLACEMENT);
- GetWindowPlacement(hwndMain, &wndpl);
-
- Settings.wi.x = wndpl.rcNormalPosition.left;
- Settings.wi.y = wndpl.rcNormalPosition.top;
- Settings.wi.cx = wndpl.rcNormalPosition.right - wndpl.rcNormalPosition.left;
- Settings.wi.cy = wndpl.rcNormalPosition.bottom - wndpl.rcNormalPosition.top;
- }
-
- WCHAR tchPosX[32], tchPosY[32], tchSizeX[32], tchSizeY[32], tchMaximized[32];
- int ResX = GetSystemMetrics(SM_CXSCREEN);
- int ResY = GetSystemMetrics(SM_CYSCREEN);
- wsprintf(tchPosX, L"%ix%i PosX", ResX, ResY);
- wsprintf(tchPosY, L"%ix%i PosY", ResX, ResY);
- wsprintf(tchSizeX, L"%ix%i SizeX", ResX, ResY);
- wsprintf(tchSizeY, L"%ix%i SizeY", ResX, ResY);
- wsprintf(tchMaximized, L"%ix%i Maximized", ResX, ResY);
-
- const WCHAR* const Windows_Section = L"Window";
-
- IniSectionSetInt(Windows_Section, tchPosX, Settings.wi.x);
- IniSectionSetInt(Windows_Section, tchPosY, Settings.wi.y);
- IniSectionSetInt(Windows_Section, tchSizeX, Settings.wi.cx);
- IniSectionSetInt(Windows_Section, tchSizeY, Settings.wi.cy);
-
- SaveIniFile(g_wchIniFile);
}
//=============================================================================
diff --git a/minipath/src/Config.h b/minipath/src/Config.h
index 69083f3cd..a4c4a9aff 100644
--- a/minipath/src/Config.h
+++ b/minipath/src/Config.h
@@ -34,12 +34,11 @@ extern "C" {
int FindIniFile();
int TestIniFile();
int CreateIniFile();
- int CreateIniFileEx(LPCWSTR);
// ----------------------------------------------------------------------------
BOOL LoadIniFile(LPCWSTR lpIniFilePath);
- BOOL SaveIniFile(LPCWSTR lpIniFilePath);
+ BOOL SaveIniFile();
void ReleaseIniFile();
size_t IniSectionGetString(LPCWSTR lpSectionName, LPCWSTR lpKeyName, LPCWSTR lpDefault,
diff --git a/minipath/src/Dialogs.c b/minipath/src/Dialogs.c
index 4045705fc..c3d1477de 100644
--- a/minipath/src/Dialogs.c
+++ b/minipath/src/Dialogs.c
@@ -2687,87 +2687,92 @@ INT_PTR CALLBACK FindTargetDlgProc(HWND hwnd,UINT umsg,WPARAM wParam,LPARAM lPar
int i;
// input validation
- if ((IsDlgButtonChecked(hwnd,IDC_TARGET) && GetDlgItemText(hwnd,IDC_TARGETPATH,tch,COUNTOF(tch)) == 0) ||
- (IsDlgButtonChecked(hwnd,IDC_SENDDROPMSG) && StrIsEmpty(szTargetWndClass)) ||
- (IsDlgButtonChecked(hwnd,IDC_USEDDE) &&
- (GetDlgItemText(hwnd,IDC_DDEMSG,tch,COUNTOF(tch)) == 0 ||
- GetDlgItemText(hwnd,IDC_DDEAPP,tch,COUNTOF(tch)) == 0 ||
- GetDlgItemText(hwnd,IDC_DDETOPIC,tch,COUNTOF(tch)) == 0)))
+ if ((IsDlgButtonChecked(hwnd, IDC_TARGET) && GetDlgItemText(hwnd, IDC_TARGETPATH, tch, COUNTOF(tch)) == 0) ||
+ (IsDlgButtonChecked(hwnd, IDC_SENDDROPMSG) && StrIsEmpty(szTargetWndClass)) ||
+ (IsDlgButtonChecked(hwnd, IDC_USEDDE) &&
+ (GetDlgItemText(hwnd, IDC_DDEMSG, tch, COUNTOF(tch)) == 0 ||
+ GetDlgItemText(hwnd, IDC_DDEAPP, tch, COUNTOF(tch)) == 0 ||
+ GetDlgItemText(hwnd, IDC_DDETOPIC, tch, COUNTOF(tch)) == 0)))
- ErrorMessage(1,IDS_ERR_INVALIDTARGET);
+ ErrorMessage(1, IDS_ERR_INVALIDTARGET);
- else {
+ else {
+
+ __try {
LoadIniFile(g_wchIniFile);
+
const WCHAR* const TargetApp_Section = L"Target Application";
i = (BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_LAUNCH));
eUseTargetApplication = ((i) ? UTA_UNDEFINED : UTA_LAUNCH_TARGET);
- IniSectionSetInt(TargetApp_Section,L"UseTargetApplication",eUseTargetApplication);
+ IniSectionSetInt(TargetApp_Section, L"UseTargetApplication", eUseTargetApplication);
if (eUseTargetApplication != UTA_UNDEFINED) {
- GetDlgItemText(hwnd,IDC_TARGETPATH,tch,COUNTOF(tch));
- ExtractFirstArgument(tch,szTargetApplication,szTargetApplicationParams);
+ GetDlgItemText(hwnd, IDC_TARGETPATH, tch, COUNTOF(tch));
+ ExtractFirstArgument(tch, szTargetApplication, szTargetApplicationParams);
}
else {
- lstrcpy(szTargetApplication,L"");
- lstrcpy(szTargetApplicationParams,L"");
+ lstrcpy(szTargetApplication, L"");
+ lstrcpy(szTargetApplicationParams, L"");
}
- IniSectionSetString(TargetApp_Section,L"TargetApplicationPath",szTargetApplication);
- IniSectionSetString(TargetApp_Section,L"TargetApplicationParams",szTargetApplicationParams);
+ IniSectionSetString(TargetApp_Section, L"TargetApplicationPath", szTargetApplication);
+ IniSectionSetString(TargetApp_Section, L"TargetApplicationParams", szTargetApplicationParams);
if (eUseTargetApplication == UTA_UNDEFINED) {
eTargetApplicationMode = TAM_ALWAYS_RUN;
- IniSectionSetInt(TargetApp_Section,L"TargetApplicationMode",eTargetApplicationMode);
+ IniSectionSetInt(TargetApp_Section, L"TargetApplicationMode", eTargetApplicationMode);
}
else {
- if (BST_CHECKED == IsDlgButtonChecked(hwnd,IDC_ALWAYSRUN)) {
+ if (BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_ALWAYSRUN)) {
eTargetApplicationMode = TAM_ALWAYS_RUN;
- IniSectionSetInt(TargetApp_Section,L"TargetApplicationMode",eTargetApplicationMode);
+ IniSectionSetInt(TargetApp_Section, L"TargetApplicationMode", eTargetApplicationMode);
}
- else if (BST_CHECKED == IsDlgButtonChecked(hwnd,IDC_SENDDROPMSG)) {
+ else if (BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_SENDDROPMSG)) {
eTargetApplicationMode = TAM_SEND_DROP_MSG;
- IniSectionSetInt(TargetApp_Section,L"TargetApplicationMode",eTargetApplicationMode);
+ IniSectionSetInt(TargetApp_Section, L"TargetApplicationMode", eTargetApplicationMode);
}
else {
eTargetApplicationMode = TAM_SEND_DDE_MSG;
- IniSectionSetInt(TargetApp_Section,L"TargetApplicationMode",eTargetApplicationMode);
+ IniSectionSetInt(TargetApp_Section, L"TargetApplicationMode", eTargetApplicationMode);
}
}
- if (BST_CHECKED == IsDlgButtonChecked(hwnd,IDC_SENDDROPMSG) && !i) {
- lstrcpy(szTargetApplicationWndClass,szTargetWndClass);
- IniSectionSetString(TargetApp_Section,L"TargetApplicationWndClass",szTargetApplicationWndClass);
+ if (BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_SENDDROPMSG) && !i) {
+ lstrcpy(szTargetApplicationWndClass, szTargetWndClass);
+ IniSectionSetString(TargetApp_Section, L"TargetApplicationWndClass", szTargetApplicationWndClass);
}
else {
- lstrcpy(szTargetApplicationWndClass,L"");
- IniSectionSetString(TargetApp_Section,L"TargetApplicationWndClass",szTargetApplicationWndClass);
+ lstrcpy(szTargetApplicationWndClass, L"");
+ IniSectionSetString(TargetApp_Section, L"TargetApplicationWndClass", szTargetApplicationWndClass);
}
- i = (BST_CHECKED == IsDlgButtonChecked(hwnd,IDC_USEDDE));
+ i = (BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_USEDDE));
if (i)
- GetDlgItemText(hwnd,IDC_DDEMSG,szDDEMsg,COUNTOF(szDDEMsg));
+ GetDlgItemText(hwnd, IDC_DDEMSG, szDDEMsg, COUNTOF(szDDEMsg));
else
- lstrcpy(szDDEMsg,L"");
- IniSectionSetString(TargetApp_Section,L"DDEMessage",szDDEMsg);
+ lstrcpy(szDDEMsg, L"");
+ IniSectionSetString(TargetApp_Section, L"DDEMessage", szDDEMsg);
if (i)
- GetDlgItemText(hwnd,IDC_DDEAPP,szDDEApp,COUNTOF(szDDEApp));
+ GetDlgItemText(hwnd, IDC_DDEAPP, szDDEApp, COUNTOF(szDDEApp));
else
- lstrcpy(szDDEApp,L"");
- IniSectionSetString(TargetApp_Section,L"DDEApplication",szDDEApp);
+ lstrcpy(szDDEApp, L"");
+ IniSectionSetString(TargetApp_Section, L"DDEApplication", szDDEApp);
if (i)
- GetDlgItemText(hwnd,IDC_DDETOPIC,szDDETopic,COUNTOF(szDDETopic));
+ GetDlgItemText(hwnd, IDC_DDETOPIC, szDDETopic, COUNTOF(szDDETopic));
else
- lstrcpy(szDDETopic,L"");
- IniSectionSetString(TargetApp_Section,L"DDETopic",szDDETopic);
+ lstrcpy(szDDETopic, L"");
+ IniSectionSetString(TargetApp_Section, L"DDETopic", szDDETopic);
- SaveIniFile(g_wchIniFile);
-
- EndDialog(hwnd,IDOK);
}
+ __finally {
+ SaveIniFile();
+ }
+ EndDialog(hwnd, IDOK);
}
+ }
break;
diff --git a/minipath/src/Helpers.c b/minipath/src/Helpers.c
index cc741f51b..5d12bc37d 100644
--- a/minipath/src/Helpers.c
+++ b/minipath/src/Helpers.c
@@ -1529,28 +1529,33 @@ BOOL MRU_Load(LPMRULIST pmru) {
WCHAR tchItem[1024];
MRU_Empty(pmru);
- LoadIniFile(g_wchIniFile);
+ __try {
+ LoadIniFile(g_wchIniFile);
- const WCHAR* const RegKey_Section = pmru->szRegKey;
+ const WCHAR* const RegKey_Section = pmru->szRegKey;
- for (i = 0; i < pmru->iSize; i++) {
- StringCchPrintf(tchName, COUNTOF(tchName), L"%.2i", i + 1);
- if (IniSectionGetString(RegKey_Section, tchName, L"", tchItem, COUNTOF(tchItem))) {
- size_t const len = (size_t)lstrlen(tchItem);
- if ((len > 0) && (tchItem[0] == L'"') && (tchItem[len - 1] == L'"')) {
- MoveMemory(tchItem, (tchItem + 1), len * sizeof(WCHAR));
- tchItem[len - 2] = L'\0'; // clear dangling '"'
+ for (i = 0; i < pmru->iSize; i++) {
+ StringCchPrintf(tchName, COUNTOF(tchName), L"%.2i", i + 1);
+ if (IniSectionGetString(RegKey_Section, tchName, L"", tchItem, COUNTOF(tchItem))) {
+ size_t const len = (size_t)lstrlen(tchItem);
+ if ((len > 0) && (tchItem[0] == L'"') && (tchItem[len - 1] == L'"')) {
+ MoveMemory(tchItem, (tchItem + 1), len * sizeof(WCHAR));
+ tchItem[len - 2] = L'\0'; // clear dangling '"'
+ }
+ pmru->pszItems[n++] = StrDup(tchItem);
}
- pmru->pszItems[n++] = StrDup(tchItem);
}
}
- ReleaseIniFile();
+ __finally {
+ ReleaseIniFile();
+ }
return(1);
}
BOOL MRU_Save(LPMRULIST pmru) {
- if (LoadIniFile(g_wchIniFile)) {
+ __try {
+ LoadIniFile(g_wchIniFile);
WCHAR tchName[32];
WCHAR tchItem[1024] = { L'\0' };
@@ -1565,10 +1570,11 @@ BOOL MRU_Save(LPMRULIST pmru) {
IniSectionSetString(RegKey_Section, tchName, tchItem);
}
}
- SaveIniFile(g_wchIniFile);
- return TRUE;
}
- return FALSE;
+ __finally {
+ SaveIniFile(g_wchIniFile);
+ }
+ return TRUE;
}
void MRU_LoadToCombobox(HWND hwnd,LPCWSTR pszKey)
diff --git a/minipath/src/SimpleIni.h b/minipath/src/SimpleIni.h
deleted file mode 100644
index 20edafe9b..000000000
--- a/minipath/src/SimpleIni.h
+++ /dev/null
@@ -1,3726 +0,0 @@
-// encoding: UTF-8
-/** @mainpage
-
-
- | Library | SimpleIni
- |
|---|
| File | SimpleIni.h
- |
|---|
| Author | Brodie Thiesfield [code at jellycan dot com]
- |
|---|
| Source | https://github.com/brofield/simpleini
- |
|---|
| Version | 4.17
- |
|---|
-
- Jump to the @link CSimpleIniTempl CSimpleIni @endlink interface documentation.
-
- @section intro INTRODUCTION
-
- This component allows an INI-style configuration file to be used on both
- Windows and Linux/Unix. It is fast, simple and source code using this
- component will compile unchanged on either OS.
-
-
- @section features FEATURES
-
- - MIT Licence allows free use in all software (including GPL and commercial)
- - multi-platform (Windows CE/9x/NT..10/etc, Linux, MacOSX, Unix)
- - loading and saving of INI-style configuration files
- - configuration files can have any newline format on all platforms
- - liberal acceptance of file format
- - key/values with no section
- - removal of whitespace around sections, keys and values
- - support for multi-line values (values with embedded newline characters)
- - optional support for multiple keys with the same name
- - optional case-insensitive sections and keys (for ASCII characters only)
- - saves files with sections and keys in the same order as they were loaded
- - preserves comments on the file, section and keys where possible.
- - supports both char or wchar_t programming interfaces
- - supports both MBCS (system locale) and UTF-8 file encodings
- - system locale does not need to be UTF-8 on Linux/Unix to load UTF-8 file
- - support for non-ASCII characters in section, keys, values and comments
- - support for non-standard character types or file encodings
- via user-written converter classes
- - support for adding/modifying values programmatically
- - compiles cleanly in the following compilers:
- - Windows/VC6 (warning level 3)
- - Windows/VC.NET 2003 (warning level 4)
- - Windows/VC 2005 (warning level 4)
- - Linux/gcc (-Wall)
-
-
- @section usage USAGE SUMMARY
-
- -# Define the appropriate symbol for the converter you wish to use and
- include the SimpleIni.h header file. If no specific converter is defined
- then the default converter is used. The default conversion mode uses
- SI_CONVERT_WIN32 on Windows and SI_CONVERT_GENERIC on all other
- platforms. If you are using ICU then SI_CONVERT_ICU is supported on all
- platforms.
- -# Declare an instance the appropriate class. Note that the following
- definitions are just shortcuts for commonly used types. Other types
- (PRUnichar, unsigned short, unsigned char) are also possible.
-
- | Interface | Case-sensitive | Load UTF-8 | Load MBCS | Typedef
- |
|---|
| SI_CONVERT_GENERIC
- |
|---|
| char | No | Yes | Yes #1 | CSimpleIniA
- |
| char | Yes | Yes | Yes | CSimpleIniCaseA
- |
| wchar_t | No | Yes | Yes | CSimpleIniW
- |
| wchar_t | Yes | Yes | Yes | CSimpleIniCaseW
- |
| SI_CONVERT_WIN32
- |
|---|
| char | No | No #2 | Yes | CSimpleIniA
- |
| char | Yes | Yes | Yes | CSimpleIniCaseA
- |
| wchar_t | No | Yes | Yes | CSimpleIniW
- |
| wchar_t | Yes | Yes | Yes | CSimpleIniCaseW
- |
| SI_CONVERT_ICU
- |
|---|
| char | No | Yes | Yes | CSimpleIniA
- |
| char | Yes | Yes | Yes | CSimpleIniCaseA
- |
| UChar | No | Yes | Yes | CSimpleIniW
- |
| UChar | Yes | Yes | Yes | CSimpleIniCaseW
- |
- #1 On Windows you are better to use CSimpleIniA with SI_CONVERT_WIN32.
- #2 Only affects Windows. On Windows this uses MBCS functions and
- so may fold case incorrectly leading to uncertain results.
- -# Call LoadData() or LoadFile() to load and parse the INI configuration file
- -# Access and modify the data of the file using the following functions
-
- | GetAllSections | Return all section names
- |
| GetAllKeys | Return all key names within a section
- |
| GetAllValues | Return all values within a section & key
- |
| GetSection | Return all key names and values in a section
- |
| GetSectionSize | Return the number of keys in a section
- |
| GetValue | Return a value for a section & key
- |
| SetValue | Add or update a value for a section & key
- |
| Delete | Remove a section, or a key from a section
- |
- -# Call Save() or SaveFile() to save the INI configuration data
-
- @section iostreams IO STREAMS
-
- SimpleIni supports reading from and writing to STL IO streams. Enable this
- by defining SI_SUPPORT_IOSTREAMS before including the SimpleIni.h header
- file. Ensure that if the streams are backed by a file (e.g. ifstream or
- ofstream) then the flag ios_base::binary has been used when the file was
- opened.
-
- @section multiline MULTI-LINE VALUES
-
- Values that span multiple lines are created using the following format.
-
-
- key = <<
-
- Note the following:
- - The text used for ENDTAG can be anything and is used to find
- where the multi-line text ends.
- - The newline after ENDTAG in the start tag, and the newline
- before ENDTAG in the end tag is not included in the data value.
- - The ending tag must be on it's own line with no whitespace before
- or after it.
- - The multi-line value is modified at load so that each line in the value
- is delimited by a single '\\n' character on all platforms. At save time
- it will be converted into the newline format used by the current
- platform.
-
- @section comments COMMENTS
-
- Comments are preserved in the file within the following restrictions:
- - Every file may have a single "file comment". It must start with the
- first character in the file, and will end with the first non-comment
- line in the file.
- - Every section may have a single "section comment". It will start
- with the first comment line following the file comment, or the last
- data entry. It ends at the beginning of the section.
- - Every key may have a single "key comment". This comment will start
- with the first comment line following the section start, or the file
- comment if there is no section name.
- - Comments are set at the time that the file, section or key is first
- created. The only way to modify a comment on a section or a key is to
- delete that entry and recreate it with the new comment. There is no
- way to change the file comment.
-
- @section save SAVE ORDER
-
- The sections and keys are written out in the same order as they were
- read in from the file. Sections and keys added to the data after the
- file has been loaded will be added to the end of the file when it is
- written. There is no way to specify the location of a section or key
- other than in first-created, first-saved order.
-
- @section notes NOTES
-
- - To load UTF-8 data on Windows 95, you need to use Microsoft Layer for
- Unicode, or SI_CONVERT_GENERIC, or SI_CONVERT_ICU.
- - When using SI_CONVERT_GENERIC, ConvertUTF.c must be compiled and linked.
- - When using SI_CONVERT_ICU, ICU header files must be on the include
- path and icuuc.lib must be linked in.
- - To load a UTF-8 file on Windows AND expose it with SI_CHAR == char,
- you should use SI_CONVERT_GENERIC.
- - The collation (sorting) order used for sections and keys returned from
- iterators is NOT DEFINED. If collation order of the text is important
- then it should be done yourself by either supplying a replacement
- SI_STRLESS class, or by sorting the strings external to this library.
- - Usage of the header on Windows can be disabled by defining
- SI_NO_MBCS. This is defined automatically on Windows CE platforms.
- - Not thread-safe so manage your own locking
-
- @section contrib CONTRIBUTIONS
-
- - 2010/05/03: Tobias Gehrig: added GetDoubleValue()
-
- @section licence MIT LICENCE
-
- The licence text below is the boilerplate "MIT Licence" used from:
- http://www.opensource.org/licenses/mit-license.php
-
- Copyright (c) 2006-2012, Brodie Thiesfield
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is furnished
- to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef INCLUDED_SimpleIni_h
-#define INCLUDED_SimpleIni_h
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-// Disable these warnings in MSVC:
-// 4127 "conditional expression is constant" as the conversion classes trigger
-// it with the statement if (sizeof(SI_CHAR) == sizeof(char)). This test will
-// be optimized away in a release build.
-// 4503 'insert' : decorated name length exceeded, name was truncated
-// 4702 "unreachable code" as the MS STL header causes it in release mode.
-// Again, the code causing the warning will be cleaned up by the compiler.
-// 4786 "identifier truncated to 256 characters" as this is thrown hundreds
-// of times VC6 as soon as STL is used.
-#ifdef _MSC_VER
-# pragma warning (push)
-# pragma warning (disable: 4127 4503 4702 4786)
-#endif
-
-
-// Defines the conversion classes for different libraries. Before including
-// SimpleIni.h, set the converter that you wish you use by defining one of the
-// following symbols.
-//
-// SI_CONVERT_GENERIC Use the Unicode reference conversion library in
-// the accompanying files ConvertUTF.h/c
-// SI_CONVERT_ICU Use the IBM ICU conversion library. Requires
-// ICU headers on include path and icuuc.lib
-// SI_CONVERT_WIN32 Use the Win32 API functions for conversion.
-
-#if !defined(SI_CONVERT_GENERIC) && !defined(SI_CONVERT_WIN32) && !defined(SI_CONVERT_ICU)
-# ifdef _WIN32
-# define SI_CONVERT_WIN32
-# else
-# define SI_CONVERT_GENERIC
-# endif
-#endif
-
-#ifdef SI_CONVERT_WIN32
-#define VC_EXTRALEAN 1
-#define WIN32_LEAN_AND_MEAN 1
-#include
-#endif
-
-#include // for wcscpy_s, wcscat_s
-#include // for _countof
-#include
-#include