Fix file status detection issue under Windows XP (32-bit only)
Close #4226
This commit is contained in:
parent
6c9a5a2afe
commit
58fa70b580
@ -34,6 +34,7 @@
|
||||
|
||||
#include "Common.h"
|
||||
#include "../Utf8.h"
|
||||
#include <Parameters.h>
|
||||
|
||||
WcharMbcsConvertor* WcharMbcsConvertor::_pSelf = new WcharMbcsConvertor;
|
||||
|
||||
@ -1192,4 +1193,65 @@ bool isAssoCommandExisting(LPCTSTR FullPathName)
|
||||
|
||||
}
|
||||
return isAssoCommandExisting;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _WIN64
|
||||
static bool IsWindows2000orXP()
|
||||
{
|
||||
bool isWin2kXP = false;
|
||||
switch (NppParameters::getInstance()->getWinVersion())
|
||||
{
|
||||
case WV_W2K:
|
||||
case WV_XP:
|
||||
case WV_S2003:
|
||||
isWin2kXP = true;
|
||||
break;
|
||||
}
|
||||
return isWin2kXP;
|
||||
}
|
||||
|
||||
static ULONGLONG filetime_to_time_ull(const FILETIME* ft)
|
||||
{
|
||||
ULARGE_INTEGER ull;
|
||||
ull.LowPart = ft->dwLowDateTime;
|
||||
ull.HighPart = ft->dwHighDateTime;
|
||||
return (ull.QuadPart / 10000000ULL - 11644473600ULL);
|
||||
}
|
||||
|
||||
int custom_wstat(wchar_t const* _FileName, struct _stat* _Stat)
|
||||
{
|
||||
static bool isWin2kXP = IsWindows2000orXP();
|
||||
if (!isWin2kXP)
|
||||
return _wstat(_FileName, _Stat);
|
||||
|
||||
// In Visual Studio 2015, _wstat always returns -1 in Windows XP.
|
||||
// So here is a WinAPI-based implementation of _wstat.
|
||||
int nResult = -1;
|
||||
HANDLE hFile = ::CreateFile(_FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
LARGE_INTEGER fileSize;
|
||||
FILETIME creationTime, accessTime, writeTime;
|
||||
if (::GetFileSizeEx(hFile, &fileSize) &&
|
||||
::GetFileTime(hFile, &creationTime, &accessTime, &writeTime))
|
||||
{
|
||||
DWORD dwAttr = ::GetFileAttributes(_FileName);
|
||||
::ZeroMemory(_Stat, sizeof(struct _stat));
|
||||
_Stat->st_atime = static_cast<decltype(_Stat->st_atime)>(filetime_to_time_ull(&accessTime));
|
||||
_Stat->st_ctime = static_cast<decltype(_Stat->st_ctime)>(filetime_to_time_ull(&creationTime));
|
||||
_Stat->st_mtime = static_cast<decltype(_Stat->st_mtime)>(filetime_to_time_ull(&writeTime));
|
||||
_Stat->st_size = static_cast<decltype(_Stat->st_size)>(fileSize.QuadPart);
|
||||
_Stat->st_mode = _S_IREAD | _S_IEXEC; // S_IEXEC : Execute (for ordinary files) or search (for directories)
|
||||
if ((dwAttr & FILE_ATTRIBUTE_READONLY) == 0)
|
||||
_Stat->st_mode |= _S_IWRITE;
|
||||
if ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
||||
_Stat->st_mode |= _S_IFDIR;
|
||||
else
|
||||
_Stat->st_mode |= _S_IFREG;
|
||||
nResult = 0;
|
||||
}
|
||||
::CloseHandle(hFile);
|
||||
}
|
||||
return nResult;
|
||||
}
|
||||
#endif
|
||||
|
@ -62,7 +62,11 @@ const bool dirDown = false;
|
||||
#define generic_sscanf swscanf
|
||||
#define generic_fopen _wfopen
|
||||
#define generic_fgets fgetws
|
||||
#define generic_stat _wstat
|
||||
#ifdef _WIN64
|
||||
#define generic_stat _wstat
|
||||
#else
|
||||
#define generic_stat custom_wstat
|
||||
#endif
|
||||
#define COPYDATA_FILENAMES COPYDATA_FILENAMESW
|
||||
|
||||
typedef std::basic_string<TCHAR> generic_string;
|
||||
@ -192,3 +196,7 @@ HWND CreateToolTip(int toolID, HWND hDlg, HINSTANCE hInst, const PTSTR pszText);
|
||||
|
||||
bool isCertificateValidated(const generic_string & fullFilePath, const generic_string & subjectName2check);
|
||||
bool isAssoCommandExisting(LPCTSTR FullPathName);
|
||||
|
||||
#ifndef _WIN64
|
||||
int custom_wstat(wchar_t const* _FileName, struct _stat* _Stat);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user