aboutsummaryrefslogtreecommitdiff
path: root/CPP/Windows
diff options
context:
space:
mode:
authorIgor Pavlov <87184205+ip7z@users.noreply.github.com>2024-05-14 00:00:00 +0000
committerIgor Pavlov <87184205+ip7z@users.noreply.github.com>2024-05-15 23:55:04 +0500
commitfc662341e6f85da78ada0e443f6116b978f79f22 (patch)
tree1be1cc402a7a9cbc18d4eeea6b141354c2d559e3 /CPP/Windows
parent5b39dc76f1bc82f941d5c800ab9f34407a06b53a (diff)
download7zip-24.05.tar.gz
7zip-24.05.tar.bz2
7zip-24.05.zip
24.0524.05
Diffstat (limited to 'CPP/Windows')
-rw-r--r--CPP/Windows/Control/Dialog.cpp1
-rw-r--r--CPP/Windows/Control/Dialog.h19
-rw-r--r--CPP/Windows/Control/PropertyPage.cpp4
-rw-r--r--CPP/Windows/DLL.cpp9
-rw-r--r--CPP/Windows/FileDir.cpp26
-rw-r--r--CPP/Windows/FileFind.cpp177
-rw-r--r--CPP/Windows/FileFind.h19
-rw-r--r--CPP/Windows/FileIO.cpp125
-rw-r--r--CPP/Windows/FileIO.h76
-rw-r--r--CPP/Windows/FileLink.cpp17
-rw-r--r--CPP/Windows/FileName.cpp8
-rw-r--r--CPP/Windows/FileSystem.cpp27
-rw-r--r--CPP/Windows/MemoryLock.cpp3
-rw-r--r--CPP/Windows/ProcessUtils.cpp2
-rw-r--r--CPP/Windows/PropVariant.cpp2
-rw-r--r--CPP/Windows/PropVariantConv.cpp104
-rw-r--r--CPP/Windows/PropVariantConv.h9
-rw-r--r--CPP/Windows/Registry.cpp15
-rw-r--r--CPP/Windows/SecurityUtils.h2
-rw-r--r--CPP/Windows/Shell.cpp26
-rw-r--r--CPP/Windows/Shell.h1
-rw-r--r--CPP/Windows/StdAfx.h1
-rw-r--r--CPP/Windows/Synchronization.h5
-rw-r--r--CPP/Windows/System.cpp78
-rw-r--r--CPP/Windows/System.h2
-rw-r--r--CPP/Windows/SystemInfo.cpp225
-rw-r--r--CPP/Windows/TimeUtils.cpp90
27 files changed, 857 insertions, 216 deletions
diff --git a/CPP/Windows/Control/Dialog.cpp b/CPP/Windows/Control/Dialog.cpp
index c8f1bd2..cbb000b 100644
--- a/CPP/Windows/Control/Dialog.cpp
+++ b/CPP/Windows/Control/Dialog.cpp
@@ -93,6 +93,7 @@ bool CDialog::OnButtonClicked(unsigned buttonID, HWND /* buttonHWND */)
93 case IDOK: OnOK(); break; 93 case IDOK: OnOK(); break;
94 case IDCANCEL: OnCancel(); break; 94 case IDCANCEL: OnCancel(); break;
95 case IDCLOSE: OnClose(); break; 95 case IDCLOSE: OnClose(); break;
96 case IDCONTINUE: OnContinue(); break;
96 case IDHELP: OnHelp(); break; 97 case IDHELP: OnHelp(); break;
97 default: return false; 98 default: return false;
98 } 99 }
diff --git a/CPP/Windows/Control/Dialog.h b/CPP/Windows/Control/Dialog.h
index 06be4bf..2510c8f 100644
--- a/CPP/Windows/Control/Dialog.h
+++ b/CPP/Windows/Control/Dialog.h
@@ -8,6 +8,10 @@
8namespace NWindows { 8namespace NWindows {
9namespace NControl { 9namespace NControl {
10 10
11#ifndef IDCONTINUE
12#define IDCONTINUE 11
13#endif
14
11class CDialog: public CWindow 15class CDialog: public CWindow
12{ 16{
13 // Z7_CLASS_NO_COPY(CDialog) 17 // Z7_CLASS_NO_COPY(CDialog)
@@ -64,14 +68,26 @@ public:
64 return window.GetText(s); 68 return window.GetText(s);
65 } 69 }
66 70
71/*
67 bool SetItemInt(unsigned itemID, UINT value, bool isSigned) 72 bool SetItemInt(unsigned itemID, UINT value, bool isSigned)
68 { return BOOLToBool(SetDlgItemInt(_window, (int)itemID, value, BoolToBOOL(isSigned))); } 73 { return BOOLToBool(SetDlgItemInt(_window, (int)itemID, value, BoolToBOOL(isSigned))); }
74*/
75 bool SetItemUInt(unsigned itemID, UINT value)
76 { return BOOLToBool(SetDlgItemInt(_window, (int)itemID, value, FALSE)); }
77/*
69 bool GetItemInt(unsigned itemID, bool isSigned, UINT &value) 78 bool GetItemInt(unsigned itemID, bool isSigned, UINT &value)
70 { 79 {
71 BOOL result; 80 BOOL result;
72 value = GetDlgItemInt(_window, (int)itemID, &result, BoolToBOOL(isSigned)); 81 value = GetDlgItemInt(_window, (int)itemID, &result, BoolToBOOL(isSigned));
73 return BOOLToBool(result); 82 return BOOLToBool(result);
74 } 83 }
84*/
85 bool GetItemUInt(unsigned itemID, UINT &value)
86 {
87 BOOL result;
88 value = GetDlgItemInt(_window, (int)itemID, &result, FALSE);
89 return BOOLToBool(result);
90 }
75 91
76 HWND GetNextGroupItem(HWND control, bool previous) 92 HWND GetNextGroupItem(HWND control, bool previous)
77 { return GetNextDlgGroupItem(_window, control, BoolToBOOL(previous)); } 93 { return GetNextDlgGroupItem(_window, control, BoolToBOOL(previous)); }
@@ -126,6 +142,7 @@ public:
126 142
127 virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND); 143 virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND);
128 virtual void OnOK() {} 144 virtual void OnOK() {}
145 virtual void OnContinue() {}
129 virtual void OnCancel() {} 146 virtual void OnCancel() {}
130 virtual void OnClose() {} 147 virtual void OnClose() {}
131 virtual bool OnNotify(UINT /* controlID */, LPNMHDR /* lParam */) { return false; } 148 virtual bool OnNotify(UINT /* controlID */, LPNMHDR /* lParam */) { return false; }
@@ -157,6 +174,7 @@ public:
157 bool Create(LPCWSTR templateName, HWND parentWindow); 174 bool Create(LPCWSTR templateName, HWND parentWindow);
158 #endif 175 #endif
159 virtual void OnOK() Z7_override { Destroy(); } 176 virtual void OnOK() Z7_override { Destroy(); }
177 virtual void OnContinue() Z7_override { Destroy(); }
160 virtual void OnCancel() Z7_override { Destroy(); } 178 virtual void OnCancel() Z7_override { Destroy(); }
161 virtual void OnClose() Z7_override { Destroy(); } 179 virtual void OnClose() Z7_override { Destroy(); }
162}; 180};
@@ -172,6 +190,7 @@ public:
172 190
173 bool End(INT_PTR result) { return BOOLToBool(::EndDialog(_window, result)); } 191 bool End(INT_PTR result) { return BOOLToBool(::EndDialog(_window, result)); }
174 virtual void OnOK() Z7_override { End(IDOK); } 192 virtual void OnOK() Z7_override { End(IDOK); }
193 virtual void OnContinue() Z7_override { End(IDCONTINUE); }
175 virtual void OnCancel() Z7_override { End(IDCANCEL); } 194 virtual void OnCancel() Z7_override { End(IDCANCEL); }
176 virtual void OnClose() Z7_override { End(IDCLOSE); } 195 virtual void OnClose() Z7_override { End(IDCLOSE); }
177}; 196};
diff --git a/CPP/Windows/Control/PropertyPage.cpp b/CPP/Windows/Control/PropertyPage.cpp
index f8effe6..9b36cbe 100644
--- a/CPP/Windows/Control/PropertyPage.cpp
+++ b/CPP/Windows/Control/PropertyPage.cpp
@@ -141,7 +141,7 @@ INT_PTR MyPropertySheet(const CObjectVector<CPageInfo> &pagesInfo, HWND hwndPare
141 sheet.pszCaption = titleA; 141 sheet.pszCaption = titleA;
142 sheet.nPages = pagesA.Size(); 142 sheet.nPages = pagesA.Size();
143 sheet.nStartPage = 0; 143 sheet.nStartPage = 0;
144 sheet.ppsp = (LPCPROPSHEETPAGEA)(const void *)&pagesA.Front(); 144 sheet.ppsp = (LPCPROPSHEETPAGEA)(const void *)pagesA.ConstData();
145 sheet.pfnCallback = NULL; 145 sheet.pfnCallback = NULL;
146 return ::PropertySheetA(&sheet); 146 return ::PropertySheetA(&sheet);
147 } 147 }
@@ -156,7 +156,7 @@ INT_PTR MyPropertySheet(const CObjectVector<CPageInfo> &pagesInfo, HWND hwndPare
156 sheet.pszCaption = title; 156 sheet.pszCaption = title;
157 sheet.nPages = pagesW.Size(); 157 sheet.nPages = pagesW.Size();
158 sheet.nStartPage = 0; 158 sheet.nStartPage = 0;
159 sheet.ppsp = (LPCPROPSHEETPAGEW)(const void *)&pagesW.Front(); 159 sheet.ppsp = (LPCPROPSHEETPAGEW)(const void *)pagesW.ConstData();
160 sheet.pfnCallback = NULL; 160 sheet.pfnCallback = NULL;
161 return ::PropertySheetW(&sheet); 161 return ::PropertySheetW(&sheet);
162 } 162 }
diff --git a/CPP/Windows/DLL.cpp b/CPP/Windows/DLL.cpp
index b2499ec..025df17 100644
--- a/CPP/Windows/DLL.cpp
+++ b/CPP/Windows/DLL.cpp
@@ -61,14 +61,14 @@ bool CLibrary::Load(CFSTR path) throw()
61 61
62bool MyGetModuleFileName(FString &path) 62bool MyGetModuleFileName(FString &path)
63{ 63{
64 HMODULE hModule = g_hInstance; 64 const HMODULE hModule = g_hInstance;
65 path.Empty(); 65 path.Empty();
66 #ifndef _UNICODE 66 #ifndef _UNICODE
67 if (!g_IsNT) 67 if (!g_IsNT)
68 { 68 {
69 TCHAR s[MAX_PATH + 2]; 69 TCHAR s[MAX_PATH + 2];
70 s[0] = 0; 70 s[0] = 0;
71 DWORD size = ::GetModuleFileName(hModule, s, MAX_PATH + 1); 71 const DWORD size = ::GetModuleFileName(hModule, s, MAX_PATH + 1);
72 if (size <= MAX_PATH && size != 0) 72 if (size <= MAX_PATH && size != 0)
73 { 73 {
74 path = fas2fs(s); 74 path = fas2fs(s);
@@ -80,7 +80,7 @@ bool MyGetModuleFileName(FString &path)
80 { 80 {
81 WCHAR s[MAX_PATH + 2]; 81 WCHAR s[MAX_PATH + 2];
82 s[0] = 0; 82 s[0] = 0;
83 DWORD size = ::GetModuleFileNameW(hModule, s, MAX_PATH + 1); 83 const DWORD size = ::GetModuleFileNameW(hModule, s, MAX_PATH + 1);
84 if (size <= MAX_PATH && size != 0) 84 if (size <= MAX_PATH && size != 0)
85 { 85 {
86 path = us2fs(s); 86 path = us2fs(s);
@@ -97,7 +97,7 @@ FString GetModuleDirPrefix()
97 FString s; 97 FString s;
98 if (MyGetModuleFileName(s)) 98 if (MyGetModuleFileName(s))
99 { 99 {
100 int pos = s.ReverseFind_PathSepar(); 100 const int pos = s.ReverseFind_PathSepar();
101 if (pos >= 0) 101 if (pos >= 0)
102 s.DeleteFrom((unsigned)(pos + 1)); 102 s.DeleteFrom((unsigned)(pos + 1));
103 } 103 }
@@ -114,7 +114,6 @@ FString GetModuleDirPrefix()
114 114
115#include <dlfcn.h> 115#include <dlfcn.h>
116#include <stdlib.h> 116#include <stdlib.h>
117#include "../Common/Common.h"
118 117
119// FARPROC 118// FARPROC
120void *GetProcAddress(HMODULE module, LPCSTR procName) 119void *GetProcAddress(HMODULE module, LPCSTR procName)
diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp
index 5b1f340..dfeed82 100644
--- a/CPP/Windows/FileDir.cpp
+++ b/CPP/Windows/FileDir.cpp
@@ -37,7 +37,12 @@ static bool FiTime_To_timespec(const CFiTime *ft, timespec &ts)
37{ 37{
38 if (ft) 38 if (ft)
39 { 39 {
40#if defined(_AIX)
41 ts.tv_sec = ft->tv_sec;
42 ts.tv_nsec = ft->tv_nsec;
43#else
40 ts = *ft; 44 ts = *ft;
45#endif
41 return true; 46 return true;
42 } 47 }
43 // else 48 // else
@@ -246,6 +251,11 @@ bool MyMoveFile(CFSTR oldFile, CFSTR newFile)
246} 251}
247 252
248#ifndef UNDER_CE 253#ifndef UNDER_CE
254#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0500 // Win2000
255#define Z7_USE_DYN_CreateHardLink
256#endif
257
258#ifdef Z7_USE_DYN_CreateHardLink
249EXTERN_C_BEGIN 259EXTERN_C_BEGIN
250typedef BOOL (WINAPI *Func_CreateHardLinkW)( 260typedef BOOL (WINAPI *Func_CreateHardLinkW)(
251 LPCWSTR lpFileName, 261 LPCWSTR lpFileName,
@@ -253,6 +263,7 @@ typedef BOOL (WINAPI *Func_CreateHardLinkW)(
253 LPSECURITY_ATTRIBUTES lpSecurityAttributes 263 LPSECURITY_ATTRIBUTES lpSecurityAttributes
254 ); 264 );
255EXTERN_C_END 265EXTERN_C_END
266#endif
256#endif // UNDER_CE 267#endif // UNDER_CE
257 268
258bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName) 269bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName)
@@ -270,6 +281,7 @@ bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName)
270 else 281 else
271 #endif 282 #endif
272 { 283 {
284#ifdef Z7_USE_DYN_CreateHardLink
273 const 285 const
274 Func_CreateHardLinkW 286 Func_CreateHardLinkW
275 my_CreateHardLinkW = Z7_GET_PROC_ADDRESS( 287 my_CreateHardLinkW = Z7_GET_PROC_ADDRESS(
@@ -277,9 +289,13 @@ bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName)
277 "CreateHardLinkW"); 289 "CreateHardLinkW");
278 if (!my_CreateHardLinkW) 290 if (!my_CreateHardLinkW)
279 return false; 291 return false;
292 #define MY_CreateHardLinkW my_CreateHardLinkW
293#else
294 #define MY_CreateHardLinkW CreateHardLinkW
295#endif
280 IF_USE_MAIN_PATH_2(newFileName, existFileName) 296 IF_USE_MAIN_PATH_2(newFileName, existFileName)
281 { 297 {
282 if (my_CreateHardLinkW(fs2us(newFileName), fs2us(existFileName), NULL)) 298 if (MY_CreateHardLinkW(fs2us(newFileName), fs2us(existFileName), NULL))
283 return true; 299 return true;
284 } 300 }
285 #ifdef Z7_LONG_PATH 301 #ifdef Z7_LONG_PATH
@@ -287,7 +303,7 @@ bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName)
287 { 303 {
288 UString d1, d2; 304 UString d1, d2;
289 if (GetSuperPaths(newFileName, existFileName, d1, d2, USE_MAIN_PATH_2)) 305 if (GetSuperPaths(newFileName, existFileName, d1, d2, USE_MAIN_PATH_2))
290 return BOOLToBool(my_CreateHardLinkW(d1, d2, NULL)); 306 return BOOLToBool(MY_CreateHardLinkW(d1, d2, NULL));
291 } 307 }
292 #endif 308 #endif
293 } 309 }
@@ -780,7 +796,7 @@ bool CreateTempFile2(CFSTR prefix, bool addRandom, AString &postfix, NIO::COutFi
780 unsigned k; 796 unsigned k;
781 for (k = 0; k < 8; k++) 797 for (k = 0; k < 8; k++)
782 { 798 {
783 const unsigned t = val & 0xF; 799 const unsigned t = (unsigned)val & 0xF;
784 val >>= 4; 800 val >>= 4;
785 s[k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); 801 s[k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
786 } 802 }
@@ -805,7 +821,7 @@ bool CreateTempFile2(CFSTR prefix, bool addRandom, AString &postfix, NIO::COutFi
805 } 821 }
806 if (outFile) 822 if (outFile)
807 { 823 {
808 if (outFile->Create(path, false)) 824 if (outFile->Create_NEW(path))
809 return true; 825 return true;
810 } 826 }
811 else 827 else
@@ -928,7 +944,7 @@ bool RemoveDir(CFSTR path)
928static BOOL My_CopyFile(CFSTR oldFile, CFSTR newFile) 944static BOOL My_CopyFile(CFSTR oldFile, CFSTR newFile)
929{ 945{
930 NWindows::NFile::NIO::COutFile outFile; 946 NWindows::NFile::NIO::COutFile outFile;
931 if (!outFile.Create(newFile, false)) 947 if (!outFile.Create_NEW(newFile))
932 return FALSE; 948 return FALSE;
933 949
934 NWindows::NFile::NIO::CInFile inFile; 950 NWindows::NFile::NIO::CInFile inFile;
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)
diff --git a/CPP/Windows/FileFind.h b/CPP/Windows/FileFind.h
index 11408d0..f68673a 100644
--- a/CPP/Windows/FileFind.h
+++ b/CPP/Windows/FileFind.h
@@ -99,12 +99,12 @@ public:
99 99
100 CFileInfoBase() { ClearBase(); } 100 CFileInfoBase() { ClearBase(); }
101 void ClearBase() throw(); 101 void ClearBase() throw();
102 bool SetAs_StdInFile();
102 103
103 #ifdef _WIN32 104 #ifdef _WIN32
104 105
105 bool Fill_From_ByHandleFileInfo(CFSTR path); 106 bool Fill_From_ByHandleFileInfo(CFSTR path);
106 void SetAsDir() { Attrib = FILE_ATTRIBUTE_DIRECTORY; } // |= (FILE_ATTRIBUTE_UNIX_EXTENSION + (S_IFDIR << 16)); 107 void SetAsDir() { Attrib = FILE_ATTRIBUTE_DIRECTORY; } // |= (FILE_ATTRIBUTE_UNIX_EXTENSION + (S_IFDIR << 16));
107 void SetAsFile() { Attrib = 0; }
108 108
109 bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); } 109 bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); }
110 bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); } 110 bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); }
@@ -132,8 +132,8 @@ public:
132 UInt32 GetWinAttrib() const { return Get_WinAttribPosix_From_PosixMode(mode); } 132 UInt32 GetWinAttrib() const { return Get_WinAttribPosix_From_PosixMode(mode); }
133 133
134 bool IsDir() const { return S_ISDIR(mode); } 134 bool IsDir() const { return S_ISDIR(mode); }
135 void SetAsDir() { mode = S_IFDIR; } 135 void SetAsDir() { mode = S_IFDIR | 0777; }
136 void SetAsFile() { mode = S_IFREG; } 136 void SetFrom_stat(const struct stat &st);
137 137
138 bool IsReadOnly() const 138 bool IsReadOnly() const
139 { 139 {
@@ -173,7 +173,6 @@ struct CFileInfo: public CFileInfoBase
173 // bool FollowReparse(CFSTR path, bool isDir); 173 // bool FollowReparse(CFSTR path, bool isDir);
174 #else 174 #else
175 bool Find_DontFill_Name(CFSTR path, bool followLink = false); 175 bool Find_DontFill_Name(CFSTR path, bool followLink = false);
176 void SetFrom_stat(const struct stat &st);
177 #endif 176 #endif
178}; 177};
179 178
@@ -278,19 +277,19 @@ typedef CFileInfo CDirEntry;
278struct CDirEntry 277struct CDirEntry
279{ 278{
280 ino_t iNode; 279 ino_t iNode;
281 #if !defined(_AIX) 280#if !defined(_AIX) && !defined(__sun)
282 Byte Type; 281 Byte Type;
283 #endif 282#endif
284 FString Name; 283 FString Name;
285 284
286 /* 285 /*
287 #if !defined(_AIX) 286#if !defined(_AIX) && !defined(__sun)
288 bool IsDir() const 287 bool IsDir() const
289 { 288 {
290 // (Type == DT_UNKNOWN) on some systems 289 // (Type == DT_UNKNOWN) on some systems
291 return Type == DT_DIR; 290 return Type == DT_DIR;
292 } 291 }
293 #endif 292#endif
294 */ 293 */
295 294
296 bool IsDots() const throw(); 295 bool IsDots() const throw();
@@ -311,12 +310,12 @@ public:
311 bool Fill_FileInfo(const CDirEntry &de, CFileInfo &fileInfo, bool followLink) const; 310 bool Fill_FileInfo(const CDirEntry &de, CFileInfo &fileInfo, bool followLink) const;
312 bool DirEntry_IsDir(const CDirEntry &de, bool followLink) const 311 bool DirEntry_IsDir(const CDirEntry &de, bool followLink) const
313 { 312 {
314 #if !defined(_AIX) 313#if !defined(_AIX) && !defined(__sun)
315 if (de.Type == DT_DIR) 314 if (de.Type == DT_DIR)
316 return true; 315 return true;
317 if (de.Type != DT_UNKNOWN) 316 if (de.Type != DT_UNKNOWN)
318 return false; 317 return false;
319 #endif 318#endif
320 CFileInfo fileInfo; 319 CFileInfo fileInfo;
321 if (Fill_FileInfo(de, fileInfo, followLink)) 320 if (Fill_FileInfo(de, fileInfo, followLink))
322 { 321 {
diff --git a/CPP/Windows/FileIO.cpp b/CPP/Windows/FileIO.cpp
index 4ecbb7e..dc4de14 100644
--- a/CPP/Windows/FileIO.cpp
+++ b/CPP/Windows/FileIO.cpp
@@ -141,8 +141,17 @@ bool CFileBase::Close() throw()
141{ 141{
142 if (_handle == INVALID_HANDLE_VALUE) 142 if (_handle == INVALID_HANDLE_VALUE)
143 return true; 143 return true;
144 if (!::CloseHandle(_handle)) 144#if 0
145 return false; 145 if (!IsStdStream)
146#endif
147 {
148 if (!::CloseHandle(_handle))
149 return false;
150 }
151#if 0
152 IsStdStream = false;
153 IsStdPipeStream = false;
154#endif
146 _handle = INVALID_HANDLE_VALUE; 155 _handle = INVALID_HANDLE_VALUE;
147 return true; 156 return true;
148} 157}
@@ -457,7 +466,7 @@ bool CInFile::Open(CFSTR fileName)
457// for 32 MB (maybe also for 16 MB). 466// for 32 MB (maybe also for 16 MB).
458// And message can be "Network connection was lost" 467// And message can be "Network connection was lost"
459 468
460static const UInt32 kChunkSizeMax = (1 << 22); 469static const UInt32 kChunkSizeMax = 1 << 22;
461 470
462bool CInFile::Read1(void *data, UInt32 size, UInt32 &processedSize) throw() 471bool CInFile::Read1(void *data, UInt32 size, UInt32 &processedSize) throw()
463{ 472{
@@ -469,8 +478,14 @@ bool CInFile::Read1(void *data, UInt32 size, UInt32 &processedSize) throw()
469 478
470bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize) throw() 479bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize) throw()
471{ 480{
481#if 0
482 const UInt32 chunkSizeMax = (0 || IsStdStream) ? (1 << 20) : kChunkSizeMax;
483 if (size > chunkSizeMax)
484 size = chunkSizeMax;
485#else
472 if (size > kChunkSizeMax) 486 if (size > kChunkSizeMax)
473 size = kChunkSizeMax; 487 size = kChunkSizeMax;
488#endif
474 return Read1(data, size, processedSize); 489 return Read1(data, size, processedSize);
475} 490}
476 491
@@ -486,10 +501,10 @@ bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize) throw()
486 return false; 501 return false;
487 if (processedLoc == 0) 502 if (processedLoc == 0)
488 return true; 503 return true;
489 data = (void *)((unsigned char *)data + processedLoc); 504 data = (void *)((Byte *)data + processedLoc);
490 size -= processedLoc; 505 size -= processedLoc;
491 } 506 }
492 while (size > 0); 507 while (size);
493 return true; 508 return true;
494} 509}
495 510
@@ -506,29 +521,23 @@ bool CInFile::ReadFull(void *data, size_t size, size_t &processedSize) throw()
506 return false; 521 return false;
507 if (processedLoc == 0) 522 if (processedLoc == 0)
508 return true; 523 return true;
509 data = (void *)((unsigned char *)data + processedLoc); 524 data = (void *)((Byte *)data + processedLoc);
510 size -= processedLoc; 525 size -= processedLoc;
511 } 526 }
512 while (size > 0); 527 while (size);
513 return true; 528 return true;
514} 529}
515 530
516// ---------- COutFile --------- 531// ---------- COutFile ---------
517 532
518static inline DWORD GetCreationDisposition(bool createAlways)
519 { return createAlways? CREATE_ALWAYS: CREATE_NEW; }
520
521bool COutFile::Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) 533bool COutFile::Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
522 { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); } 534 { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
523 535
524bool COutFile::Open(CFSTR fileName, DWORD creationDisposition) 536bool COutFile::Open_Disposition(CFSTR fileName, DWORD creationDisposition)
525 { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); } 537 { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
526 538
527bool COutFile::Create(CFSTR fileName, bool createAlways) 539bool COutFile::Create_ALWAYS_with_Attribs(CFSTR fileName, DWORD flagsAndAttributes)
528 { return Open(fileName, GetCreationDisposition(createAlways)); } 540 { return Open(fileName, FILE_SHARE_READ, CREATE_ALWAYS, flagsAndAttributes); }
529
530bool COutFile::CreateAlways(CFSTR fileName, DWORD flagsAndAttributes)
531 { return Open(fileName, FILE_SHARE_READ, GetCreationDisposition(true), flagsAndAttributes); }
532 541
533bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw() 542bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw()
534 { return BOOLToBool(::SetFileTime(_handle, cTime, aTime, mTime)); } 543 { return BOOLToBool(::SetFileTime(_handle, cTime, aTime, mTime)); }
@@ -557,10 +566,10 @@ bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize) throw
557 return false; 566 return false;
558 if (processedLoc == 0) 567 if (processedLoc == 0)
559 return true; 568 return true;
560 data = (const void *)((const unsigned char *)data + processedLoc); 569 data = (const void *)((const Byte *)data + processedLoc);
561 size -= processedLoc; 570 size -= processedLoc;
562 } 571 }
563 while (size != 0); 572 while (size);
564 return true; 573 return true;
565} 574}
566 575
@@ -574,10 +583,10 @@ bool COutFile::WriteFull(const void *data, size_t size) throw()
574 return false; 583 return false;
575 if (processedLoc == 0) 584 if (processedLoc == 0)
576 return (size == 0); 585 return (size == 0);
577 data = (const void *)((const unsigned char *)data + processedLoc); 586 data = (const void *)((const Byte *)data + processedLoc);
578 size -= processedLoc; 587 size -= processedLoc;
579 } 588 }
580 while (size != 0); 589 while (size);
581 return true; 590 return true;
582} 591}
583 592
@@ -786,11 +795,11 @@ bool CInFile::ReadFull(void *data, size_t size, size_t &processed) throw()
786 return false; 795 return false;
787 if (res == 0) 796 if (res == 0)
788 break; 797 break;
789 data = (void *)((unsigned char *)data + (size_t)res); 798 data = (void *)((Byte *)data + (size_t)res);
790 size -= (size_t)res;
791 processed += (size_t)res; 799 processed += (size_t)res;
800 size -= (size_t)res;
792 } 801 }
793 while (size > 0); 802 while (size);
794 return true; 803 return true;
795} 804}
796 805
@@ -798,23 +807,63 @@ bool CInFile::ReadFull(void *data, size_t size, size_t &processed) throw()
798///////////////////////// 807/////////////////////////
799// COutFile 808// COutFile
800 809
801bool COutFile::Create(const char *name, bool createAlways) 810bool COutFile::OpenBinary_forWrite_oflag(const char *name, int oflag)
802{ 811{
803 Path = name; // change it : set it only if open is success. 812 Path = name; // change it : set it only if open is success.
804 if (createAlways) 813 return OpenBinary(name, oflag, mode_for_Create);
805 {
806 Close();
807 _handle = ::creat(name, mode_for_Create);
808 return _handle != -1;
809 }
810 return OpenBinary(name, O_CREAT | O_EXCL | O_WRONLY, mode_for_Create);
811} 814}
812 815
813bool COutFile::Open(const char *name, DWORD creationDisposition) 816
817/*
818 windows exist non-exist posix
819 CREATE_NEW Fail Create O_CREAT | O_EXCL
820 CREATE_ALWAYS Trunc Create O_CREAT | O_TRUNC
821 OPEN_ALWAYS Open Create O_CREAT
822 OPEN_EXISTING Open Fail 0
823 TRUNCATE_EXISTING Trunc Fail O_TRUNC ???
824
825 // O_CREAT = If the file exists, this flag has no effect except as noted under O_EXCL below.
826 // If O_CREAT and O_EXCL are set, open() shall fail if the file exists.
827 // O_TRUNC : If the file exists and the file is successfully opened, its length shall be truncated to 0.
828*/
829bool COutFile::Open_EXISTING(const char *name)
830 { return OpenBinary_forWrite_oflag(name, O_WRONLY); }
831bool COutFile::Create_ALWAYS(const char *name)
832 { return OpenBinary_forWrite_oflag(name, O_WRONLY | O_CREAT | O_TRUNC); }
833bool COutFile::Create_NEW(const char *name)
834 { return OpenBinary_forWrite_oflag(name, O_WRONLY | O_CREAT | O_EXCL); }
835bool COutFile::Create_ALWAYS_or_Open_ALWAYS(const char *name, bool createAlways)
836{
837 return OpenBinary_forWrite_oflag(name,
838 createAlways ?
839 O_WRONLY | O_CREAT | O_TRUNC :
840 O_WRONLY | O_CREAT);
841}
842/*
843bool COutFile::Create_ALWAYS_or_NEW(const char *name, bool createAlways)
844{
845 return OpenBinary_forWrite_oflag(name,
846 createAlways ?
847 O_WRONLY | O_CREAT | O_TRUNC :
848 O_WRONLY | O_CREAT | O_EXCL);
849}
850bool COutFile::Open_Disposition(const char *name, DWORD creationDisposition)
814{ 851{
815 UNUSED_VAR(creationDisposition) // FIXME 852 int flag;
816 return Create(name, false); 853 switch (creationDisposition)
854 {
855 case CREATE_NEW: flag = O_WRONLY | O_CREAT | O_EXCL; break;
856 case CREATE_ALWAYS: flag = O_WRONLY | O_CREAT | O_TRUNC; break;
857 case OPEN_ALWAYS: flag = O_WRONLY | O_CREAT; break;
858 case OPEN_EXISTING: flag = O_WRONLY; break;
859 case TRUNCATE_EXISTING: flag = O_WRONLY | O_TRUNC; break;
860 default:
861 SetLastError(EINVAL);
862 return false;
863 }
864 return OpenBinary_forWrite_oflag(name, flag);
817} 865}
866*/
818 867
819ssize_t COutFile::write_part(const void *data, size_t size) throw() 868ssize_t COutFile::write_part(const void *data, size_t size) throw()
820{ 869{
@@ -833,11 +882,11 @@ ssize_t COutFile::write_full(const void *data, size_t size, size_t &processed) t
833 return res; 882 return res;
834 if (res == 0) 883 if (res == 0)
835 break; 884 break;
836 data = (const void *)((const unsigned char *)data + (size_t)res); 885 data = (const void *)((const Byte *)data + (size_t)res);
837 size -= (size_t)res;
838 processed += (size_t)res; 886 processed += (size_t)res;
887 size -= (size_t)res;
839 } 888 }
840 while (size > 0); 889 while (size);
841 return (ssize_t)processed; 890 return (ssize_t)processed;
842} 891}
843 892
diff --git a/CPP/Windows/FileIO.h b/CPP/Windows/FileIO.h
index 03e061a..6ba40eb 100644
--- a/CPP/Windows/FileIO.h
+++ b/CPP/Windows/FileIO.h
@@ -141,13 +141,24 @@ public:
141 141
142public: 142public:
143 bool PreserveATime; 143 bool PreserveATime;
144 #ifdef Z7_DEVICE_FILE 144#if 0
145 bool IsStdStream;
146 bool IsStdPipeStream;
147#endif
148#ifdef Z7_DEVICE_FILE
145 bool IsDeviceFile; 149 bool IsDeviceFile;
146 bool SizeDefined; 150 bool SizeDefined;
147 UInt64 Size; // it can be larger than real available size 151 UInt64 Size; // it can be larger than real available size
148 #endif 152#endif
149 153
150 CFileBase(): _handle(INVALID_HANDLE_VALUE), PreserveATime(false) {} 154 CFileBase():
155 _handle(INVALID_HANDLE_VALUE),
156 PreserveATime(false)
157#if 0
158 , IsStdStream(false),
159 , IsStdPipeStream(false)
160#endif
161 {}
151 ~CFileBase() { Close(); } 162 ~CFileBase() { Close(); }
152 163
153 HANDLE GetHandle() const { return _handle; } 164 HANDLE GetHandle() const { return _handle; }
@@ -223,6 +234,20 @@ public:
223 bool OpenShared(CFSTR fileName, bool shareForWrite); 234 bool OpenShared(CFSTR fileName, bool shareForWrite);
224 bool Open(CFSTR fileName); 235 bool Open(CFSTR fileName);
225 236
237#if 0
238 bool AttachStdIn()
239 {
240 IsDeviceFile = false;
241 const HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
242 if (h == INVALID_HANDLE_VALUE || !h)
243 return false;
244 IsStdStream = true;
245 IsStdPipeStream = true;
246 _handle = h;
247 return true;
248 }
249#endif
250
226 #ifndef UNDER_CE 251 #ifndef UNDER_CE
227 252
228 bool Open_for_ReadAttributes(CFSTR fileName) 253 bool Open_for_ReadAttributes(CFSTR fileName)
@@ -263,11 +288,21 @@ public:
263 288
264class COutFile: public CFileBase 289class COutFile: public CFileBase
265{ 290{
291 bool Open_Disposition(CFSTR fileName, DWORD creationDisposition);
266public: 292public:
267 bool Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); 293 bool Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
268 bool Open(CFSTR fileName, DWORD creationDisposition); 294 bool Open_EXISTING(CFSTR fileName)
269 bool Create(CFSTR fileName, bool createAlways); 295 { return Open_Disposition(fileName, OPEN_EXISTING); }
270 bool CreateAlways(CFSTR fileName, DWORD flagsAndAttributes); 296 bool Create_ALWAYS_or_Open_ALWAYS(CFSTR fileName, bool createAlways)
297 { return Open_Disposition(fileName, createAlways ? CREATE_ALWAYS : OPEN_ALWAYS); }
298 bool Create_ALWAYS_or_NEW(CFSTR fileName, bool createAlways)
299 { return Open_Disposition(fileName, createAlways ? CREATE_ALWAYS : CREATE_NEW); }
300 bool Create_ALWAYS(CFSTR fileName)
301 { return Open_Disposition(fileName, CREATE_ALWAYS); }
302 bool Create_NEW(CFSTR fileName)
303 { return Open_Disposition(fileName, CREATE_NEW); }
304
305 bool Create_ALWAYS_with_Attribs(CFSTR fileName, DWORD flagsAndAttributes);
271 306
272 bool SetTime(const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) throw(); 307 bool SetTime(const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) throw();
273 bool SetMTime(const CFiTime *mTime) throw(); 308 bool SetMTime(const CFiTime *mTime) throw();
@@ -308,8 +343,15 @@ protected:
308 bool OpenBinary(const char *name, int flags, mode_t mode = 0666); 343 bool OpenBinary(const char *name, int flags, mode_t mode = 0666);
309public: 344public:
310 bool PreserveATime; 345 bool PreserveATime;
346#if 0
347 bool IsStdStream;
348#endif
311 349
312 CFileBase(): _handle(-1), PreserveATime(false) {} 350 CFileBase(): _handle(-1), PreserveATime(false)
351#if 0
352 , IsStdStream(false)
353#endif
354 {}
313 ~CFileBase() { Close(); } 355 ~CFileBase() { Close(); }
314 // void Detach() { _handle = -1; } 356 // void Detach() { _handle = -1; }
315 bool Close(); 357 bool Close();
@@ -331,6 +373,15 @@ class CInFile: public CFileBase
331public: 373public:
332 bool Open(const char *name); 374 bool Open(const char *name);
333 bool OpenShared(const char *name, bool shareForWrite); 375 bool OpenShared(const char *name, bool shareForWrite);
376#if 0
377 bool AttachStdIn()
378 {
379 _handle = GetStdHandle(STD_INPUT_HANDLE);
380 if (_handle == INVALID_HANDLE_VALUE || !_handle)
381 return false;
382 IsStdStream = true;
383 }
384#endif
334 ssize_t read_part(void *data, size_t size) throw(); 385 ssize_t read_part(void *data, size_t size) throw();
335 // ssize_t read_full(void *data, size_t size, size_t &processed); 386 // ssize_t read_full(void *data, size_t size, size_t &processed);
336 bool ReadFull(void *data, size_t size, size_t &processedSize) throw(); 387 bool ReadFull(void *data, size_t size, size_t &processedSize) throw();
@@ -347,6 +398,7 @@ class COutFile: public CFileBase
347 398
348 AString Path; 399 AString Path;
349 ssize_t write_part(const void *data, size_t size) throw(); 400 ssize_t write_part(const void *data, size_t size) throw();
401 bool OpenBinary_forWrite_oflag(const char *name, int oflag);
350public: 402public:
351 mode_t mode_for_Create; 403 mode_t mode_for_Create;
352 404
@@ -358,8 +410,14 @@ public:
358 {} 410 {}
359 411
360 bool Close(); 412 bool Close();
361 bool Create(const char *name, bool createAlways); 413
362 bool Open(const char *name, DWORD creationDisposition); 414 bool Open_EXISTING(CFSTR fileName);
415 bool Create_ALWAYS_or_Open_ALWAYS(CFSTR fileName, bool createAlways);
416 bool Create_ALWAYS(CFSTR fileName);
417 bool Create_NEW(CFSTR fileName);
418 // bool Create_ALWAYS_or_NEW(CFSTR fileName, bool createAlways);
419 // bool Open_Disposition(const char *name, DWORD creationDisposition);
420
363 ssize_t write_full(const void *data, size_t size, size_t &processed) throw(); 421 ssize_t write_full(const void *data, size_t size, size_t &processed) throw();
364 422
365 bool WriteFull(const void *data, size_t size) throw() 423 bool WriteFull(const void *data, size_t size) throw()
diff --git a/CPP/Windows/FileLink.cpp b/CPP/Windows/FileLink.cpp
index 2b9fa1a..bb380ec 100644
--- a/CPP/Windows/FileLink.cpp
+++ b/CPP/Windows/FileLink.cpp
@@ -249,9 +249,13 @@ bool CReparseAttr::Parse(const Byte *p, size_t size)
249 if (size < 8) 249 if (size < 8)
250 return false; 250 return false;
251 Tag = Get32(p); 251 Tag = Get32(p);
252 UInt32 len = Get16(p + 4); 252 if (Get16(p + 6) != 0) // padding
253 if (len + 8 != size) 253 return false;
254 // if (len + 8 > size) 254 unsigned len = Get16(p + 4);
255 p += 8;
256 size -= 8;
257 if (len != size)
258 // if (len > size)
255 return false; 259 return false;
256 /* 260 /*
257 if ((type & kReparseFlags_Alias) == 0 || 261 if ((type & kReparseFlags_Alias) == 0 ||
@@ -259,8 +263,6 @@ bool CReparseAttr::Parse(const Byte *p, size_t size)
259 (type & 0xFFFF) != 3) 263 (type & 0xFFFF) != 3)
260 */ 264 */
261 265
262 if (Get16(p + 6) != 0) // padding
263 return false;
264 266
265 HeaderError = false; 267 HeaderError = false;
266 268
@@ -276,9 +278,6 @@ bool CReparseAttr::Parse(const Byte *p, size_t size)
276 278
277 TagIsUnknown = false; 279 TagIsUnknown = false;
278 280
279 p += 8;
280 size -= 8;
281
282 if (Tag == Z7_WIN_IO_REPARSE_TAG_LX_SYMLINK) 281 if (Tag == Z7_WIN_IO_REPARSE_TAG_LX_SYMLINK)
283 { 282 {
284 if (len < 4) 283 if (len < 4)
@@ -518,7 +517,7 @@ bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size)
518 { 517 {
519 CreatePrefixDirOfFile(path); 518 CreatePrefixDirOfFile(path);
520 COutFile file; 519 COutFile file;
521 if (!file.Create(path, CREATE_NEW)) 520 if (!file.Create_NEW(path))
522 return false; 521 return false;
523 } 522 }
524 } 523 }
diff --git a/CPP/Windows/FileName.cpp b/CPP/Windows/FileName.cpp
index c9c4f8b..c16b3d4 100644
--- a/CPP/Windows/FileName.cpp
+++ b/CPP/Windows/FileName.cpp
@@ -302,13 +302,13 @@ int FindAltStreamColon(CFSTR path) throw()
302static unsigned GetRootPrefixSize_Of_NetworkPath(CFSTR s) 302static unsigned GetRootPrefixSize_Of_NetworkPath(CFSTR s)
303{ 303{
304 // Network path: we look "server\path\" as root prefix 304 // Network path: we look "server\path\" as root prefix
305 int pos = FindSepar(s); 305 const int pos = FindSepar(s);
306 if (pos < 0) 306 if (pos < 0)
307 return 0; 307 return 0;
308 int pos2 = FindSepar(s + (unsigned)pos + 1); 308 const int pos2 = FindSepar(s + (unsigned)pos + 1);
309 if (pos2 < 0) 309 if (pos2 < 0)
310 return 0; 310 return 0;
311 return pos + pos2 + 2; 311 return (unsigned)pos + (unsigned)pos2 + 2;
312} 312}
313 313
314static unsigned GetRootPrefixSize_Of_SimplePath(CFSTR s) 314static unsigned GetRootPrefixSize_Of_SimplePath(CFSTR s)
@@ -334,7 +334,7 @@ static unsigned GetRootPrefixSize_Of_SuperPath(CFSTR s)
334 const int pos = FindSepar(s + kSuperPathPrefixSize); 334 const int pos = FindSepar(s + kSuperPathPrefixSize);
335 if (pos < 0) 335 if (pos < 0)
336 return 0; 336 return 0;
337 return kSuperPathPrefixSize + pos + 1; 337 return kSuperPathPrefixSize + (unsigned)pos + 1;
338} 338}
339 339
340unsigned GetRootPrefixSize(CFSTR s) throw() 340unsigned GetRootPrefixSize(CFSTR s) throw()
diff --git a/CPP/Windows/FileSystem.cpp b/CPP/Windows/FileSystem.cpp
index 6a262d9..d11f02e 100644
--- a/CPP/Windows/FileSystem.cpp
+++ b/CPP/Windows/FileSystem.cpp
@@ -71,6 +71,12 @@ UINT MyGetDriveType(CFSTR pathName)
71 } 71 }
72} 72}
73 73
74#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0400
75// GetDiskFreeSpaceEx requires Windows95-OSR2, NT4
76#define Z7_USE_DYN_GetDiskFreeSpaceEx
77#endif
78
79#ifdef Z7_USE_DYN_GetDiskFreeSpaceEx
74typedef BOOL (WINAPI * Func_GetDiskFreeSpaceExA)( 80typedef BOOL (WINAPI * Func_GetDiskFreeSpaceExA)(
75 LPCSTR lpDirectoryName, // directory name 81 LPCSTR lpDirectoryName, // directory name
76 PULARGE_INTEGER lpFreeBytesAvailable, // bytes available to caller 82 PULARGE_INTEGER lpFreeBytesAvailable, // bytes available to caller
@@ -84,6 +90,7 @@ typedef BOOL (WINAPI * Func_GetDiskFreeSpaceExW)(
84 PULARGE_INTEGER lpTotalNumberOfBytes, // bytes on disk 90 PULARGE_INTEGER lpTotalNumberOfBytes, // bytes on disk
85 PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk 91 PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk
86); 92);
93#endif
87 94
88bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize) 95bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize)
89{ 96{
@@ -92,14 +99,22 @@ bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize,
92 #ifndef _UNICODE 99 #ifndef _UNICODE
93 if (!g_IsNT) 100 if (!g_IsNT)
94 { 101 {
102#ifdef Z7_USE_DYN_GetDiskFreeSpaceEx
95 const 103 const
96 Func_GetDiskFreeSpaceExA f = Z7_GET_PROC_ADDRESS( 104 Func_GetDiskFreeSpaceExA f = Z7_GET_PROC_ADDRESS(
97 Func_GetDiskFreeSpaceExA, GetModuleHandle(TEXT("kernel32.dll")), 105 Func_GetDiskFreeSpaceExA, GetModuleHandle(TEXT("kernel32.dll")),
98 "GetDiskFreeSpaceExA"); 106 "GetDiskFreeSpaceExA");
99 if (f) 107 if (f)
108#endif
100 { 109 {
101 ULARGE_INTEGER freeBytesToCaller2, totalSize2, freeSize2; 110 ULARGE_INTEGER freeBytesToCaller2, totalSize2, freeSize2;
102 sizeIsDetected = BOOLToBool(f(fs2fas(rootPath), &freeBytesToCaller2, &totalSize2, &freeSize2)); 111 sizeIsDetected = BOOLToBool(
112#ifdef Z7_USE_DYN_GetDiskFreeSpaceEx
113 f
114#else
115 GetDiskFreeSpaceExA
116#endif
117 (fs2fas(rootPath), &freeBytesToCaller2, &totalSize2, &freeSize2));
103 totalSize = totalSize2.QuadPart; 118 totalSize = totalSize2.QuadPart;
104 freeSize = freeSize2.QuadPart; 119 freeSize = freeSize2.QuadPart;
105 } 120 }
@@ -109,14 +124,22 @@ bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize,
109 else 124 else
110 #endif 125 #endif
111 { 126 {
127#ifdef Z7_USE_DYN_GetDiskFreeSpaceEx
112 const 128 const
113 Func_GetDiskFreeSpaceExW f = Z7_GET_PROC_ADDRESS( 129 Func_GetDiskFreeSpaceExW f = Z7_GET_PROC_ADDRESS(
114 Func_GetDiskFreeSpaceExW, GetModuleHandle(TEXT("kernel32.dll")), 130 Func_GetDiskFreeSpaceExW, GetModuleHandle(TEXT("kernel32.dll")),
115 "GetDiskFreeSpaceExW"); 131 "GetDiskFreeSpaceExW");
116 if (f) 132 if (f)
133#endif
117 { 134 {
118 ULARGE_INTEGER freeBytesToCaller2, totalSize2, freeSize2; 135 ULARGE_INTEGER freeBytesToCaller2, totalSize2, freeSize2;
119 sizeIsDetected = BOOLToBool(f(fs2us(rootPath), &freeBytesToCaller2, &totalSize2, &freeSize2)); 136 sizeIsDetected = BOOLToBool(
137#ifdef Z7_USE_DYN_GetDiskFreeSpaceEx
138 f
139#else
140 GetDiskFreeSpaceExW
141#endif
142 (fs2us(rootPath), &freeBytesToCaller2, &totalSize2, &freeSize2));
120 totalSize = totalSize2.QuadPart; 143 totalSize = totalSize2.QuadPart;
121 freeSize = freeSize2.QuadPart; 144 freeSize = freeSize2.QuadPart;
122 } 145 }
diff --git a/CPP/Windows/MemoryLock.cpp b/CPP/Windows/MemoryLock.cpp
index 0bd7504..bc2d7c7 100644
--- a/CPP/Windows/MemoryLock.cpp
+++ b/CPP/Windows/MemoryLock.cpp
@@ -37,6 +37,8 @@ bool EnablePrivilege(LPCTSTR privilegeName, bool enable)
37 if (!hModule) 37 if (!hModule)
38 return false; 38 return false;
39 39
40Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
41
40 GET_PROC_ADDR( 42 GET_PROC_ADDR(
41 OpenProcessToken, 43 OpenProcessToken,
42 "OpenProcessToken") 44 "OpenProcessToken")
@@ -79,6 +81,7 @@ bool EnablePrivilege(LPCTSTR privilegeName, bool enable)
79} 81}
80 82
81 83
84Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
82 85
83typedef void (WINAPI * Func_RtlGetVersion) (OSVERSIONINFOEXW *); 86typedef void (WINAPI * Func_RtlGetVersion) (OSVERSIONINFOEXW *);
84 87
diff --git a/CPP/Windows/ProcessUtils.cpp b/CPP/Windows/ProcessUtils.cpp
index 607b4bb..f5e156c 100644
--- a/CPP/Windows/ProcessUtils.cpp
+++ b/CPP/Windows/ProcessUtils.cpp
@@ -17,7 +17,7 @@ static UString GetQuotedString(const UString &s)
17{ 17{
18 UString s2 ('\"'); 18 UString s2 ('\"');
19 s2 += s; 19 s2 += s;
20 s2 += '\"'; 20 s2.Add_Char('\"');
21 return s2; 21 return s2;
22} 22}
23#endif 23#endif
diff --git a/CPP/Windows/PropVariant.cpp b/CPP/Windows/PropVariant.cpp
index 457b1dc..678f970 100644
--- a/CPP/Windows/PropVariant.cpp
+++ b/CPP/Windows/PropVariant.cpp
@@ -252,6 +252,7 @@ CPropVariant::~CPropVariant() throw()
252 CASE_SIMPLE_VT_VALUES 252 CASE_SIMPLE_VT_VALUES
253 // vt = VT_EMPTY; // it's optional 253 // vt = VT_EMPTY; // it's optional
254 return; 254 return;
255 default: break;
255 } 256 }
256 ::VariantClear((tagVARIANT *)this); 257 ::VariantClear((tagVARIANT *)this);
257} 258}
@@ -296,6 +297,7 @@ HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw()
296 CASE_SIMPLE_VT_VALUES 297 CASE_SIMPLE_VT_VALUES
297 memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT)); 298 memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT));
298 return S_OK; 299 return S_OK;
300 default: break;
299 } 301 }
300 return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)const_cast<PROPVARIANT *>(pSrc)); 302 return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)const_cast<PROPVARIANT *>(pSrc));
301} 303}
diff --git a/CPP/Windows/PropVariantConv.cpp b/CPP/Windows/PropVariantConv.cpp
index 5fb96a7..21a7b4e 100644
--- a/CPP/Windows/PropVariantConv.cpp
+++ b/CPP/Windows/PropVariantConv.cpp
@@ -9,12 +9,45 @@
9 9
10#define UINT_TO_STR_2(c, val) { s[0] = (c); s[1] = (char)('0' + (val) / 10); s[2] = (char)('0' + (val) % 10); s += 3; } 10#define UINT_TO_STR_2(c, val) { s[0] = (c); s[1] = (char)('0' + (val) / 10); s[2] = (char)('0' + (val) % 10); s += 3; }
11 11
12bool ConvertUtcFileTimeToString2(const FILETIME &utc, unsigned ns100, char *s, int level) throw() 12static const unsigned k_TimeStringBufferSize = 64;
13
14bool g_Timestamp_Show_UTC;
15#if 0
16bool g_Timestamp_Show_DisableZ;
17bool g_Timestamp_Show_TDelimeter;
18bool g_Timestamp_Show_ZoneOffset;
19#endif
20
21Z7_NO_INLINE
22bool ConvertUtcFileTimeToString2(const FILETIME &utc, unsigned ns100, char *s, int level, unsigned flags) throw()
13{ 23{
14 *s = 0; 24 *s = 0;
15 FILETIME ft; 25 FILETIME ft;
16 if (!FileTimeToLocalFileTime(&utc, &ft)) 26
17 return false; 27#if 0
28 Int64 bias64 = 0;
29#endif
30
31 const bool show_utc =
32 (flags & kTimestampPrintFlags_Force_UTC) ? true :
33 (flags & kTimestampPrintFlags_Force_LOCAL) ? false :
34 g_Timestamp_Show_UTC;
35
36 if (show_utc)
37 ft = utc;
38 else
39 {
40 if (!FileTimeToLocalFileTime(&utc, &ft))
41 return false;
42#if 0
43 if (g_Timestamp_Show_ZoneOffset)
44 {
45 const UInt64 utc64 = (((UInt64)utc.dwHighDateTime) << 32) + utc.dwLowDateTime;
46 const UInt64 loc64 = (((UInt64) ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
47 bias64 = (Int64)utc64 - (Int64)loc64;
48 }
49#endif
50 }
18 51
19 SYSTEMTIME st; 52 SYSTEMTIME st;
20 if (!BOOLToBool(FileTimeToSystemTime(&ft, &st))) 53 if (!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
@@ -41,7 +74,12 @@ bool ConvertUtcFileTimeToString2(const FILETIME &utc, unsigned ns100, char *s, i
41 74
42 if (level > kTimestampPrintLevel_DAY) 75 if (level > kTimestampPrintLevel_DAY)
43 { 76 {
44 UINT_TO_STR_2(' ', st.wHour) 77 const char setChar =
78#if 0
79 g_Timestamp_Show_TDelimeter ? 'T' : // ISO 8601
80#endif
81 ' ';
82 UINT_TO_STR_2(setChar, st.wHour)
45 UINT_TO_STR_2(':', st.wMinute) 83 UINT_TO_STR_2(':', st.wMinute)
46 84
47 if (level >= kTimestampPrintLevel_SEC) 85 if (level >= kTimestampPrintLevel_SEC)
@@ -84,6 +122,52 @@ bool ConvertUtcFileTimeToString2(const FILETIME &utc, unsigned ns100, char *s, i
84 } 122 }
85 } 123 }
86 124
125 if (show_utc)
126 {
127 if ((flags & kTimestampPrintFlags_DisableZ) == 0
128#if 0
129 && !g_Timestamp_Show_DisableZ
130#endif
131 )
132 *s++ = 'Z';
133 }
134#if 0
135 else if (g_Timestamp_Show_ZoneOffset)
136 {
137#if 1
138 {
139 char c;
140 if (bias64 < 0)
141 {
142 bias64 = -bias64;
143 c = '+';
144 }
145 else
146 c = '-';
147 UInt32 bias = (UInt32)((UInt64)bias64 / (10000000 * 60));
148#else
149 TIME_ZONE_INFORMATION zi;
150 const DWORD dw = GetTimeZoneInformation(&zi);
151 if (dw <= TIME_ZONE_ID_DAYLIGHT) // == 2
152 {
153 // UTC = LOCAL + Bias
154 Int32 bias = zi.Bias;
155 char c;
156 if (bias < 0)
157 {
158 bias = -bias;
159 c = '+';
160 }
161 else
162 c = '-';
163#endif
164 const UInt32 hours = (UInt32)bias / 60;
165 const UInt32 mins = (UInt32)bias % 60;
166 UINT_TO_STR_2(c, hours)
167 UINT_TO_STR_2(':', mins)
168 }
169 }
170#endif
87 *s = 0; 171 *s = 0;
88 return true; 172 return true;
89} 173}
@@ -96,11 +180,11 @@ bool ConvertUtcFileTimeToString(const FILETIME &utc, char *s, int level) throw()
96 180
97bool ConvertUtcFileTimeToString2(const FILETIME &ft, unsigned ns100, wchar_t *dest, int level) throw() 181bool ConvertUtcFileTimeToString2(const FILETIME &ft, unsigned ns100, wchar_t *dest, int level) throw()
98{ 182{
99 char s[32]; 183 char s[k_TimeStringBufferSize];
100 bool res = ConvertUtcFileTimeToString2(ft, ns100, s, level); 184 const bool res = ConvertUtcFileTimeToString2(ft, ns100, s, level);
101 for (unsigned i = 0;; i++) 185 for (unsigned i = 0;; i++)
102 { 186 {
103 Byte c = (Byte)s[i]; 187 const Byte c = (Byte)s[i];
104 dest[i] = c; 188 dest[i] = c;
105 if (c == 0) 189 if (c == 0)
106 break; 190 break;
@@ -110,11 +194,11 @@ bool ConvertUtcFileTimeToString2(const FILETIME &ft, unsigned ns100, wchar_t *de
110 194
111bool ConvertUtcFileTimeToString(const FILETIME &ft, wchar_t *dest, int level) throw() 195bool ConvertUtcFileTimeToString(const FILETIME &ft, wchar_t *dest, int level) throw()
112{ 196{
113 char s[32]; 197 char s[k_TimeStringBufferSize];
114 bool res = ConvertUtcFileTimeToString(ft, s, level); 198 const bool res = ConvertUtcFileTimeToString(ft, s, level);
115 for (unsigned i = 0;; i++) 199 for (unsigned i = 0;; i++)
116 { 200 {
117 Byte c = (Byte)s[i]; 201 const Byte c = (Byte)s[i];
118 dest[i] = c; 202 dest[i] = c;
119 if (c == 0) 203 if (c == 0)
120 break; 204 break;
diff --git a/CPP/Windows/PropVariantConv.h b/CPP/Windows/PropVariantConv.h
index ec5223b..8782507 100644
--- a/CPP/Windows/PropVariantConv.h
+++ b/CPP/Windows/PropVariantConv.h
@@ -7,6 +7,8 @@
7 7
8// provide at least 32 bytes for buffer including zero-end 8// provide at least 32 bytes for buffer including zero-end
9 9
10extern bool g_Timestamp_Show_UTC;
11
10#define kTimestampPrintLevel_DAY -3 12#define kTimestampPrintLevel_DAY -3
11// #define kTimestampPrintLevel_HOUR -2 13// #define kTimestampPrintLevel_HOUR -2
12#define kTimestampPrintLevel_MIN -1 14#define kTimestampPrintLevel_MIN -1
@@ -14,9 +16,14 @@
14#define kTimestampPrintLevel_NTFS 7 16#define kTimestampPrintLevel_NTFS 7
15#define kTimestampPrintLevel_NS 9 17#define kTimestampPrintLevel_NS 9
16 18
19
20#define kTimestampPrintFlags_Force_UTC (1 << 0)
21#define kTimestampPrintFlags_Force_LOCAL (1 << 1)
22#define kTimestampPrintFlags_DisableZ (1 << 4)
23
17bool ConvertUtcFileTimeToString(const FILETIME &ft, char *s, int level = kTimestampPrintLevel_SEC) throw(); 24bool ConvertUtcFileTimeToString(const FILETIME &ft, char *s, int level = kTimestampPrintLevel_SEC) throw();
18bool ConvertUtcFileTimeToString(const FILETIME &ft, wchar_t *s, int level = kTimestampPrintLevel_SEC) throw(); 25bool ConvertUtcFileTimeToString(const FILETIME &ft, wchar_t *s, int level = kTimestampPrintLevel_SEC) throw();
19bool ConvertUtcFileTimeToString2(const FILETIME &ft, unsigned ns100, char *s, int level = kTimestampPrintLevel_SEC) throw(); 26bool ConvertUtcFileTimeToString2(const FILETIME &ft, unsigned ns100, char *s, int level = kTimestampPrintLevel_SEC, unsigned flags = 0) throw();
20bool ConvertUtcFileTimeToString2(const FILETIME &ft, unsigned ns100, wchar_t *s, int level = kTimestampPrintLevel_SEC) throw(); 27bool ConvertUtcFileTimeToString2(const FILETIME &ft, unsigned ns100, wchar_t *s, int level = kTimestampPrintLevel_SEC) throw();
21 28
22// provide at least 32 bytes for buffer including zero-end 29// provide at least 32 bytes for buffer including zero-end
diff --git a/CPP/Windows/Registry.cpp b/CPP/Windows/Registry.cpp
index b20157d..c8b1709 100644
--- a/CPP/Windows/Registry.cpp
+++ b/CPP/Windows/Registry.cpp
@@ -254,8 +254,8 @@ LONG CKey::QueryValue(LPCTSTR name, CSysString &value)
254{ 254{
255 value.Empty(); 255 value.Empty();
256 DWORD type = 0; 256 DWORD type = 0;
257 UInt32 curSize = 0; 257 DWORD curSize = 0;
258 LONG res = RegQueryValueEx(_object, name, NULL, &type, NULL, (DWORD *)&curSize); 258 LONG res = RegQueryValueEx(_object, name, NULL, &type, NULL, &curSize);
259 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) 259 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
260 return res; 260 return res;
261 UInt32 curSize2 = curSize; 261 UInt32 curSize2 = curSize;
@@ -281,13 +281,11 @@ LONG CKey::QueryValue(LPCWSTR name, UString &value)
281{ 281{
282 value.Empty(); 282 value.Empty();
283 DWORD type = 0; 283 DWORD type = 0;
284 UInt32 curSize = 0; 284 DWORD curSize = 0;
285
286 LONG res; 285 LONG res;
287
288 if (g_IsNT) 286 if (g_IsNT)
289 { 287 {
290 res = RegQueryValueExW(_object, name, NULL, &type, NULL, (DWORD *)&curSize); 288 res = RegQueryValueExW(_object, name, NULL, &type, NULL, &curSize);
291 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) 289 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
292 return res; 290 return res;
293 UInt32 curSize2 = curSize; 291 UInt32 curSize2 = curSize;
@@ -302,7 +300,6 @@ LONG CKey::QueryValue(LPCWSTR name, UString &value)
302 res = QueryValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name), vTemp); 300 res = QueryValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name), vTemp);
303 value = GetUnicodeString(vTemp); 301 value = GetUnicodeString(vTemp);
304 } 302 }
305
306 return res; 303 return res;
307} 304}
308 305
@@ -377,7 +374,7 @@ LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings)
377 strings.Clear(); 374 strings.Clear();
378 CByteBuffer buffer; 375 CByteBuffer buffer;
379 UInt32 dataSize = 0; 376 UInt32 dataSize = 0;
380 LONG res = QueryValue(valueName, buffer, dataSize); 377 const LONG res = QueryValue(valueName, buffer, dataSize);
381 if (res != ERROR_SUCCESS) 378 if (res != ERROR_SUCCESS)
382 return res; 379 return res;
383 if (dataSize > buffer.Size()) 380 if (dataSize > buffer.Size())
@@ -386,7 +383,7 @@ LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings)
386 return E_FAIL; 383 return E_FAIL;
387 384
388 const wchar_t *data = (const wchar_t *)(const void *)(const Byte *)buffer; 385 const wchar_t *data = (const wchar_t *)(const void *)(const Byte *)buffer;
389 size_t numChars = dataSize / sizeof(wchar_t); 386 const size_t numChars = dataSize / sizeof(wchar_t);
390 size_t prev = 0; 387 size_t prev = 0;
391 UString s; 388 UString s;
392 389
diff --git a/CPP/Windows/SecurityUtils.h b/CPP/Windows/SecurityUtils.h
index 4ef3939..7219f06 100644
--- a/CPP/Windows/SecurityUtils.h
+++ b/CPP/Windows/SecurityUtils.h
@@ -18,6 +18,8 @@ typedef NTSTATUS (NTAPI *Func_LsaAddAccountRights)(LSA_HANDLE PolicyHandle,
18#define MY_STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L) 18#define MY_STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L)
19} 19}
20 20
21Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
22
21#define POLICY_FUNC_CALL(fff, str) \ 23#define POLICY_FUNC_CALL(fff, str) \
22 if (hModule == NULL) return MY_STATUS_NOT_IMPLEMENTED; \ 24 if (hModule == NULL) return MY_STATUS_NOT_IMPLEMENTED; \
23 const Func_ ## fff v = Z7_GET_PROC_ADDRESS(Func_ ## fff, hModule, str); \ 25 const Func_ ## fff v = Z7_GET_PROC_ADDRESS(Func_ ## fff, hModule, str); \
diff --git a/CPP/Windows/Shell.cpp b/CPP/Windows/Shell.cpp
index b2a3489..01ceb22 100644
--- a/CPP/Windows/Shell.cpp
+++ b/CPP/Windows/Shell.cpp
@@ -162,7 +162,7 @@ static HRESULT ReadAnsiStrings(const char *p, size_t size, UStringVector &names)
162 name.Empty(); 162 name.Empty();
163 } 163 }
164 else 164 else
165 name += c; 165 name.Add_Char(c);
166 } 166 }
167 return E_INVALIDARG; 167 return E_INVALIDARG;
168} 168}
@@ -543,8 +543,18 @@ void CDrop::QueryFileNames(UStringVector &fileNames)
543typedef int Z7_WIN_GPFIDL_FLAGS; 543typedef int Z7_WIN_GPFIDL_FLAGS;
544 544
545extern "C" { 545extern "C" {
546typedef BOOL (WINAPI * Func_SHGetPathFromIDListW)(LPCITEMIDLIST pidl, LPWSTR pszPath); 546#ifndef _UNICODE
547typedef BOOL (WINAPI * Func_SHGetPathFromIDListEx)(LPCITEMIDLIST pidl, PWSTR pszPath, DWORD cchPath, Z7_WIN_GPFIDL_FLAGS uOpts); 547typedef BOOL (WINAPI * Func_SHGetPathFromIDListW)(LPCITEMIDLIST pidl, LPWSTR pszPath); // nt4
548#endif
549
550#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0600 // Vista
551#define Z7_USE_DYN_SHGetPathFromIDListEx
552#endif
553
554#ifdef Z7_USE_DYN_SHGetPathFromIDListEx
555Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
556typedef BOOL (WINAPI * Func_SHGetPathFromIDListEx)(LPCITEMIDLIST pidl, PWSTR pszPath, DWORD cchPath, Z7_WIN_GPFIDL_FLAGS uOpts); // vista
557#endif
548} 558}
549 559
550#ifndef _UNICODE 560#ifndef _UNICODE
@@ -584,18 +594,26 @@ bool GetPathFromIDList(LPCITEMIDLIST itemIDList, UString &path)
584 /* for long path we need SHGetPathFromIDListEx(). 594 /* for long path we need SHGetPathFromIDListEx().
585 win10: SHGetPathFromIDListEx() for long path returns path with 595 win10: SHGetPathFromIDListEx() for long path returns path with
586 with super path prefix "\\\\?\\". */ 596 with super path prefix "\\\\?\\". */
597#ifdef Z7_USE_DYN_SHGetPathFromIDListEx
587 const 598 const
588 Func_SHGetPathFromIDListEx 599 Func_SHGetPathFromIDListEx
589 func_SHGetPathFromIDListEx = Z7_GET_PROC_ADDRESS( 600 func_SHGetPathFromIDListEx = Z7_GET_PROC_ADDRESS(
590 Func_SHGetPathFromIDListEx, ::GetModuleHandleW(L"shell32.dll"), 601 Func_SHGetPathFromIDListEx, ::GetModuleHandleW(L"shell32.dll"),
591 "SHGetPathFromIDListEx"); 602 "SHGetPathFromIDListEx");
592 if (func_SHGetPathFromIDListEx) 603 if (func_SHGetPathFromIDListEx)
604#endif
593 { 605 {
594 ODS("==== GetPathFromIDList() (SHGetPathFromIDListEx)") 606 ODS("==== GetPathFromIDList() (SHGetPathFromIDListEx)")
595 do 607 do
596 { 608 {
597 len *= 4; 609 len *= 4;
598 result = BOOLToBool(func_SHGetPathFromIDListEx(itemIDList, path.GetBuf(len), len, 0)); 610 result = BOOLToBool(
611#ifdef Z7_USE_DYN_SHGetPathFromIDListEx
612 func_SHGetPathFromIDListEx
613#else
614 SHGetPathFromIDListEx
615#endif
616 (itemIDList, path.GetBuf(len), len, 0));
599 if (result) 617 if (result)
600 break; 618 break;
601 } 619 }
diff --git a/CPP/Windows/Shell.h b/CPP/Windows/Shell.h
index b4cdb30..9e58e25 100644
--- a/CPP/Windows/Shell.h
+++ b/CPP/Windows/Shell.h
@@ -3,7 +3,6 @@
3#ifndef ZIP7_WINDOWS_SHELL_H 3#ifndef ZIP7_WINDOWS_SHELL_H
4#define ZIP7_WINDOWS_SHELL_H 4#define ZIP7_WINDOWS_SHELL_H
5 5
6#include "../Common/Common.h"
7#include "../Common/MyWindows.h" 6#include "../Common/MyWindows.h"
8#if defined(__MINGW32__) || defined(__MINGW64__) 7#if defined(__MINGW32__) || defined(__MINGW64__)
9#include <shlobj.h> 8#include <shlobj.h>
diff --git a/CPP/Windows/StdAfx.h b/CPP/Windows/StdAfx.h
index bd5084f..4441a5f 100644
--- a/CPP/Windows/StdAfx.h
+++ b/CPP/Windows/StdAfx.h
@@ -6,7 +6,6 @@
6#if defined(_MSC_VER) && _MSC_VER >= 1800 6#if defined(_MSC_VER) && _MSC_VER >= 1800
7#pragma warning(disable : 4464) // relative include path contains '..' 7#pragma warning(disable : 4464) // relative include path contains '..'
8#endif 8#endif
9
10#include "../Common/Common.h" 9#include "../Common/Common.h"
11 10
12#endif 11#endif
diff --git a/CPP/Windows/Synchronization.h b/CPP/Windows/Synchronization.h
index afd03d2..1df84d3 100644
--- a/CPP/Windows/Synchronization.h
+++ b/CPP/Windows/Synchronization.h
@@ -234,6 +234,11 @@ public:
234 } 234 }
235 WRes Enter() 235 WRes Enter()
236 { 236 {
237#if defined(Z7_LLVM_CLANG_VERSION) && (__clang_major__ == 13) \
238 && defined(__FreeBSD__)
239 #pragma GCC diagnostic ignored "-Wthread-safety-negative"
240 #pragma GCC diagnostic ignored "-Wthread-safety-analysis"
241#endif
237 return ::pthread_mutex_lock(&_mutex); 242 return ::pthread_mutex_lock(&_mutex);
238 } 243 }
239 WRes Leave() 244 WRes Leave()
diff --git a/CPP/Windows/System.cpp b/CPP/Windows/System.cpp
index dbe287a..03c8988 100644
--- a/CPP/Windows/System.cpp
+++ b/CPP/Windows/System.cpp
@@ -5,7 +5,8 @@
5#ifndef _WIN32 5#ifndef _WIN32
6#include <unistd.h> 6#include <unistd.h>
7#include <limits.h> 7#include <limits.h>
8#ifdef __APPLE__ 8#if defined(__APPLE__) || defined(__DragonFly__) || \
9 defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
9#include <sys/sysctl.h> 10#include <sys/sysctl.h>
10#else 11#else
11#include <sys/sysinfo.h> 12#include <sys/sysinfo.h>
@@ -28,7 +29,10 @@ UInt32 CountAffinity(DWORD_PTR mask)
28{ 29{
29 UInt32 num = 0; 30 UInt32 num = 0;
30 for (unsigned i = 0; i < sizeof(mask) * 8; i++) 31 for (unsigned i = 0; i < sizeof(mask) * 8; i++)
31 num += (UInt32)((mask >> i) & 1); 32 {
33 num += (UInt32)(mask & 1);
34 mask >>= 1;
35 }
32 return num; 36 return num;
33} 37}
34 38
@@ -114,7 +118,7 @@ UInt32 GetNumberOfProcessors()
114#if !defined(_WIN64) && \ 118#if !defined(_WIN64) && \
115 (defined(__MINGW32_VERSION) || defined(Z7_OLD_WIN_SDK)) 119 (defined(__MINGW32_VERSION) || defined(Z7_OLD_WIN_SDK))
116 120
117typedef struct _MY_MEMORYSTATUSEX { 121typedef struct {
118 DWORD dwLength; 122 DWORD dwLength;
119 DWORD dwMemoryLoad; 123 DWORD dwMemoryLoad;
120 DWORDLONG ullTotalPhys; 124 DWORDLONG ullTotalPhys;
@@ -187,26 +191,58 @@ bool GetRamSize(UInt64 &size)
187{ 191{
188 size = (UInt64)(sizeof(size_t)) << 29; 192 size = (UInt64)(sizeof(size_t)) << 29;
189 193
190 #ifdef __APPLE__ 194#if defined(__APPLE__) || defined(__DragonFly__) || \
195 defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
196
197 uint64_t val = 0;
198 int mib[2];
199 mib[0] = CTL_HW;
191 200
192 #ifdef HW_MEMSIZE 201 #ifdef HW_MEMSIZE
193 uint64_t val = 0; // support 2Gb+ RAM 202 mib[1] = HW_MEMSIZE;
194 int mib[2] = { CTL_HW, HW_MEMSIZE }; 203 // printf("\n sysctl HW_MEMSIZE");
195 #elif defined(HW_PHYSMEM64) 204 #elif defined(HW_PHYSMEM64)
196 uint64_t val = 0; // support 2Gb+ RAM 205 mib[1] = HW_PHYSMEM64;
197 int mib[2] = { CTL_HW, HW_PHYSMEM64 }; 206 // printf("\n sysctl HW_PHYSMEM64");
198 #else 207 #else
199 unsigned int val = 0; // For old system 208 mib[1] = HW_PHYSMEM;
200 int mib[2] = { CTL_HW, HW_PHYSMEM }; 209 // printf("\n sysctl HW_PHYSMEM");
201 #endif // HW_MEMSIZE 210 #endif
202 size_t size_sys = sizeof(val);
203 211
204 sysctl(mib, 2, &val, &size_sys, NULL, 0); 212 size_t size_sys = sizeof(val);
205 if (val) 213 int res = sysctl(mib, 2, &val, &size_sys, NULL, 0);
206 size = val; 214 // printf("\n sysctl res=%d val=%llx size_sys = %d, %d\n", res, (long long int)val, (int)size_sys, errno);
215 // we use strict check (size_sys == sizeof(val)) for returned value
216 // because big-endian encoding is possible:
217 if (res == 0 && size_sys == sizeof(val) && val)
218 size = val;
219 else
220 {
221 uint32_t val32 = 0;
222 size_sys = sizeof(val32);
223 res = sysctl(mib, 2, &val32, &size_sys, NULL, 0);
224 // printf("\n sysctl res=%d val=%llx size_sys = %d, %d\n", res, (long long int)val32, (int)size_sys, errno);
225 if (res == 0 && size_sys == sizeof(val32) && val32)
226 size = val32;
227 }
207 228
208 #elif defined(_AIX) 229 #elif defined(_AIX)
209 // fixme 230 #if defined(_SC_AIX_REALMEM) // AIX
231 size = (UInt64)sysconf(_SC_AIX_REALMEM) * 1024;
232 #endif
233 #elif 0 || defined(__sun)
234 #if defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
235 // FreeBSD, Linux, OpenBSD, and Solaris.
236 {
237 const long phys_pages = sysconf(_SC_PHYS_PAGES);
238 const long page_size = sysconf(_SC_PAGESIZE);
239 // #pragma message("GetRamSize : sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE)")
240 // printf("\n_SC_PHYS_PAGES (hex) = %lx", (unsigned long)phys_pages);
241 // printf("\n_SC_PAGESIZE = %lu\n", (unsigned long)page_size);
242 if (phys_pages != -1 && page_size != -1)
243 size = (UInt64)(Int64)phys_pages * (UInt64)(Int64)page_size;
244 }
245 #endif
210 #elif defined(__gnu_hurd__) 246 #elif defined(__gnu_hurd__)
211 // fixme 247 // fixme
212 #elif defined(__FreeBSD_kernel__) && defined(__GLIBC__) 248 #elif defined(__FreeBSD_kernel__) && defined(__GLIBC__)
@@ -218,10 +254,6 @@ bool GetRamSize(UInt64 &size)
218 if (::sysinfo(&info) != 0) 254 if (::sysinfo(&info) != 0)
219 return false; 255 return false;
220 size = (UInt64)info.mem_unit * info.totalram; 256 size = (UInt64)info.mem_unit * info.totalram;
221 const UInt64 kLimit = (UInt64)1 << (sizeof(size_t) * 8 - 1);
222 if (size > kLimit)
223 size = kLimit;
224
225 /* 257 /*
226 printf("\n mem_unit = %lld", (UInt64)info.mem_unit); 258 printf("\n mem_unit = %lld", (UInt64)info.mem_unit);
227 printf("\n totalram = %lld", (UInt64)info.totalram); 259 printf("\n totalram = %lld", (UInt64)info.totalram);
@@ -230,6 +262,10 @@ bool GetRamSize(UInt64 &size)
230 262
231 #endif 263 #endif
232 264
265 const UInt64 kLimit = (UInt64)1 << (sizeof(size_t) * 8 - 1);
266 if (size > kLimit)
267 size = kLimit;
268
233 return true; 269 return true;
234} 270}
235 271
@@ -269,7 +305,7 @@ unsigned Get_File_OPEN_MAX_Reduced_for_3_tasks()
269 numFiles_OPEN_MAX = 1; 305 numFiles_OPEN_MAX = 1;
270 numFiles_OPEN_MAX /= 3; // we suppose that we have up to 3 tasks in total for multiple file processing 306 numFiles_OPEN_MAX /= 3; // we suppose that we have up to 3 tasks in total for multiple file processing
271 numFiles_OPEN_MAX = MyMax(numFiles_OPEN_MAX, (unsigned long)3); 307 numFiles_OPEN_MAX = MyMax(numFiles_OPEN_MAX, (unsigned long)3);
272 unsigned n = (UInt32)(UInt32)-1; 308 unsigned n = (unsigned)(int)-1;
273 if (n > numFiles_OPEN_MAX) 309 if (n > numFiles_OPEN_MAX)
274 n = (unsigned)numFiles_OPEN_MAX; 310 n = (unsigned)numFiles_OPEN_MAX;
275 return n; 311 return n;
diff --git a/CPP/Windows/System.h b/CPP/Windows/System.h
index 0650007..b17111c 100644
--- a/CPP/Windows/System.h
+++ b/CPP/Windows/System.h
@@ -105,7 +105,7 @@ struct CProcessAffinity
105 } 105 }
106 106
107 void CpuZero() { } 107 void CpuZero() { }
108 void CpuSet(unsigned cpuIndex) { UNUSED_VAR(cpuIndex); } 108 void CpuSet(unsigned /* cpuIndex */) { /* UNUSED_VAR(cpuIndex) */ }
109 int IsCpuSet(unsigned cpuIndex) const { return (cpuIndex < numSysThreads) ? 1 : 0; } 109 int IsCpuSet(unsigned cpuIndex) const { return (cpuIndex < numSysThreads) ? 1 : 0; }
110 110
111 BOOL SetProcAffinity() const 111 BOOL SetProcAffinity() const
diff --git a/CPP/Windows/SystemInfo.cpp b/CPP/Windows/SystemInfo.cpp
index 6bafc80..d23e84b 100644
--- a/CPP/Windows/SystemInfo.cpp
+++ b/CPP/Windows/SystemInfo.cpp
@@ -16,9 +16,28 @@
16#include <sys/utsname.h> 16#include <sys/utsname.h>
17#ifdef __APPLE__ 17#ifdef __APPLE__
18#include <sys/sysctl.h> 18#include <sys/sysctl.h>
19
19#elif !defined(_AIX) 20#elif !defined(_AIX)
20 21
22#if defined(__GLIBC__) && (__GLIBC__ * 100 + __GLIBC_MINOR__ >= 216)
23 #define Z7_GETAUXV_AVAILABLE
24#else
25// #pragma message("=== is not NEW GLIBC === ")
26 #if defined __has_include
27 #if __has_include (<sys/auxv.h>)
28// #pragma message("=== sys/auxv.h is avail=== ")
29 #define Z7_GETAUXV_AVAILABLE
30 #endif
31 #endif
32#endif
33
34#ifdef Z7_GETAUXV_AVAILABLE
35// #if defined __has_include
36// #if __has_include (<sys/auxv.h>)
21#include <sys/auxv.h> 37#include <sys/auxv.h>
38#define USE_HWCAP
39// #endif
40// #endif
22 41
23// #undef AT_HWCAP // to debug 42// #undef AT_HWCAP // to debug
24// #undef AT_HWCAP2 // to debug 43// #undef AT_HWCAP2 // to debug
@@ -36,11 +55,39 @@
36#endif 55#endif
37*/ 56*/
38 57
58#ifdef USE_HWCAP
59
60#if defined(__FreeBSD__)
61
62// #if (__FreeBSD__ >= 13) // (FreeBSD 12.01 is required for elf_aux_info() ???)
63static unsigned long MY_getauxval(int aux)
64{
65 unsigned long val;
66 if (elf_aux_info(aux, &val, sizeof(val)))
67 return 0;
68 return val;
69}
70
71#else // ! __FreeBSD__
72
39#ifdef MY_CPU_ARM_OR_ARM64 73#ifdef MY_CPU_ARM_OR_ARM64
74 #if defined __has_include
75 #if __has_include (<asm/hwcap.h>)
40#include <asm/hwcap.h> 76#include <asm/hwcap.h>
77 #endif
78 #endif
41#endif 79#endif
80
81#if defined(AT_HWCAP) || defined(AT_HWCAP2)
82#define MY_getauxval getauxval
42#endif 83#endif
43 84
85#endif // ! __FreeBSD__
86#endif // USE_HWCAP
87#endif // Z7_GETAUXV_AVAILABLE
88
89#endif // !defined(_AIX)
90
44#ifdef __linux__ 91#ifdef __linux__
45#include "../Windows/FileIO.h" 92#include "../Windows/FileIO.h"
46#endif 93#endif
@@ -70,13 +117,13 @@ static bool ReadFile_to_Buffer(CFSTR fileName, CByteBuffer &buf)
70 return false; 117 return false;
71 */ 118 */
72 size_t size = 0; 119 size_t size = 0;
73 size_t addSize = ((size_t)1 << 12); 120 size_t addSize = (size_t)1 << 12;
74 for (;;) 121 for (;;)
75 { 122 {
76 // printf("\nsize = %d\n", (unsigned)size); 123 // printf("\nsize = %d\n", (unsigned)size);
77 buf.ChangeSize_KeepData(size + addSize, size); 124 buf.ChangeSize_KeepData(size + addSize, size);
78 size_t processed; 125 size_t processed;
79 if (!file.ReadFull(buf + size, addSize, processed)) 126 if (!file.ReadFull(buf.NonConstData() + size, addSize, processed))
80 return false; 127 return false;
81 if (processed == 0) 128 if (processed == 0)
82 { 129 {
@@ -107,19 +154,19 @@ static void PrintCpuChars(AString &s, UInt32 v)
107{ 154{
108 for (unsigned j = 0; j < 4; j++) 155 for (unsigned j = 0; j < 4; j++)
109 { 156 {
110 Byte b = (Byte)(v & 0xFF); 157 const Byte b = (Byte)(v & 0xFF);
111 v >>= 8; 158 v >>= 8;
112 if (b == 0) 159 if (b == 0)
113 break; 160 break;
114 if (b >= 0x20 && b <= 0x7f) 161 if (b >= 0x20 && b <= 0x7f)
115 s += (char)b; 162 s.Add_Char((char)b);
116 else 163 else
117 { 164 {
118 s += '['; 165 s.Add_Char('[');
119 char temp[16]; 166 char temp[16];
120 ConvertUInt32ToHex(b, temp); 167 ConvertUInt32ToHex(b, temp);
121 s += temp; 168 s += temp;
122 s += ']'; 169 s.Add_Char(']');
123 } 170 }
124 } 171 }
125} 172}
@@ -137,7 +184,7 @@ static void x86cpuid_to_String(AString &s)
137 { 184 {
138 for (unsigned i = 0; i < 3; i++) 185 for (unsigned i = 0; i < 3; i++)
139 { 186 {
140 z7_x86_cpuid(a, 0x80000002 + i); 187 z7_x86_cpuid(a, (UInt32)(0x80000002 + i));
141 for (unsigned j = 0; j < 4; j++) 188 for (unsigned j = 0; j < 4; j++)
142 PrintCpuChars(s, a[j]); 189 PrintCpuChars(s, a[j]);
143 } 190 }
@@ -353,8 +400,8 @@ void PrintSize_KMGT_Or_Hex(AString &s, UInt64 v)
353 } 400 }
354 s.Add_UInt64(v); 401 s.Add_UInt64(v);
355 if (c) 402 if (c)
356 s += c; 403 s.Add_Char(c);
357 s += 'B'; 404 s.Add_Char('B');
358} 405}
359// #endif 406// #endif
360// #endif 407// #endif
@@ -380,7 +427,7 @@ static void SysInfo_To_String(AString &s, const SYSTEM_INFO &si)
380 s += " act:"; 427 s += " act:";
381 PrintHex(s, si.dwActiveProcessorMask); 428 PrintHex(s, si.dwActiveProcessorMask);
382 } 429 }
383 s += " cpus:"; 430 s += " threads:";
384 s.Add_UInt32(si.dwNumberOfProcessors); 431 s.Add_UInt32(si.dwNumberOfProcessors);
385 if (si.dwPageSize != 1 << 12) 432 if (si.dwPageSize != 1 << 12)
386 { 433 {
@@ -400,7 +447,7 @@ static void SysInfo_To_String(AString &s, const SYSTEM_INFO &si)
400 if (minAdd != kReserveSize) 447 if (minAdd != kReserveSize)
401 { 448 {
402 PrintSize_KMGT_Or_Hex(s, minAdd); 449 PrintSize_KMGT_Or_Hex(s, minAdd);
403 s += "-"; 450 s.Add_Minus();
404 } 451 }
405 else 452 else
406 { 453 {
@@ -470,11 +517,10 @@ static void AddBracedString(AString &dest, AString &src)
470{ 517{
471 if (!src.IsEmpty()) 518 if (!src.IsEmpty())
472 { 519 {
473 AString s; 520 dest.Add_Space_if_NotEmpty();
474 s += '('; 521 dest.Add_Char('(');
475 s += src; 522 dest += src;
476 s += ')'; 523 dest.Add_Char(')');
477 dest.Add_OptSpaced(s);
478 } 524 }
479} 525}
480 526
@@ -527,6 +573,13 @@ void CCpuName::Fill()
527 { 573 {
528 Add_sysctlbyname_to_String("machdep.cpu.brand_string", s); 574 Add_sysctlbyname_to_String("machdep.cpu.brand_string", s);
529 } 575 }
576 #elif defined(MY_CPU_E2K) && defined(Z7_MCST_LCC_VERSION) && (Z7_MCST_LCC_VERSION >= 12323)
577 {
578 s += "mcst ";
579 s += __builtin_cpu_name();
580 s.Add_Space();
581 s += __builtin_cpu_arch();
582 }
530 #endif 583 #endif
531 584
532 585
@@ -592,11 +645,11 @@ void CCpuName::Fill()
592 const CByteBuffer &buf = bufs[i]; 645 const CByteBuffer &buf = bufs[i];
593 if (buf.Size() == 8) 646 if (buf.Size() == 8)
594 { 647 {
595 UInt32 high = GetUi32(buf); 648 const UInt32 high = GetUi32(buf);
596 if (high != 0) 649 if (high != 0)
597 { 650 {
598 PrintHex(Microcode, high); 651 PrintHex(Microcode, high);
599 Microcode += "."; 652 Microcode.Add_Dot();
600 } 653 }
601 PrintHex(Microcode, GetUi32(buf + 4)); 654 PrintHex(Microcode, GetUi32(buf + 4));
602 } 655 }
@@ -622,7 +675,7 @@ void AddCpuFeatures(AString &s)
622 UInt64 flags = 0; 675 UInt64 flags = 0;
623 for (unsigned i = 0; i < kNumFeatures; i++) 676 for (unsigned i = 0; i < kNumFeatures; i++)
624 { 677 {
625 if (IsProcessorFeaturePresent(i)) 678 if (IsProcessorFeaturePresent((DWORD)i))
626 { 679 {
627 flags += (UInt64)1 << i; 680 flags += (UInt64)1 << i;
628 // s.Add_Space_if_NotEmpty(); 681 // s.Add_Space_if_NotEmpty();
@@ -682,7 +735,7 @@ void AddCpuFeatures(AString &s)
682 #ifdef AT_HWCAP 735 #ifdef AT_HWCAP
683 s.Add_OptSpaced("hwcap:"); 736 s.Add_OptSpaced("hwcap:");
684 { 737 {
685 unsigned long h = getauxval(AT_HWCAP); 738 unsigned long h = MY_getauxval(AT_HWCAP);
686 PrintHex(s, h); 739 PrintHex(s, h);
687 #ifdef MY_CPU_ARM64 740 #ifdef MY_CPU_ARM64
688 if (h & HWCAP_CRC32) s += ":CRC32"; 741 if (h & HWCAP_CRC32) s += ":CRC32";
@@ -698,7 +751,7 @@ void AddCpuFeatures(AString &s)
698 751
699 #ifdef AT_HWCAP2 752 #ifdef AT_HWCAP2
700 { 753 {
701 unsigned long h = getauxval(AT_HWCAP2); 754 unsigned long h = MY_getauxval(AT_HWCAP2);
702 #ifndef MY_CPU_ARM 755 #ifndef MY_CPU_ARM
703 if (h != 0) 756 if (h != 0)
704 #endif 757 #endif
@@ -722,6 +775,8 @@ void AddCpuFeatures(AString &s)
722#ifdef _WIN32 775#ifdef _WIN32
723#ifndef UNDER_CE 776#ifndef UNDER_CE
724 777
778Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
779
725EXTERN_C_BEGIN 780EXTERN_C_BEGIN
726typedef void (WINAPI * Func_RtlGetVersion) (OSVERSIONINFOEXW *); 781typedef void (WINAPI * Func_RtlGetVersion) (OSVERSIONINFOEXW *);
727EXTERN_C_END 782EXTERN_C_END
@@ -952,24 +1007,13 @@ void GetVirtCpuid(AString &s)
952 1007
953void GetCompiler(AString &s) 1008void GetCompiler(AString &s)
954{ 1009{
955 #ifdef __VERSION__
956 s += __VERSION__;
957 #endif
958
959 #ifdef __GNUC__
960 s += " GCC ";
961 s.Add_UInt32(__GNUC__);
962 s.Add_Dot();
963 s.Add_UInt32(__GNUC_MINOR__);
964 s.Add_Dot();
965 s.Add_UInt32(__GNUC_PATCHLEVEL__);
966 #endif
967
968 #ifdef __clang__ 1010 #ifdef __clang__
969 s += " CLANG "; 1011 s += " CLANG ";
970 s.Add_UInt32(__clang_major__); 1012 s.Add_UInt32(__clang_major__);
971 s.Add_Dot(); 1013 s.Add_Dot();
972 s.Add_UInt32(__clang_minor__); 1014 s.Add_UInt32(__clang_minor__);
1015 s.Add_Dot();
1016 s.Add_UInt32(__clang_patchlevel__);
973 #endif 1017 #endif
974 1018
975 #ifdef __xlC__ 1019 #ifdef __xlC__
@@ -985,12 +1029,67 @@ void GetCompiler(AString &s)
985 #endif 1029 #endif
986 #endif 1030 #endif
987 1031
1032 // #define __LCC__ 126
1033 // #define __LCC_MINOR__ 20
1034 // #define __MCST__ 1
1035 #ifdef __MCST__
1036 s += " MCST";
1037 #endif
1038 #ifdef __LCC__
1039 s += " LCC ";
1040 s.Add_UInt32(__LCC__ / 100);
1041 s.Add_Dot();
1042 s.Add_UInt32(__LCC__ % 100 / 10);
1043 s.Add_UInt32(__LCC__ % 10);
1044 #ifdef __LCC_MINOR__
1045 s.Add_Dot();
1046 s.Add_UInt32(__LCC_MINOR__ / 10);
1047 s.Add_UInt32(__LCC_MINOR__ % 10);
1048 #endif
1049 #endif
1050
1051 // #define __EDG_VERSION__ 602
1052 #ifdef __EDG_VERSION__
1053 s += " EDG ";
1054 s.Add_UInt32(__EDG_VERSION__ / 100);
1055 s.Add_Dot();
1056 s.Add_UInt32(__EDG_VERSION__ % 100 / 10);
1057 s.Add_UInt32(__EDG_VERSION__ % 10);
1058 #endif
1059
1060 #ifdef __VERSION__
1061 s.Add_Space();
1062 s += "ver:";
1063 s += __VERSION__;
1064 #endif
1065
1066 #ifdef __GNUC__
1067 s += " GCC ";
1068 s.Add_UInt32(__GNUC__);
1069 s.Add_Dot();
1070 s.Add_UInt32(__GNUC_MINOR__);
1071 s.Add_Dot();
1072 s.Add_UInt32(__GNUC_PATCHLEVEL__);
1073 #endif
1074
1075
988 #ifdef _MSC_VER 1076 #ifdef _MSC_VER
989 s += " MSC "; 1077 s += " MSC ";
990 s.Add_UInt32(_MSC_VER); 1078 s.Add_UInt32(_MSC_VER);
1079 #ifdef _MSC_FULL_VER
1080 s.Add_Dot();
1081 s.Add_UInt32(_MSC_FULL_VER);
1082 #endif
1083
991 #endif 1084 #endif
992 1085
993 #if defined(__AVX2__) 1086 #if defined(__AVX512F__)
1087 #if defined(__AVX512VL__)
1088 #define MY_CPU_COMPILE_ISA "AVX512VL"
1089 #else
1090 #define MY_CPU_COMPILE_ISA "AVX512F"
1091 #endif
1092 #elif defined(__AVX2__)
994 #define MY_CPU_COMPILE_ISA "AVX2" 1093 #define MY_CPU_COMPILE_ISA "AVX2"
995 #elif defined(__AVX__) 1094 #elif defined(__AVX__)
996 #define MY_CPU_COMPILE_ISA "AVX" 1095 #define MY_CPU_COMPILE_ISA "AVX"
@@ -1014,9 +1113,61 @@ void GetCompiler(AString &s)
1014 #define MY_CPU_COMPILE_ISA "IA32" 1113 #define MY_CPU_COMPILE_ISA "IA32"
1015 #endif 1114 #endif
1016 1115
1116 AString s2;
1017 1117
1018 #ifdef MY_CPU_COMPILE_ISA 1118 #ifdef MY_CPU_COMPILE_ISA
1019 s += ':'; 1119 s2.Add_OptSpaced(MY_CPU_COMPILE_ISA);
1020 s.Add_OptSpaced(MY_CPU_COMPILE_ISA); 1120 #endif
1121
1122#ifndef MY_CPU_ARM64
1123 #ifdef __ARM_FP
1124 s2.Add_OptSpaced("FP");
1125 #endif
1126 #ifdef __ARM_NEON
1127 s2.Add_OptSpaced("NEON");
1021 #endif 1128 #endif
1129 #ifdef __NEON__
1130 s2.Add_OptSpaced("__NEON__");
1131 #endif
1132 #ifdef __ARM_FEATURE_SIMD32
1133 s2.Add_OptSpaced("SIMD32");
1134 #endif
1135#endif
1136
1137 #ifdef __ARM_FEATURE_CRYPTO
1138 s2.Add_OptSpaced("CRYPTO");
1139 #endif
1140
1141 #ifdef __ARM_FEATURE_SHA2
1142 s2.Add_OptSpaced("SHA2");
1143 #endif
1144
1145 #ifdef __ARM_FEATURE_AES
1146 s2.Add_OptSpaced("AES");
1147 #endif
1148
1149 #ifdef __ARM_FEATURE_CRC32
1150 s2.Add_OptSpaced("CRC32");
1151 #endif
1152
1153 #ifdef __ARM_FEATURE_UNALIGNED
1154 s2.Add_OptSpaced("UNALIGNED");
1155 #endif
1156
1157
1158 #ifdef MY_CPU_BE
1159 s2.Add_OptSpaced("BE");
1160 #endif
1161
1162 #if defined(MY_CPU_LE_UNALIGN) \
1163 && !defined(MY_CPU_X86_OR_AMD64) \
1164 && !defined(MY_CPU_ARM64)
1165 s2.Add_OptSpaced("LE-unaligned");
1166 #endif
1167
1168 if (!s2.IsEmpty())
1169 {
1170 s.Add_OptSpaced(": ");
1171 s += s2;
1172 }
1022} 1173}
diff --git a/CPP/Windows/TimeUtils.cpp b/CPP/Windows/TimeUtils.cpp
index e80ae13..bbd79ba 100644
--- a/CPP/Windows/TimeUtils.cpp
+++ b/CPP/Windows/TimeUtils.cpp
@@ -4,6 +4,7 @@
4 4
5#ifndef _WIN32 5#ifndef _WIN32
6#include <sys/time.h> 6#include <sys/time.h>
7#include <time.h>
7#endif 8#endif
8 9
9#include "Defs.h" 10#include "Defs.h"
@@ -13,13 +14,13 @@ namespace NWindows {
13namespace NTime { 14namespace NTime {
14 15
15static const UInt32 kNumTimeQuantumsInSecond = 10000000; 16static const UInt32 kNumTimeQuantumsInSecond = 10000000;
16static const UInt32 kFileTimeStartYear = 1601; 17static const unsigned kFileTimeStartYear = 1601;
17#if !defined(_WIN32) || defined(UNDER_CE) 18#if !defined(_WIN32) || defined(UNDER_CE)
18static const UInt32 kDosTimeStartYear = 1980; 19static const unsigned kDosTimeStartYear = 1980;
19#endif 20#endif
20static const UInt32 kUnixTimeStartYear = 1970; 21static const unsigned kUnixTimeStartYear = 1970;
21static const UInt64 kUnixTimeOffset = 22static const UInt64 kUnixTimeOffset =
22 (UInt64)60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear)); 23 (UInt64)60 * 60 * 24 * (89 + 365 * (UInt32)(kUnixTimeStartYear - kFileTimeStartYear));
23static const UInt64 kNumSecondsInFileTime = (UInt64)(Int64)-1 / kNumTimeQuantumsInSecond; 24static const UInt64 kNumSecondsInFileTime = (UInt64)(Int64)-1 / kNumTimeQuantumsInSecond;
24 25
25bool DosTime_To_FileTime(UInt32 dosTime, FILETIME &ft) throw() 26bool DosTime_To_FileTime(UInt32 dosTime, FILETIME &ft) throw()
@@ -30,8 +31,14 @@ bool DosTime_To_FileTime(UInt32 dosTime, FILETIME &ft) throw()
30 ft.dwLowDateTime = 0; 31 ft.dwLowDateTime = 0;
31 ft.dwHighDateTime = 0; 32 ft.dwHighDateTime = 0;
32 UInt64 res; 33 UInt64 res;
33 if (!GetSecondsSince1601(kDosTimeStartYear + (dosTime >> 25), (dosTime >> 21) & 0xF, (dosTime >> 16) & 0x1F, 34 if (!GetSecondsSince1601(
34 (dosTime >> 11) & 0x1F, (dosTime >> 5) & 0x3F, (dosTime & 0x1F) * 2, res)) 35 kDosTimeStartYear + (unsigned)(dosTime >> 25),
36 (unsigned)((dosTime >> 21) & 0xF),
37 (unsigned)((dosTime >> 16) & 0x1F),
38 (unsigned)((dosTime >> 11) & 0x1F),
39 (unsigned)((dosTime >> 5) & 0x3F),
40 (unsigned)((dosTime & 0x1F)) * 2,
41 res))
35 return false; 42 return false;
36 res *= kNumTimeQuantumsInSecond; 43 res *= kNumTimeQuantumsInSecond;
37 ft.dwLowDateTime = (UInt32)res; 44 ft.dwLowDateTime = (UInt32)res;
@@ -77,7 +84,7 @@ bool FileTime_To_DosTime(const FILETIME &ft, UInt32 &dosTime) throw()
77 84
78 v = (UInt32)v64; 85 v = (UInt32)v64;
79 86
80 year = (unsigned)(kFileTimeStartYear + v / PERIOD_400 * 400); 87 year = kFileTimeStartYear + (unsigned)(v / PERIOD_400 * 400);
81 v %= PERIOD_400; 88 v %= PERIOD_400;
82 89
83 temp = (unsigned)(v / PERIOD_100); 90 temp = (unsigned)(v / PERIOD_100);
@@ -116,7 +123,13 @@ bool FileTime_To_DosTime(const FILETIME &ft, UInt32 &dosTime) throw()
116 dosTime = kHighDosTime; 123 dosTime = kHighDosTime;
117 if (year >= 128) 124 if (year >= 128)
118 return false; 125 return false;
119 dosTime = (year << 25) | (mon << 21) | (day << 16) | (hour << 11) | (min << 5) | (sec >> 1); 126 dosTime =
127 ((UInt32)year << 25)
128 | ((UInt32)mon << 21)
129 | ((UInt32)day << 16)
130 | ((UInt32)hour << 11)
131 | ((UInt32)min << 5)
132 | ((UInt32)sec >> 1);
120 #endif 133 #endif
121 return true; 134 return true;
122} 135}
@@ -226,20 +239,34 @@ bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
226 if (year < kFileTimeStartYear || year >= 10000 || month < 1 || month > 12 || 239 if (year < kFileTimeStartYear || year >= 10000 || month < 1 || month > 12 ||
227 day < 1 || day > 31 || hour > 23 || min > 59 || sec > 59) 240 day < 1 || day > 31 || hour > 23 || min > 59 || sec > 59)
228 return false; 241 return false;
229 UInt32 numYears = year - kFileTimeStartYear; 242 const unsigned numYears = year - kFileTimeStartYear;
230 UInt32 numDays = numYears * 365 + numYears / 4 - numYears / 100 + numYears / 400; 243 UInt32 numDays = (UInt32)((UInt32)numYears * 365 + numYears / 4 - numYears / 100 + numYears / 400);
231 Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 244 Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
232 if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) 245 if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
233 ms[1] = 29; 246 ms[1] = 29;
234 month--; 247 month--;
235 for (unsigned i = 0; i < month; i++) 248 for (unsigned i = 0; i < month; i++)
236 numDays += ms[i]; 249 numDays += ms[i];
237 numDays += day - 1; 250 numDays += (UInt32)(day - 1);
238 resSeconds = ((UInt64)(numDays * 24 + hour) * 60 + min) * 60 + sec; 251 resSeconds = ((UInt64)(numDays * 24 + hour) * 60 + min) * 60 + sec;
239 return true; 252 return true;
240} 253}
241 254
242 255
256/* docs: TIME_UTC is not defined on many platforms:
257 glibc 2.15, macOS 10.13
258 FreeBSD 11.0, NetBSD 7.1, OpenBSD 6.0,
259 Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.3,
260 Cygwin 2.9, mingw, MSVC 14, Android 9.0.
261*/
262#if defined(TIME_UTC)
263#define ZIP7_USE_timespec_get
264// #pragma message("ZIP7_USE_timespec_get")
265#elif defined(CLOCK_REALTIME)
266#define ZIP7_USE_clock_gettime
267// #pragma message("ZIP7_USE_clock_gettime")
268#endif
269
243void GetCurUtc_FiTime(CFiTime &ft) throw() 270void GetCurUtc_FiTime(CFiTime &ft) throw()
244{ 271{
245 #ifdef _WIN32 272 #ifdef _WIN32
@@ -257,12 +284,33 @@ void GetCurUtc_FiTime(CFiTime &ft) throw()
257 #else 284 #else
258 285
259 FiTime_Clear(ft); 286 FiTime_Clear(ft);
287#ifdef ZIP7_USE_timespec_get
288 timespec_get(&ft, TIME_UTC);
289#elif defined ZIP7_USE_clock_gettime
290
291#if defined(_AIX)
292 {
293 timespec ts;
294 clock_gettime(CLOCK_REALTIME, &ts);
295 ft.tv_sec = ts.tv_sec;
296 ft.tv_nsec = ts.tv_nsec;
297 }
298#else
299 clock_gettime(CLOCK_REALTIME, &ft);
300#endif
301
302#else
260 struct timeval now; 303 struct timeval now;
261 if (gettimeofday(&now, NULL) == 0) 304 if (gettimeofday(&now, NULL) == 0)
262 { 305 {
263 ft.tv_sec = now.tv_sec; 306 ft.tv_sec = now.tv_sec;
264 ft.tv_nsec = now.tv_usec * 1000; 307 // timeval::tv_usec can be 64-bit signed in some cases
308 // timespec::tv_nsec can be 32-bit signed in some cases
309 ft.tv_nsec =
310 (Int32) // to eliminate compiler conversion error
311 (now.tv_usec * 1000);
265 } 312 }
313#endif
266 314
267 #endif 315 #endif
268} 316}
@@ -271,12 +319,26 @@ void GetCurUtc_FiTime(CFiTime &ft) throw()
271void GetCurUtcFileTime(FILETIME &ft) throw() 319void GetCurUtcFileTime(FILETIME &ft) throw()
272{ 320{
273 UInt64 v = 0; 321 UInt64 v = 0;
322#if defined(ZIP7_USE_timespec_get) || \
323 defined(ZIP7_USE_clock_gettime)
324 timespec ts;
325#if defined(ZIP7_USE_timespec_get)
326 if (timespec_get(&ts, TIME_UTC))
327#else
328 if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
329#endif
330 {
331 v = ((UInt64)ts.tv_sec + kUnixTimeOffset) *
332 kNumTimeQuantumsInSecond + (UInt64)ts.tv_nsec / 100;
333 }
334#else
274 struct timeval now; 335 struct timeval now;
275 if (gettimeofday(&now, NULL) == 0) 336 if (gettimeofday(&now, NULL) == 0)
276 { 337 {
277 v = ((UInt64)now.tv_sec + kUnixTimeOffset) * 338 v = ((UInt64)now.tv_sec + kUnixTimeOffset) *
278 kNumTimeQuantumsInSecond + (UInt64)now.tv_usec * 10; 339 kNumTimeQuantumsInSecond + (UInt64)now.tv_usec * 10;
279 } 340 }
341#endif
280 ft.dwLowDateTime = (DWORD)v; 342 ft.dwLowDateTime = (DWORD)v;
281 ft.dwHighDateTime = (DWORD)(v >> 32); 343 ft.dwHighDateTime = (DWORD)(v >> 32);
282} 344}
@@ -371,7 +433,7 @@ int Compare_FiTime(const CFiTime *a1, const CFiTime *a2)
371 return 0; 433 return 0;
372} 434}
373 435
374bool FILETIME_To_timespec(const FILETIME &ft, timespec &ts) 436bool FILETIME_To_timespec(const FILETIME &ft, CFiTime &ts)
375{ 437{
376 UInt32 quantums; 438 UInt32 quantums;
377 const Int64 sec = NWindows::NTime::FileTime_To_UnixTime64_and_Quantums(ft, quantums); 439 const Int64 sec = NWindows::NTime::FileTime_To_UnixTime64_and_Quantums(ft, quantums);
@@ -380,7 +442,7 @@ bool FILETIME_To_timespec(const FILETIME &ft, timespec &ts)
380 if (sec2 == sec) 442 if (sec2 == sec)
381 { 443 {
382 ts.tv_sec = sec2; 444 ts.tv_sec = sec2;
383 ts.tv_nsec = (long)(quantums * 100); 445 ts.tv_nsec = (Int32)(quantums * 100);
384 return true; 446 return true;
385 } 447 }
386 return false; 448 return false;