This commit is contained in:
Igor Pavlov
2022-06-23 11:43:16 +01:00
committed by Kornel
parent c3529a41f5
commit ec44a8a070
1248 changed files with 15242 additions and 2443 deletions

0
CPP/Windows/COM.cpp Normal file → Executable file
View File

0
CPP/Windows/COM.h Normal file → Executable file
View File

0
CPP/Windows/Clipboard.cpp Normal file → Executable file
View File

0
CPP/Windows/Clipboard.h Normal file → Executable file
View File

0
CPP/Windows/CommonDialog.cpp Normal file → Executable file
View File

0
CPP/Windows/CommonDialog.h Normal file → Executable file
View File

0
CPP/Windows/Console.cpp Normal file → Executable file
View File

0
CPP/Windows/Console.h Normal file → Executable file
View File

0
CPP/Windows/Control/ComboBox.cpp Normal file → Executable file
View File

0
CPP/Windows/Control/ComboBox.h Normal file → Executable file
View File

0
CPP/Windows/Control/CommandBar.h Normal file → Executable file
View File

0
CPP/Windows/Control/Dialog.cpp Normal file → Executable file
View File

0
CPP/Windows/Control/Dialog.h Normal file → Executable file
View File

0
CPP/Windows/Control/Edit.h Normal file → Executable file
View File

0
CPP/Windows/Control/ImageList.cpp Normal file → Executable file
View File

0
CPP/Windows/Control/ImageList.h Normal file → Executable file
View File

0
CPP/Windows/Control/ListView.cpp Normal file → Executable file
View File

0
CPP/Windows/Control/ListView.h Normal file → Executable file
View File

0
CPP/Windows/Control/ProgressBar.h Normal file → Executable file
View File

0
CPP/Windows/Control/PropertyPage.cpp Normal file → Executable file
View File

0
CPP/Windows/Control/PropertyPage.h Normal file → Executable file
View File

0
CPP/Windows/Control/ReBar.h Normal file → Executable file
View File

0
CPP/Windows/Control/Static.h Normal file → Executable file
View File

0
CPP/Windows/Control/StatusBar.h Normal file → Executable file
View File

0
CPP/Windows/Control/StdAfx.h Normal file → Executable file
View File

0
CPP/Windows/Control/ToolBar.h Normal file → Executable file
View File

0
CPP/Windows/Control/Trackbar.h Normal file → Executable file
View File

0
CPP/Windows/Control/Window2.cpp Normal file → Executable file
View File

0
CPP/Windows/Control/Window2.h Normal file → Executable file
View File

0
CPP/Windows/DLL.cpp Normal file → Executable file
View File

0
CPP/Windows/DLL.h Normal file → Executable file
View File

0
CPP/Windows/Defs.h Normal file → Executable file
View File

0
CPP/Windows/ErrorMsg.cpp Normal file → Executable file
View File

0
CPP/Windows/ErrorMsg.h Normal file → Executable file
View File

73
CPP/Windows/FileDir.cpp Normal file → Executable file
View File

