aboutsummaryrefslogtreecommitdiff
path: root/CPP/Windows/FileFind.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--CPP/Windows/FileFind.cpp177
1 files changed, 145 insertions, 32 deletions
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;
25 25
26#if defined(_WIN32) && !defined(UNDER_CE) 26#if defined(_WIN32) && !defined(UNDER_CE)
27 27
28#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0502 // Win2003
29#define Z7_USE_DYN_FindFirstStream
30#endif
31
32#ifdef Z7_USE_DYN_FindFirstStream
33
34Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
35
28EXTERN_C_BEGIN 36EXTERN_C_BEGIN
29 37
30typedef enum 38typedef enum
@@ -46,6 +54,12 @@ typedef BOOL (APIENTRY *Func_FindNextStreamW)(HANDLE findStream, LPVOID findStre
46 54
47EXTERN_C_END 55EXTERN_C_END
48 56
57#else
58
59#define MY_WIN32_FIND_STREAM_DATA WIN32_FIND_STREAM_DATA
60#define My_FindStreamInfoStandard FindStreamInfoStandard
61
62#endif
49#endif // defined(_WIN32) && !defined(UNDER_CE) 63#endif // defined(_WIN32) && !defined(UNDER_CE)
50 64
51 65
@@ -95,6 +109,86 @@ void CFileInfoBase::ClearBase() throw()
95 #endif 109 #endif
96} 110}
97 111
112
113bool CFileInfoBase::SetAs_StdInFile()
114{
115 ClearBase();
116 Size = (UInt64)(Int64)-1;
117 NTime::GetCurUtc_FiTime(MTime);
118 CTime = ATime = MTime;
119
120#ifdef _WIN32
121
122 /* in GUI mode : GetStdHandle(STD_INPUT_HANDLE) returns NULL,
123 and it doesn't set LastError. */
124#if 1
125 SetLastError(0);
126 const HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
127 if (!h || h == INVALID_HANDLE_VALUE)
128 {
129 if (GetLastError() == 0)
130 SetLastError(ERROR_INVALID_HANDLE);
131 return false;
132 }
133 BY_HANDLE_FILE_INFORMATION info;
134 if (GetFileInformationByHandle(h, &info)
135 && info.dwVolumeSerialNumber)
136 {
137 Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow;
138 // FileID_Low = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow;
139 // NumLinks = SupportHardLinks ? info.nNumberOfLinks : 1;
140 Attrib = info.dwFileAttributes;
141 CTime = info.ftCreationTime;
142 ATime = info.ftLastAccessTime;
143 MTime = info.ftLastWriteTime;
144 }
145#if 0
146 printf(
147 "\ndwFileAttributes = %8x"
148 "\nftCreationTime = %8x"
149 "\nftLastAccessTime = %8x"
150 "\nftLastWriteTime = %8x"
151 "\ndwVolumeSerialNumber = %8x"
152 "\nnFileSizeHigh = %8x"
153 "\nnFileSizeLow = %8x"
154 "\nnNumberOfLinks = %8x"
155 "\nnFileIndexHigh = %8x"
156 "\nnFileIndexLow = %8x \n",
157 (unsigned)info.dwFileAttributes,
158 (unsigned)info.ftCreationTime.dwHighDateTime,
159 (unsigned)info.ftLastAccessTime.dwHighDateTime,
160 (unsigned)info.ftLastWriteTime.dwHighDateTime,
161 (unsigned)info.dwVolumeSerialNumber,
162 (unsigned)info.nFileSizeHigh,
163 (unsigned)info.nFileSizeLow,
164 (unsigned)info.nNumberOfLinks,
165 (unsigned)info.nFileIndexHigh,
166 (unsigned)info.nFileIndexLow);
167#endif
168#endif
169
170#else // non-Wiondow
171
172 mode = S_IFIFO | 0777; // 0755 : 0775 : 0664 : 0644 :
173#if 1
174 struct stat st;
175 if (fstat(0, &st) == 0)
176 {
177 SetFrom_stat(st);
178 if (!S_ISREG(st.st_mode)
179 // S_ISFIFO(st->st_mode)
180 || st.st_size == 0)
181 {
182 Size = (UInt64)(Int64)-1;
183 // mode = S_IFIFO | 0777;
184 }
185 }
186#endif
187#endif
188
189 return true;
190}
191
98bool CFileInfo::IsDots() const throw() 192bool CFileInfo::IsDots() const throw()
99{ 193{
100 if (!IsDir() || Name.IsEmpty()) 194 if (!IsDir() || Name.IsEmpty())
@@ -252,9 +346,11 @@ bool CFindFile::FindNext(CFileInfo &fi)
252//////////////////////////////// 346////////////////////////////////
253// AltStreams 347// AltStreams
254 348
349#ifdef Z7_USE_DYN_FindFirstStream
255static Func_FindFirstStreamW g_FindFirstStreamW; 350static Func_FindFirstStreamW g_FindFirstStreamW;
256static Func_FindNextStreamW g_FindNextStreamW; 351static Func_FindNextStreamW g_FindNextStreamW;
257 352#define MY_FindFirstStreamW g_FindFirstStreamW
353#define MY_FindNextStreamW g_FindNextStreamW
258static struct CFindStreamLoader 354static struct CFindStreamLoader
259{ 355{
260 CFindStreamLoader() 356 CFindStreamLoader()
@@ -268,6 +364,11 @@ static struct CFindStreamLoader
268 "FindNextStreamW"); 364 "FindNextStreamW");
269 } 365 }
270} g_FindStreamLoader; 366} g_FindStreamLoader;
367#else
368#define MY_FindFirstStreamW FindFirstStreamW
369#define MY_FindNextStreamW FindNextStreamW
370#endif
371
271 372
272bool CStreamInfo::IsMainStream() const throw() 373bool CStreamInfo::IsMainStream() const throw()
273{ 374{
@@ -320,16 +421,18 @@ bool CFindStream::FindFirst(CFSTR path, CStreamInfo &si)
320{ 421{
321 if (!Close()) 422 if (!Close())
322 return false; 423 return false;
424#ifdef Z7_USE_DYN_FindFirstStream
323 if (!g_FindFirstStreamW) 425 if (!g_FindFirstStreamW)
324 { 426 {
325 ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 427 ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
326 return false; 428 return false;
327 } 429 }
430#endif
328 { 431 {
329 MY_WIN32_FIND_STREAM_DATA sd; 432 MY_WIN32_FIND_STREAM_DATA sd;
330 SetLastError(0); 433 SetLastError(0);
331 IF_USE_MAIN_PATH 434 IF_USE_MAIN_PATH
332 _handle = g_FindFirstStreamW(fs2us(path), My_FindStreamInfoStandard, &sd, 0); 435 _handle = MY_FindFirstStreamW(fs2us(path), My_FindStreamInfoStandard, &sd, 0);
333 if (_handle == INVALID_HANDLE_VALUE) 436 if (_handle == INVALID_HANDLE_VALUE)
334 { 437 {
335 if (::GetLastError() == ERROR_HANDLE_EOF) 438 if (::GetLastError() == ERROR_HANDLE_EOF)
@@ -340,7 +443,7 @@ bool CFindStream::FindFirst(CFSTR path, CStreamInfo &si)
340 { 443 {
341 UString superPath; 444 UString superPath;
342 if (GetSuperPath(path, superPath, USE_MAIN_PATH)) 445 if (GetSuperPath(path, superPath, USE_MAIN_PATH))
343 _handle = g_FindFirstStreamW(superPath, My_FindStreamInfoStandard, &sd, 0); 446 _handle = MY_FindFirstStreamW(superPath, My_FindStreamInfoStandard, &sd, 0);
344 } 447 }
345 #endif 448 #endif
346 } 449 }
@@ -353,14 +456,16 @@ bool CFindStream::FindFirst(CFSTR path, CStreamInfo &si)
353 456
354bool CFindStream::FindNext(CStreamInfo &si) 457bool CFindStream::FindNext(CStreamInfo &si)
355{ 458{
459#ifdef Z7_USE_DYN_FindFirstStream
356 if (!g_FindNextStreamW) 460 if (!g_FindNextStreamW)
357 { 461 {
358 ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 462 ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
359 return false; 463 return false;
360 } 464 }
465#endif
361 { 466 {
362 MY_WIN32_FIND_STREAM_DATA sd; 467 MY_WIN32_FIND_STREAM_DATA sd;
363 if (!g_FindNextStreamW(_handle, &sd)) 468 if (!MY_FindNextStreamW(_handle, &sd))
364 return false; 469 return false;
365 Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(sd, si); 470 Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(sd, si);
366 } 471 }
@@ -622,7 +727,7 @@ bool CFileInfo::Find(CFSTR path, bool followLink)
622 727
623 FString s (path); 728 FString s (path);
624 s.Add_PathSepar(); 729 s.Add_PathSepar();
625 s += '*'; // CHAR_ANY_MASK 730 s.Add_Char('*'); // CHAR_ANY_MASK
626 bool isOK = false; 731 bool isOK = false;
627 if (finder.FindFirst(s, *this)) 732 if (finder.FindFirst(s, *this))
628 { 733 {
@@ -636,7 +741,7 @@ bool CFileInfo::Find(CFSTR path, bool followLink)
636 But it's possible that there are another items */ 741 But it's possible that there are another items */
637 } 742 }
638 { 743 {
639 DWORD attrib = GetFileAttrib(path); 744 const DWORD attrib = GetFileAttrib(path);
640 if (isOK || (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0)) 745 if (isOK || (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0))
641 { 746 {
642 ClearBase(); 747 ClearBase();
@@ -763,7 +868,7 @@ bool DoesFileOrDirExist(CFSTR name)
763void CEnumerator::SetDirPrefix(const FString &dirPrefix) 868void CEnumerator::SetDirPrefix(const FString &dirPrefix)
764{ 869{
765 _wildcard = dirPrefix; 870 _wildcard = dirPrefix;
766 _wildcard += '*'; 871 _wildcard.Add_Char('*');
767} 872}
768 873
769bool CEnumerator::NextAny(CFileInfo &fi) 874bool CEnumerator::NextAny(CFileInfo &fi)
@@ -925,7 +1030,7 @@ bool MyGetLogicalDriveStrings(CObjectVector<FString> &driveStrings)
925 1030
926// ---------- POSIX ---------- 1031// ---------- POSIX ----------
927 1032
928static int MY__lstat(CFSTR path, struct stat *st, bool followLink) 1033static int MY_lstat(CFSTR path, struct stat *st, bool followLink)
929{ 1034{
930 memset(st, 0, sizeof(*st)); 1035 memset(st, 0, sizeof(*st));
931 int res; 1036 int res;
@@ -941,18 +1046,26 @@ static int MY__lstat(CFSTR path, struct stat *st, bool followLink)
941 // printf("\nstat\n"); 1046 // printf("\nstat\n");
942 res = stat(path, st); 1047 res = stat(path, st);
943 } 1048 }
944 /* 1049#if 0
945 printf("\nres = %d\n", res); 1050#if defined(__clang__) && __clang_major__ >= 14
946 printf("\n st_dev = %lld \n", (long long)(st->st_dev)); 1051 #pragma GCC diagnostic ignored "-Wc++98-compat-pedantic"
947 printf("\n st_ino = %lld \n", (long long)(st->st_ino)); 1052#endif
948 printf("\n st_mode = %lld \n", (long long)(st->st_mode)); 1053
949 printf("\n st_nlink = %lld \n", (long long)(st->st_nlink)); 1054 printf("\n st_dev = %lld", (long long)(st->st_dev));
950 printf("\n st_uid = %lld \n", (long long)(st->st_uid)); 1055 printf("\n st_ino = %lld", (long long)(st->st_ino));
951 printf("\n st_gid = %lld \n", (long long)(st->st_gid)); 1056 printf("\n st_mode = %llx", (long long)(st->st_mode));
952 printf("\n st_size = %lld \n", (long long)(st->st_size)); 1057 printf("\n st_nlink = %lld", (long long)(st->st_nlink));
953 printf("\n st_blksize = %lld \n", (long long)(st->st_blksize)); 1058 printf("\n st_uid = %lld", (long long)(st->st_uid));
954 printf("\n st_blocks = %lld \n", (long long)(st->st_blocks)); 1059 printf("\n st_gid = %lld", (long long)(st->st_gid));
955 */ 1060 printf("\n st_size = %lld", (long long)(st->st_size));
1061 printf("\n st_blksize = %lld", (long long)(st->st_blksize));
1062 printf("\n st_blocks = %lld", (long long)(st->st_blocks));
1063 printf("\n st_ctim = %lld", (long long)(ST_CTIME((*st)).tv_sec));
1064 printf("\n st_mtim = %lld", (long long)(ST_MTIME((*st)).tv_sec));
1065 printf("\n st_atim = %lld", (long long)(ST_ATIME((*st)).tv_sec));
1066 printf(S_ISFIFO(st->st_mode) ? "\n FIFO" : "\n NO FIFO");
1067 printf("\n");
1068#endif
956 1069
957 return res; 1070 return res;
958} 1071}
@@ -1006,7 +1119,7 @@ UInt32 Get_WinAttrib_From_stat(const struct stat &st)
1006} 1119}
1007*/ 1120*/
1008 1121
1009void CFileInfo::SetFrom_stat(const struct stat &st) 1122void CFileInfoBase::SetFrom_stat(const struct stat &st)
1010{ 1123{
1011 // IsDevice = false; 1124 // IsDevice = false;
1012 1125
@@ -1114,7 +1227,7 @@ int Uid_To_Uname(uid_t uid, AString &name)
1114bool CFileInfo::Find_DontFill_Name(CFSTR path, bool followLink) 1227bool CFileInfo::Find_DontFill_Name(CFSTR path, bool followLink)
1115{ 1228{
1116 struct stat st; 1229 struct stat st;
1117 if (MY__lstat(path, &st, followLink) != 0) 1230 if (MY_lstat(path, &st, followLink) != 0)
1118 return false; 1231 return false;
1119 // printf("\nFind_DontFill_Name : name=%s\n", path); 1232 // printf("\nFind_DontFill_Name : name=%s\n", path);
1120 SetFrom_stat(st); 1233 SetFrom_stat(st);
@@ -1145,7 +1258,7 @@ bool DoesFileExist_Raw(CFSTR name)
1145{ 1258{
1146 // FIXME for symbolic links. 1259 // FIXME for symbolic links.
1147 struct stat st; 1260 struct stat st;
1148 if (MY__lstat(name, &st, false) != 0) 1261 if (MY_lstat(name, &st, false) != 0)
1149 return false; 1262 return false;
1150 return !S_ISDIR(st.st_mode); 1263 return !S_ISDIR(st.st_mode);
1151} 1264}
@@ -1154,7 +1267,7 @@ bool DoesFileExist_FollowLink(CFSTR name)
1154{ 1267{
1155 // FIXME for symbolic links. 1268 // FIXME for symbolic links.
1156 struct stat st; 1269 struct stat st;
1157 if (MY__lstat(name, &st, true) != 0) 1270 if (MY_lstat(name, &st, true) != 0)
1158 return false; 1271 return false;
1159 return !S_ISDIR(st.st_mode); 1272 return !S_ISDIR(st.st_mode);
1160} 1273}
@@ -1162,7 +1275,7 @@ bool DoesFileExist_FollowLink(CFSTR name)
1162bool DoesDirExist(CFSTR name, bool followLink) 1275bool DoesDirExist(CFSTR name, bool followLink)
1163{ 1276{
1164 struct stat st; 1277 struct stat st;
1165 if (MY__lstat(name, &st, followLink) != 0) 1278 if (MY_lstat(name, &st, followLink) != 0)
1166 return false; 1279 return false;
1167 return S_ISDIR(st.st_mode); 1280 return S_ISDIR(st.st_mode);
1168} 1281}
@@ -1170,7 +1283,7 @@ bool DoesDirExist(CFSTR name, bool followLink)
1170bool DoesFileOrDirExist(CFSTR name) 1283bool DoesFileOrDirExist(CFSTR name)
1171{ 1284{
1172 struct stat st; 1285 struct stat st;
1173 if (MY__lstat(name, &st, false) != 0) 1286 if (MY_lstat(name, &st, false) != 0)
1174 return false; 1287 return false;
1175 return true; 1288 return true;
1176} 1289}
@@ -1192,10 +1305,10 @@ bool CDirEntry::IsDots() const throw()
1192 /* some systems (like CentOS 7.x on XFS) have (Type == DT_UNKNOWN) 1305 /* some systems (like CentOS 7.x on XFS) have (Type == DT_UNKNOWN)
1193 we can call fstatat() for that case, but we use only (Name) check here */ 1306 we can call fstatat() for that case, but we use only (Name) check here */
1194 1307
1195 #if !defined(_AIX) 1308#if !defined(_AIX) && !defined(__sun)
1196 if (Type != DT_DIR && Type != DT_UNKNOWN) 1309 if (Type != DT_DIR && Type != DT_UNKNOWN)
1197 return false; 1310 return false;
1198 #endif 1311#endif
1199 1312
1200 return Name.Len() != 0 1313 return Name.Len() != 0
1201 && Name.Len() <= 2 1314 && Name.Len() <= 2
@@ -1232,7 +1345,7 @@ bool CEnumerator::NextAny(CDirEntry &fi, bool &found)
1232 1345
1233 fi.iNode = de->d_ino; 1346 fi.iNode = de->d_ino;
1234 1347
1235 #if !defined(_AIX) 1348#if !defined(_AIX) && !defined(__sun)
1236 fi.Type = de->d_type; 1349 fi.Type = de->d_type;
1237 /* some systems (like CentOS 7.x on XFS) have (Type == DT_UNKNOWN) 1350 /* some systems (like CentOS 7.x on XFS) have (Type == DT_UNKNOWN)
1238 we can set (Type) from fstatat() in that case. 1351 we can set (Type) from fstatat() in that case.
@@ -1247,7 +1360,7 @@ bool CEnumerator::NextAny(CDirEntry &fi, bool &found)
1247 fi.Type = DT_DIR; 1360 fi.Type = DT_DIR;
1248 } 1361 }
1249 */ 1362 */
1250 #endif 1363#endif
1251 1364
1252 /* 1365 /*
1253 if (de->d_type == DT_DIR) 1366 if (de->d_type == DT_DIR)
@@ -1313,7 +1426,7 @@ bool CEnumerator::Fill_FileInfo(const CDirEntry &de, CFileInfo &fileInfo, bool f
1313 1426
1314 /* 1427 /*
1315 const FString path = _wildcard + s; 1428 const FString path = _wildcard + s;
1316 int res = MY__lstat(path, &st, followLink); 1429 int res = MY_lstat(path, &st, followLink);
1317 */ 1430 */
1318 1431
1319 if (res != 0) 1432 if (res != 0)