Fix saving file and false alert on network drive issues
And add log ability for debugging network drive file status detection issue. To activate log, user should: 1. Add an empty "nppLogNetworkDriveIssue.xml" file beside of notepad++.exe, or if user has no admin previlege, he/she can add this file into %APPDATA%\Notepad++\. 2. Create "C:\temp\" directory, if it doesn't exist yet. 3. Start notepad++.exe, and wait for the file status (timestamp) detection error from the network drive. If the errors occur, there should be some trace in "C:\temp\nppLogNetworkDriveIssue.log". People who have had the network drive file status detection issue in #10688, #10753, #10757, #10751 & #10787 are welcome to download the binary and provide the generated log in order to fix this issue. Fix #10751, fix #10688, fix #10753, fix #10757, fix #10751, fix #10787, close #10847
This commit is contained in:
parent
e87342fef6
commit
12a13b1c0a
|
@ -115,7 +115,7 @@ generic_string relativeFilePathToFullFilePath(const TCHAR *relativeFilePath)
|
||||||
|
|
||||||
void writeFileContent(const TCHAR *file2write, const char *content2write)
|
void writeFileContent(const TCHAR *file2write, const char *content2write)
|
||||||
{
|
{
|
||||||
Win32_IO_File file(file2write, Win32_IO_File::Mode::WRITE);
|
Win32_IO_File file(file2write);
|
||||||
|
|
||||||
if (file.isOpened())
|
if (file.isOpened())
|
||||||
file.writeStr(content2write);
|
file.writeStr(content2write);
|
||||||
|
@ -124,10 +124,29 @@ void writeFileContent(const TCHAR *file2write, const char *content2write)
|
||||||
|
|
||||||
void writeLog(const TCHAR *logFileName, const char *log2write)
|
void writeLog(const TCHAR *logFileName, const char *log2write)
|
||||||
{
|
{
|
||||||
Win32_IO_File file(logFileName, Win32_IO_File::Mode::APPEND);
|
const DWORD accessParam{ GENERIC_READ | GENERIC_WRITE };
|
||||||
|
const DWORD shareParam{ FILE_SHARE_READ | FILE_SHARE_WRITE };
|
||||||
|
const DWORD dispParam{ OPEN_ALWAYS }; // Open existing file for writing without destroying it or create new
|
||||||
|
const DWORD attribParam{ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH };
|
||||||
|
HANDLE hFile = ::CreateFileW(logFileName, accessParam, shareParam, NULL, dispParam, attribParam, NULL);
|
||||||
|
|
||||||
if (file.isOpened())
|
if (hFile != INVALID_HANDLE_VALUE)
|
||||||
file.writeStr(log2write);
|
{
|
||||||
|
LARGE_INTEGER offset;
|
||||||
|
offset.QuadPart = 0;
|
||||||
|
::SetFilePointerEx(hFile, offset, NULL, FILE_END);
|
||||||
|
|
||||||
|
SYSTEMTIME currentTime = { 0 };
|
||||||
|
::GetLocalTime(¤tTime);
|
||||||
|
generic_string dateTimeStrW = getDateTimeStrFrom(TEXT("yyyy-MM-dd HH:mm:ss"), currentTime);
|
||||||
|
std::string log2writeStr(dateTimeStrW.begin(), dateTimeStrW.end());
|
||||||
|
log2writeStr += " ";
|
||||||
|
log2writeStr += log2write;
|
||||||
|
log2writeStr += "\n";
|
||||||
|
|
||||||
|
DWORD bytes_written = 0;
|
||||||
|
::WriteFile(hFile, log2writeStr.c_str(), static_cast<DWORD>(log2writeStr.length()), &bytes_written, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,39 +16,27 @@
|
||||||
|
|
||||||
|
|
||||||
#include "FileInterface.h"
|
#include "FileInterface.h"
|
||||||
|
#include "Parameters.h"
|
||||||
|
|
||||||
|
|
||||||
Win32_IO_File::Win32_IO_File(const char *fname, Mode fmode) : _hMode(fmode)
|
Win32_IO_File::Win32_IO_File(const char *fname)
|
||||||
{
|
{
|
||||||
if (fname)
|
if (fname)
|
||||||
{
|
{
|
||||||
|
_path = fname;
|
||||||
_hFile = ::CreateFileA(fname, _accessParam, _shareParam, NULL, _dispParam, _attribParam, NULL);
|
_hFile = ::CreateFileA(fname, _accessParam, _shareParam, NULL, _dispParam, _attribParam, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_hFile != INVALID_HANDLE_VALUE) && (_hMode == Mode::APPEND))
|
|
||||||
{
|
|
||||||
LARGE_INTEGER offset;
|
|
||||||
offset.QuadPart = 0;
|
|
||||||
|
|
||||||
::SetFilePointerEx(_hFile, offset, NULL, FILE_END);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Win32_IO_File::Win32_IO_File(const wchar_t *fname, Mode fmode) : _hMode(fmode)
|
Win32_IO_File::Win32_IO_File(const wchar_t *fname)
|
||||||
{
|
{
|
||||||
if (fname)
|
if (fname)
|
||||||
{
|
{
|
||||||
|
generic_string fn = fname;
|
||||||
|
_path = std::string(fn.begin(), fn.end());
|
||||||
_hFile = ::CreateFileW(fname, _accessParam, _shareParam, NULL, _dispParam, _attribParam, NULL);
|
_hFile = ::CreateFileW(fname, _accessParam, _shareParam, NULL, _dispParam, _attribParam, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_hFile != INVALID_HANDLE_VALUE) && (_hMode == Mode::APPEND))
|
|
||||||
{
|
|
||||||
LARGE_INTEGER offset;
|
|
||||||
offset.QuadPart = 0;
|
|
||||||
|
|
||||||
::SetFilePointerEx(_hFile, offset, NULL, FILE_END);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,8 +46,22 @@ void Win32_IO_File::close()
|
||||||
{
|
{
|
||||||
if (_written)
|
if (_written)
|
||||||
{
|
{
|
||||||
::SetEndOfFile(_hFile);
|
BOOL isOK = ::FlushFileBuffers(_hFile);
|
||||||
::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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::CloseHandle(_hFile);
|
::CloseHandle(_hFile);
|
||||||
|
|
|
@ -26,13 +26,8 @@
|
||||||
class Win32_IO_File final
|
class Win32_IO_File final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum class Mode {
|
Win32_IO_File(const char *fname);
|
||||||
WRITE,
|
Win32_IO_File(const wchar_t *fname);
|
||||||
APPEND
|
|
||||||
};
|
|
||||||
|
|
||||||
Win32_IO_File(const char *fname, Mode fmode);
|
|
||||||
Win32_IO_File(const wchar_t *fname, Mode fmode);
|
|
||||||
|
|
||||||
Win32_IO_File() = delete;
|
Win32_IO_File() = delete;
|
||||||
Win32_IO_File(const Win32_IO_File&) = delete;
|
Win32_IO_File(const Win32_IO_File&) = delete;
|
||||||
|
@ -57,11 +52,11 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HANDLE _hFile {INVALID_HANDLE_VALUE};
|
HANDLE _hFile {INVALID_HANDLE_VALUE};
|
||||||
Mode _hMode {Mode::WRITE};
|
|
||||||
bool _written {false};
|
bool _written {false};
|
||||||
|
std::string _path;
|
||||||
|
|
||||||
const DWORD _accessParam { GENERIC_READ | GENERIC_WRITE };
|
const DWORD _accessParam { GENERIC_READ | GENERIC_WRITE };
|
||||||
const DWORD _shareParam { FILE_SHARE_READ | FILE_SHARE_WRITE };
|
const DWORD _shareParam { FILE_SHARE_READ | FILE_SHARE_WRITE };
|
||||||
const DWORD _dispParam { OPEN_ALWAYS }; // Open existing file for writing without destroying it or create new
|
const DWORD _dispParam { CREATE_ALWAYS };
|
||||||
const DWORD _attribParam { FILE_ATTRIBUTE_NORMAL | FILE_FLAG_POSIX_SEMANTICS | FILE_FLAG_WRITE_THROUGH }; // FILE_FLAG_POSIX_SEMANTICS: distinguish between upper/lower case in name
|
const DWORD _attribParam { FILE_ATTRIBUTE_NORMAL | FILE_FLAG_POSIX_SEMANTICS | FILE_FLAG_WRITE_THROUGH }; // FILE_FLAG_POSIX_SEMANTICS: distinguish between upper/lower case in name
|
||||||
};
|
};
|
||||||
|
|
|
@ -1458,6 +1458,23 @@ bool NppParameters::load()
|
||||||
{
|
{
|
||||||
_isSelectFgColorEnabled = true;
|
_isSelectFgColorEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 nppLogNetworkDriveIssueFilePath2(_userPath);
|
||||||
|
PathAppend(nppLogNetworkDriveIssueFilePath2, nppLogNetworkDriveIssueFile);
|
||||||
|
doNppLogNetworkDriveIssue = (PathFileExists(nppLogNetworkDriveIssueFilePath2.c_str()) == TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
_doNppLogNetworkDriveIssue = doNppLogNetworkDriveIssue;
|
||||||
|
|
||||||
|
|
||||||
return isAllLaoded;
|
return isAllLaoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,8 @@ const TCHAR fontSizeStrs[][3] = {TEXT(""), TEXT("5"), TEXT("6"), TEXT("7"), TEXT
|
||||||
|
|
||||||
const TCHAR localConfFile[] = TEXT("doLocalConf.xml");
|
const TCHAR localConfFile[] = TEXT("doLocalConf.xml");
|
||||||
const TCHAR notepadStyleFile[] = TEXT("asNotepad.xml");
|
const TCHAR notepadStyleFile[] = TEXT("asNotepad.xml");
|
||||||
const TCHAR pluginsForAllUsersFile[] = TEXT("pluginsForAllUsers.xml");
|
|
||||||
|
const TCHAR nppLogNetworkDriveIssue[] = TEXT("nppLogNetworkDriveIssue");
|
||||||
|
|
||||||
void cutString(const TCHAR *str2cut, std::vector<generic_string> & patternVect);
|
void cutString(const TCHAR *str2cut, std::vector<generic_string> & patternVect);
|
||||||
|
|
||||||
|
@ -1798,6 +1799,8 @@ private:
|
||||||
|
|
||||||
bool _isSelectFgColorEnabled = false;
|
bool _isSelectFgColorEnabled = false;
|
||||||
|
|
||||||
|
bool _doNppLogNetworkDriveIssue = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
generic_string getWingupFullPath() const { return _wingupFullPath; };
|
generic_string getWingupFullPath() const { return _wingupFullPath; };
|
||||||
generic_string getWingupParams() const { return _wingupParams; };
|
generic_string getWingupParams() const { return _wingupParams; };
|
||||||
|
@ -1808,6 +1811,8 @@ public:
|
||||||
void setWingupDir(const generic_string& val2set) { _wingupDir = val2set; };
|
void setWingupDir(const generic_string& val2set) { _wingupDir = val2set; };
|
||||||
void setElevationRequired(bool val2set) { _isElevationRequired = val2set; };
|
void setElevationRequired(bool val2set) { _isElevationRequired = val2set; };
|
||||||
|
|
||||||
|
bool doNppLogNetworkDriveIssue() { return _doNppLogNetworkDriveIssue; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void getLangKeywordsFromXmlTree();
|
void getLangKeywordsFromXmlTree();
|
||||||
bool getUserParametersFromXmlTree();
|
bool getUserParametersFromXmlTree();
|
||||||
|
|
|
@ -147,6 +147,21 @@ void Buffer::updateTimeStamp()
|
||||||
// It can happen when user copies a backup of editing file somewhere-else firstly, then modifies the editing file in Notepad++ and saves it.
|
// It can happen when user copies a backup of editing file somewhere-else firstly, then modifies the editing file in Notepad++ and saves it.
|
||||||
// Now user copies the backup back to erase the modified editing file outside Notepad++ (via Explorer).
|
// Now user copies the backup back to erase the modified editing file outside Notepad++ (via Explorer).
|
||||||
{
|
{
|
||||||
|
if (res == 1)
|
||||||
|
{
|
||||||
|
if (NppParameters::getInstance().doNppLogNetworkDriveIssue())
|
||||||
|
{
|
||||||
|
generic_string nppLogNetworkDriveIssueLog = TEXT("c:\\temp\\");
|
||||||
|
nppLogNetworkDriveIssueLog += nppLogNetworkDriveIssue;
|
||||||
|
nppLogNetworkDriveIssueLog += TEXT(".log");
|
||||||
|
|
||||||
|
std::string msg = std::string(_fullPathName.begin(), _fullPathName.end());
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
_timeStamp = timeStampLive;
|
_timeStamp = timeStampLive;
|
||||||
doNotify(BufferChangeTimestamp);
|
doNotify(BufferChangeTimestamp);
|
||||||
}
|
}
|
||||||
|
@ -280,6 +295,21 @@ bool Buffer::checkFileState() // returns true if the status has been changed (it
|
||||||
// It can happen when user copies a backup of editing file somewhere-else firstly, then modifies the editing file in Notepad++ and saves it.
|
// It can happen when user copies a backup of editing file somewhere-else firstly, then modifies the editing file in Notepad++ and saves it.
|
||||||
// Now user copies the backup back to erase the modified editing file outside Notepad++ (via Explorer).
|
// Now user copies the backup back to erase the modified editing file outside Notepad++ (via Explorer).
|
||||||
{
|
{
|
||||||
|
if (res == 1)
|
||||||
|
{
|
||||||
|
if (NppParameters::getInstance().doNppLogNetworkDriveIssue())
|
||||||
|
{
|
||||||
|
generic_string nppLogNetworkDriveIssueLog = TEXT("c:\\temp\\");
|
||||||
|
nppLogNetworkDriveIssueLog += nppLogNetworkDriveIssue;
|
||||||
|
nppLogNetworkDriveIssueLog += TEXT(".log");
|
||||||
|
|
||||||
|
std::string msg = std::string(_fullPathName.begin(), _fullPathName.end());
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
_timeStamp = attributes.ftLastWriteTime;
|
_timeStamp = attributes.ftLastWriteTime;
|
||||||
mask |= BufferChangeTimestamp;
|
mask |= BufferChangeTimestamp;
|
||||||
_currentStatus = DOC_MODIFIED;
|
_currentStatus = DOC_MODIFIED;
|
||||||
|
@ -1499,7 +1529,7 @@ BufferID FileManager::getBufferFromDocument(Document doc)
|
||||||
|
|
||||||
bool FileManager::createEmptyFile(const TCHAR * path)
|
bool FileManager::createEmptyFile(const TCHAR * path)
|
||||||
{
|
{
|
||||||
Win32_IO_File file(path, Win32_IO_File::Mode::WRITE);
|
Win32_IO_File file(path);
|
||||||
return file.isOpened();
|
return file.isOpened();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -790,7 +790,7 @@ bool TiXmlDocument::SaveFile( const TCHAR * filename ) const
|
||||||
return false;
|
return false;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Win32_IO_File file(filename, Win32_IO_File::Mode::WRITE);
|
Win32_IO_File file(filename);
|
||||||
|
|
||||||
if (file.isOpened())
|
if (file.isOpened())
|
||||||
{
|
{
|
||||||
|
|
|
@ -290,7 +290,7 @@ Utf8_16_Write::~Utf8_16_Write()
|
||||||
|
|
||||||
bool Utf8_16_Write::openFile(const TCHAR *name)
|
bool Utf8_16_Write::openFile(const TCHAR *name)
|
||||||
{
|
{
|
||||||
m_pFile = std::make_unique<Win32_IO_File>(name, Win32_IO_File::Mode::WRITE);
|
m_pFile = std::make_unique<Win32_IO_File>(name);
|
||||||
|
|
||||||
if (!m_pFile)
|
if (!m_pFile)
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in New Issue