@@ -17,7 +17,6 @@
#include "../Common/StringConvert.h"
#include "../Common/C_FileIO.h"
#include "TimeUtils.h"
#endif
#include "FileDir.h"
@@ -32,6 +31,30 @@ using namespace NWindows;
using namespace NFile;
using namespace NName;
#ifndef _WIN32
static bool FiTime_To_timespec(const CFiTime *ft, timespec &ts)
{
if (ft)
{
ts = *ft;
return true;
}
// else
{
ts.tv_sec = 0;
ts.tv_nsec =
#ifdef UTIME_OMIT
UTIME_OMIT; // -2 keep old timesptamp
#else
// UTIME_NOW; -1 // set to the current time
0;
#endif
return false;
}
}
#endif
namespace NWindows {
namespace NFile {
namespace NDir {
@@ -86,7 +109,7 @@ bool GetSystemDir(FString &path)
#endif // UNDER_CE
bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime)
{
#ifndef _UNICODE
if (!g_IsNT)
@@ -920,39 +943,11 @@ bool GetCurrentDir(FString &path)
// #define UTIME_OMIT -2
#endif
static bool FILETME_To_timespec(const FILETIME *ft, timespec &ts)
{
if (ft)
{
const Int64 sec = NTime::FileTimeToUnixTime64(*ft);
// time_t is long
const time_t sec2 = (time_t)sec;
if (sec2 == sec)
{
ts.tv_sec = sec2;
const UInt64 winTime = (((UInt64)ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
ts.tv_nsec = (long)((winTime % 10000000) * 100);
return true;
}
}
// else
{
ts.tv_sec = 0;
ts.tv_nsec =
#ifdef UTIME_OMIT
UTIME_OMIT; // keep old timesptamp
#else
// UTIME_NOW; // set to the current time
0;
#endif
return false;
}
}
bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime)
{
// need testing
/*
@@ -998,12 +993,18 @@ bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const
UNUSED_VAR(cTime)
bool needChange;
needChange = FILETME_To_timespec(aTime, times[0]);
needChange |= FILETME_To_timespec(mTime, times[1]);
needChange = FiTime_To_timespec(aTime, times[0]);
needChange |= FiTime_To_timespec(mTime, times[1]);
/*
if (mTime)
{
printf("\n time = %ld.%9ld\n", mTime->tv_sec, mTime->tv_nsec);
}
*/
if (!needChange)
return true;
const int flags = 0; // follow link
// = AT_SYMLINK_NOFOLLOW; // don't follow link
return utimensat(AT_FDCWD, path, times, flags) == 0;
@@ -1039,6 +1040,10 @@ static C_umask g_umask;
#define TRACE_chmod(s, mode) \
PRF(printf("\n chmod(%s, %o)\n", (const char *)path, (unsigned)(mode)));
int my_chown(CFSTR path, uid_t owner, gid_t group)
{
return chown(path, owner, group);
}
bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib)
{

10
CPP/Windows/FileDir.h Normal file → Executable file
View File

@@ -14,7 +14,12 @@ namespace NDir {
bool GetWindowsDir(FString &path);
bool GetSystemDir(FString &path);
bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
/*
WIN32 API : SetFileTime() doesn't allow to set zero timestamps in file
but linux : allows unix time = 0 in filesystem
*/
bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime);
#ifdef _WIN32
@@ -27,6 +32,9 @@ bool SetFileAttrib(CFSTR path, DWORD attrib);
SetFileAttrib_PosixHighDetect() tries to detect posix field, and it extracts only attribute
bits that are related to current system only.
*/
#else
int my_chown(CFSTR path, uid_t owner, gid_t group);
#endif

133
CPP/Windows/FileFind.cpp Normal file → Executable file
View File

@@ -7,6 +7,8 @@
#ifndef _WIN32
#include <fcntl.h> /* Definition of AT_* constants */
#include "TimeUtils.h"
// for major
// #include <sys/sysmacros.h>
#endif
#include "FileFind.h"
@@ -62,24 +64,35 @@ bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize,
namespace NFind {
/*
#ifdef _WIN32
#define MY_CLEAR_FILETIME(ft) ft.dwLowDateTime = ft.dwHighDateTime = 0;
#else
#define MY_CLEAR_FILETIME(ft) ft.tv_sec = 0; ft.tv_nsec = 0;
#endif
*/
void CFileInfoBase::ClearBase() throw()
{
Size = 0;
MY_CLEAR_FILETIME(CTime);
MY_CLEAR_FILETIME(ATime);
MY_CLEAR_FILETIME(MTime);
FiTime_Clear(CTime);
FiTime_Clear(ATime);
FiTime_Clear(MTime);
#ifdef _WIN32
Attrib = 0;
// ReparseTag = 0;
IsAltStream = false;
IsDevice = false;
#ifndef _WIN32
#else
dev = 0;
ino = 0;
nlink = 0;
mode = 0;
#endif
nlink = 0;
uid = 0;
gid = 0;
rdev = 0;
#endif
}
bool CFileInfo::IsDots() const throw()
@@ -439,6 +452,20 @@ also we support paths that are not supported by FindFirstFile:
bool CFileInfo::Find(CFSTR path, bool followLink)
{
#ifdef SUPPORT_DEVICE_FILE
if (IS_PATH_SEPAR(path[0]) &&
IS_PATH_SEPAR(path[1]) &&
path[2] == '.' &&
path[3] == 0)
{
// 22.00 : it's virtual directory for devices
// IsDevice = true;
ClearBase();
Name = path + 2;
Attrib = FILE_ATTRIBUTE_DIRECTORY;
return true;
}
if (IsDevicePath(path))
{
ClearBase();
@@ -469,7 +496,7 @@ bool CFileInfo::Find(CFSTR path, bool followLink)
#if defined(_WIN32) && !defined(UNDER_CE)
int colonPos = FindAltStreamColon(path);
const int colonPos = FindAltStreamColon(path);
if (colonPos >= 0 && path[(unsigned)colonPos + 1] != 0)
{
UString streamName = fs2us(path + (unsigned)colonPos);
@@ -635,7 +662,7 @@ bool CFileInfo::Find(CFSTR path, bool followLink)
return Fill_From_ByHandleFileInfo(path);
}
bool CFileInfo::Fill_From_ByHandleFileInfo(CFSTR path)
bool CFileInfoBase::Fill_From_ByHandleFileInfo(CFSTR path)
{
BY_HANDLE_FILE_INFORMATION info;
if (!NIO::CFileBase::GetFileInformation(path, &info))
@@ -950,13 +977,6 @@ static const char *Get_Name_from_Path(CFSTR path) throw()
}
void timespec_To_FILETIME(const MY_ST_TIMESPEC &ts, FILETIME &ft)
{
UInt64 v = NTime::UnixTime64ToFileTime64(ts.tv_sec) + ((UInt64)ts.tv_nsec / 100);
ft.dwLowDateTime = (DWORD)v;
ft.dwHighDateTime = (DWORD)(v >> 32);
}
UInt32 Get_WinAttribPosix_From_PosixMode(UInt32 mode)
{
UInt32 attrib = S_ISDIR(mode) ?
@@ -984,7 +1004,7 @@ UInt32 Get_WinAttrib_From_stat(const struct stat &st)
void CFileInfo::SetFrom_stat(const struct stat &st)
{
IsDevice = false;
// IsDevice = false;
if (S_ISDIR(st.st_mode))
{
@@ -995,7 +1015,7 @@ void CFileInfo::SetFrom_stat(const struct stat &st)
Size = (UInt64)st.st_size; // for a symbolic link, size = size of filename
}
Attrib = Get_WinAttribPosix_From_PosixMode(st.st_mode);
// Attrib = Get_WinAttribPosix_From_PosixMode(st.st_mode);
// NTime::UnixTimeToFileTime(st.st_ctime, CTime);
// NTime::UnixTimeToFileTime(st.st_mtime, MTime);
@@ -1010,27 +1030,89 @@ void CFileInfo::SetFrom_stat(const struct stat &st)
*/
// timespec_To_FILETIME(st.st_birthtimespec, CTime);
// #else
timespec_To_FILETIME(st.st_ctimespec, CTime);
// timespec_To_FILETIME(st.st_ctimespec, CTime);
// #endif
timespec_To_FILETIME(st.st_mtimespec, MTime);
timespec_To_FILETIME(st.st_atimespec, ATime);
// timespec_To_FILETIME(st.st_mtimespec, MTime);
// timespec_To_FILETIME(st.st_atimespec, ATime);
CTime = st.st_ctimespec;
MTime = st.st_mtimespec;
ATime = st.st_atimespec;
#else
timespec_To_FILETIME(st.st_ctim, CTime);
timespec_To_FILETIME(st.st_mtim, MTime);
timespec_To_FILETIME(st.st_atim, ATime);
// timespec_To_FILETIME(st.st_ctim, CTime, &CTime_ns100);
// timespec_To_FILETIME(st.st_mtim, MTime, &MTime_ns100);
// timespec_To_FILETIME(st.st_atim, ATime, &ATime_ns100);
CTime = st.st_ctim;
MTime = st.st_mtim;
ATime = st.st_atim;
#endif
dev = st.st_dev;
ino = st.st_ino;
nlink = st.st_nlink;
mode = st.st_mode;
nlink = st.st_nlink;
uid = st.st_uid;
gid = st.st_gid;
rdev = st.st_rdev;
/*
printf("\n sizeof timespec = %d", (int)sizeof(timespec));
printf("\n sizeof st_rdev = %d", (int)sizeof(rdev));
printf("\n sizeof st_ino = %d", (int)sizeof(ino));
printf("\n sizeof mode_t = %d", (int)sizeof(mode_t));
printf("\n sizeof nlink_t = %d", (int)sizeof(nlink_t));
printf("\n sizeof uid_t = %d", (int)sizeof(uid_t));
printf("\n");
*/
/*
printf("\n st_rdev = %llx", (long long)rdev);
printf("\n st_dev = %llx", (long long)dev);
printf("\n dev : major = %5x minor = %5x", (unsigned)major(dev), (unsigned)minor(dev));
printf("\n st_ino = %lld", (long long)(ino));
printf("\n rdev : major = %5x minor = %5x", (unsigned)major(rdev), (unsigned)minor(rdev));
printf("\n size = %lld \n", (long long)(Size));
printf("\n");
*/
}
/*
int Uid_To_Uname(uid_t uid, AString &name)
{
name.Empty();
struct passwd *passwd;
if (uid != 0 && uid == cached_no_such_uid)
{
*uname = xstrdup ("");
return;
}
if (!cached_uname || uid != cached_uid)
{
passwd = getpwuid (uid);
if (passwd)
{
cached_uid = uid;
assign_string (&cached_uname, passwd->pw_name);
}
else
{
cached_no_such_uid = uid;
*uname = xstrdup ("");
return;
}
}
*uname = xstrdup (cached_uname);
}
*/
bool CFileInfo::Find_DontFill_Name(CFSTR path, bool followLink)
{
struct stat st;
if (MY__lstat(path, &st, followLink) != 0)
return false;
// printf("\nFind_DontFill_Name : name=%s\n", path);
SetFrom_stat(st);
return true;
}
@@ -1232,6 +1314,7 @@ bool CEnumerator::Fill_FileInfo(const CDirEntry &de, CFileInfo &fileInfo, bool f
if (res != 0)
return false;
// printf("\nname=%s\n", de.Name.Ptr());
fileInfo.SetFrom_stat(st);
fileInfo.Name = de.Name;
return true;

95
CPP/Windows/FileFind.h Normal file → Executable file
View File

@@ -9,10 +9,14 @@
#include <dirent.h>
#endif
#include "../Common/MyLinux.h"
#include "../Common/MyString.h"
#include "../Common/MyWindows.h"
#include "Defs.h"
#include "FileIO.h"
namespace NWindows {
namespace NFile {
namespace NFind {
@@ -32,6 +36,7 @@ bool DoesFileOrDirExist(CFSTR name);
DWORD GetFileAttrib(CFSTR path);
#ifdef _WIN32
namespace NAttributes
{
@@ -42,21 +47,38 @@ namespace NAttributes
inline bool IsArchived(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_ARCHIVE) != 0; }
inline bool IsCompressed(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_COMPRESSED) != 0; }
inline bool IsEncrypted(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_ENCRYPTED) != 0; }
inline UInt32 Get_PosixMode_From_WinAttrib(DWORD attrib)
{
UInt32 v = IsDir(attrib) ? MY_LIN_S_IFDIR : MY_LIN_S_IFREG;
/* 21.06: as WSL we allow write permissions (0222) for directories even for (FILE_ATTRIBUTE_READONLY).
So extracting at Linux will be allowed to write files inside (0777) directories. */
v |= ((IsReadOnly(attrib) && !IsDir(attrib)) ? 0555 : 0777);
return v;
}
}
#else
UInt32 Get_WinAttribPosix_From_PosixMode(UInt32 mode);
#endif
class CFileInfoBase
{
#ifdef _WIN32
bool MatchesMask(UINT32 mask) const { return ((Attrib & mask) != 0); }
#endif
public:
UInt64 Size;
FILETIME CTime;
FILETIME ATime;
FILETIME MTime;
CFiTime CTime;
CFiTime ATime;
CFiTime MTime;
#ifdef _WIN32
DWORD Attrib;
bool IsAltStream;
bool IsDevice;
#ifdef _WIN32
/*
#ifdef UNDER_CE
DWORD ObjectID;
@@ -64,24 +86,25 @@ public:
UINT32 ReparseTag;
#endif
*/
#else
dev_t dev;
#else
dev_t dev; /* ID of device containing file */
ino_t ino;
nlink_t nlink;
mode_t mode;
nlink_t nlink;
uid_t uid; /* user ID of owner */
gid_t gid; /* group ID of owner */
dev_t rdev; /* device ID (defined, if S_ISCHR(mode) || S_ISBLK(mode)) */
// bool Use_lstat;
#endif
#endif
CFileInfoBase() { ClearBase(); }
void ClearBase() throw();
void SetAsDir()
{
Attrib = FILE_ATTRIBUTE_DIRECTORY;
#ifndef _WIN32
Attrib |= (FILE_ATTRIBUTE_UNIX_EXTENSION + (S_IFDIR << 16));
#endif
}
#ifdef _WIN32
bool Fill_From_ByHandleFileInfo(CFSTR path);
void SetAsDir() { Attrib = FILE_ATTRIBUTE_DIRECTORY; } // |= (FILE_ATTRIBUTE_UNIX_EXTENSION + (S_IFDIR << 16));
void SetAsFile() { Attrib = 0; }
bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); }
bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); }
@@ -96,13 +119,33 @@ public:
bool IsSystem() const { return MatchesMask(FILE_ATTRIBUTE_SYSTEM); }
bool IsTemporary() const { return MatchesMask(FILE_ATTRIBUTE_TEMPORARY); }
#ifndef _WIN32
bool IsPosixLink() const
UInt32 GetWinAttrib() const { return Attrib; }
UInt32 GetPosixAttrib() const
{
const UInt32 mod = Attrib >> 16;
return S_ISLNK(mod);
return NAttributes::Get_PosixMode_From_WinAttrib(Attrib);
}
#endif
bool Has_Attrib_ReparsePoint() const { return (Attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0; }
#else
UInt32 GetPosixAttrib() const { return mode; }
UInt32 GetWinAttrib() const { return Get_WinAttribPosix_From_PosixMode(mode); }
bool IsDir() const { return S_ISDIR(mode); }
void SetAsDir() { mode = S_IFDIR; }
void SetAsFile() { mode = S_IFREG; }
bool IsReadOnly() const
{
// does linux support writing to ReadOnly files?
if ((mode & 0222) == 0) // S_IWUSR in p7zip
return true;
return false;
}
bool IsPosixLink() const { return S_ISLNK(mode); }
#endif
bool IsOsSymLink() const
{
@@ -126,7 +169,7 @@ struct CFileInfo: public CFileInfoBase
bool Find_FollowLink(CFSTR path) { return Find(path, true); }
#ifdef _WIN32
bool Fill_From_ByHandleFileInfo(CFSTR path);
// bool Fill_From_ByHandleFileInfo(CFSTR path);
// bool FollowReparse(CFSTR path, bool isDir);
#else
bool Find_DontFill_Name(CFSTR path, bool followLink = false);
@@ -287,16 +330,8 @@ inline UInt32 Get_WinAttrib_From_PosixMode(UInt32 mode)
}
*/
UInt32 Get_WinAttribPosix_From_PosixMode(UInt32 mode);
// UInt32 Get_WinAttrib_From_stat(const struct stat &st);
#if defined(_AIX)
#define MY_ST_TIMESPEC st_timespec
#else
#define MY_ST_TIMESPEC timespec
#endif
void timespec_To_FILETIME(const MY_ST_TIMESPEC &ts, FILETIME &ft);
#endif // WIN32

88
CPP/Windows/FileIO.cpp Normal file → Executable file
View File

@@ -8,6 +8,14 @@
// #include <stdio.h>
/*
#ifndef _WIN32
// for ioctl BLKGETSIZE64
#include <sys/ioctl.h>
#include <linux/fs.h>
#endif
*/
#include "FileIO.h"
#include "FileName.h"
@@ -615,7 +623,7 @@ namespace NWindows {
namespace NFile {
namespace NDir {
bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime);
}
namespace NIO {
@@ -629,6 +637,19 @@ bool CFileBase::OpenBinary(const char *name, int flags)
Close();
_handle = ::open(name, flags, 0666);
return _handle != -1;
/*
if (_handle == -1)
return false;
if (IsString1PrefixedByString2(name, "/dev/"))
{
// /dev/sda
// IsDeviceFile = true; // for debug
// SizeDefined = false;
// SizeDefined = (GetDeviceSize_InBytes(Size) == 0);
}
return true;
*/
}
bool CFileBase::Close()
@@ -638,6 +659,10 @@ bool CFileBase::Close()
if (close(_handle) != 0)
return false;
_handle = -1;
/*
IsDeviceFile = false;
SizeDefined = false;
*/
return true;
}
@@ -651,15 +676,35 @@ bool CFileBase::GetLength(UInt64 &length) const
const off_t lengthTemp = seek(0, SEEK_END);
seek(curPos, SEEK_SET);
length = (UInt64)lengthTemp;
/*
// 22.00:
if (lengthTemp == 1)
if (IsDeviceFile && SizeDefined)
{
length = Size;
return true;
}
*/
return (lengthTemp != -1);
}
off_t CFileBase::seek(off_t distanceToMove, int moveMethod) const
{
/*
if (IsDeviceFile && SizeDefined && moveMethod == SEEK_END)
{
printf("\n seek : IsDeviceFile moveMethod = %d distanceToMove = %ld\n", moveMethod, distanceToMove);
distanceToMove += Size;
moveMethod = SEEK_SET;
}
*/
// printf("\nCFileBase::seek() moveMethod = %d, distanceToMove = %lld", moveMethod, (long long)distanceToMove);
// off_t res = ::lseek(_handle, distanceToMove, moveMethod);
// printf("\n lseek : moveMethod = %d distanceToMove = %ld\n", moveMethod, distanceToMove);
return ::lseek(_handle, distanceToMove, moveMethod);
// printf(" res = %lld", (long long)res);
// return res;
}
@@ -694,6 +739,28 @@ bool CInFile::OpenShared(const char *name, bool)
return Open(name);
}
/*
int CFileBase::my_ioctl_BLKGETSIZE64(unsigned long long *numBlocks)
{
// we can read "/sys/block/sda/size" "/sys/block/sda/sda1/size" - partition
// #include <linux/fs.h>
return ioctl(_handle, BLKGETSIZE64, numBlocks);
// in block size
}
int CFileBase::GetDeviceSize_InBytes(UInt64 &size)
{
size = 0;
unsigned long long numBlocks;
int res = my_ioctl_BLKGETSIZE64(&numBlocks);
if (res == 0)
size = numBlocks; // another blockSize s possible?
printf("\nGetDeviceSize_InBytes res = %d, size = %lld\n", res, (long long)size);
return res;
}
*/
/*
On Linux (32-bit and 64-bit):
read(), write() (and similar system calls) will transfer at most
@@ -802,7 +869,7 @@ bool COutFile::Close()
return res;
}
bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw()
bool COutFile::SetTime(const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) throw()
{
// On some OS (cygwin, MacOSX ...), you must close the file before updating times
// return true;
@@ -811,9 +878,22 @@ bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILET
if (aTime) { ATime = *aTime; ATime_defined = true; } else ATime_defined = false;
if (mTime) { MTime = *mTime; MTime_defined = true; } else MTime_defined = false;
return true;
/*
struct timespec times[2];
UNUSED_VAR(cTime)
if (!aTime && !mTime)
return true;
bool needChange;
needChange = FiTime_To_timespec(aTime, times[0]);
needChange |= FiTime_To_timespec(mTime, times[1]);
if (!needChange)
return true;
return futimens(_handle, times) == 0;
*/
}
bool COutFile::SetMTime(const FILETIME *mTime) throw()
bool COutFile::SetMTime(const CFiTime *mTime) throw()
{
if (mTime) { MTime = *mTime; MTime_defined = true; } else MTime_defined = false;
return true;

44
CPP/Windows/FileIO.h Normal file → Executable file
View File

@@ -30,6 +30,8 @@
#include "../Common/MyString.h"
#include "../Common/MyBuffer.h"
#include "../Windows/TimeUtils.h"
#include "Defs.h"
HRESULT GetLastError_noZero_HRESULT();
@@ -94,6 +96,12 @@ struct CReparseAttr
UString GetPath() const;
};
#ifdef _WIN32
#define CFiInfo BY_HANDLE_FILE_INFORMATION
#define ST_MTIME(st) (st).ftLastWriteTime
#else
#define CFiInfo stat
#endif
#ifdef _WIN32
@@ -142,6 +150,8 @@ public:
CFileBase(): _handle(INVALID_HANDLE_VALUE), PreserveATime(false) {};
~CFileBase() { Close(); }
HANDLE GetHandle() const { return _handle; }
bool Close() throw();
bool GetPosition(UInt64 &position) const throw();
@@ -213,6 +223,15 @@ public:
#ifndef UNDER_CE
bool Open_for_ReadAttributes(CFSTR fileName)
{
return Create(fileName, FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS);
// we must use (FILE_FLAG_BACKUP_SEMANTICS) to open handle of directory.
}
bool OpenReparse(CFSTR fileName)
{
// 17.02 fix: to support Windows XP compatibility junctions:
@@ -240,8 +259,8 @@ public:
bool Create(CFSTR fileName, bool createAlways);
bool CreateAlways(CFSTR fileName, DWORD flagsAndAttributes);
bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw();
bool SetMTime(const FILETIME *mTime) throw();
bool SetTime(const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) throw();
bool SetMTime(const CFiTime *mTime) throw();
bool WritePart(const void *data, UInt32 size, UInt32 &processedSize) throw();
bool Write(const void *data, UInt32 size, UInt32 &processedSize) throw();
bool WriteFull(const void *data, size_t size) throw();
@@ -270,6 +289,12 @@ class CFileBase
protected:
int _handle;
/*
bool IsDeviceFile;
bool SizeDefined;
UInt64 Size; // it can be larger than real available size
*/
bool OpenBinary(const char *name, int flags);
public:
bool PreserveATime;
@@ -283,6 +308,11 @@ public:
off_t seekToCur() const throw();
// bool SeekToBegin() throw();
int my_fstat(struct stat *st) const { return fstat(_handle, st); }
/*
int my_ioctl_BLKGETSIZE64(unsigned long long *val);
int GetDeviceSize_InBytes(UInt64 &size);
void CalcDeviceSize(CFSTR s);
*/
};
class CInFile: public CFileBase
@@ -301,9 +331,9 @@ class COutFile: public CFileBase
bool ATime_defined;
bool MTime_defined;
FILETIME CTime;
FILETIME ATime;
FILETIME MTime;
CFiTime CTime;
CFiTime ATime;
CFiTime MTime;
AString Path;
ssize_t write_part(const void *data, size_t size) throw();
@@ -333,8 +363,8 @@ public:
{
return SetLength(length);
}
bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw();
bool SetMTime(const FILETIME *mTime) throw();
bool SetTime(const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) throw();
bool SetMTime(const CFiTime *mTime) throw();
};
}

0
CPP/Windows/FileLink.cpp Normal file → Executable file
View File

0
CPP/Windows/FileMapping.cpp Normal file → Executable file
View File

0
CPP/Windows/FileMapping.h Normal file → Executable file
View File

0
CPP/Windows/FileName.cpp Normal file → Executable file
View File

0
CPP/Windows/FileName.h Normal file → Executable file
View File

0
CPP/Windows/FileSystem.cpp Normal file → Executable file
View File

0
CPP/Windows/FileSystem.h Normal file → Executable file
View File

0
CPP/Windows/Handle.h Normal file → Executable file
View File

0
CPP/Windows/MemoryGlobal.cpp Normal file → Executable file
View File

0
CPP/Windows/MemoryGlobal.h Normal file → Executable file
View File

0
CPP/Windows/MemoryLock.cpp Normal file → Executable file
View File

0
CPP/Windows/MemoryLock.h Normal file → Executable file
View File

0
CPP/Windows/Menu.cpp Normal file → Executable file
View File

0
CPP/Windows/Menu.h Normal file → Executable file
View File

0
CPP/Windows/NationalTime.cpp Normal file → Executable file
View File

0
CPP/Windows/NationalTime.h Normal file → Executable file
View File

0
CPP/Windows/Net.cpp Normal file → Executable file
View File

0
CPP/Windows/Net.h Normal file → Executable file
View File

0
CPP/Windows/NtCheck.h Normal file → Executable file
View File

0
CPP/Windows/ProcessMessages.cpp Normal file → Executable file
View File

0
CPP/Windows/ProcessMessages.h Normal file → Executable file
View File

0
CPP/Windows/ProcessUtils.cpp Normal file → Executable file
View File

0
CPP/Windows/ProcessUtils.h Normal file → Executable file
View File

132
CPP/Windows/PropVariant.cpp Normal file → Executable file
View File

@@ -193,7 +193,7 @@ BSTR CPropVariant::AllocBstr(unsigned numChars)
}
#define SET_PROP_id_dest(id, dest) \
if (vt != id) { InternalClear(); vt = id; } dest = value;
if (vt != id) { InternalClear(); vt = id; } dest = value; wReserved1 = 0;
void CPropVariant::Set_Int32(Int32 value) throw()
{
@@ -217,67 +217,83 @@ SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart)
// SET_PROP_FUNC(Int64, VT_I8, hVal.QuadPart)
SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime)
#define CASE_SIMPLE_VT_VALUES \
case VT_EMPTY: \
case VT_BOOL: \
case VT_FILETIME: \
case VT_UI8: \
case VT_UI4: \
case VT_UI2: \
case VT_UI1: \
case VT_I8: \
case VT_I4: \
case VT_I2: \
case VT_I1: \
case VT_UINT: \
case VT_INT: \
case VT_NULL: \
case VT_ERROR: \
case VT_R4: \
case VT_R8: \
case VT_CY: \
case VT_DATE: \
/*
::VariantClear() and ::VariantCopy() don't work, if (vt == VT_FILETIME)
So we handle VT_FILETIME and another simple types directly
we call system functions for VT_BSTR and for unknown typed
*/
CPropVariant::~CPropVariant()
{
switch ((unsigned)vt)
{
CASE_SIMPLE_VT_VALUES
// vt = VT_EMPTY; // it's optional
return;
}
::VariantClear((tagVARIANT *)this);
}
HRESULT PropVariant_Clear(PROPVARIANT *prop) throw()
{
switch (prop->vt)
switch ((unsigned)prop->vt)
{
case VT_EMPTY:
case VT_UI1:
case VT_I1:
case VT_I2:
case VT_UI2:
case VT_BOOL:
case VT_I4:
case VT_UI4:
case VT_R4:
case VT_INT:
case VT_UINT:
case VT_ERROR:
case VT_FILETIME:
case VT_UI8:
case VT_R8:
case VT_CY:
case VT_DATE:
CASE_SIMPLE_VT_VALUES
prop->vt = VT_EMPTY;
prop->wReserved1 = 0;
prop->wReserved2 = 0;
prop->wReserved3 = 0;
prop->uhVal.QuadPart = 0;
return S_OK;
break;
default:
{
const HRESULT res = ::VariantClear((VARIANTARG *)prop);
if (res != S_OK || prop->vt != VT_EMPTY)
return res;
break;
}
}
return ::VariantClear((VARIANTARG *)prop);
// return ::PropVariantClear(prop);
// PropVariantClear can clear VT_BLOB.
prop->wReserved1 = 0;
prop->wReserved2 = 0;
prop->wReserved3 = 0;
prop->uhVal.QuadPart = 0;
return S_OK;
}
HRESULT CPropVariant::Clear() throw()
{
if (vt == VT_EMPTY)
{
wReserved1 = 0;
return S_OK;
}
return PropVariant_Clear(this);
}
HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw()
{
::VariantClear((tagVARIANT *)this);
switch (pSrc->vt)
Clear();
switch ((unsigned)pSrc->vt)
{
case VT_UI1:
case VT_I1:
case VT_I2:
case VT_UI2:
case VT_BOOL:
case VT_I4:
case VT_UI4:
case VT_R4:
case VT_INT:
case VT_UINT:
case VT_ERROR:
case VT_FILETIME:
case VT_UI8:
case VT_R8:
case VT_CY:
case VT_DATE:
CASE_SIMPLE_VT_VALUES
memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT));
return S_OK;
}
@@ -287,12 +303,13 @@ HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw()
HRESULT CPropVariant::Attach(PROPVARIANT *pSrc) throw()
{
HRESULT hr = Clear();
const HRESULT hr = Clear();
if (FAILED(hr))
return hr;
// memcpy((PROPVARIANT *)this, pSrc, sizeof(PROPVARIANT));
*(PROPVARIANT *)this = *pSrc;
pSrc->vt = VT_EMPTY;
pSrc->wReserved1 = 0;
return S_OK;
}
@@ -300,21 +317,25 @@ HRESULT CPropVariant::Detach(PROPVARIANT *pDest) throw()
{
if (pDest->vt != VT_EMPTY)
{
HRESULT hr = PropVariant_Clear(pDest);
const HRESULT hr = PropVariant_Clear(pDest);
if (FAILED(hr))
return hr;
}
// memcpy(pDest, this, sizeof(PROPVARIANT));
*pDest = *(PROPVARIANT *)this;
vt = VT_EMPTY;
wReserved1 = 0;
return S_OK;
}
HRESULT CPropVariant::InternalClear() throw()
{
if (vt == VT_EMPTY)
{
wReserved1 = 0;
return S_OK;
HRESULT hr = Clear();
}
const HRESULT hr = Clear();
if (FAILED(hr))
{
vt = VT_ERROR;
@@ -325,7 +346,7 @@ HRESULT CPropVariant::InternalClear() throw()
void CPropVariant::InternalCopy(const PROPVARIANT *pSrc)
{
HRESULT hr = Copy(pSrc);
const HRESULT hr = Copy(pSrc);
if (FAILED(hr))
{
if (hr == E_OUTOFMEMORY)
@@ -335,11 +356,12 @@ void CPropVariant::InternalCopy(const PROPVARIANT *pSrc)
}
}
int CPropVariant::Compare(const CPropVariant &a) throw()
{
if (vt != a.vt)
return MyCompare(vt, a.vt);
switch (vt)
switch ((unsigned)vt)
{
case VT_EMPTY: return 0;
// case VT_I1: return MyCompare(cVal, a.cVal);
@@ -352,7 +374,15 @@ int CPropVariant::Compare(const CPropVariant &a) throw()
case VT_I8: return MyCompare(hVal.QuadPart, a.hVal.QuadPart);
case VT_UI8: return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart);
case VT_BOOL: return -MyCompare(boolVal, a.boolVal);
case VT_FILETIME: return ::CompareFileTime(&filetime, &a.filetime);
case VT_FILETIME:
{
const int res = CompareFileTime(&filetime, &a.filetime);
if (res != 0)
return res;
const unsigned v1 = Get_Ns100();
const unsigned v2 = a.Get_Ns100();
return MyCompare(v1, v2);
}
case VT_BSTR: return 0; // Not implemented
default: return 0;
}

52
CPP/Windows/PropVariant.h Normal file → Executable file
View File

@@ -29,11 +29,14 @@ inline void PropVarEm_Set_UInt64(PROPVARIANT *p, UInt64 v) throw()
p->uhVal.QuadPart = v;
}
inline void PropVarEm_Set_FileTime64(PROPVARIANT *p, UInt64 v) throw()
inline void PropVarEm_Set_FileTime64_Prec(PROPVARIANT *p, UInt64 v, unsigned prec) throw()
{
p->vt = VT_FILETIME;
p->filetime.dwLowDateTime = (DWORD)v;
p->filetime.dwHighDateTime = (DWORD)(v >> 32);
p->wReserved1 = (WORD)prec;
p->wReserved2 = 0;
p->wReserved3 = 0;
}
inline void PropVarEm_Set_Bool(PROPVARIANT *p, bool b) throw()
@@ -63,7 +66,51 @@ public:
// uhVal.QuadPart = 0;
bstrVal = 0;
}
~CPropVariant() throw() { Clear(); }
void Set_FtPrec(unsigned prec)
{
wReserved1 = (WORD)prec;
wReserved2 = 0;
wReserved3 = 0;
}
void SetAsTimeFrom_FT_Prec(const FILETIME &ft, unsigned prec)
{
operator=(ft);
Set_FtPrec(prec);
}
void SetAsTimeFrom_Ft64_Prec(UInt64 v, unsigned prec)
{
FILETIME ft;
ft.dwLowDateTime = (DWORD)(UInt32)v;
ft.dwHighDateTime = (DWORD)(UInt32)(v >> 32);
operator=(ft);
Set_FtPrec(prec);
}
void SetAsTimeFrom_FT_Prec_Ns100(const FILETIME &ft, unsigned prec, unsigned ns100)
{
operator=(ft);
wReserved1 = (WORD)prec;
wReserved2 = (WORD)ns100;
wReserved3 = 0;
}
unsigned Get_Ns100() const
{
const unsigned prec = wReserved1;
const unsigned ns100 = wReserved2;
if (prec == 0
&& prec <= k_PropVar_TimePrec_1ns
&& ns100 < 100
&& wReserved3 == 0)
return ns100;
return 0;
}
~CPropVariant();
CPropVariant(const PROPVARIANT &varSrc);
CPropVariant(const CPropVariant &varSrc);
CPropVariant(BSTR bstrSrc);
@@ -118,7 +165,6 @@ public:
HRESULT InternalClear() throw();
void InternalCopy(const PROPVARIANT *pSrc);
int Compare(const CPropVariant &a) throw();
};

