From fc662341e6f85da78ada0e443f6116b978f79f22 Mon Sep 17 00:00:00 2001 From: Igor Pavlov <87184205+ip7z@users.noreply.github.com> Date: Tue, 14 May 2024 00:00:00 +0000 Subject: 24.05 --- CPP/Windows/FileFind.cpp | 177 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 145 insertions(+), 32 deletions(-) (limited to 'CPP/Windows/FileFind.cpp') diff --git a/CPP/Windows/FileFind.cpp b/CPP/Windows/FileFind.cpp index c562a90..ca387f6 100644 --- a/CPP/Windows/FileFind.cpp +++ b/CPP/Windows/FileFind.cpp @@ -25,6 +25,14 @@ using namespace NName; #if defined(_WIN32) && !defined(UNDER_CE) +#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0502 // Win2003 +#define Z7_USE_DYN_FindFirstStream +#endif + +#ifdef Z7_USE_DYN_FindFirstStream + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + EXTERN_C_BEGIN typedef enum @@ -46,6 +54,12 @@ typedef BOOL (APIENTRY *Func_FindNextStreamW)(HANDLE findStream, LPVOID findStre EXTERN_C_END +#else + +#define MY_WIN32_FIND_STREAM_DATA WIN32_FIND_STREAM_DATA +#define My_FindStreamInfoStandard FindStreamInfoStandard + +#endif #endif // defined(_WIN32) && !defined(UNDER_CE) @@ -95,6 +109,86 @@ void CFileInfoBase::ClearBase() throw() #endif } + +bool CFileInfoBase::SetAs_StdInFile() +{ + ClearBase(); + Size = (UInt64)(Int64)-1; + NTime::GetCurUtc_FiTime(MTime); + CTime = ATime = MTime; + +#ifdef _WIN32 + + /* in GUI mode : GetStdHandle(STD_INPUT_HANDLE) returns NULL, + and it doesn't set LastError. */ +#if 1 + SetLastError(0); + const HANDLE h = GetStdHandle(STD_INPUT_HANDLE); + if (!h || h == INVALID_HANDLE_VALUE) + { + if (GetLastError() == 0) + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + BY_HANDLE_FILE_INFORMATION info; + if (GetFileInformationByHandle(h, &info) + && info.dwVolumeSerialNumber) + { + Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; + // FileID_Low = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow; + // NumLinks = SupportHardLinks ? info.nNumberOfLinks : 1; + Attrib = info.dwFileAttributes; + CTime = info.ftCreationTime; + ATime = info.ftLastAccessTime; + MTime = info.ftLastWriteTime; + } +#if 0 + printf( + "\ndwFileAttributes = %8x" + "\nftCreationTime = %8x" + "\nftLastAccessTime = %8x" + "\nftLastWriteTime = %8x" + "\ndwVolumeSerialNumber = %8x" + "\nnFileSizeHigh = %8x" + "\nnFileSizeLow = %8x" + "\nnNumberOfLinks = %8x" + "\nnFileIndexHigh = %8x" + "\nnFileIndexLow = %8x \n", + (unsigned)info.dwFileAttributes, + (unsigned)info.ftCreationTime.dwHighDateTime, + (unsigned)info.ftLastAccessTime.dwHighDateTime, + (unsigned)info.ftLastWriteTime.dwHighDateTime, + (unsigned)info.dwVolumeSerialNumber, + (unsigned)info.nFileSizeHigh, + (unsigned)info.nFileSizeLow, + (unsigned)info.nNumberOfLinks, + (unsigned)info.nFileIndexHigh, + (unsigned)info.nFileIndexLow); +#endif +#endif + +#else // non-Wiondow + + mode = S_IFIFO | 0777; // 0755 : 0775 : 0664 : 0644 : +#if 1 + struct stat st; + if (fstat(0, &st) == 0) + { + SetFrom_stat(st); + if (!S_ISREG(st.st_mode) + // S_ISFIFO(st->st_mode) + || st.st_size == 0) + { + Size = (UInt64)(Int64)-1; + // mode = S_IFIFO | 0777; + } + } +#endif +#endif + + return true; +} + bool CFileInfo::IsDots() const throw() { if (!IsDir() || Name.IsEmpty()) @@ -252,9 +346,11 @@ bool CFindFile::FindNext(CFileInfo &fi) //////////////////////////////// // AltStreams +#ifdef Z7_USE_DYN_FindFirstStream static Func_FindFirstStreamW g_FindFirstStreamW; -static Func_FindNextStreamW g_FindNextStreamW; - +static Func_FindNextStreamW g_FindNextStreamW; +#define MY_FindFirstStreamW g_FindFirstStreamW +#define MY_FindNextStreamW g_FindNextStreamW static struct CFindStreamLoader { CFindStreamLoader() @@ -268,6 +364,11 @@ static struct CFindStreamLoader "FindNextStreamW"); } } g_FindStreamLoader; +#else +#define MY_FindFirstStreamW FindFirstStreamW +#define MY_FindNextStreamW FindNextStreamW +#endif + bool CStreamInfo::IsMainStream() const throw() { @@ -320,16 +421,18 @@ bool CFindStream::FindFirst(CFSTR path, CStreamInfo &si) { if (!Close()) return false; +#ifdef Z7_USE_DYN_FindFirstStream if (!g_FindFirstStreamW) { ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return false; } +#endif { MY_WIN32_FIND_STREAM_DATA sd; SetLastError(0); IF_USE_MAIN_PATH - _handle = g_FindFirstStreamW(fs2us(path), My_FindStreamInfoStandard, &sd, 0); + _handle = MY_FindFirstStreamW(fs2us(path), My_FindStreamInfoStandard, &sd, 0); if (_handle == INVALID_HANDLE_VALUE) { if (::GetLastError() == ERROR_HANDLE_EOF) @@ -340,7 +443,7 @@ bool CFindStream::FindFirst(CFSTR path, CStreamInfo &si) { UString superPath; if (GetSuperPath(path, superPath, USE_MAIN_PATH)) - _handle = g_FindFirstStreamW(superPath, My_FindStreamInfoStandard, &sd, 0); + _handle = MY_FindFirstStreamW(superPath, My_FindStreamInfoStandard, &sd, 0); } #endif } @@ -353,14 +456,16 @@ bool CFindStream::FindFirst(CFSTR path, CStreamInfo &si) bool CFindStream::FindNext(CStreamInfo &si) { +#ifdef Z7_USE_DYN_FindFirstStream if (!g_FindNextStreamW) { ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return false; } +#endif { MY_WIN32_FIND_STREAM_DATA sd; - if (!g_FindNextStreamW(_handle, &sd)) + if (!MY_FindNextStreamW(_handle, &sd)) return false; Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(sd, si); } @@ -622,7 +727,7 @@ bool CFileInfo::Find(CFSTR path, bool followLink) FString s (path); s.Add_PathSepar(); - s += '*'; // CHAR_ANY_MASK + s.Add_Char('*'); // CHAR_ANY_MASK bool isOK = false; if (finder.FindFirst(s, *this)) { @@ -636,7 +741,7 @@ bool CFileInfo::Find(CFSTR path, bool followLink) But it's possible that there are another items */ } { - DWORD attrib = GetFileAttrib(path); + const DWORD attrib = GetFileAttrib(path); if (isOK || (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0)) { ClearBase(); @@ -763,7 +868,7 @@ bool DoesFileOrDirExist(CFSTR name) void CEnumerator::SetDirPrefix(const FString &dirPrefix) { _wildcard = dirPrefix; - _wildcard += '*'; + _wildcard.Add_Char('*'); } bool CEnumerator::NextAny(CFileInfo &fi) @@ -925,7 +1030,7 @@ bool MyGetLogicalDriveStrings(CObjectVector &driveStrings) // ---------- POSIX ---------- -static int MY__lstat(CFSTR path, struct stat *st, bool followLink) +static int MY_lstat(CFSTR path, struct stat *st, bool followLink) { memset(st, 0, sizeof(*st)); int res; @@ -941,18 +1046,26 @@ static int MY__lstat(CFSTR path, struct stat *st, bool followLink) // printf("\nstat\n"); res = stat(path, st); } - /* - printf("\nres = %d\n", res); - printf("\n st_dev = %lld \n", (long long)(st->st_dev)); - printf("\n st_ino = %lld \n", (long long)(st->st_ino)); - printf("\n st_mode = %lld \n", (long long)(st->st_mode)); - printf("\n st_nlink = %lld \n", (long long)(st->st_nlink)); - printf("\n st_uid = %lld \n", (long long)(st->st_uid)); - printf("\n st_gid = %lld \n", (long long)(st->st_gid)); - printf("\n st_size = %lld \n", (long long)(st->st_size)); - printf("\n st_blksize = %lld \n", (long long)(st->st_blksize)); - printf("\n st_blocks = %lld \n", (long long)(st->st_blocks)); - */ +#if 0 +#if defined(__clang__) && __clang_major__ >= 14 + #pragma GCC diagnostic ignored "-Wc++98-compat-pedantic" +#endif + + printf("\n st_dev = %lld", (long long)(st->st_dev)); + printf("\n st_ino = %lld", (long long)(st->st_ino)); + printf("\n st_mode = %llx", (long long)(st->st_mode)); + printf("\n st_nlink = %lld", (long long)(st->st_nlink)); + printf("\n st_uid = %lld", (long long)(st->st_uid)); + printf("\n st_gid = %lld", (long long)(st->st_gid)); + printf("\n st_size = %lld", (long long)(st->st_size)); + printf("\n st_blksize = %lld", (long long)(st->st_blksize)); + printf("\n st_blocks = %lld", (long long)(st->st_blocks)); + printf("\n st_ctim = %lld", (long long)(ST_CTIME((*st)).tv_sec)); + printf("\n st_mtim = %lld", (long long)(ST_MTIME((*st)).tv_sec)); + printf("\n st_atim = %lld", (long long)(ST_ATIME((*st)).tv_sec)); + printf(S_ISFIFO(st->st_mode) ? "\n FIFO" : "\n NO FIFO"); + printf("\n"); +#endif return res; } @@ -1006,7 +1119,7 @@ UInt32 Get_WinAttrib_From_stat(const struct stat &st) } */ -void CFileInfo::SetFrom_stat(const struct stat &st) +void CFileInfoBase::SetFrom_stat(const struct stat &st) { // IsDevice = false; @@ -1114,7 +1227,7 @@ int Uid_To_Uname(uid_t uid, AString &name) bool CFileInfo::Find_DontFill_Name(CFSTR path, bool followLink) { struct stat st; - if (MY__lstat(path, &st, followLink) != 0) + if (MY_lstat(path, &st, followLink) != 0) return false; // printf("\nFind_DontFill_Name : name=%s\n", path); SetFrom_stat(st); @@ -1145,7 +1258,7 @@ bool DoesFileExist_Raw(CFSTR name) { // FIXME for symbolic links. struct stat st; - if (MY__lstat(name, &st, false) != 0) + if (MY_lstat(name, &st, false) != 0) return false; return !S_ISDIR(st.st_mode); } @@ -1154,7 +1267,7 @@ bool DoesFileExist_FollowLink(CFSTR name) { // FIXME for symbolic links. struct stat st; - if (MY__lstat(name, &st, true) != 0) + if (MY_lstat(name, &st, true) != 0) return false; return !S_ISDIR(st.st_mode); } @@ -1162,7 +1275,7 @@ bool DoesFileExist_FollowLink(CFSTR name) bool DoesDirExist(CFSTR name, bool followLink) { struct stat st; - if (MY__lstat(name, &st, followLink) != 0) + if (MY_lstat(name, &st, followLink) != 0) return false; return S_ISDIR(st.st_mode); } @@ -1170,7 +1283,7 @@ bool DoesDirExist(CFSTR name, bool followLink) bool DoesFileOrDirExist(CFSTR name) { struct stat st; - if (MY__lstat(name, &st, false) != 0) + if (MY_lstat(name, &st, false) != 0) return false; return true; } @@ -1192,10 +1305,10 @@ bool CDirEntry::IsDots() const throw() /* some systems (like CentOS 7.x on XFS) have (Type == DT_UNKNOWN) we can call fstatat() for that case, but we use only (Name) check here */ - #if !defined(_AIX) +#if !defined(_AIX) && !defined(__sun) if (Type != DT_DIR && Type != DT_UNKNOWN) return false; - #endif +#endif return Name.Len() != 0 && Name.Len() <= 2 @@ -1232,7 +1345,7 @@ bool CEnumerator::NextAny(CDirEntry &fi, bool &found) fi.iNode = de->d_ino; - #if !defined(_AIX) +#if !defined(_AIX) && !defined(__sun) fi.Type = de->d_type; /* some systems (like CentOS 7.x on XFS) have (Type == DT_UNKNOWN) we can set (Type) from fstatat() in that case. @@ -1247,7 +1360,7 @@ bool CEnumerator::NextAny(CDirEntry &fi, bool &found) fi.Type = DT_DIR; } */ - #endif +#endif /* if (de->d_type == DT_DIR) @@ -1313,7 +1426,7 @@ bool CEnumerator::Fill_FileInfo(const CDirEntry &de, CFileInfo &fileInfo, bool f /* const FString path = _wildcard + s; - int res = MY__lstat(path, &st, followLink); + int res = MY_lstat(path, &st, followLink); */ if (res != 0) -- cgit v1.2.3-55-g6feb