diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2022-06-23 13:43:16 +0300 |
---|---|---|
committer | Kornel <kornel@geekhood.net> | 2022-06-23 13:43:16 +0300 |
commit | ec44a8a0700a8b2444b07f576be332f756754323 (patch) | |
tree | 0b19ee3b63dd53aacca6990451022aee54d0aa69 /CPP/Windows | |
parent | c3529a41f527101f05e9e834a19205ee33a3b097 (diff) |
Diffstat (limited to 'CPP/Windows')
89 files changed, 848 insertions, 194 deletions
diff --git a/CPP/Windows/COM.cpp b/CPP/Windows/COM.cpp index d0cb3211..d0cb3211 100644..100755 --- a/CPP/Windows/COM.cpp +++ b/CPP/Windows/COM.cpp diff --git a/CPP/Windows/COM.h b/CPP/Windows/COM.h index cee7f702..cee7f702 100644..100755 --- a/CPP/Windows/COM.h +++ b/CPP/Windows/COM.h diff --git a/CPP/Windows/Clipboard.cpp b/CPP/Windows/Clipboard.cpp index bc7e201d..bc7e201d 100644..100755 --- a/CPP/Windows/Clipboard.cpp +++ b/CPP/Windows/Clipboard.cpp diff --git a/CPP/Windows/Clipboard.h b/CPP/Windows/Clipboard.h index 60fedc13..60fedc13 100644..100755 --- a/CPP/Windows/Clipboard.h +++ b/CPP/Windows/Clipboard.h diff --git a/CPP/Windows/CommonDialog.cpp b/CPP/Windows/CommonDialog.cpp index eaaecada..eaaecada 100644..100755 --- a/CPP/Windows/CommonDialog.cpp +++ b/CPP/Windows/CommonDialog.cpp diff --git a/CPP/Windows/CommonDialog.h b/CPP/Windows/CommonDialog.h index aaf17ac5..aaf17ac5 100644..100755 --- a/CPP/Windows/CommonDialog.h +++ b/CPP/Windows/CommonDialog.h diff --git a/CPP/Windows/Console.cpp b/CPP/Windows/Console.cpp index 28ba1c47..28ba1c47 100644..100755 --- a/CPP/Windows/Console.cpp +++ b/CPP/Windows/Console.cpp diff --git a/CPP/Windows/Console.h b/CPP/Windows/Console.h index 43e02fa6..43e02fa6 100644..100755 --- a/CPP/Windows/Console.h +++ b/CPP/Windows/Console.h diff --git a/CPP/Windows/Control/ComboBox.cpp b/CPP/Windows/Control/ComboBox.cpp index f6ed8d34..f6ed8d34 100644..100755 --- a/CPP/Windows/Control/ComboBox.cpp +++ b/CPP/Windows/Control/ComboBox.cpp diff --git a/CPP/Windows/Control/ComboBox.h b/CPP/Windows/Control/ComboBox.h index f08b1f7c..f08b1f7c 100644..100755 --- a/CPP/Windows/Control/ComboBox.h +++ b/CPP/Windows/Control/ComboBox.h diff --git a/CPP/Windows/Control/CommandBar.h b/CPP/Windows/Control/CommandBar.h index a6197447..a6197447 100644..100755 --- a/CPP/Windows/Control/CommandBar.h +++ b/CPP/Windows/Control/CommandBar.h diff --git a/CPP/Windows/Control/Dialog.cpp b/CPP/Windows/Control/Dialog.cpp index 9ddd2342..9ddd2342 100644..100755 --- a/CPP/Windows/Control/Dialog.cpp +++ b/CPP/Windows/Control/Dialog.cpp diff --git a/CPP/Windows/Control/Dialog.h b/CPP/Windows/Control/Dialog.h index 8a39e996..8a39e996 100644..100755 --- a/CPP/Windows/Control/Dialog.h +++ b/CPP/Windows/Control/Dialog.h diff --git a/CPP/Windows/Control/Edit.h b/CPP/Windows/Control/Edit.h index 51a22c53..51a22c53 100644..100755 --- a/CPP/Windows/Control/Edit.h +++ b/CPP/Windows/Control/Edit.h diff --git a/CPP/Windows/Control/ImageList.cpp b/CPP/Windows/Control/ImageList.cpp index 3e22b956..3e22b956 100644..100755 --- a/CPP/Windows/Control/ImageList.cpp +++ b/CPP/Windows/Control/ImageList.cpp diff --git a/CPP/Windows/Control/ImageList.h b/CPP/Windows/Control/ImageList.h index 19feb117..19feb117 100644..100755 --- a/CPP/Windows/Control/ImageList.h +++ b/CPP/Windows/Control/ImageList.h diff --git a/CPP/Windows/Control/ListView.cpp b/CPP/Windows/Control/ListView.cpp index 16cfd396..16cfd396 100644..100755 --- a/CPP/Windows/Control/ListView.cpp +++ b/CPP/Windows/Control/ListView.cpp diff --git a/CPP/Windows/Control/ListView.h b/CPP/Windows/Control/ListView.h index a13b1041..a13b1041 100644..100755 --- a/CPP/Windows/Control/ListView.h +++ b/CPP/Windows/Control/ListView.h diff --git a/CPP/Windows/Control/ProgressBar.h b/CPP/Windows/Control/ProgressBar.h index 03743067..03743067 100644..100755 --- a/CPP/Windows/Control/ProgressBar.h +++ b/CPP/Windows/Control/ProgressBar.h diff --git a/CPP/Windows/Control/PropertyPage.cpp b/CPP/Windows/Control/PropertyPage.cpp index ce8696d4..ce8696d4 100644..100755 --- a/CPP/Windows/Control/PropertyPage.cpp +++ b/CPP/Windows/Control/PropertyPage.cpp diff --git a/CPP/Windows/Control/PropertyPage.h b/CPP/Windows/Control/PropertyPage.h index b68fd8fe..b68fd8fe 100644..100755 --- a/CPP/Windows/Control/PropertyPage.h +++ b/CPP/Windows/Control/PropertyPage.h diff --git a/CPP/Windows/Control/ReBar.h b/CPP/Windows/Control/ReBar.h index c2d58dbe..c2d58dbe 100644..100755 --- a/CPP/Windows/Control/ReBar.h +++ b/CPP/Windows/Control/ReBar.h diff --git a/CPP/Windows/Control/Static.h b/CPP/Windows/Control/Static.h index 5523b2e6..5523b2e6 100644..100755 --- a/CPP/Windows/Control/Static.h +++ b/CPP/Windows/Control/Static.h diff --git a/CPP/Windows/Control/StatusBar.h b/CPP/Windows/Control/StatusBar.h index 988b8470..988b8470 100644..100755 --- a/CPP/Windows/Control/StatusBar.h +++ b/CPP/Windows/Control/StatusBar.h diff --git a/CPP/Windows/Control/StdAfx.h b/CPP/Windows/Control/StdAfx.h index 1cbd7fea..1cbd7fea 100644..100755 --- a/CPP/Windows/Control/StdAfx.h +++ b/CPP/Windows/Control/StdAfx.h diff --git a/CPP/Windows/Control/ToolBar.h b/CPP/Windows/Control/ToolBar.h index 7bc93a24..7bc93a24 100644..100755 --- a/CPP/Windows/Control/ToolBar.h +++ b/CPP/Windows/Control/ToolBar.h diff --git a/CPP/Windows/Control/Trackbar.h b/CPP/Windows/Control/Trackbar.h index 313e0c85..313e0c85 100644..100755 --- a/CPP/Windows/Control/Trackbar.h +++ b/CPP/Windows/Control/Trackbar.h diff --git a/CPP/Windows/Control/Window2.cpp b/CPP/Windows/Control/Window2.cpp index 994d96e0..994d96e0 100644..100755 --- a/CPP/Windows/Control/Window2.cpp +++ b/CPP/Windows/Control/Window2.cpp diff --git a/CPP/Windows/Control/Window2.h b/CPP/Windows/Control/Window2.h index 7ac580cb..7ac580cb 100644..100755 --- a/CPP/Windows/Control/Window2.h +++ b/CPP/Windows/Control/Window2.h diff --git a/CPP/Windows/DLL.cpp b/CPP/Windows/DLL.cpp index cf5d01a3..cf5d01a3 100644..100755 --- a/CPP/Windows/DLL.cpp +++ b/CPP/Windows/DLL.cpp diff --git a/CPP/Windows/DLL.h b/CPP/Windows/DLL.h index 0c093eed..0c093eed 100644..100755 --- a/CPP/Windows/DLL.h +++ b/CPP/Windows/DLL.h diff --git a/CPP/Windows/Defs.h b/CPP/Windows/Defs.h index 1d96078d..1d96078d 100644..100755 --- a/CPP/Windows/Defs.h +++ b/CPP/Windows/Defs.h diff --git a/CPP/Windows/ErrorMsg.cpp b/CPP/Windows/ErrorMsg.cpp index f6343a5c..f6343a5c 100644..100755 --- a/CPP/Windows/ErrorMsg.cpp +++ b/CPP/Windows/ErrorMsg.cpp diff --git a/CPP/Windows/ErrorMsg.h b/CPP/Windows/ErrorMsg.h index 01204eb9..01204eb9 100644..100755 --- a/CPP/Windows/ErrorMsg.h +++ b/CPP/Windows/ErrorMsg.h diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp index 8a33fc8e..cce26385 100644..100755 --- a/CPP/Windows/FileDir.cpp +++ b/CPP/Windows/FileDir.cpp @@ -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) { diff --git a/CPP/Windows/FileDir.h b/CPP/Windows/FileDir.h index 6d6ddeaf..08281aaa 100644..100755 --- a/CPP/Windows/FileDir.h +++ b/CPP/Windows/FileDir.h @@ -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 diff --git a/CPP/Windows/FileFind.cpp b/CPP/Windows/FileFind.cpp index 591f8df0..c6557599 100644..100755 --- a/CPP/Windows/FileFind.cpp +++ b/CPP/Windows/FileFind.cpp @@ -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; diff --git a/CPP/Windows/FileFind.h b/CPP/Windows/FileFind.h index 8f28ee33..fcfe02c7 100644..100755 --- a/CPP/Windows/FileFind.h +++ b/CPP/Windows/FileFind.h @@ -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 diff --git a/CPP/Windows/FileIO.cpp b/CPP/Windows/FileIO.cpp index 2974b1b7..e51b0eb3 100644..100755 --- a/CPP/Windows/FileIO.cpp +++ b/CPP/Windows/FileIO.cpp @@ -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; diff --git a/CPP/Windows/FileIO.h b/CPP/Windows/FileIO.h index 22998ebe..80509653 100644..100755 --- a/CPP/Windows/FileIO.h +++ b/CPP/Windows/FileIO.h @@ -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(); }; } diff --git a/CPP/Windows/FileLink.cpp b/CPP/Windows/FileLink.cpp index 8ce634fd..8ce634fd 100644..100755 --- a/CPP/Windows/FileLink.cpp +++ b/CPP/Windows/FileLink.cpp diff --git a/CPP/Windows/FileMapping.cpp b/CPP/Windows/FileMapping.cpp index 1933f7c8..1933f7c8 100644..100755 --- a/CPP/Windows/FileMapping.cpp +++ b/CPP/Windows/FileMapping.cpp diff --git a/CPP/Windows/FileMapping.h b/CPP/Windows/FileMapping.h index f90c429f..f90c429f 100644..100755 --- a/CPP/Windows/FileMapping.h +++ b/CPP/Windows/FileMapping.h diff --git a/CPP/Windows/FileName.cpp b/CPP/Windows/FileName.cpp index d61ff7e1..d61ff7e1 100644..100755 --- a/CPP/Windows/FileName.cpp +++ b/CPP/Windows/FileName.cpp diff --git a/CPP/Windows/FileName.h b/CPP/Windows/FileName.h index de8bd134..de8bd134 100644..100755 --- a/CPP/Windows/FileName.h +++ b/CPP/Windows/FileName.h diff --git a/CPP/Windows/FileSystem.cpp b/CPP/Windows/FileSystem.cpp index 62594532..62594532 100644..100755 --- a/CPP/Windows/FileSystem.cpp +++ b/CPP/Windows/FileSystem.cpp diff --git a/CPP/Windows/FileSystem.h b/CPP/Windows/FileSystem.h index 9b49a025..9b49a025 100644..100755 --- a/CPP/Windows/FileSystem.h +++ b/CPP/Windows/FileSystem.h diff --git a/CPP/Windows/Handle.h b/CPP/Windows/Handle.h index 5878c830..5878c830 100644..100755 --- a/CPP/Windows/Handle.h +++ b/CPP/Windows/Handle.h diff --git a/CPP/Windows/MemoryGlobal.cpp b/CPP/Windows/MemoryGlobal.cpp index 2a22394b..2a22394b 100644..100755 --- a/CPP/Windows/MemoryGlobal.cpp +++ b/CPP/Windows/MemoryGlobal.cpp diff --git a/CPP/Windows/MemoryGlobal.h b/CPP/Windows/MemoryGlobal.h index c217510e..c217510e 100644..100755 --- a/CPP/Windows/MemoryGlobal.h +++ b/CPP/Windows/MemoryGlobal.h diff --git a/CPP/Windows/MemoryLock.cpp b/CPP/Windows/MemoryLock.cpp index fdfbeb9d..fdfbeb9d 100644..100755 --- a/CPP/Windows/MemoryLock.cpp +++ b/CPP/Windows/MemoryLock.cpp diff --git a/CPP/Windows/MemoryLock.h b/CPP/Windows/MemoryLock.h index dcaf182e..dcaf182e 100644..100755 --- a/CPP/Windows/MemoryLock.h +++ b/CPP/Windows/MemoryLock.h diff --git a/CPP/Windows/Menu.cpp b/CPP/Windows/Menu.cpp index 3ad69530..3ad69530 100644..100755 --- a/CPP/Windows/Menu.cpp +++ b/CPP/Windows/Menu.cpp diff --git a/CPP/Windows/Menu.h b/CPP/Windows/Menu.h index aacdc7c3..aacdc7c3 100644..100755 --- a/CPP/Windows/Menu.h +++ b/CPP/Windows/Menu.h diff --git a/CPP/Windows/NationalTime.cpp b/CPP/Windows/NationalTime.cpp index 0dcd31e0..0dcd31e0 100644..100755 --- a/CPP/Windows/NationalTime.cpp +++ b/CPP/Windows/NationalTime.cpp diff --git a/CPP/Windows/NationalTime.h b/CPP/Windows/NationalTime.h index 49b0e5e8..49b0e5e8 100644..100755 --- a/CPP/Windows/NationalTime.h +++ b/CPP/Windows/NationalTime.h diff --git a/CPP/Windows/Net.cpp b/CPP/Windows/Net.cpp index 2a3952a1..2a3952a1 100644..100755 --- a/CPP/Windows/Net.cpp +++ b/CPP/Windows/Net.cpp diff --git a/CPP/Windows/Net.h b/CPP/Windows/Net.h index 7b60b1b4..7b60b1b4 100644..100755 --- a/CPP/Windows/Net.h +++ b/CPP/Windows/Net.h diff --git a/CPP/Windows/NtCheck.h b/CPP/Windows/NtCheck.h index 0af32911..0af32911 100644..100755 --- a/CPP/Windows/NtCheck.h +++ b/CPP/Windows/NtCheck.h diff --git a/CPP/Windows/ProcessMessages.cpp b/CPP/Windows/ProcessMessages.cpp index 0f48aee2..0f48aee2 100644..100755 --- a/CPP/Windows/ProcessMessages.cpp +++ b/CPP/Windows/ProcessMessages.cpp diff --git a/CPP/Windows/ProcessMessages.h b/CPP/Windows/ProcessMessages.h index b2558a01..b2558a01 100644..100755 --- a/CPP/Windows/ProcessMessages.h +++ b/CPP/Windows/ProcessMessages.h diff --git a/CPP/Windows/ProcessUtils.cpp b/CPP/Windows/ProcessUtils.cpp index 9bf05383..9bf05383 100644..100755 --- a/CPP/Windows/ProcessUtils.cpp +++ b/CPP/Windows/ProcessUtils.cpp diff --git a/CPP/Windows/ProcessUtils.h b/CPP/Windows/ProcessUtils.h index e46f9ab2..e46f9ab2 100644..100755 --- a/CPP/Windows/ProcessUtils.h +++ b/CPP/Windows/ProcessUtils.h diff --git a/CPP/Windows/PropVariant.cpp b/CPP/Windows/PropVariant.cpp index 6e43c7bc..2b179500 100644..100755 --- a/CPP/Windows/PropVariant.cpp +++ b/CPP/Windows/PropVariant.cpp @@ -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; } diff --git a/CPP/Windows/PropVariant.h b/CPP/Windows/PropVariant.h index 108bf6b9..171402f7 100644..100755 --- a/CPP/Windows/PropVariant.h +++ b/CPP/Windows/PropVariant.h @@ -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(); }; diff --git a/CPP/Windows/PropVariantConv.cpp b/CPP/Windows/PropVariantConv.cpp index b58d37e6..3c9bbd17 100644..100755 --- a/CPP/Windows/PropVariantConv.cpp +++ b/CPP/Windows/PropVariantConv.cpp @@ -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; diff --git a/CPP/Windows/PropVariantConv.h b/CPP/Windows/PropVariantConv.h index 390e0b89..60677840 100644..100755 --- a/CPP/Windows/PropVariantConv.h +++ b/CPP/Windows/PropVariantConv.h @@ -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 diff --git a/CPP/Windows/PropVariantUtils.cpp b/CPP/Windows/PropVariantUtils.cpp index 6daee839..6daee839 100644..100755 --- a/CPP/Windows/PropVariantUtils.cpp +++ b/CPP/Windows/PropVariantUtils.cpp diff --git a/CPP/Windows/PropVariantUtils.h b/CPP/Windows/PropVariantUtils.h index 3dd8295f..3dd8295f 100644..100755 --- a/CPP/Windows/PropVariantUtils.h +++ b/CPP/Windows/PropVariantUtils.h diff --git a/CPP/Windows/Registry.cpp b/CPP/Windows/Registry.cpp index b20157d5..b20157d5 100644..100755 --- a/CPP/Windows/Registry.cpp +++ b/CPP/Windows/Registry.cpp diff --git a/CPP/Windows/Registry.h b/CPP/Windows/Registry.h index ca79dfe3..ca79dfe3 100644..100755 --- a/CPP/Windows/Registry.h +++ b/CPP/Windows/Registry.h diff --git a/CPP/Windows/ResourceString.cpp b/CPP/Windows/ResourceString.cpp index ae8182ed..ae8182ed 100644..100755 --- a/CPP/Windows/ResourceString.cpp +++ b/CPP/Windows/ResourceString.cpp diff --git a/CPP/Windows/ResourceString.h b/CPP/Windows/ResourceString.h index f0bdabf4..f0bdabf4 100644..100755 --- a/CPP/Windows/ResourceString.h +++ b/CPP/Windows/ResourceString.h diff --git a/CPP/Windows/SecurityUtils.cpp b/CPP/Windows/SecurityUtils.cpp index 640c90dc..8a7f45cd 100644..100755 --- a/CPP/Windows/SecurityUtils.cpp +++ b/CPP/Windows/SecurityUtils.cpp @@ -2,8 +2,6 @@ #include "StdAfx.h" -#include "../Common/MyString.h" - #include "SecurityUtils.h" namespace NWindows { diff --git a/CPP/Windows/SecurityUtils.h b/CPP/Windows/SecurityUtils.h index 8966dfd3..8966dfd3 100644..100755 --- a/CPP/Windows/SecurityUtils.h +++ b/CPP/Windows/SecurityUtils.h diff --git a/CPP/Windows/Shell.cpp b/CPP/Windows/Shell.cpp index d0f9032c..d0f9032c 100644..100755 --- a/CPP/Windows/Shell.cpp +++ b/CPP/Windows/Shell.cpp diff --git a/CPP/Windows/Shell.h b/CPP/Windows/Shell.h index de91d3f1..de91d3f1 100644..100755 --- a/CPP/Windows/Shell.h +++ b/CPP/Windows/Shell.h diff --git a/CPP/Windows/StdAfx.h b/CPP/Windows/StdAfx.h index 1766dfa8..1766dfa8 100644..100755 --- a/CPP/Windows/StdAfx.h +++ b/CPP/Windows/StdAfx.h diff --git a/CPP/Windows/Synchronization.cpp b/CPP/Windows/Synchronization.cpp index fbf919dc..fbf919dc 100644..100755 --- a/CPP/Windows/Synchronization.cpp +++ b/CPP/Windows/Synchronization.cpp diff --git a/CPP/Windows/Synchronization.h b/CPP/Windows/Synchronization.h index 7d2e8d2a..7d2e8d2a 100644..100755 --- a/CPP/Windows/Synchronization.h +++ b/CPP/Windows/Synchronization.h diff --git a/CPP/Windows/System.cpp b/CPP/Windows/System.cpp index 3a14b77d..3a14b77d 100644..100755 --- a/CPP/Windows/System.cpp +++ b/CPP/Windows/System.cpp diff --git a/CPP/Windows/System.h b/CPP/Windows/System.h index 23cb0dab..23cb0dab 100644..100755 --- a/CPP/Windows/System.h +++ b/CPP/Windows/System.h diff --git a/CPP/Windows/SystemInfo.cpp b/CPP/Windows/SystemInfo.cpp index d882a8ee..d882a8ee 100644..100755 --- a/CPP/Windows/SystemInfo.cpp +++ b/CPP/Windows/SystemInfo.cpp diff --git a/CPP/Windows/SystemInfo.h b/CPP/Windows/SystemInfo.h index e941d0aa..e941d0aa 100644..100755 --- a/CPP/Windows/SystemInfo.h +++ b/CPP/Windows/SystemInfo.h diff --git a/CPP/Windows/Thread.h b/CPP/Windows/Thread.h index 5fca173f..5fca173f 100644..100755 --- a/CPP/Windows/Thread.h +++ b/CPP/Windows/Thread.h diff --git a/CPP/Windows/TimeUtils.cpp b/CPP/Windows/TimeUtils.cpp index 1f1335f9..77d2c510 100644..100755 --- a/CPP/Windows/TimeUtils.cpp +++ b/CPP/Windows/TimeUtils.cpp @@ -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; +} + +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 FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime) throw() +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 diff --git a/CPP/Windows/TimeUtils.h b/CPP/Windows/TimeUtils.h index d1d8c150..60ee739f 100644..100755 --- a/CPP/Windows/TimeUtils.h +++ b/CPP/Windows/TimeUtils.h @@ -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 diff --git a/CPP/Windows/Window.cpp b/CPP/Windows/Window.cpp index 32af4aab..32af4aab 100644..100755 --- a/CPP/Windows/Window.cpp +++ b/CPP/Windows/Window.cpp diff --git a/CPP/Windows/Window.h b/CPP/Windows/Window.h index 83726c7a..83726c7a 100644..100755 --- a/CPP/Windows/Window.h +++ b/CPP/Windows/Window.h |