58
CPP/Windows/PropVariantConv.cpp Normal file → Executable file
View File

@@ -9,7 +9,7 @@
#define UINT_TO_STR_2(c, val) { s[0] = (c); s[1] = (char)('0' + (val) / 10); s[2] = (char)('0' + (val) % 10); s += 3; }
bool ConvertUtcFileTimeToString(const FILETIME &utc, char *s, int level) throw()
bool ConvertUtcFileTimeToString2(const FILETIME &utc, unsigned ns100, char *s, int level) throw()
{
*s = 0;
FILETIME ft;
@@ -18,7 +18,10 @@ bool ConvertUtcFileTimeToString(const FILETIME &utc, char *s, int level) throw()
SYSTEMTIME st;
if (!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
{
// win10 : that function doesn't work, if bit 63 of 64-bit FILETIME is set.
return false;
}
{
unsigned val = st.wYear;
@@ -71,6 +74,12 @@ bool ConvertUtcFileTimeToString(const FILETIME &utc, char *s, int level) throw()
numDigits = (unsigned)level;
s += numDigits;
}
if (level >= kTimestampPrintLevel_NTFS + 1)
{
*s++ = (char)('0' + (ns100 / 10));
if (level >= kTimestampPrintLevel_NTFS + 2)
*s++ = (char)('0' + (ns100 % 10));
}
}
}
}
@@ -80,6 +89,25 @@ bool ConvertUtcFileTimeToString(const FILETIME &utc, char *s, int level) throw()
}
bool ConvertUtcFileTimeToString(const FILETIME &utc, char *s, int level) throw()
{
return ConvertUtcFileTimeToString2(utc, 0, s, level);
}
bool ConvertUtcFileTimeToString2(const FILETIME &ft, unsigned ns100, wchar_t *dest, int level) throw()
{
char s[32];
bool res = ConvertUtcFileTimeToString2(ft, ns100, s, level);
for (unsigned i = 0;; i++)
{
Byte c = (Byte)s[i];
dest[i] = c;
if (c == 0)
break;
}
return res;
}
bool ConvertUtcFileTimeToString(const FILETIME &ft, wchar_t *dest, int level) throw()
{
char s[32];
@@ -106,7 +134,19 @@ void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw(
case VT_UI2: ConvertUInt32ToString(prop.uiVal, dest); return;
case VT_UI4: ConvertUInt32ToString(prop.ulVal, dest); return;
case VT_UI8: ConvertUInt64ToString(prop.uhVal.QuadPart, dest); return;
case VT_FILETIME: ConvertUtcFileTimeToString(prop.filetime, dest); return;
case VT_FILETIME:
{
// const unsigned prec = prop.wReserved1;
int level = 0;
/*
if (prec == 0)
level = 7;
else if (prec > 16 && prec <= 16 + 9)
level = prec - 16;
*/
ConvertUtcFileTimeToString(prop.filetime, dest, level);
return;
}
// case VT_I1: return ConvertInt64ToString(prop.cVal, dest); return;
case VT_I2: ConvertInt64ToString(prop.iVal, dest); return;
case VT_I4: ConvertInt64ToString(prop.lVal, dest); return;
@@ -127,7 +167,19 @@ void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) thr
case VT_UI2: ConvertUInt32ToString(prop.uiVal, dest); return;
case VT_UI4: ConvertUInt32ToString(prop.ulVal, dest); return;
case VT_UI8: ConvertUInt64ToString(prop.uhVal.QuadPart, dest); return;
case VT_FILETIME: ConvertUtcFileTimeToString(prop.filetime, dest); return;
case VT_FILETIME:
{
// const unsigned prec = prop.wReserved1;
int level = 0;
/*
if (prec == 0)
level = 7;
else if (prec > 16 && prec <= 16 + 9)
level = prec - 16;
*/
ConvertUtcFileTimeToString(prop.filetime, dest, level);
return;
}
// case VT_I1: return ConvertInt64ToString(prop.cVal, dest); return;
case VT_I2: ConvertInt64ToString(prop.iVal, dest); return;
case VT_I4: ConvertInt64ToString(prop.lVal, dest); return;

5
CPP/Windows/PropVariantConv.h Normal file → Executable file
View File

@@ -10,11 +10,14 @@
#define kTimestampPrintLevel_DAY -3
// #define kTimestampPrintLevel_HOUR -2
#define kTimestampPrintLevel_MIN -1
#define kTimestampPrintLevel_SEC 0
#define kTimestampPrintLevel_SEC 0
#define kTimestampPrintLevel_NTFS 7
#define kTimestampPrintLevel_NS 9
bool ConvertUtcFileTimeToString(const FILETIME &ft, char *s, int level = kTimestampPrintLevel_SEC) throw();
bool ConvertUtcFileTimeToString(const FILETIME &ft, wchar_t *s, int level = kTimestampPrintLevel_SEC) throw();
bool ConvertUtcFileTimeToString2(const FILETIME &ft, unsigned ns100, char *s, int level = kTimestampPrintLevel_SEC) throw();
bool ConvertUtcFileTimeToString2(const FILETIME &ft, unsigned ns100, wchar_t *s, int level = kTimestampPrintLevel_SEC) throw();
// provide at least 32 bytes for buffer including zero-end
// don't send VT_BSTR to these functions

0
CPP/Windows/PropVariantUtils.cpp Normal file → Executable file
View File

0
CPP/Windows/PropVariantUtils.h Normal file → Executable file
View File

0
CPP/Windows/Registry.cpp Normal file → Executable file
View File

0
CPP/Windows/Registry.h Normal file → Executable file
View File

0
CPP/Windows/ResourceString.cpp Normal file → Executable file
View File

0
CPP/Windows/ResourceString.h Normal file → Executable file
View File

2
CPP/Windows/SecurityUtils.cpp Normal file → Executable file
View File

@@ -2,8 +2,6 @@
#include "StdAfx.h"
#include "../Common/MyString.h"
#include "SecurityUtils.h"
namespace NWindows {

0
CPP/Windows/SecurityUtils.h Normal file → Executable file
View File

0
CPP/Windows/Shell.cpp Normal file → Executable file
View File

0
CPP/Windows/Shell.h Normal file → Executable file
View File

0
CPP/Windows/StdAfx.h Normal file → Executable file
View File

0
CPP/Windows/Synchronization.cpp Normal file → Executable file
View File

0
CPP/Windows/Synchronization.h Normal file → Executable file
View File

0
CPP/Windows/System.cpp Normal file → Executable file
View File

0
CPP/Windows/System.h Normal file → Executable file
View File

0
CPP/Windows/SystemInfo.cpp Normal file → Executable file
View File

0
CPP/Windows/SystemInfo.h Normal file → Executable file
View File

0
CPP/Windows/Thread.h Normal file → Executable file
View File

220
CPP/Windows/TimeUtils.cpp Normal file → Executable file
View File

@@ -22,7 +22,7 @@ static const UInt64 kUnixTimeOffset =
(UInt64)60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear));
static const UInt64 kNumSecondsInFileTime = (UInt64)(Int64)-1 / kNumTimeQuantumsInSecond;
bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft) throw()
bool DosTime_To_FileTime(UInt32 dosTime, FILETIME &ft) throw()
{
#if defined(_WIN32) && !defined(UNDER_CE)
return BOOLToBool(::DosDateTimeToFileTime((UInt16)(dosTime >> 16), (UInt16)(dosTime & 0xFFFF), &ft));
@@ -43,7 +43,7 @@ bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft) throw()
static const UInt32 kHighDosTime = 0xFF9FBF7D;
static const UInt32 kLowDosTime = 0x210000;
bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime) throw()
bool FileTime_To_DosTime(const FILETIME &ft, UInt32 &dosTime) throw()
{
#if defined(_WIN32) && !defined(UNDER_CE)
@@ -121,49 +121,86 @@ bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime) throw()
return true;
}
UInt64 UnixTimeToFileTime64(UInt32 unixTime) throw()
bool UtcFileTime_To_LocalDosTime(const FILETIME &utc, UInt32 &dosTime) throw()
{
FILETIME loc = { 0, 0 };
const UInt64 u1 = FILETIME_To_UInt64(utc);
const UInt64 kDelta = ((UInt64)1 << 41); // it's larger than quantums in 1 sec.
if (u1 >= kDelta)
{
if (!FileTimeToLocalFileTime(&utc, &loc))
loc = utc;
else
{
const UInt64 u2 = FILETIME_To_UInt64(loc);
const UInt64 delta = u1 < u2 ? (u2 - u1) : (u1 - u2);
if (delta > kDelta) // if FileTimeToLocalFileTime() overflow, we use UTC time
loc = utc;
}
}
return FileTime_To_DosTime(loc, dosTime);
}
UInt64 UnixTime_To_FileTime64(UInt32 unixTime) throw()
{
return (kUnixTimeOffset + (UInt64)unixTime) * kNumTimeQuantumsInSecond;
}
void UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft) throw()
void UnixTime_To_FileTime(UInt32 unixTime, FILETIME &ft) throw()
{
UInt64 v = UnixTimeToFileTime64(unixTime);
const UInt64 v = UnixTime_To_FileTime64(unixTime);
ft.dwLowDateTime = (DWORD)v;
ft.dwHighDateTime = (DWORD)(v >> 32);
}
UInt64 UnixTime64ToFileTime64(Int64 unixTime) throw()
UInt64 UnixTime64_To_FileTime64(Int64 unixTime) throw()
{
return (UInt64)((Int64)kUnixTimeOffset + unixTime) * kNumTimeQuantumsInSecond;
}
bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &ft) throw()
bool UnixTime64_To_FileTime64(Int64 unixTime, UInt64 &fileTime) throw()
{
if (unixTime > (Int64)(kNumSecondsInFileTime - kUnixTimeOffset))
{
ft.dwLowDateTime = ft.dwHighDateTime = (UInt32)(Int32)-1;
fileTime = (UInt64)(Int64)-1;
return false;
}
Int64 v = (Int64)kUnixTimeOffset + unixTime;
if (v < 0)
if (unixTime < -(Int64)kUnixTimeOffset)
{
ft.dwLowDateTime = ft.dwHighDateTime = 0;
fileTime = 0;
return false;
}
UInt64 v2 = (UInt64)v * kNumTimeQuantumsInSecond;
ft.dwLowDateTime = (DWORD)v2;
ft.dwHighDateTime = (DWORD)(v2 >> 32);
fileTime = UnixTime64_To_FileTime64(unixTime);
return true;
}
Int64 FileTimeToUnixTime64(const FILETIME &ft) throw()
bool UnixTime64_To_FileTime(Int64 unixTime, FILETIME &ft) throw()
{
UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
UInt64 v;
const bool res = UnixTime64_To_FileTime64(unixTime, v);
ft.dwLowDateTime = (DWORD)v;
ft.dwHighDateTime = (DWORD)(v >> 32);
return res;
}
Int64 FileTime_To_UnixTime64(const FILETIME &ft) throw()
{
const UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
return (Int64)(winTime / kNumTimeQuantumsInSecond) - (Int64)kUnixTimeOffset;
}
bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime) throw()
Int64 FileTime_To_UnixTime64_and_Quantums(const FILETIME &ft, UInt32 &quantums) throw()
{
const UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
quantums = (UInt32)(winTime % kNumTimeQuantumsInSecond);
return (Int64)(winTime / kNumTimeQuantumsInSecond) - (Int64)kUnixTimeOffset;
}
bool FileTime_To_UnixTime(const FILETIME &ft, UInt32 &unixTime) throw()
{
UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
winTime /= kNumTimeQuantumsInSecond;
@@ -173,9 +210,9 @@ bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime) throw()
return false;
}
winTime -= kUnixTimeOffset;
if (winTime > 0xFFFFFFFF)
if (winTime > (UInt32)0xFFFFFFFF)
{
unixTime = 0xFFFFFFFF;
unixTime = (UInt32)0xFFFFFFFF;
return false;
}
unixTime = (UInt32)winTime;
@@ -202,12 +239,13 @@ bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
return true;
}
void GetCurUtcFileTime(FILETIME &ft) throw()
void GetCurUtc_FiTime(CFiTime &ft) throw()
{
#ifdef _WIN32
// Both variants provide same low resolution on WinXP: about 15 ms.
// But GetSystemTimeAsFileTime is much faster.
#ifdef _WIN32
#ifdef UNDER_CE
SYSTEMTIME st;
GetSystemTime(&st);
@@ -216,8 +254,22 @@ void GetCurUtcFileTime(FILETIME &ft) throw()
GetSystemTimeAsFileTime(&ft);
#endif
#else
#else
FiTime_Clear(ft);
struct timeval now;
if (gettimeofday(&now, 0 ) == 0)
{
ft.tv_sec = now.tv_sec;
ft.tv_nsec = now.tv_usec * 1000;
}
#endif
}
#ifndef _WIN32
void GetCurUtcFileTime(FILETIME &ft) throw()
{
UInt64 v = 0;
struct timeval now;
if (gettimeofday(&now, 0 ) == 0)
@@ -227,8 +279,126 @@ void GetCurUtcFileTime(FILETIME &ft) throw()
}
ft.dwLowDateTime = (DWORD)v;
ft.dwHighDateTime = (DWORD)(v >> 32);
#endif
}
#endif
}}
#ifdef _WIN32
/*
void FiTime_Normalize_With_Prec(CFiTime &ft, unsigned prec)
{
if (prec == k_PropVar_TimePrec_0
|| prec == k_PropVar_TimePrec_HighPrec
|| prec >= k_PropVar_TimePrec_100ns)
return;
UInt64 v = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
int numDigits = (int)prec - (int)k_PropVar_TimePrec_Base;
UInt32 d;
if (prec == k_PropVar_TimePrec_DOS)
{
// we round up as windows DosDateTimeToFileTime()
v += NWindows::NTime::kNumTimeQuantumsInSecond * 2 - 1;
d = NWindows::NTime::kNumTimeQuantumsInSecond * 2;
}
else
{
if (prec == k_PropVar_TimePrec_Unix)
numDigits = 0;
else if (numDigits < 0)
return;
d = 1;
for (unsigned k = numDigits; k < 7; k++)
d *= 10;
}
v /= d;
v *= d;
ft.dwLowDateTime = (DWORD)v;
ft.dwHighDateTime = (DWORD)(v >> 32);
}
*/
#else
/*
void FiTime_Normalize_With_Prec(CFiTime &ft, unsigned prec)
{
if (prec >= k_PropVar_TimePrec_1ns
|| prec == k_PropVar_TimePrec_HighPrec)
return;
int numDigits = (int)prec - (int)k_PropVar_TimePrec_Base;
UInt32 d;
if (prec == k_PropVar_TimePrec_Unix ||
prec == (int)k_PropVar_TimePrec_Base)
{
ft.tv_nsec = 0;
return;
}
if (prec == k_PropVar_TimePrec_DOS)
{
// we round up as windows DosDateTimeToFileTime()
const unsigned sec1 = (ft.tv_sec & 1);
if (ft.tv_nsec == 0 && sec1 == 0)
return;
ft.tv_nsec = 0;
ft.tv_sec += 2 - sec1;
return;
}
{
if (prec == k_PropVar_TimePrec_0
|| numDigits < 0)
numDigits = 7;
d = 1;
for (unsigned k = numDigits; k < 9; k++)
d *= 10;
ft.tv_nsec /= d;
ft.tv_nsec *= d;
}
}
*/
int Compare_FiTime(const CFiTime *a1, const CFiTime *a2)
{
if (a1->tv_sec < a2->tv_sec) return -1;
if (a1->tv_sec > a2->tv_sec) return 1;
if (a1->tv_nsec < a2->tv_nsec) return -1;
if (a1->tv_nsec > a2->tv_nsec) return 1;
return 0;
}
bool FILETIME_To_timespec(const FILETIME &ft, timespec &ts)
{
UInt32 quantums;
const Int64 sec = NWindows::NTime::FileTime_To_UnixTime64_and_Quantums(ft, quantums);
// time_t is long
const time_t sec2 = (time_t)sec;
if (sec2 == sec)
{
ts.tv_sec = sec2;
ts.tv_nsec = (long)(quantums * 100);
return true;
}
return false;
}
void FiTime_To_FILETIME_ns100(const CFiTime &ts, FILETIME &ft, unsigned &ns100)
{
const UInt64 v = NWindows::NTime::UnixTime64_To_FileTime64(ts.tv_sec) + ((UInt64)ts.tv_nsec / 100);
ns100 = (unsigned)((UInt64)ts.tv_nsec % 100);
ft.dwLowDateTime = (DWORD)v;
ft.dwHighDateTime = (DWORD)(v >> 32);
}
void FiTime_To_FILETIME(const CFiTime &ts, FILETIME &ft)
{
const UInt64 v = NWindows::NTime::UnixTime64_To_FileTime64(ts.tv_sec) + ((UInt64)ts.tv_nsec / 100);
ft.dwLowDateTime = (DWORD)v;
ft.dwHighDateTime = (DWORD)(v >> 32);
}
#endif

