From acb8a9db474f93d6eacdbee9eb287efe29970460 Mon Sep 17 00:00:00 2001 From: Don Ho Date: Thu, 2 Dec 2021 03:55:24 +0100 Subject: [PATCH] Add logs for nul content corruption issue These logs are written for debugging NUL file-corruption issue (#6133) and session lost issue (#10402) which are still problematic probably. The writting log info will be triggered only when Windows notifies Notepad++ to end session. The log file will be in "%APPDATA%\Notepad++\" or in Notepad++ installation folder if doLocalConf.xml is present. To disable the log, just remove nppLogNulContentCorruptionIssue.xml. Close #10871 --- .../bin/nppLogNulContentCorruptionIssue.xml | 0 .../nsisInclude/mainSectionFuncs.nsh | 2 + .../installer/nsisInclude/uninstall.nsh | 1 + PowerEditor/installer/packageAll.bat | 12 ++ PowerEditor/src/MISC/Common/Common.cpp | 15 +-- PowerEditor/src/MISC/Common/Common.h | 2 +- PowerEditor/src/MISC/Common/FileInterface.cpp | 93 +++++++++++---- PowerEditor/src/MISC/Common/FileInterface.h | 3 +- .../MISC/PluginsManager/PluginsManager.cpp | 12 +- PowerEditor/src/Notepad_plus.cpp | 8 +- PowerEditor/src/Notepad_plus_Window.cpp | 8 +- PowerEditor/src/NppBigSwitch.cpp | 36 ++++++ PowerEditor/src/NppCommands.cpp | 4 +- PowerEditor/src/Parameters.cpp | 106 ++++++++++-------- PowerEditor/src/Parameters.h | 8 ++ PowerEditor/src/ScintillaComponent/Buffer.cpp | 33 ++++-- .../FunctionList/functionListPanel.cpp | 6 +- .../WinControls/PluginsAdmin/pluginsAdmin.cpp | 8 +- 18 files changed, 244 insertions(+), 113 deletions(-) create mode 100644 PowerEditor/bin/nppLogNulContentCorruptionIssue.xml diff --git a/PowerEditor/bin/nppLogNulContentCorruptionIssue.xml b/PowerEditor/bin/nppLogNulContentCorruptionIssue.xml new file mode 100644 index 000000000..e69de29bb diff --git a/PowerEditor/installer/nsisInclude/mainSectionFuncs.nsh b/PowerEditor/installer/nsisInclude/mainSectionFuncs.nsh index 7a0450134..65860e764 100644 --- a/PowerEditor/installer/nsisInclude/mainSectionFuncs.nsh +++ b/PowerEditor/installer/nsisInclude/mainSectionFuncs.nsh @@ -84,6 +84,8 @@ Function copyCommonFiles SetOverwrite off File "..\bin\shortcuts.xml" + ; For debug logs + File "..\bin\nppLogNulContentCorruptionIssue.xml" ; Set Section Files and Shortcuts diff --git a/PowerEditor/installer/nsisInclude/uninstall.nsh b/PowerEditor/installer/nsisInclude/uninstall.nsh index 00e91f16a..cd4b83c77 100644 --- a/PowerEditor/installer/nsisInclude/uninstall.nsh +++ b/PowerEditor/installer/nsisInclude/uninstall.nsh @@ -228,6 +228,7 @@ Section Uninstall Delete "$INSTDIR\session.xml" Delete "$INSTDIR\nativeLang.xml" Delete "$INSTDIR\userDefineLang.xml" + Delete "$INSTDIR\nppLogNulContentCorruptionIssue.xml" ${endIf} Delete "$INSTDIR\config.model.xml" diff --git a/PowerEditor/installer/packageAll.bat b/PowerEditor/installer/packageAll.bat index e6fd29a12..b17fa504b 100644 --- a/PowerEditor/installer/packageAll.bat +++ b/PowerEditor/installer/packageAll.bat @@ -105,6 +105,8 @@ copy /Y ..\src\shortcuts.xml .\minimalist\ If ErrorLevel 1 goto End copy /Y ..\bin\doLocalConf.xml .\minimalist\ If ErrorLevel 1 goto End +copy /Y ..\bin\nppLogNulContentCorruptionIssue.xml .\minimalist\ +If ErrorLevel 1 goto End copy /Y ..\bin\"notepad++.exe" .\minimalist\ If ErrorLevel 1 goto End copy /Y ".\themes\DarkModeDefault.xml" .\minimalist\themes\ @@ -134,6 +136,8 @@ copy /Y ..\src\shortcuts.xml .\minimalist64\ If ErrorLevel 1 goto End copy /Y ..\bin\doLocalConf.xml .\minimalist64\ If ErrorLevel 1 goto End +copy /Y ..\bin\nppLogNulContentCorruptionIssue.xml .\minimalist64\ +If ErrorLevel 1 goto End copy /Y ..\bin64\"notepad++.exe" .\minimalist64\ If ErrorLevel 1 goto End copy /Y ".\themes\DarkModeDefault.xml" .\minimalist64\themes\ @@ -163,6 +167,8 @@ copy /Y ..\src\shortcuts.xml .\minimalistArm64\ If ErrorLevel 1 goto End copy /Y ..\bin\doLocalConf.xml .\minimalistArm64\ If ErrorLevel 1 goto End +copy /Y ..\bin\nppLogNulContentCorruptionIssue.xml .\minimalistArm64\ +If ErrorLevel 1 goto End copy /Y ..\binarm64\"notepad++.exe" .\minimalistArm64\ If ErrorLevel 1 goto End copy /Y ".\themes\DarkModeDefault.xml" .\minimalistArm64\themes\ @@ -243,6 +249,8 @@ copy /Y ..\src\shortcuts.xml .\zipped.package.release\ If ErrorLevel 1 goto End copy /Y ..\bin\doLocalConf.xml .\zipped.package.release\ If ErrorLevel 1 goto End +copy /Y ..\bin\nppLogNulContentCorruptionIssue.xml .\zipped.package.release\ +If ErrorLevel 1 goto End copy /Y ..\bin\"notepad++.exe" .\zipped.package.release\ If ErrorLevel 1 goto End @@ -264,6 +272,8 @@ copy /Y ..\src\shortcuts.xml .\zipped.package.release64\ If ErrorLevel 1 goto End copy /Y ..\bin\doLocalConf.xml .\zipped.package.release64\ If ErrorLevel 1 goto End +copy /Y ..\bin\nppLogNulContentCorruptionIssue.xml .\zipped.package.release64\ +If ErrorLevel 1 goto End copy /Y ..\bin64\"notepad++.exe" .\zipped.package.release64\ If ErrorLevel 1 goto End @@ -285,6 +295,8 @@ copy /Y ..\src\shortcuts.xml .\zipped.package.releaseArm64\ If ErrorLevel 1 goto End copy /Y ..\bin\doLocalConf.xml .\zipped.package.releaseArm64\ If ErrorLevel 1 goto End +copy /Y ..\bin\nppLogNulContentCorruptionIssue.xml .\zipped.package.releaseArm64\ +If ErrorLevel 1 goto End copy /Y ..\binarm64\"notepad++.exe" .\zipped.package.releaseArm64\ If ErrorLevel 1 goto End diff --git a/PowerEditor/src/MISC/Common/Common.cpp b/PowerEditor/src/MISC/Common/Common.cpp index dcb728eaf..2c0e771ef 100644 --- a/PowerEditor/src/MISC/Common/Common.cpp +++ b/PowerEditor/src/MISC/Common/Common.cpp @@ -20,7 +20,6 @@ #include #include #include - #include "StaticDialog.h" #include "CustomFileDialog.h" @@ -139,13 +138,16 @@ void writeLog(const TCHAR *logFileName, const char *log2write) SYSTEMTIME currentTime = { 0 }; ::GetLocalTime(¤tTime); generic_string dateTimeStrW = getDateTimeStrFrom(TEXT("yyyy-MM-dd HH:mm:ss"), currentTime); - std::string log2writeStr(dateTimeStrW.begin(), dateTimeStrW.end()); + std::wstring_convert> converter; + std::string log2writeStr = converter.to_bytes(dateTimeStrW); log2writeStr += " "; log2writeStr += log2write; log2writeStr += "\n"; DWORD bytes_written = 0; ::WriteFile(hFile, log2writeStr.c_str(), static_cast(log2writeStr.length()), &bytes_written, NULL); + + ::FlushFileBuffers(hFile); } } @@ -537,7 +539,6 @@ generic_string intToString(int val) return generic_string(vt.rbegin(), vt.rend()); } - generic_string uintToString(unsigned int val) { std::vector vt; @@ -628,7 +629,7 @@ generic_string PathRemoveFileSpec(generic_string& path) } -generic_string PathAppend(generic_string& strDest, const generic_string& str2append) +generic_string pathAppend(generic_string& strDest, const generic_string& str2append) { if (strDest.empty() && str2append.empty()) // "" + "" { @@ -1283,7 +1284,7 @@ bool deleteFileOrFolder(const generic_string& f2delete) void getFilesInFolder(std::vector& files, const generic_string& extTypeFilter, const generic_string& inFolder) { generic_string filter = inFolder; - PathAppend(filter, extTypeFilter); + pathAppend(filter, extTypeFilter); WIN32_FIND_DATA foundData; HANDLE hFindFile = ::FindFirstFile(filter.c_str(), &foundData); @@ -1291,13 +1292,13 @@ void getFilesInFolder(std::vector& files, const generic_string& if (hFindFile != INVALID_HANDLE_VALUE && !(foundData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { generic_string foundFullPath = inFolder; - PathAppend(foundFullPath, foundData.cFileName); + pathAppend(foundFullPath, foundData.cFileName); files.push_back(foundFullPath); while (::FindNextFile(hFindFile, &foundData)) { generic_string foundFullPath2 = inFolder; - PathAppend(foundFullPath2, foundData.cFileName); + pathAppend(foundFullPath2, foundData.cFileName); files.push_back(foundFullPath2); } } diff --git a/PowerEditor/src/MISC/Common/Common.h b/PowerEditor/src/MISC/Common/Common.h index f1c30c732..29d947f83 100644 --- a/PowerEditor/src/MISC/Common/Common.h +++ b/PowerEditor/src/MISC/Common/Common.h @@ -165,7 +165,7 @@ protected: #define REBARBAND_SIZE sizeof(REBARBANDINFO) generic_string PathRemoveFileSpec(generic_string & path); -generic_string PathAppend(generic_string &strDest, const generic_string & str2append); +generic_string pathAppend(generic_string &strDest, const generic_string & str2append); COLORREF getCtrlBgColor(HWND hWnd); generic_string stringToUpper(generic_string strToConvert); generic_string stringToLower(generic_string strToConvert); diff --git a/PowerEditor/src/MISC/Common/FileInterface.cpp b/PowerEditor/src/MISC/Common/FileInterface.cpp index d2ba07b1e..44dec3ac4 100644 --- a/PowerEditor/src/MISC/Common/FileInterface.cpp +++ b/PowerEditor/src/MISC/Common/FileInterface.cpp @@ -14,11 +14,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . - +#include +#include #include "FileInterface.h" #include "Parameters.h" - Win32_IO_File::Win32_IO_File(const char *fname) { if (fname) @@ -33,40 +33,51 @@ Win32_IO_File::Win32_IO_File(const wchar_t *fname) { if (fname) { - generic_string fn = fname; - _path = std::string(fn.begin(), fn.end()); + std::wstring fn = fname; + std::wstring_convert> converter; + _path = converter.to_bytes(fn); _hFile = ::CreateFileW(fname, _accessParam, _shareParam, NULL, _dispParam, _attribParam, NULL); + + NppParameters& nppParam = NppParameters::getInstance(); + if (nppParam.isQueryEndSessionStarted() && nppParam.doNppLogNulContentCorruptionIssue()) + { + generic_string issueFn = nppLogNulContentCorruptionIssue; + issueFn += TEXT(".log"); + generic_string nppIssueLog = nppParam.getUserPath(); + pathAppend(nppIssueLog, issueFn); + + std::string msg = _path; + msg += " is opened."; + writeLog(nppIssueLog.c_str(), msg.c_str()); + } } } - void Win32_IO_File::close() { if (isOpened()) { if (_written) { - BOOL isOK = ::FlushFileBuffers(_hFile); - if (!isOK) - { - if (NppParameters::getInstance().doNppLogNetworkDriveIssue()) - { - generic_string nppLogNetworkDriveIssueLog = TEXT("c:\\temp\\"); - nppLogNetworkDriveIssueLog += nppLogNetworkDriveIssue; - nppLogNetworkDriveIssueLog += TEXT(".log"); - - std::string msg = _path; - msg += " FlushFileBuffers call failed: "; - generic_string lastErrorMsg = GetLastErrorAsString(::GetLastError()); - msg += std::string(lastErrorMsg.begin(), lastErrorMsg.end()); - writeLog(nppLogNetworkDriveIssueLog.c_str(), msg.c_str()); - } - } + ::FlushFileBuffers(_hFile); } - ::CloseHandle(_hFile); _hFile = INVALID_HANDLE_VALUE; + + + NppParameters& nppParam = NppParameters::getInstance(); + if (nppParam.isQueryEndSessionStarted() && nppParam.doNppLogNulContentCorruptionIssue()) + { + generic_string issueFn = nppLogNulContentCorruptionIssue; + issueFn += TEXT(".log"); + generic_string nppIssueLog = nppParam.getUserPath(); + pathAppend(nppIssueLog, issueFn); + + std::string msg = _path; + msg += " is closed."; + writeLog(nppIssueLog.c_str(), msg.c_str()); + } } } @@ -81,7 +92,6 @@ int_fast64_t Win32_IO_File::getSize() return static_cast(r.QuadPart); } -*/ unsigned long Win32_IO_File::read(void *rbuf, unsigned long buf_size) { @@ -95,6 +105,7 @@ unsigned long Win32_IO_File::read(void *rbuf, unsigned long buf_size) return bytes_read; } +*/ bool Win32_IO_File::write(const void *wbuf, unsigned long buf_size) { @@ -103,8 +114,44 @@ bool Win32_IO_File::write(const void *wbuf, unsigned long buf_size) DWORD bytes_written = 0; + NppParameters& nppParam = NppParameters::getInstance(); if (::WriteFile(_hFile, wbuf, buf_size, &bytes_written, NULL) == FALSE) + { + if (nppParam.isQueryEndSessionStarted() && nppParam.doNppLogNulContentCorruptionIssue()) + { + generic_string issueFn = nppLogNulContentCorruptionIssue; + issueFn += TEXT(".log"); + generic_string nppIssueLog = nppParam.getUserPath(); + pathAppend(nppIssueLog, issueFn); + + std::string msg = _path; + msg += " written failed: "; + std::wstring lastErrorMsg = GetLastErrorAsString(::GetLastError()); + std::wstring_convert> converter; + msg += converter.to_bytes(lastErrorMsg); + writeLog(nppIssueLog.c_str(), msg.c_str()); + } + return false; + } + else + { + if (nppParam.isQueryEndSessionStarted() && nppParam.doNppLogNulContentCorruptionIssue()) + { + generic_string issueFn = nppLogNulContentCorruptionIssue; + issueFn += TEXT(".log"); + generic_string nppIssueLog = nppParam.getUserPath(); + pathAppend(nppIssueLog, issueFn); + + std::string msg = _path; + msg += " "; + msg += std::to_string(bytes_written); + msg += "/"; + msg += std::to_string(buf_size); + msg += " bytes are written."; + writeLog(nppIssueLog.c_str(), msg.c_str()); + } + } if (!_written) _written = true; diff --git a/PowerEditor/src/MISC/Common/FileInterface.h b/PowerEditor/src/MISC/Common/FileInterface.h index 3ca649b9d..7d3965de6 100644 --- a/PowerEditor/src/MISC/Common/FileInterface.h +++ b/PowerEditor/src/MISC/Common/FileInterface.h @@ -43,7 +43,8 @@ public: void close(); //int_fast64_t getSize(); - unsigned long read(void *rbuf, unsigned long buf_size); + //unsigned long read(void *rbuf, unsigned long buf_size); + bool write(const void *wbuf, unsigned long buf_size); bool writeStr(const std::string& str) { diff --git a/PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp b/PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp index 0041b70cd..8cc61b497 100644 --- a/PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp +++ b/PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp @@ -308,10 +308,10 @@ bool PluginsManager::loadPluginsV2(const TCHAR* dir) else { pluginsFolder = nppPath; - PathAppend(pluginsFolder, TEXT("plugins")); + pathAppend(pluginsFolder, TEXT("plugins")); } generic_string pluginsFolderFilter = pluginsFolder; - PathAppend(pluginsFolderFilter, TEXT("*.*")); + pathAppend(pluginsFolderFilter, TEXT("*.*")); WIN32_FIND_DATA foundData; HANDLE hFindFolder = ::FindFirstFile(pluginsFolderFilter.c_str(), &foundData); @@ -324,10 +324,10 @@ bool PluginsManager::loadPluginsV2(const TCHAR* dir) if (foundFileName != TEXT(".") && foundFileName != TEXT("..") && generic_stricmp(foundFileName.c_str(), TEXT("Config")) != 0) { generic_string pluginsFullPathFilter = pluginsFolder; - PathAppend(pluginsFullPathFilter, foundFileName); + pathAppend(pluginsFullPathFilter, foundFileName); generic_string dllName = foundFileName; dllName += TEXT(".dll"); - PathAppend(pluginsFullPathFilter, dllName); + pathAppend(pluginsFullPathFilter, dllName); // get plugin hFindDll = ::FindFirstFile(pluginsFullPathFilter.c_str(), &foundData); @@ -346,11 +346,11 @@ bool PluginsManager::loadPluginsV2(const TCHAR* dir) if (foundFileName2 != TEXT(".") && foundFileName2 != TEXT("..") && generic_stricmp(foundFileName2.c_str(), TEXT("Config")) != 0) { generic_string pluginsFullPathFilter2 = pluginsFolder; - PathAppend(pluginsFullPathFilter2, foundFileName2); + pathAppend(pluginsFullPathFilter2, foundFileName2); generic_string pluginsFolderPath2 = pluginsFullPathFilter2; generic_string dllName2 = foundFileName2; dllName2 += TEXT(".dll"); - PathAppend(pluginsFullPathFilter2, dllName2); + pathAppend(pluginsFullPathFilter2, dllName2); // get plugin if (hFindDll) diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index b60881d3b..c2914132a 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -6240,7 +6240,7 @@ vector Notepad_plus::addNppComponents(const TCHAR *destDir, cons { // Get plugins dir generic_string destDirName = (NppParameters::getInstance()).getNppPath(); - PathAppend(destDirName, destDir); + pathAppend(destDirName, destDir); if (!::PathFileExists(destDirName.c_str())) { @@ -6297,12 +6297,12 @@ vector Notepad_plus::addNppPlugins(const TCHAR *extFilterName, c continue; generic_string name = nameExt.substr(0, pos); - PathAppend(destName, name); + pathAppend(destName, name); if (!::PathFileExists(destName.c_str())) { ::CreateDirectory(destName.c_str(), NULL); } - PathAppend(destName, nameExt); + pathAppend(destName, nameExt); if (::CopyFile(fns.at(i).c_str(), destName.c_str(), FALSE)) copiedFiles.push_back(destName.c_str()); @@ -7752,7 +7752,7 @@ void Notepad_plus::refreshDarkMode(bool resetStyle) if (NppDarkMode::isEnabled()) { themePath = themeSwitcher.getThemeDirPath(); - PathAppend(themePath, darkModeXmlFileName); + pathAppend(themePath, darkModeXmlFileName); themeName = themeSwitcher.getThemeFromXmlFileName(themePath.c_str()); } diff --git a/PowerEditor/src/Notepad_plus_Window.cpp b/PowerEditor/src/Notepad_plus_Window.cpp index a2c3f3405..f033e58f1 100644 --- a/PowerEditor/src/Notepad_plus_Window.cpp +++ b/PowerEditor/src/Notepad_plus_Window.cpp @@ -203,7 +203,7 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin LocalizationSwitcher & localizationSwitcher = nppParams.getLocalizationSwitcher(); std::wstring localizationDir = nppDir; - PathAppend(localizationDir, TEXT("localization\\")); + pathAppend(localizationDir, TEXT("localization\\")); _notepad_plus_plus_core.getMatchedFileNames(localizationDir.c_str(), patterns, fileNames, false, false); for (size_t i = 0, len = fileNames.size(); i < len; ++i) @@ -219,7 +219,7 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin if (nppParams.getAppDataNppDir() && nppParams.getAppDataNppDir()[0]) { appDataThemeDir = nppParams.getAppDataNppDir(); - PathAppend(appDataThemeDir, TEXT("themes\\")); + pathAppend(appDataThemeDir, TEXT("themes\\")); _notepad_plus_plus_core.getMatchedFileNames(appDataThemeDir.c_str(), patterns, fileNames, false, false); for (size_t i = 0, len = fileNames.size() ; i < len ; ++i) { @@ -231,7 +231,7 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin generic_string nppThemeDir; nppThemeDir = nppDir.c_str(); // <- should use the pointer to avoid the constructor of copy - PathAppend(nppThemeDir, TEXT("themes\\")); + pathAppend(nppThemeDir, TEXT("themes\\")); // Set theme directory to their installation directory themeSwitcher.setThemeDirPath(nppThemeDir); @@ -254,7 +254,7 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin } TCHAR* fn = PathFindFileName(fileNames[i].c_str()); - PathAppend(appDataThemePath, fn); + pathAppend(appDataThemePath, fn); themeSwitcher.addThemeStylerSavePath(fileNames[i], appDataThemePath); } } diff --git a/PowerEditor/src/NppBigSwitch.cpp b/PowerEditor/src/NppBigSwitch.cpp index 9696a5432..c9f1be637 100644 --- a/PowerEditor/src/NppBigSwitch.cpp +++ b/PowerEditor/src/NppBigSwitch.cpp @@ -1915,6 +1915,22 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa case WM_QUERYENDSESSION: case WM_CLOSE: { + NppParameters& nppParam = NppParameters::getInstance(); + if (message == WM_QUERYENDSESSION) + { + nppParam.queryEndSessionStart(); + } + + if (nppParam.isQueryEndSessionStarted() && nppParam.doNppLogNulContentCorruptionIssue()) + { + generic_string issueFn = nppLogNulContentCorruptionIssue; + issueFn += TEXT(".log"); + generic_string nppIssueLog = nppParam.getUserPath(); + pathAppend(nppIssueLog, issueFn); + + writeLog(nppIssueLog.c_str(), "WM_QUERYENDSESSION ====================================="); + } + if (_pPublicInterface->isPrelaunch()) { SendMessage(hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0); @@ -2046,6 +2062,16 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa case WM_ENDSESSION: { + if (NppParameters::getInstance().doNppLogNulContentCorruptionIssue()) + { + generic_string issueFn = nppLogNulContentCorruptionIssue; + issueFn += TEXT(".log"); + generic_string nppIssueLog = nppParam.getUserPath(); + pathAppend(nppIssueLog, issueFn); + + writeLog(nppIssueLog.c_str(), "WM_ENDSESSION"); + } + if (wParam == TRUE) { ::DestroyWindow(hwnd); @@ -2059,6 +2085,16 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa case WM_DESTROY: { + if (NppParameters::getInstance().doNppLogNulContentCorruptionIssue()) + { + generic_string issueFn = nppLogNulContentCorruptionIssue; + issueFn += TEXT(".log"); + generic_string nppIssueLog = nppParam.getUserPath(); + pathAppend(nppIssueLog, issueFn); + + writeLog(nppIssueLog.c_str(), "WM_DESTROY"); + } + killAllChildren(); ::PostQuitMessage(0); _pPublicInterface->gNppHWND = NULL; diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp index 5b7e66901..b97bda446 100644 --- a/PowerEditor/src/NppCommands.cpp +++ b/PowerEditor/src/NppCommands.cpp @@ -3230,10 +3230,10 @@ void Notepad_plus::command(int id) else { generic_string updaterDir = (NppParameters::getInstance()).getNppPath(); - PathAppend(updaterDir, TEXT("updater")); + pathAppend(updaterDir, TEXT("updater")); generic_string updaterFullPath = updaterDir; - PathAppend(updaterFullPath, TEXT("gup.exe")); + pathAppend(updaterFullPath, TEXT("gup.exe")); #ifdef DEBUG // if not debug, then it's release diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index 027b90c0d..703660fda 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -873,7 +873,7 @@ NppParameters::NppParameters() _appdataNppDir.clear(); generic_string notepadStylePath(_nppPath); - PathAppend(notepadStylePath, notepadStyleFile); + pathAppend(notepadStylePath, notepadStyleFile); _asNotepadStyle = (PathFileExists(notepadStylePath.c_str()) == TRUE); @@ -951,7 +951,7 @@ bool NppParameters::reloadLang() if (!PathFileExists(nativeLangPath.c_str())) { nativeLangPath = _nppPath; - PathAppend(nativeLangPath, generic_string(TEXT("nativeLang.xml"))); + pathAppend(nativeLangPath, generic_string(TEXT("nativeLang.xml"))); if (!PathFileExists(nativeLangPath.c_str())) return false; } @@ -994,7 +994,7 @@ generic_string NppParameters::getSettingsFolder() if (settingsFolderPath.empty()) return _nppPath; - PathAppend(settingsFolderPath, TEXT("Notepad++")); + pathAppend(settingsFolderPath, TEXT("Notepad++")); return settingsFolderPath; } @@ -1008,7 +1008,7 @@ bool NppParameters::load() // Make localConf.xml path generic_string localConfPath(_nppPath); - PathAppend(localConfPath, localConfFile); + pathAppend(localConfPath, localConfFile); // Test if localConf.xml exist _isLocal = (PathFileExists(localConfPath.c_str()) == TRUE); @@ -1031,7 +1031,7 @@ bool NppParameters::load() } _pluginRootDir = _nppPath; - PathAppend(_pluginRootDir, TEXT("plugins")); + pathAppend(_pluginRootDir, TEXT("plugins")); // // the 3rd priority: general default configuration @@ -1041,21 +1041,21 @@ bool NppParameters::load() { _userPath = nppPluginRootParent = _nppPath; _userPluginConfDir = _pluginRootDir; - PathAppend(_userPluginConfDir, TEXT("Config")); + pathAppend(_userPluginConfDir, TEXT("Config")); } else { _userPath = getSpecialFolderLocation(CSIDL_APPDATA); - PathAppend(_userPath, TEXT("Notepad++")); + pathAppend(_userPath, TEXT("Notepad++")); if (!PathFileExists(_userPath.c_str())) ::CreateDirectory(_userPath.c_str(), NULL); _appdataNppDir = _userPluginConfDir = _userPath; - PathAppend(_userPluginConfDir, TEXT("plugins")); + pathAppend(_userPluginConfDir, TEXT("plugins")); if (!PathFileExists(_userPluginConfDir.c_str())) ::CreateDirectory(_userPluginConfDir.c_str(), NULL); - PathAppend(_userPluginConfDir, TEXT("Config")); + pathAppend(_userPluginConfDir, TEXT("Config")); if (!PathFileExists(_userPluginConfDir.c_str())) ::CreateDirectory(_userPluginConfDir.c_str(), NULL); @@ -1064,7 +1064,7 @@ bool NppParameters::load() } _pluginConfDir = _pluginRootDir; // for plugin list home - PathAppend(_pluginConfDir, TEXT("Config")); + pathAppend(_pluginConfDir, TEXT("Config")); if (!PathFileExists(nppPluginRootParent.c_str())) ::CreateDirectory(nppPluginRootParent.c_str(), NULL); @@ -1134,7 +1134,7 @@ bool NppParameters::load() // langs.xml : for per user // //--------------------------// generic_string langs_xml_path(_userPath); - PathAppend(langs_xml_path, TEXT("langs.xml")); + pathAppend(langs_xml_path, TEXT("langs.xml")); BOOL doRecover = FALSE; if (::PathFileExists(langs_xml_path.c_str())) @@ -1166,7 +1166,7 @@ bool NppParameters::load() if (doRecover) { generic_string srcLangsPath(_nppPath); - PathAppend(srcLangsPath, TEXT("langs.model.xml")); + pathAppend(srcLangsPath, TEXT("langs.model.xml")); ::CopyFile(srcLangsPath.c_str(), langs_xml_path.c_str(), FALSE); } @@ -1200,10 +1200,10 @@ bool NppParameters::load() // config.xml : for per user // //---------------------------// generic_string configPath(_userPath); - PathAppend(configPath, TEXT("config.xml")); + pathAppend(configPath, TEXT("config.xml")); generic_string srcConfigPath(_nppPath); - PathAppend(srcConfigPath, TEXT("config.model.xml")); + pathAppend(srcConfigPath, TEXT("config.model.xml")); if (!::PathFileExists(configPath.c_str())) ::CopyFile(srcConfigPath.c_str(), configPath.c_str(), FALSE); @@ -1226,12 +1226,12 @@ bool NppParameters::load() //----------------------------// _stylerPath = _userPath; - PathAppend(_stylerPath, TEXT("stylers.xml")); + pathAppend(_stylerPath, TEXT("stylers.xml")); if (!PathFileExists(_stylerPath.c_str())) { generic_string srcStylersPath(_nppPath); - PathAppend(srcStylersPath, TEXT("stylers.model.xml")); + pathAppend(srcStylersPath, TEXT("stylers.model.xml")); ::CopyFile(srcStylersPath.c_str(), _stylerPath.c_str(), TRUE); } @@ -1273,8 +1273,8 @@ bool NppParameters::load() // userDefineLang.xml : for per user // //-----------------------------------// _userDefineLangsFolderPath = _userDefineLangPath = _userPath; - PathAppend(_userDefineLangPath, TEXT("userDefineLang.xml")); - PathAppend(_userDefineLangsFolderPath, TEXT("userDefineLangs")); + pathAppend(_userDefineLangPath, TEXT("userDefineLang.xml")); + pathAppend(_userDefineLangsFolderPath, TEXT("userDefineLangs")); std::vector udlFiles; getFilesInFolder(udlFiles, TEXT("*.xml"), _userDefineLangsFolderPath); @@ -1318,7 +1318,7 @@ bool NppParameters::load() generic_string nativeLangPath; nativeLangPath = _userPath; - PathAppend(nativeLangPath, TEXT("nativeLang.xml")); + pathAppend(nativeLangPath, TEXT("nativeLang.xml")); // LocalizationSwitcher should use always user path _localizationSwitcher._nativeLangPath = nativeLangPath; @@ -1327,15 +1327,15 @@ bool NppParameters::load() { // overwrite nativeLangPath variable nativeLangPath = _nppPath; - PathAppend(nativeLangPath, TEXT("localization\\")); - PathAppend(nativeLangPath, _startWithLocFileName); + pathAppend(nativeLangPath, TEXT("localization\\")); + pathAppend(nativeLangPath, _startWithLocFileName); } else // use %appdata% location, or (if absence then) npp installed location { if (!PathFileExists(nativeLangPath.c_str())) { nativeLangPath = _nppPath; - PathAppend(nativeLangPath, TEXT("nativeLang.xml")); + pathAppend(nativeLangPath, TEXT("nativeLang.xml")); } } @@ -1354,7 +1354,7 @@ bool NppParameters::load() // toolbarIcons.xml : for per user // //---------------------------------// generic_string toolbarIconsPath(_userPath); - PathAppend(toolbarIconsPath, TEXT("toolbarIcons.xml")); + pathAppend(toolbarIconsPath, TEXT("toolbarIcons.xml")); _pXmlToolIconsDoc = new TiXmlDocument(toolbarIconsPath); loadOkay = _pXmlToolIconsDoc->LoadFile(); @@ -1369,12 +1369,12 @@ bool NppParameters::load() // shortcuts.xml : for per user // //------------------------------// _shortcutsPath = _userPath; - PathAppend(_shortcutsPath, TEXT("shortcuts.xml")); + pathAppend(_shortcutsPath, TEXT("shortcuts.xml")); if (!PathFileExists(_shortcutsPath.c_str())) { generic_string srcShortcutsPath(_nppPath); - PathAppend(srcShortcutsPath, TEXT("shortcuts.xml")); + pathAppend(srcShortcutsPath, TEXT("shortcuts.xml")); ::CopyFile(srcShortcutsPath.c_str(), _shortcutsPath.c_str(), TRUE); } @@ -1402,12 +1402,12 @@ bool NppParameters::load() // contextMenu.xml : for per user // //---------------------------------// _contextMenuPath = _userPath; - PathAppend(_contextMenuPath, TEXT("contextMenu.xml")); + pathAppend(_contextMenuPath, TEXT("contextMenu.xml")); if (!PathFileExists(_contextMenuPath.c_str())) { generic_string srcContextMenuPath(_nppPath); - PathAppend(srcContextMenuPath, TEXT("contextMenu.xml")); + pathAppend(srcContextMenuPath, TEXT("contextMenu.xml")); ::CopyFile(srcContextMenuPath.c_str(), _contextMenuPath.c_str(), TRUE); } @@ -1425,7 +1425,7 @@ bool NppParameters::load() // session.xml : for per user // //----------------------------// - PathAppend(_sessionPath, TEXT("session.xml")); + pathAppend(_sessionPath, TEXT("session.xml")); // Don't load session.xml if not required in order to speed up!! const NppGUI & nppGUI = (NppParameters::getInstance()).getNppGUI(); @@ -1452,7 +1452,7 @@ bool NppParameters::load() // manually in order to set selected text's foreground color. // //-------------------------------------------------------------// generic_string enableSelectFgColorPath = _userPath; - PathAppend(enableSelectFgColorPath, TEXT("enableSelectFgColor.xml")); + pathAppend(enableSelectFgColorPath, TEXT("enableSelectFgColor.xml")); if (PathFileExists(enableSelectFgColorPath.c_str())) { @@ -1460,19 +1460,33 @@ bool NppParameters::load() } - generic_string nppLogNetworkDriveIssueFilePath(_nppPath); - generic_string nppLogNetworkDriveIssueFile = nppLogNetworkDriveIssue; - nppLogNetworkDriveIssueFile += TEXT(".xml"); - PathAppend(nppLogNetworkDriveIssueFilePath, nppLogNetworkDriveIssueFile); - bool doNppLogNetworkDriveIssue = (PathFileExists(nppLogNetworkDriveIssueFilePath.c_str()) == TRUE); - if (!doNppLogNetworkDriveIssue) + generic_string filePath, filePath2, issueFileName; + + filePath = _nppPath; + issueFileName = nppLogNetworkDriveIssue; + issueFileName += TEXT(".xml"); + pathAppend(filePath, issueFileName); + _doNppLogNetworkDriveIssue = (PathFileExists(filePath.c_str()) == TRUE); + if (!_doNppLogNetworkDriveIssue) { - generic_string nppLogNetworkDriveIssueFilePath2(_userPath); - PathAppend(nppLogNetworkDriveIssueFilePath2, nppLogNetworkDriveIssueFile); - doNppLogNetworkDriveIssue = (PathFileExists(nppLogNetworkDriveIssueFilePath2.c_str()) == TRUE); + filePath2 = _userPath; + pathAppend(filePath2, issueFileName); + _doNppLogNetworkDriveIssue = (PathFileExists(filePath2.c_str()) == TRUE); } - _doNppLogNetworkDriveIssue = doNppLogNetworkDriveIssue; + filePath = _nppPath; + issueFileName = nppLogNulContentCorruptionIssue; + issueFileName += TEXT(".xml"); + pathAppend(filePath, issueFileName); + _doNppLogNulContentCorruptionIssue = (PathFileExists(filePath.c_str()) == TRUE); + if (!_doNppLogNulContentCorruptionIssue) + { + filePath2 = _userPath; + pathAppend(filePath2, issueFileName); + _doNppLogNulContentCorruptionIssue = (PathFileExists(filePath2.c_str()) == TRUE); + } + + return isAllLaoded; @@ -2942,7 +2956,7 @@ bool NppParameters::writeSettingsFilesOnCloudForThe1stTime(const generic_string // config.xml generic_string cloudConfigPath = cloudSettingsPath; - PathAppend(cloudConfigPath, TEXT("config.xml")); + pathAppend(cloudConfigPath, TEXT("config.xml")); if (!::PathFileExists(cloudConfigPath.c_str()) && _pXmlUserDoc) { isOK = _pXmlUserDoc->SaveFile(cloudConfigPath.c_str()); @@ -2952,7 +2966,7 @@ bool NppParameters::writeSettingsFilesOnCloudForThe1stTime(const generic_string // stylers.xml generic_string cloudStylersPath = cloudSettingsPath; - PathAppend(cloudStylersPath, TEXT("stylers.xml")); + pathAppend(cloudStylersPath, TEXT("stylers.xml")); if (!::PathFileExists(cloudStylersPath.c_str()) && _pXmlUserStylerDoc) { isOK = _pXmlUserStylerDoc->SaveFile(cloudStylersPath.c_str()); @@ -2962,7 +2976,7 @@ bool NppParameters::writeSettingsFilesOnCloudForThe1stTime(const generic_string // langs.xml generic_string cloudLangsPath = cloudSettingsPath; - PathAppend(cloudLangsPath, TEXT("langs.xml")); + pathAppend(cloudLangsPath, TEXT("langs.xml")); if (!::PathFileExists(cloudLangsPath.c_str()) && _pXmlUserDoc) { isOK = _pXmlDoc->SaveFile(cloudLangsPath.c_str()); @@ -2972,7 +2986,7 @@ bool NppParameters::writeSettingsFilesOnCloudForThe1stTime(const generic_string // userDefineLang.xml generic_string cloudUserLangsPath = cloudSettingsPath; - PathAppend(cloudUserLangsPath, TEXT("userDefineLang.xml")); + pathAppend(cloudUserLangsPath, TEXT("userDefineLang.xml")); if (!::PathFileExists(cloudUserLangsPath.c_str()) && _pXmlUserLangDoc) { isOK = _pXmlUserLangDoc->SaveFile(cloudUserLangsPath.c_str()); @@ -2982,7 +2996,7 @@ bool NppParameters::writeSettingsFilesOnCloudForThe1stTime(const generic_string // shortcuts.xml generic_string cloudShortcutsPath = cloudSettingsPath; - PathAppend(cloudShortcutsPath, TEXT("shortcuts.xml")); + pathAppend(cloudShortcutsPath, TEXT("shortcuts.xml")); if (!::PathFileExists(cloudShortcutsPath.c_str()) && _pXmlShortcutDoc) { isOK = _pXmlShortcutDoc->SaveFile(cloudShortcutsPath.c_str()); @@ -2992,7 +3006,7 @@ bool NppParameters::writeSettingsFilesOnCloudForThe1stTime(const generic_string // contextMenu.xml generic_string cloudContextMenuPath = cloudSettingsPath; - PathAppend(cloudContextMenuPath, TEXT("contextMenu.xml")); + pathAppend(cloudContextMenuPath, TEXT("contextMenu.xml")); if (!::PathFileExists(cloudContextMenuPath.c_str()) && _pXmlContextMenuDocA) { isOK = _pXmlContextMenuDocA->SaveUnicodeFilePath(cloudContextMenuPath.c_str()); @@ -3002,7 +3016,7 @@ bool NppParameters::writeSettingsFilesOnCloudForThe1stTime(const generic_string // nativeLang.xml generic_string cloudNativeLangPath = cloudSettingsPath; - PathAppend(cloudNativeLangPath, TEXT("nativeLang.xml")); + pathAppend(cloudNativeLangPath, TEXT("nativeLang.xml")); if (!::PathFileExists(cloudNativeLangPath.c_str()) && _pXmlNativeLangDocA) { isOK = _pXmlNativeLangDocA->SaveUnicodeFilePath(cloudNativeLangPath.c_str()); diff --git a/PowerEditor/src/Parameters.h b/PowerEditor/src/Parameters.h index afc8a8da7..e18186370 100644 --- a/PowerEditor/src/Parameters.h +++ b/PowerEditor/src/Parameters.h @@ -134,7 +134,9 @@ const TCHAR fontSizeStrs[][3] = {TEXT(""), TEXT("5"), TEXT("6"), TEXT("7"), TEXT const TCHAR localConfFile[] = TEXT("doLocalConf.xml"); const TCHAR notepadStyleFile[] = TEXT("asNotepad.xml"); +// issue xml/log file name const TCHAR nppLogNetworkDriveIssue[] = TEXT("nppLogNetworkDriveIssue"); +const TCHAR nppLogNulContentCorruptionIssue[] = TEXT("nppLogNulContentCorruptionIssue"); void cutString(const TCHAR *str2cut, std::vector & patternVect); @@ -1801,6 +1803,9 @@ private: bool _doNppLogNetworkDriveIssue = false; + bool _doNppLogNulContentCorruptionIssue = false; + bool _isQueryEndSessionStarted = false; + public: generic_string getWingupFullPath() const { return _wingupFullPath; }; generic_string getWingupParams() const { return _wingupParams; }; @@ -1812,6 +1817,9 @@ public: void setElevationRequired(bool val2set) { _isElevationRequired = val2set; }; bool doNppLogNetworkDriveIssue() { return _doNppLogNetworkDriveIssue; }; + bool doNppLogNulContentCorruptionIssue() { return _doNppLogNulContentCorruptionIssue; }; + void queryEndSessionStart() { _isQueryEndSessionStarted = true; }; + bool isQueryEndSessionStarted() { return _isQueryEndSessionStarted; }; private: void getLangKeywordsFromXmlTree(); diff --git a/PowerEditor/src/ScintillaComponent/Buffer.cpp b/PowerEditor/src/ScintillaComponent/Buffer.cpp index 19dc6d6ea..fbdf30142 100644 --- a/PowerEditor/src/ScintillaComponent/Buffer.cpp +++ b/PowerEditor/src/ScintillaComponent/Buffer.cpp @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include "Buffer.h" #include "Scintilla.h" @@ -27,6 +29,7 @@ #include "uchardet.h" #include "FileInterface.h" + static const int blockSize = 128 * 1024 + 4; static const int CR = 0x0D; static const int LF = 0x0A; @@ -149,17 +152,20 @@ void Buffer::updateTimeStamp() { if (res == 1) { - if (NppParameters::getInstance().doNppLogNetworkDriveIssue()) + NppParameters& nppParam = NppParameters::getInstance(); + if (nppParam.doNppLogNetworkDriveIssue()) { - generic_string nppLogNetworkDriveIssueLog = TEXT("c:\\temp\\"); - nppLogNetworkDriveIssueLog += nppLogNetworkDriveIssue; - nppLogNetworkDriveIssueLog += TEXT(".log"); + generic_string issueFn = nppLogNetworkDriveIssue; + issueFn += TEXT(".log"); + generic_string nppIssueLog = nppParam.getUserPath(); + pathAppend(nppIssueLog, issueFn); - std::string msg = std::string(_fullPathName.begin(), _fullPathName.end()); + std::wstring_convert> converter; + std::string msg = converter.to_bytes(_fullPathName); char buf[1024]; sprintf(buf, " in updateTimeStamp(): timeStampLive (%u/%u) < _timeStamp (%u/%u)", timeStampLive.dwLowDateTime, timeStampLive.dwHighDateTime, _timeStamp.dwLowDateTime, _timeStamp.dwHighDateTime); msg += buf; - writeLog(nppLogNetworkDriveIssueLog.c_str(), msg.c_str()); + writeLog(nppIssueLog.c_str(), msg.c_str()); } } _timeStamp = timeStampLive; @@ -297,17 +303,20 @@ bool Buffer::checkFileState() // returns true if the status has been changed (it { if (res == 1) { - if (NppParameters::getInstance().doNppLogNetworkDriveIssue()) + NppParameters& nppParam = NppParameters::getInstance(); + if (nppParam.doNppLogNetworkDriveIssue()) { - generic_string nppLogNetworkDriveIssueLog = TEXT("c:\\temp\\"); - nppLogNetworkDriveIssueLog += nppLogNetworkDriveIssue; - nppLogNetworkDriveIssueLog += TEXT(".log"); + generic_string issueFn = nppLogNetworkDriveIssue; + issueFn += TEXT(".log"); + generic_string nppIssueLog = nppParam.getUserPath(); + pathAppend(nppIssueLog, issueFn); - std::string msg = std::string(_fullPathName.begin(), _fullPathName.end()); + std::wstring_convert> converter; + std::string msg = converter.to_bytes(_fullPathName); char buf[1024]; sprintf(buf, " in checkFileState(): attributes.ftLastWriteTime (%u/%u) < _timeStamp (%u/%u)", attributes.ftLastWriteTime.dwLowDateTime, attributes.ftLastWriteTime.dwHighDateTime, _timeStamp.dwLowDateTime, _timeStamp.dwHighDateTime); msg += buf; - writeLog(nppLogNetworkDriveIssueLog.c_str(), msg.c_str()); + writeLog(nppIssueLog.c_str(), msg.c_str()); } } _timeStamp = attributes.ftLastWriteTime; diff --git a/PowerEditor/src/WinControls/FunctionList/functionListPanel.cpp b/PowerEditor/src/WinControls/FunctionList/functionListPanel.cpp index 8b998bac5..04a9bc686 100644 --- a/PowerEditor/src/WinControls/FunctionList/functionListPanel.cpp +++ b/PowerEditor/src/WinControls/FunctionList/functionListPanel.cpp @@ -490,10 +490,10 @@ void FunctionListPanel::init(HINSTANCE hInst, HWND hPere, ScintillaEditView **pp NppParameters& nppParams = NppParameters::getInstance(); generic_string funcListXmlPath = nppParams.getUserPath(); - PathAppend(funcListXmlPath, TEXT("functionList")); + pathAppend(funcListXmlPath, TEXT("functionList")); generic_string funcListDefaultXmlPath = nppParams.getNppPath(); - PathAppend(funcListDefaultXmlPath, TEXT("functionList")); + pathAppend(funcListDefaultXmlPath, TEXT("functionList")); bool doLocalConf = nppParams.isLocal(); @@ -515,7 +515,7 @@ void FunctionListPanel::init(HINSTANCE hInst, HWND hPere, ScintillaEditView **pp else { generic_string funcListDefaultXmlPath = nppParams.getNppPath(); - PathAppend(funcListDefaultXmlPath, TEXT("functionList")); + pathAppend(funcListDefaultXmlPath, TEXT("functionList")); if (PathFileExists(funcListDefaultXmlPath.c_str())) { _funcParserMgr.init(funcListDefaultXmlPath, funcListDefaultXmlPath, ppEditView); diff --git a/PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.cpp b/PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.cpp index 07c09ce47..69a688444 100644 --- a/PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.cpp +++ b/PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.cpp @@ -428,18 +428,18 @@ PluginsAdminDlg::PluginsAdminDlg() // Get wingup path NppParameters& nppParameters = NppParameters::getInstance(); _updaterDir = nppParameters.getNppPath(); - PathAppend(_updaterDir, TEXT("updater")); + pathAppend(_updaterDir, TEXT("updater")); _updaterFullPath = _updaterDir; - PathAppend(_updaterFullPath, TEXT("gup.exe")); + pathAppend(_updaterFullPath, TEXT("gup.exe")); // get plugin-list path _pluginListFullPath = nppParameters.getPluginConfDir(); #ifdef DEBUG // if not debug, then it's release // load from nppPluginList.json instead of nppPluginList.dll - PathAppend(_pluginListFullPath, TEXT("nppPluginList.json")); + pathAppend(_pluginListFullPath, TEXT("nppPluginList.json")); #else //RELEASE - PathAppend(_pluginListFullPath, TEXT("nppPluginList.dll")); + pathAppend(_pluginListFullPath, TEXT("nppPluginList.dll")); #endif }