diff options
Diffstat (limited to '')
-rw-r--r-- | CPP/Windows/FileFind.cpp | 177 |
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 | |||
34 | Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION | ||
35 | |||
28 | EXTERN_C_BEGIN | 36 | EXTERN_C_BEGIN |
29 | 37 | ||
30 | typedef enum | 38 | typedef enum |
@@ -46,6 +54,12 @@ typedef BOOL (APIENTRY *Func_FindNextStreamW)(HANDLE findStream, LPVOID findStre | |||
46 | 54 | ||
47 | EXTERN_C_END | 55 | EXTERN_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 | |||
113 | bool 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 | |||
98 | bool CFileInfo::IsDots() const throw() | 192 | bool 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 | ||
255 | static Func_FindFirstStreamW g_FindFirstStreamW; | 350 | static Func_FindFirstStreamW g_FindFirstStreamW; |
256 | static Func_FindNextStreamW g_FindNextStreamW; | 351 | static Func_FindNextStreamW g_FindNextStreamW; |
257 | 352 | #define MY_FindFirstStreamW g_FindFirstStreamW | |
353 | #define MY_FindNextStreamW g_FindNextStreamW | ||
258 | static struct CFindStreamLoader | 354 | static 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 | ||
272 | bool CStreamInfo::IsMainStream() const throw() | 373 | bool 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 | ||
354 | bool CFindStream::FindNext(CStreamInfo &si) | 457 | bool 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) | |||
763 | void CEnumerator::SetDirPrefix(const FString &dirPrefix) | 868 | void CEnumerator::SetDirPrefix(const FString &dirPrefix) |
764 | { | 869 | { |
765 | _wildcard = dirPrefix; | 870 | _wildcard = dirPrefix; |
766 | _wildcard += '*'; | 871 | _wildcard.Add_Char('*'); |
767 | } | 872 | } |
768 | 873 | ||
769 | bool CEnumerator::NextAny(CFileInfo &fi) | 874 | bool CEnumerator::NextAny(CFileInfo &fi) |
@@ -925,7 +1030,7 @@ bool MyGetLogicalDriveStrings(CObjectVector<FString> &driveStrings) | |||
925 | 1030 | ||
926 | // ---------- POSIX ---------- | 1031 | // ---------- POSIX ---------- |
927 | 1032 | ||
928 | static int MY__lstat(CFSTR path, struct stat *st, bool followLink) | 1033 | static 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 | ||
1009 | void CFileInfo::SetFrom_stat(const struct stat &st) | 1122 | void 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) | |||
1114 | bool CFileInfo::Find_DontFill_Name(CFSTR path, bool followLink) | 1227 | bool 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) | |||
1162 | bool DoesDirExist(CFSTR name, bool followLink) | 1275 | bool 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) | |||
1170 | bool DoesFileOrDirExist(CFSTR name) | 1283 | bool 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) |