diff options
Diffstat (limited to '3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp')
-rw-r--r-- | 3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp | 361 |
1 files changed, 264 insertions, 97 deletions
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp index dccc08b171e..ee9ff323632 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp @@ -14,17 +14,23 @@ #include "PropIDUtils.h" +#ifndef Z7_SFX #define Get16(x) GetUi16(x) #define Get32(x) GetUi32(x) +#endif using namespace NWindows; -static const char g_WinAttribChars[16 + 1] = "RHS8DAdNTsLCOnE_"; +static const unsigned kNumWinAtrribFlags = 21; +static const char g_WinAttribChars[kNumWinAtrribFlags + 1] = "RHS8DAdNTsLCOIEV.X.PU"; + /* +FILE_ATTRIBUTE_ + 0 READONLY 1 HIDDEN 2 SYSTEM - +3 (Volume label - obsolete) 4 DIRECTORY 5 ARCHIVE 6 DEVICE @@ -34,14 +40,21 @@ static const char g_WinAttribChars[16 + 1] = "RHS8DAdNTsLCOnE_"; 10 REPARSE_POINT 11 COMPRESSED 12 OFFLINE -13 NOT_CONTENT_INDEXED +13 NOT_CONTENT_INDEXED (I - Win10 attrib/Explorer) 14 ENCRYPTED - -16 VIRTUAL +15 INTEGRITY_STREAM (V - ReFS Win8/Win2012) +16 VIRTUAL (reserved) +17 NO_SCRUB_DATA (X - ReFS Win8/Win2012 attrib) +18 RECALL_ON_OPEN or EA +19 PINNED +20 UNPINNED +21 STRICTLY_SEQUENTIAL +22 RECALL_ON_DATA_ACCESS */ + static const char kPosixTypes[16] = { '0', 'p', 'c', '3', 'd', '5', 'b', '7', '-', '9', 'l', 'B', 's', 'D', 'E', 'F' }; -#define MY_ATTR_CHAR(a, n, c) ((a) & (1 << (n))) ? c : '-'; +#define MY_ATTR_CHAR(a, n, c) (((a) & (1 << (n))) ? c : '-') static void ConvertPosixAttribToString(char *s, UInt32 a) throw() { @@ -52,9 +65,9 @@ static void ConvertPosixAttribToString(char *s, UInt32 a) throw() s[8 - i] = MY_ATTR_CHAR(a, i + 1, 'w'); s[9 - i] = MY_ATTR_CHAR(a, i + 0, 'x'); } - if ((a & 0x800) != 0) s[3] = ((a & (1 << 6)) ? 's' : 'S'); - if ((a & 0x400) != 0) s[6] = ((a & (1 << 3)) ? 's' : 'S'); - if ((a & 0x200) != 0) s[9] = ((a & (1 << 0)) ? 't' : 'T'); + if ((a & 0x800) != 0) s[3] = ((a & (1 << 6)) ? 's' : 'S'); // S_ISUID + if ((a & 0x400) != 0) s[6] = ((a & (1 << 3)) ? 's' : 'S'); // S_ISGID + if ((a & 0x200) != 0) s[9] = ((a & (1 << 0)) ? 't' : 'T'); // S_ISVTX s[10] = 0; a &= ~(UInt32)0xFFFF; @@ -65,36 +78,95 @@ static void ConvertPosixAttribToString(char *s, UInt32 a) throw() } } + void ConvertWinAttribToString(char *s, UInt32 wa) throw() { - for (int i = 0; i < 16; i++) - if ((wa & (1 << i)) && i != 7) - *s++ = g_WinAttribChars[i]; - *s = 0; + /* + some programs store posix attributes in high 16 bits. + p7zip - stores additional 0x8000 flag marker. + macos - stores additional 0x4000 flag marker. + info-zip - no additional marker. + */ + + const bool isPosix = ((wa & 0xF0000000) != 0); + + UInt32 posix = 0; + if (isPosix) + { + posix = wa >> 16; + wa &= (UInt32)0x3FFF; + } - // we support p7zip trick that stores posix attributes in high 16 bits, and 0x8000 flag - // we also support ZIP archives created in Unix, that store posix attributes in high 16 bits without 0x8000 flag + for (unsigned i = 0; i < kNumWinAtrribFlags; i++) + { + UInt32 flag = (1 << i); + if ((wa & flag) != 0) + { + char c = g_WinAttribChars[i]; + if (c != '.') + { + wa &= ~flag; + // if (i != 7) // we can disable N (NORMAL) printing + *s++ = c; + } + } + } - // if (wa & 0x8000) - if ((wa >> 16) != 0) + if (wa != 0) + { + *s++ = ' '; + ConvertUInt32ToHex8Digits(wa, s); + s += strlen(s); + } + + *s = 0; + + if (isPosix) { *s++ = ' '; - ConvertPosixAttribToString(s, wa >> 16); + ConvertPosixAttribToString(s, posix); } } -void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID propID, bool full) throw() + +void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &prop, PROPID propID, int level) throw() { *dest = 0; if (prop.vt == VT_FILETIME) { - FILETIME localFileTime; - if ((prop.filetime.dwHighDateTime == 0 && - prop.filetime.dwLowDateTime == 0) || - !::FileTimeToLocalFileTime(&prop.filetime, &localFileTime)) + const FILETIME &ft = prop.filetime; + unsigned ns100 = 0; + int numDigits = kTimestampPrintLevel_NTFS; + const unsigned prec = prop.wReserved1; + const unsigned ns100_Temp = prop.wReserved2; + if (prec != 0 + && prec <= k_PropVar_TimePrec_1ns + && ns100_Temp < 100 + && prop.wReserved3 == 0) + { + ns100 = ns100_Temp; + if (prec == k_PropVar_TimePrec_Unix || + prec == k_PropVar_TimePrec_DOS) + numDigits = 0; + else if (prec == k_PropVar_TimePrec_HighPrec) + numDigits = 9; + else + { + numDigits = (int)prec - (int)k_PropVar_TimePrec_Base; + if ( + // numDigits < kTimestampPrintLevel_DAY // for debuf + numDigits < kTimestampPrintLevel_SEC + ) + + numDigits = kTimestampPrintLevel_NTFS; + } + } + if (ft.dwHighDateTime == 0 && ft.dwLowDateTime == 0 && ns100 == 0) return; - ConvertFileTimeToString(localFileTime, dest, true, full); + if (level > numDigits) + level = numDigits; + ConvertUtcFileTimeToString2(ft, ns100, dest, level); return; } @@ -111,7 +183,7 @@ void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID pr { if (prop.vt != VT_UI4) break; - UInt32 a = prop.ulVal; + const UInt32 a = prop.ulVal; /* if ((a & 0x8000) && (a & 0x7FFF) == 0) @@ -135,7 +207,7 @@ void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID pr ConvertUInt32ToString((UInt32)(prop.uhVal.QuadPart >> 48), dest); dest += strlen(dest); *dest++ = '-'; - UInt64 low = prop.uhVal.QuadPart & (((UInt64)1 << 48) - 1); + const UInt64 low = prop.uhVal.QuadPart & (((UInt64)1 << 48) - 1); ConvertUInt64ToString(low, dest); return; } @@ -153,12 +225,30 @@ void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID pr ConvertUInt64ToHex(v, dest + 2); return; } + + /* + case kpidDevice: + { + UInt64 v = 0; + if (prop.vt == VT_UI4) + v = prop.ulVal; + else if (prop.vt == VT_UI8) + v = (UInt64)prop.uhVal.QuadPart; + else + break; + ConvertUInt32ToString(MY_dev_major(v), dest); + dest += strlen(dest); + *dest++ = ','; + ConvertUInt32ToString(MY_dev_minor(v), dest); + return; + } + */ } ConvertPropVariantToShortString(prop, dest); } -void ConvertPropertyToString(UString &dest, const PROPVARIANT &prop, PROPID propID, bool full) +void ConvertPropertyToString2(UString &dest, const PROPVARIANT &prop, PROPID propID, int level) { if (prop.vt == VT_BSTR) { @@ -166,22 +256,21 @@ void ConvertPropertyToString(UString &dest, const PROPVARIANT &prop, PROPID prop return; } char temp[64]; - ConvertPropertyToShortString(temp, prop, propID, full); - dest.SetFromAscii(temp); + ConvertPropertyToShortString2(temp, prop, propID, level); + dest = temp; } +#ifndef Z7_SFX + static inline unsigned GetHex(unsigned v) { return (v < 10) ? ('0' + v) : ('A' + (v - 10)); } -#ifndef _SFX - static inline void AddHexToString(AString &res, unsigned v) { res += (char)GetHex(v >> 4); res += (char)GetHex(v & 0xF); - res += ' '; } /* @@ -226,6 +315,14 @@ struct CSecID2Name const char *sz; }; +static int FindPairIndex(const CSecID2Name * pairs, unsigned num, UInt32 id) +{ + for (unsigned i = 0; i < num; i++) + if (pairs[i].n == id) + return (int)i; + return -1; +} + static const CSecID2Name sid_32_Names[] = { { 544, "Administrators" }, @@ -290,52 +387,52 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize) s += "ERROR"; return; } - UInt32 rev = p[0]; + const UInt32 rev = p[0]; if (rev != 1) { s += "UNSUPPORTED"; return; } - UInt32 num = p[1]; + const UInt32 num = p[1]; if (8 + num * 4 > lim) { s += "ERROR"; return; } sidSize = 8 + num * 4; - UInt32 authority = GetBe32(p + 4); + const UInt32 authority = GetBe32(p + 4); if (p[2] == 0 && p[3] == 0 && authority == 5 && num >= 1) { - UInt32 v0 = Get32(p + 8); - if (v0 < ARRAY_SIZE(sidNames)) + const UInt32 v0 = Get32(p + 8); + if (v0 < Z7_ARRAY_SIZE(sidNames)) { s += sidNames[v0]; return; } if (v0 == 32 && num == 2) { - UInt32 v1 = Get32(p + 12); - for (unsigned i = 0; i < ARRAY_SIZE(sid_32_Names); i++) - if (sid_32_Names[i].n == v1) - { - s += sid_32_Names[i].sz; - return; - } + const UInt32 v1 = Get32(p + 12); + const int index = FindPairIndex(sid_32_Names, Z7_ARRAY_SIZE(sid_32_Names), v1); + if (index >= 0) + { + s += sid_32_Names[(unsigned)index].sz; + return; + } } if (v0 == 21 && num == 5) { UInt32 v4 = Get32(p + 8 + 4 * 4); - for (unsigned i = 0; i < ARRAY_SIZE(sid_21_Names); i++) - if (sid_21_Names[i].n == v4) - { - s += sid_21_Names[i].sz; - return; - } + const int index = FindPairIndex(sid_21_Names, Z7_ARRAY_SIZE(sid_21_Names), v4); + if (index >= 0) + { + s += sid_21_Names[(unsigned)index].sz; + return; + } } if (v0 == 80 && num == 6) { - for (unsigned i = 0; i < ARRAY_SIZE(services_to_name); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(services_to_name); i++) { const CServicesToName &sn = services_to_name[i]; int j; @@ -349,13 +446,9 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize) } } - char sz[16]; s += "S-1-"; if (p[2] == 0 && p[3] == 0) - { - ConvertUInt32ToString(authority, sz); - s += sz; - } + s.Add_UInt32(authority); else { s += "0x"; @@ -364,9 +457,8 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize) } for (UInt32 i = 0; i < num; i++) { - s += '-'; - ConvertUInt32ToString(Get32(p + 8 + i * 4), sz); - s += sz; + s.Add_Minus(); + s.Add_UInt32(Get32(p + 8 + i * 4)); } } @@ -381,20 +473,13 @@ static void ParseOwner(AString &s, const Byte *p, UInt32 size, UInt32 pos) ParseSid(s, p + pos, size - pos, sidSize); } -static void AddUInt32ToString(AString &s, UInt32 val) -{ - char sz[16]; - ConvertUInt32ToString(val, sz); - s += sz; -} - static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName, UInt32 flags, UInt32 offset) { - UInt32 control = Get16(p + 2); + const UInt32 control = Get16(p + 2); if ((flags & control) == 0) return; - UInt32 pos = Get32(p + offset); - s += ' '; + const UInt32 pos = Get32(p + offset); + s.Add_Space(); s += strName; if (pos >= size) return; @@ -404,8 +489,8 @@ static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName return; if (Get16(p) != 2) // revision return; - UInt32 num = Get32(p + 4); - AddUInt32ToString(s, num); + const UInt32 num = Get32(p + 4); + s.Add_UInt32(num); /* UInt32 aclSize = Get16(p + 2); @@ -428,7 +513,7 @@ static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName size -= 8; UInt32 sidSize = 0; - s += ' '; + s.Add_Space(); ParseSid(s, p, size, sidSize); if (sidSize == 0) return; @@ -441,11 +526,16 @@ static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName */ } +/* #define MY_SE_OWNER_DEFAULTED (0x0001) #define MY_SE_GROUP_DEFAULTED (0x0002) +*/ #define MY_SE_DACL_PRESENT (0x0004) +/* #define MY_SE_DACL_DEFAULTED (0x0008) +*/ #define MY_SE_SACL_PRESENT (0x0010) +/* #define MY_SE_SACL_DEFAULTED (0x0020) #define MY_SE_DACL_AUTO_INHERIT_REQ (0x0100) #define MY_SE_SACL_AUTO_INHERIT_REQ (0x0200) @@ -455,6 +545,7 @@ static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName #define MY_SE_SACL_PROTECTED (0x2000) #define MY_SE_RM_CONTROL_VALID (0x4000) #define MY_SE_SELF_RELATIVE (0x8000) +*/ void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s) { @@ -470,12 +561,12 @@ void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s) return; } ParseOwner(s, data, size, Get32(data + 4)); - s += ' '; + s.Add_Space(); ParseOwner(s, data, size, Get32(data + 8)); ParseAcl(s, data, size, "s:", MY_SE_SACL_PRESENT, 12); ParseAcl(s, data, size, "d:", MY_SE_DACL_PRESENT, 16); - s += ' '; - AddUInt32ToString(s, size); + s.Add_Space(); + s.Add_UInt32(size); // s += '\n'; // s += Data_To_Hex(data, size); } @@ -489,26 +580,26 @@ static bool CheckSid(const Byte *data, UInt32 size, UInt32 pos) throw() size -= pos; if (size < 8) return false; - UInt32 rev = data[pos]; + const UInt32 rev = data[pos]; if (rev != 1) return false; - UInt32 num = data[pos + 1]; + const UInt32 num = data[pos + 1]; return (8 + num * 4 <= size); } static bool CheckAcl(const Byte *p, UInt32 size, UInt32 flags, UInt32 offset) throw() { - UInt32 control = Get16(p + 2); + const UInt32 control = Get16(p + 2); if ((flags & control) == 0) return true; - UInt32 pos = Get32(p + offset); + const UInt32 pos = Get32(p + offset); if (pos >= size) return false; p += pos; size -= pos; if (size < 8) return false; - UInt32 aclSize = Get16(p + 2); + const UInt32 aclSize = Get16(p + 2); return (aclSize <= size); } @@ -529,45 +620,121 @@ bool CheckNtSecure(const Byte *data, UInt32 size) throw() #endif + + +// IO_REPARSE_TAG_* + +static const CSecID2Name k_ReparseTags[] = +{ + { 0xA0000003, "MOUNT_POINT" }, + { 0xC0000004, "HSM" }, + { 0x80000005, "DRIVE_EXTENDER" }, + { 0x80000006, "HSM2" }, + { 0x80000007, "SIS" }, + { 0x80000008, "WIM" }, + { 0x80000009, "CSV" }, + { 0x8000000A, "DFS" }, + { 0x8000000B, "FILTER_MANAGER" }, + { 0xA000000C, "SYMLINK" }, + { 0xA0000010, "IIS_CACHE" }, + { 0x80000012, "DFSR" }, + { 0x80000013, "DEDUP" }, + { 0xC0000014, "APPXSTRM" }, + { 0x80000014, "NFS" }, + { 0x80000015, "FILE_PLACEHOLDER" }, + { 0x80000016, "DFM" }, + { 0x80000017, "WOF" }, + { 0x80000018, "WCI" }, + { 0x8000001B, "APPEXECLINK" }, + { 0xA000001D, "LX_SYMLINK" }, + { 0x80000023, "AF_UNIX" }, + { 0x80000024, "LX_FIFO" }, + { 0x80000025, "LX_CHR" }, + { 0x80000026, "LX_BLK" } +}; + bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s) { s.Empty(); NFile::CReparseAttr attr; + if (attr.Parse(data, size)) { - if (!attr.IsSymLink()) - s.AddAscii("Junction: "); - s += attr.GetPath(); - if (!attr.IsOkNamePair()) + if (attr.IsSymLink_WSL()) { - s.AddAscii(" : "); - s += attr.PrintName; + s += "WSL: "; + s += attr.GetPath(); } + else + { + if (!attr.IsSymLink_Win()) + s += "Junction: "; + s += attr.GetPath(); + if (s.IsEmpty()) + s += "Link: "; + if (!attr.IsOkNamePair()) + { + s += " : "; + s += attr.PrintName; + } + } + if (attr.MinorError) + s += " : MINOR_ERROR"; return true; + // s += " "; // for debug } if (size < 8) return false; - UInt32 tag = Get32(data); - UInt32 len = Get16(data + 4); + const UInt32 tag = Get32(data); + const UInt32 len = Get16(data + 4); if (len + 8 > size) return false; if (Get16(data + 6) != 0) // padding return false; - char hex[16]; - ConvertUInt32ToHex8Digits(tag, hex); - s.AddAscii(hex); - s.Add_Space(); + /* + #define my_IO_REPARSE_TAG_DEDUP (0x80000013L) + if (tag == my_IO_REPARSE_TAG_DEDUP) + { + } + */ + + { + const int index = FindPairIndex(k_ReparseTags, Z7_ARRAY_SIZE(k_ReparseTags), tag); + if (index >= 0) + s += k_ReparseTags[(unsigned)index].sz; + else + { + s += "REPARSE:"; + char hex[16]; + ConvertUInt32ToHex8Digits(tag, hex); + s += hex; + } + } - data += 8; + s += ":"; + s.Add_UInt32(len); - for (UInt32 i = 0; i < len; i++) + if (len != 0) { - unsigned b = ((const Byte *)data)[i]; - s += (wchar_t)GetHex((b >> 4) & 0xF); - s += (wchar_t)GetHex(b & 0xF); + s.Add_Space(); + + data += 8; + + for (UInt32 i = 0; i < len; i++) + { + if (i >= 16) + { + s += "..."; + break; + } + const unsigned b = data[i]; + s += (char)GetHex((b >> 4) & 0xF); + s += (char)GetHex(b & 0xF); + } } + return true; } |