130
CPP/Windows/TimeUtils.h Normal file → Executable file
View File

@@ -5,28 +5,142 @@
#include "../Common/MyTypes.h"
#include "../Common/MyWindows.h"
#include "PropVariant.h"
inline UInt64 FILETIME_To_UInt64(const FILETIME &ft)
{
return (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
}
inline void FILETIME_Clear(FILETIME &ft)
{
ft.dwLowDateTime = 0;
ft.dwHighDateTime = 0;
}
inline bool FILETIME_IsZero(const FILETIME &ft)
{
return (ft.dwHighDateTime == 0 && ft.dwLowDateTime == 0);
}
#ifdef _WIN32
#define CFiTime FILETIME
#define Compare_FiTime ::CompareFileTime
inline void FiTime_To_FILETIME(const CFiTime &ts, FILETIME &ft)
{
ft = ts;
}
/*
inline void FILETIME_To_FiTime(const FILETIME &ft, CFiTime &ts)
{
ts = ft;
}
*/
inline void FiTime_Clear(CFiTime &ft)
{
ft.dwLowDateTime = 0;
ft.dwHighDateTime = 0;
}
#else
#include <sys/stat.h>
#if defined(_AIX)
#define CFiTime st_timespec
#else
#define CFiTime timespec
#endif
int Compare_FiTime(const CFiTime *a1, const CFiTime *a2);
bool FILETIME_To_timespec(const FILETIME &ft, CFiTime &ts);
void FiTime_To_FILETIME(const CFiTime &ts, FILETIME &ft);
void FiTime_To_FILETIME_ns100(const CFiTime &ts, FILETIME &ft, unsigned &ns100);
inline void FiTime_Clear(CFiTime &ft)
{
ft.tv_sec = 0;
ft.tv_nsec = 0;
}
#ifdef __APPLE__
#define ST_MTIME(st) st.st_mtimespec
#define ST_ATIME(st) st.st_atimespec
#define ST_CTIME(st) st.st_ctimespec
#else
#define ST_MTIME(st) st.st_mtim
#define ST_ATIME(st) st.st_atim
#define ST_CTIME(st) st.st_ctim
#endif
#endif
// void FiTime_Normalize_With_Prec(CFiTime &ft, unsigned prec);
namespace NWindows {
namespace NTime {
bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime) throw();
bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime) throw();
bool DosTime_To_FileTime(UInt32 dosTime, FILETIME &fileTime) throw();
bool UtcFileTime_To_LocalDosTime(const FILETIME &utc, UInt32 &dosTime) throw();
bool FileTime_To_DosTime(const FILETIME &fileTime, UInt32 &dosTime) throw();
// UInt32 Unix Time : for dates 1970-2106
UInt64 UnixTimeToFileTime64(UInt32 unixTime) throw();
void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime) throw();
UInt64 UnixTime_To_FileTime64(UInt32 unixTime) throw();
void UnixTime_To_FileTime(UInt32 unixTime, FILETIME &fileTime) throw();
// Int64 Unix Time : negative values for dates before 1970
UInt64 UnixTime64ToFileTime64(Int64 unixTime) throw();
bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &fileTime) throw();
UInt64 UnixTime64_To_FileTime64(Int64 unixTime) throw(); // no check
bool UnixTime64_To_FileTime64(Int64 unixTime, UInt64 &fileTime) throw();
bool UnixTime64_To_FileTime(Int64 unixTime, FILETIME &fileTime) throw();
bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime) throw();
Int64 FileTimeToUnixTime64(const FILETIME &ft) throw();
Int64 FileTime64_To_UnixTime64(UInt64 ft64) throw();
bool FileTime_To_UnixTime(const FILETIME &fileTime, UInt32 &unixTime) throw();
Int64 FileTime_To_UnixTime64(const FILETIME &ft) throw();
Int64 FileTime_To_UnixTime64_and_Quantums(const FILETIME &ft, UInt32 &quantums) throw();
bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds) throw();
void GetCurUtc_FiTime(CFiTime &ft) throw();
#ifdef _WIN32
#define GetCurUtcFileTime GetCurUtc_FiTime
#else
void GetCurUtcFileTime(FILETIME &ft) throw();
#endif
}}
inline void PropVariant_SetFrom_UnixTime(NWindows::NCOM::CPropVariant &prop, UInt32 unixTime)
{
FILETIME ft;
NWindows::NTime::UnixTime_To_FileTime(unixTime, ft);
prop.SetAsTimeFrom_FT_Prec(ft, k_PropVar_TimePrec_Unix);
}
inline void PropVariant_SetFrom_NtfsTime(NWindows::NCOM::CPropVariant &prop, const FILETIME &ft)
{
prop.SetAsTimeFrom_FT_Prec(ft, k_PropVar_TimePrec_100ns);
}
inline void PropVariant_SetFrom_FiTime(NWindows::NCOM::CPropVariant &prop, const CFiTime &fts)
{
#ifdef _WIN32
PropVariant_SetFrom_NtfsTime(prop, fts);
#else
unsigned ns100;
FILETIME ft;
FiTime_To_FILETIME_ns100(fts, ft, ns100);
prop.SetAsTimeFrom_FT_Prec_Ns100(ft, k_PropVar_TimePrec_1ns, ns100);
#endif
}
inline bool PropVariant_SetFrom_DosTime(NWindows::NCOM::CPropVariant &prop, UInt32 dosTime)
{
FILETIME localFileTime, utc;
if (!NWindows::NTime::DosTime_To_FileTime(dosTime, localFileTime))
return false;
if (!LocalFileTimeToFileTime(&localFileTime, &utc))
return false;
prop.SetAsTimeFrom_FT_Prec(utc, k_PropVar_TimePrec_DOS);
return true;
}
#endif

0
CPP/Windows/Window.cpp Normal file → Executable file
View File

0
CPP/Windows/Window.h Normal file → Executable file
View File