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)
|
||||
{
|
||||
Win32_IO_File file(file2write, Win32_IO_File::Mode::WRITE);
|
||||
Win32_IO_File file(file2write);
|
||||
|
||||
if (file.isOpened())
|
||||
file.writeStr(content2write);
|
||||
|
@ -124,10 +124,29 @@ void writeFileContent(const TCHAR *file2write, const char *content2write)
|
|||
|
||||
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())
|
||||
file.writeStr(log2write);
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
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 "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)
|
||||
{
|
||||
_path = fname;
|
||||
_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)
|
||||
{
|
||||
generic_string fn = fname;
|
||||
_path = std::string(fn.begin(), fn.end());
|
||||
_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)
|
||||
{
|
||||
::SetEndOfFile(_hFile);
|
||||
::FlushFileBuffers(_hFile);
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::CloseHandle(_hFile);
|
||||
|
|
|
@ -26,13 +26,8 @@
|
|||
class Win32_IO_File final
|
||||
{
|
||||
public:
|
||||
enum class Mode {
|
||||
WRITE,
|
||||
APPEND
|
||||
};
|
||||
|
||||
Win32_IO_File(const char *fname, Mode fmode);
|
||||
Win32_IO_File(const wchar_t *fname, Mode fmode);
|
||||
Win32_IO_File(const char *fname);
|
||||
Win32_IO_File(const wchar_t *fname);
|
||||
|
||||
Win32_IO_File() = delete;
|
||||
Win32_IO_File(const Win32_IO_File&) = delete;
|
||||
|
@ -57,11 +52,11 @@ public:
|
|||
|
||||
private:
|
||||
HANDLE _hFile {INVALID_HANDLE_VALUE};
|
||||
Mode _hMode {Mode::WRITE};
|
||||
bool _written {false};
|
||||
std::string _path;
|
||||
|
||||
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 _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
|
||||
};
|
||||
|
|
|
@ -1458,6 +1458,23 @@ bool NppParameters::load()
|
|||
{
|
||||
_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;
|
||||
}
|
||||
|
||||
|
|
|
@ -133,7 +133,8 @@ const TCHAR fontSizeStrs[][3] = {TEXT(""), TEXT("5"), TEXT("6"), TEXT("7"), TEXT
|
|||
|
||||
const TCHAR localConfFile[] = TEXT("doLocalConf.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);
|
||||
|
||||
|
@ -1798,6 +1799,8 @@ private:
|
|||
|
||||
bool _isSelectFgColorEnabled = false;
|
||||
|
||||
bool _doNppLogNetworkDriveIssue = false;
|
||||
|
||||
public:
|
||||
generic_string getWingupFullPath() const { return _wingupFullPath; };
|
||||
generic_string getWingupParams() const { return _wingupParams; };
|
||||
|
@ -1808,6 +1811,8 @@ public:
|
|||
void setWingupDir(const generic_string& val2set) { _wingupDir = val2set; };
|
||||
void setElevationRequired(bool val2set) { _isElevationRequired = val2set; };
|
||||
|
||||
bool doNppLogNetworkDriveIssue() { return _doNppLogNetworkDriveIssue; };
|
||||
|
||||
private:
|
||||
void getLangKeywordsFromXmlTree();
|
||||
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.
|
||||
// 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;
|
||||
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.
|
||||
// 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;
|
||||
mask |= BufferChangeTimestamp;
|
||||
_currentStatus = DOC_MODIFIED;
|
||||
|
@ -1499,7 +1529,7 @@ BufferID FileManager::getBufferFromDocument(Document doc)
|
|||
|
||||
bool FileManager::createEmptyFile(const TCHAR * path)
|
||||
{
|
||||
Win32_IO_File file(path, Win32_IO_File::Mode::WRITE);
|
||||
Win32_IO_File file(path);
|
||||
return file.isOpened();
|
||||
}
|
||||
|
||||
|
|
|
@ -790,7 +790,7 @@ bool TiXmlDocument::SaveFile( const TCHAR * filename ) const
|
|||
return false;
|
||||
*/
|
||||
|
||||
Win32_IO_File file(filename, Win32_IO_File::Mode::WRITE);
|
||||
Win32_IO_File file(filename);
|
||||
|
||||
if (file.isOpened())
|
||||
{
|
||||
|
|
|
@ -290,7 +290,7 @@ Utf8_16_Write::~Utf8_16_Write()
|
|||
|
||||
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)
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue